[Libreoffice-commits] core.git: include/vcl sd/source vcl/source

Miklos Vajna vmiklos at collabora.co.uk
Wed Jan 4 16:28:07 UTC 2017


 include/vcl/pdfextoutdevdata.hxx    |    4 +-
 include/vcl/pdfwriter.hxx           |    2 +
 sd/source/ui/unoidl/unomodel.cxx    |    9 ++++-
 vcl/source/gdi/pdfextoutdevdata.cxx |   16 +++++++++
 vcl/source/gdi/pdfwriter.cxx        |    5 +++
 vcl/source/gdi/pdfwriter_impl.cxx   |   60 ++++++++++++++++++++++++++++++++----
 vcl/source/gdi/pdfwriter_impl.hxx   |   11 ++++++
 7 files changed, 99 insertions(+), 8 deletions(-)

New commits:
commit 4ad249af88d15f2c8a09f0721a59d82718fcc201
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Jan 4 15:28:41 2017 +0100

    tdf#105093 sd PDF export: handle embedded videos
    
    In practie embedded files always have a temp file URL, so from the PDF
    export's point of view they are still URLs, just at the end the contents
    of the URL is embedded to the PDF, not just the URL itself.
    
    So add a SetScreenStream() that's similar to SetScreenURL(), but it's
    for embedded, not linked videos.
    
    Change-Id: Ifcc60357ef0f5fed0bdec02e0c84cb16ee147781
    Reviewed-on: https://gerrit.libreoffice.org/32727
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/include/vcl/pdfextoutdevdata.hxx b/include/vcl/pdfextoutdevdata.hxx
index e3a05d9..566ff2a 100644
--- a/include/vcl/pdfextoutdevdata.hxx
+++ b/include/vcl/pdfextoutdevdata.hxx
@@ -298,8 +298,10 @@ public:
     */
     sal_Int32 SetLinkURL( sal_Int32 nLinkId, const OUString& rURL );
 
-    /// Set URL for a Screen annotation.
+    /// Set URL for a linked Screen annotation.
     void SetScreenURL(sal_Int32 nScreenId, const OUString& rURL);
+    /// Set URL for an embedded Screen annotation.
+    void SetScreenStream(sal_Int32 nScreenId, const OUString& rURL);
 
     /** Create a new outline item
 
diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index 888cddb..29aecc7 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -979,6 +979,8 @@ The following structure describes the permissions used in PDF security
 
     /// Sets the URL of a linked screen annotation.
     void SetScreenURL(sal_Int32 nScreenId, const OUString& rURL);
+    /// Sets the URL of an embedded screen annotation.
+    void SetScreenStream(sal_Int32 nScreenId, const OUString& rURL);
 
     /** Resolve link in logical structure
 
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index 073e70d..d305a29 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -1660,7 +1660,14 @@ void ImplPDFExportShapeInteraction( const uno::Reference< drawing::XShape >& xSh
                 if (!aMediaURL.isEmpty())
                 {
                     sal_Int32 nScreenId = rPDFExtOutDevData.CreateScreen(aLinkRect, rPDFExtOutDevData.GetCurrentPageNumber());
-                    rPDFExtOutDevData.SetScreenURL(nScreenId, aMediaURL);
+                    if (aMediaURL.startsWith("vnd.sun.star.Package:"))
+                    {
+                        OUString aTempFileURL;
+                        xShapePropSet->getPropertyValue("PrivateTempFileURL") >>= aTempFileURL;
+                        rPDFExtOutDevData.SetScreenStream(nScreenId, aTempFileURL);
+                    }
+                    else
+                        rPDFExtOutDevData.SetScreenURL(nScreenId, aMediaURL);
                 }
             }
 
diff --git a/vcl/source/gdi/pdfextoutdevdata.cxx b/vcl/source/gdi/pdfextoutdevdata.cxx
index 0649b45..386e6837 100644
--- a/vcl/source/gdi/pdfextoutdevdata.cxx
+++ b/vcl/source/gdi/pdfextoutdevdata.cxx
@@ -40,6 +40,7 @@ struct PDFExtOutDevDataSync
                     SetLinkDest,
                     SetLinkURL,
                     SetScreenURL,
+                    SetScreenStream,
                     RegisterDest,
                     CreateOutlineItem,
                     SetOutlineItemParent,
@@ -217,6 +218,13 @@ void GlobalSyncData::PlayGlobalActions( PDFWriter& rWriter )
                 mParaOUStrings.pop_front();
             }
             break;
+            case PDFExtOutDevDataSync::SetScreenStream:
+            {
+                sal_Int32 nScreenId = GetMappedId();
+                rWriter.SetScreenStream(nScreenId, mParaOUStrings.front());
+                mParaOUStrings.pop_front();
+            }
+            break;
             case PDFExtOutDevDataSync::RegisterDest :
             {
                 const sal_Int32 nDestId = mParaInts.front();
@@ -518,6 +526,7 @@ bool PageSyncData::PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAc
             case PDFExtOutDevDataSync::SetLinkDest:
             case PDFExtOutDevDataSync::SetLinkURL:
             case PDFExtOutDevDataSync::SetScreenURL:
+            case PDFExtOutDevDataSync::SetScreenStream:
             case PDFExtOutDevDataSync::RegisterDest:
             case PDFExtOutDevDataSync::CreateOutlineItem:
             case PDFExtOutDevDataSync::SetOutlineItemParent:
@@ -726,6 +735,13 @@ void PDFExtOutDevData::SetScreenURL(sal_Int32 nScreenId, const OUString& rURL)
     mpGlobalSyncData->mParaOUStrings.push_back(rURL);
 }
 
+void PDFExtOutDevData::SetScreenStream(sal_Int32 nScreenId, const OUString& rURL)
+{
+    mpGlobalSyncData->mActions.push_back(PDFExtOutDevDataSync::SetScreenStream);
+    mpGlobalSyncData->mParaInts.push_back(nScreenId);
+    mpGlobalSyncData->mParaOUStrings.push_back(rURL);
+}
+
 sal_Int32 PDFExtOutDevData::CreateOutlineItem( sal_Int32 nParent, const OUString& rText, sal_Int32 nDestID )
 {
     mpGlobalSyncData->mActions.push_back( PDFExtOutDevDataSync::CreateOutlineItem );
diff --git a/vcl/source/gdi/pdfwriter.cxx b/vcl/source/gdi/pdfwriter.cxx
index 7463e77..cda66dd 100644
--- a/vcl/source/gdi/pdfwriter.cxx
+++ b/vcl/source/gdi/pdfwriter.cxx
@@ -378,6 +378,11 @@ void PDFWriter::SetScreenURL(sal_Int32 nScreenId, const OUString& rURL)
     xImplementation->setScreenURL(nScreenId, rURL);
 }
 
+void PDFWriter::SetScreenStream(sal_Int32 nScreenId, const OUString& rURL)
+{
+    xImplementation->setScreenStream(nScreenId, rURL);
+}
+
 void PDFWriter::SetLinkPropertyID( sal_Int32 nLinkId, sal_Int32 nPropertyId )
 {
     xImplementation->setLinkPropertyId( nLinkId, nPropertyId );
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 83672f1..d1987dc 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -3772,11 +3772,38 @@ bool PDFWriterImpl::emitScreenAnnotations()
     for (int i = 0; i < nAnnots; i++)
     {
         const PDFScreen& rScreen = m_aScreens[i];
+
+        OStringBuffer aLine;
+        bool bEmbed = false;
+        if (!rScreen.m_aTempFileURL.isEmpty())
+        {
+            bEmbed = true;
+            if (!updateObject(rScreen.m_nTempFileObject))
+                continue;
+
+            SvFileStream aFileStream(rScreen.m_aTempFileURL, StreamMode::READ);
+            SvMemoryStream aMemoryStream;
+            aMemoryStream.WriteStream(aFileStream);
+
+            aLine.append(rScreen.m_nTempFileObject);
+            aLine.append(" 0 obj\n");
+            aLine.append("<< /Type /EmbeddedFile /Length ");
+            aLine.append(static_cast<sal_Int64>(aMemoryStream.GetSize()));
+            aLine.append(" >>\nstream\n");
+            CHECK_RETURN(writeBuffer(aLine.getStr(), aLine.getLength()));
+            aLine.setLength(0);
+
+            CHECK_RETURN(writeBuffer(aMemoryStream.GetData(), aMemoryStream.GetSize()));
+
+            aLine.append("\nendstream\nendobj\n\n");
+            CHECK_RETURN(writeBuffer(aLine.getStr(), aLine.getLength()));
+            aLine.setLength(0);
+        }
+
         if (!updateObject(rScreen.m_nObject))
             continue;
 
         // Annot dictionary.
-        OStringBuffer aLine;
         aLine.append(rScreen.m_nObject);
         aLine.append(" 0 obj\n");
         aLine.append("<</Type/Annot");
@@ -3800,11 +3827,23 @@ bool PDFWriterImpl::emitScreenAnnotations()
 
         // MediaClip dictionary.
         aLine.append("/C<</Type/MediaClip /S/MCD ");
-        aLine.append("/D << /FS /URL /Type /Filespec /F ");
-        appendLiteralStringEncrypt(rScreen.m_aURL, rScreen.m_nObject, aLine, osl_getThreadTextEncoding());
-        aLine.append(" >>");
-        // Is there anything Acrobat supports natively other than this?
-        aLine.append("/CT (video/mpeg)");
+        if (bEmbed)
+        {
+            aLine.append("/D << /Type /Filespec /F (<embedded file>) /EF << /F ");
+            aLine.append(rScreen.m_nTempFileObject);
+            aLine.append(" 0 R >> >>");
+        }
+        else
+        {
+            // Linked.
+            aLine.append("/D << /Type /Filespec /FS /URL /F ");
+            appendLiteralStringEncrypt(rScreen.m_aURL, rScreen.m_nObject, aLine, osl_getThreadTextEncoding());
+            aLine.append(" >>");
+        }
+        // Allow playing the video via a tempfile.
+        aLine.append("/P <</TF (TEMPACCESS)>>");
+        // Until the real MIME type (instead of application/vnd.sun.star.media) is available here.
+        aLine.append("/CT (video/mp4)");
         aLine.append(">>");
 
         // End Rendition dictionary by requesting play/pause/stop controls.
@@ -11986,6 +12025,15 @@ void PDFWriterImpl::setScreenURL(sal_Int32 nScreenId, const OUString& rURL)
     m_aScreens[nScreenId].m_aURL = rURL;
 }
 
+void PDFWriterImpl::setScreenStream(sal_Int32 nScreenId, const OUString& rURL)
+{
+    if (nScreenId < 0 || nScreenId >= static_cast<sal_Int32>(m_aScreens.size()))
+        return;
+
+    m_aScreens[nScreenId].m_aTempFileURL = rURL;
+    m_aScreens[nScreenId].m_nTempFileObject = createObject();
+}
+
 void PDFWriterImpl::setLinkPropertyId( sal_Int32 nLinkId, sal_Int32 nPropertyId )
 {
     m_aLinkPropertyMap[ nPropertyId ] = nLinkId;
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index 8f9a9d6..b50dc4d 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -417,7 +417,17 @@ public:
     /// A PDF Screen annotation.
     struct PDFScreen : public PDFAnnotation
     {
+        /// Linked video.
         OUString m_aURL;
+        /// Embedded video.
+        OUString m_aTempFileURL;
+        /// ID of the EmbeddedFile object.
+        sal_Int32 m_nTempFileObject;
+
+        PDFScreen()
+            : m_nTempFileObject(0)
+        {
+        }
     };
 
     struct PDFNoteEntry : public PDFAnnotation
@@ -1202,6 +1212,7 @@ public:
     // screens
     sal_Int32 createScreen(const Rectangle& rRect, sal_Int32 nPageNr);
     void setScreenURL(sal_Int32 nScreenId, const OUString& rURL);
+    void setScreenStream(sal_Int32 nScreenId, const OUString& rURL);
 
     // outline
     sal_Int32 createOutlineItem( sal_Int32 nParent, const OUString& rText, sal_Int32 nDestID );


More information about the Libreoffice-commits mailing list