[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.3' - 7 commits - include/vcl sd/source sw/source vcl/source

Miklos Vajna vmiklos at collabora.co.uk
Tue Mar 14 09:07:37 UTC 2017


 include/vcl/pdfextoutdevdata.hxx                |   10 +
 include/vcl/pdfwriter.hxx                       |    9 +
 sd/source/ui/unoidl/unomodel.cxx                |   19 +++
 sw/source/core/text/EnhancedPDFExportHelper.cxx |   43 ++++++-
 vcl/source/gdi/pdfextoutdevdata.cxx             |   56 +++++++++
 vcl/source/gdi/pdfwriter.cxx                    |   16 ++
 vcl/source/gdi/pdfwriter_impl.cxx               |  146 ++++++++++++++++++++++++
 vcl/source/gdi/pdfwriter_impl.hxx               |   37 ++++--
 8 files changed, 323 insertions(+), 13 deletions(-)

New commits:
commit 8012b806c545f9c1e9a37205848adca7db66a2e6
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Jan 5 10:55:57 2017 +0100

    Related: tdf#105093 sw PDF export: handle embedded videos
    
    Use vcl::PDFExtOutDevData::SetScreenStream() for embedded media to make
    sure that vnd.sun.star.Package: URLs don't end up in PDF out literally.
    Acrobat Reader obviously doesn't understand that protocol.
    
    Change-Id: I384891b3ef2dcea25bbf591bd210ccf899d30a61
    (cherry picked from commit 46153bdcf2f89e88607dfb0dd0003108796424e9)

diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index ce971f3..993935d 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -1813,7 +1813,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
             }
             else if (pFrameFormat->Which() == RES_DRAWFRMFMT)
             {
-                // Handle linked videos.
+                // Turn media shapes into Screen annotations.
                 if (SdrObject* pObject = pFrameFormat->FindRealSdrObject())
                 {
                     SwRect aSnapRect = pObject->GetSnapRect();
@@ -1834,7 +1834,16 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                             for (sal_Int32 nScreenPageNum : aScreenPageNums)
                             {
                                 sal_Int32 nScreenId = pPDFExtOutDevData->CreateScreen(aPDFRect, nScreenPageNum);
-                                pPDFExtOutDevData->SetScreenURL(nScreenId, aMediaURL);
+                                if (aMediaURL.startsWith("vnd.sun.star.Package:"))
+                                {
+                                    // Embedded media.
+                                    OUString aTempFileURL;
+                                    xShapePropSet->getPropertyValue("PrivateTempFileURL") >>= aTempFileURL;
+                                    pPDFExtOutDevData->SetScreenStream(nScreenId, aTempFileURL);
+                                }
+                                else
+                                    // Linked media.
+                                    pPDFExtOutDevData->SetScreenURL(nScreenId, aMediaURL);
                             }
                         }
                     }
commit 35941f2d670a6b197980f226343419cdd729560d
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Jan 4 17:41:07 2017 +0100

    Related: tdf#105093 sd PDF export: handle css.presentation.MediaShape as well
    
    It's exactly the same as css.drawing.MediaShape in this context.
    
    Change-Id: I4be114ef731e85222f0dd1d897f646ad8da3849d
    (cherry picked from commit 64d80d22851a38eb3f320f4e2b2bdf875da4d8b4)

diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index c71b4b7..7791e41 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -1669,7 +1669,7 @@ void ImplPDFExportShapeInteraction( const uno::Reference< drawing::XShape >& xSh
             Rectangle   aLinkRect( Point( aShapePos.X, aShapePos.Y ), Size( aShapeSize.Width, aShapeSize.Height ) );
 
             // Handle linked videos.
-            if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape")
+            if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape" || xShape->getShapeType() == "com.sun.star.presentation.MediaShape")
             {
                 OUString aMediaURL;
                 xShapePropSet->getPropertyValue("MediaURL") >>= aMediaURL;
commit 62ae0997ac331dea2cc7837ca2320cf49d3eb6b3
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>
    (cherry picked from commit 4ad249af88d15f2c8a09f0721a59d82718fcc201)

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 2c2f8a2..5d4ce70 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -980,6 +980,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 ebc0c31..c71b4b7 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -1676,7 +1676,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 25f245d..961e9d3 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -4424,11 +4424,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");
@@ -4452,11 +4479,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.
@@ -12791,6 +12830,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 fa8244e..328752d 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -398,7 +398,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
@@ -1195,6 +1205,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 );
commit 7ec4d95702ecf94b47ef3c48e0059280eb7f100c
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Jan 3 15:41:58 2017 +0100

    Related: tdf#104841 sw PDF export: handle linked videos on non-first pages
    
    Be explicit about the page number, this way a video on the second page
    doesn't end up as an annotation for the first page. (In the Impress case
    each slide is exported separately, so there this wasn't a problem.)
    
    Change-Id: I83ba9cb4a3b2a6734bd88a138654e391199651c6
    Reviewed-on: https://gerrit.libreoffice.org/32696
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 0e71075bb7379af318482bb3abbb630c58db9ec9)

diff --git a/include/vcl/pdfextoutdevdata.hxx b/include/vcl/pdfextoutdevdata.hxx
index 1a0c941..e3a05d9 100644
--- a/include/vcl/pdfextoutdevdata.hxx
+++ b/include/vcl/pdfextoutdevdata.hxx
@@ -264,7 +264,7 @@ public:
     sal_Int32 CreateLink( const Rectangle& rRect, sal_Int32 nPageNr = -1 );
 
     /// Create a Screen annotation.
-    sal_Int32 CreateScreen(const Rectangle& rRect);
+    sal_Int32 CreateScreen(const Rectangle& rRect, sal_Int32 nPageNr);
 
     /** Set the destination for a link
         <p>will change a URL type link to a dest link if necessary</p>
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index 338df9a..ebc0c31 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -1675,7 +1675,7 @@ void ImplPDFExportShapeInteraction( const uno::Reference< drawing::XShape >& xSh
                 xShapePropSet->getPropertyValue("MediaURL") >>= aMediaURL;
                 if (!aMediaURL.isEmpty())
                 {
-                    sal_Int32 nScreenId = rPDFExtOutDevData.CreateScreen(aLinkRect);
+                    sal_Int32 nScreenId = rPDFExtOutDevData.CreateScreen(aLinkRect, rPDFExtOutDevData.GetCurrentPageNumber());
                     rPDFExtOutDevData.SetScreenURL(nScreenId, aMediaURL);
                 }
             }
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index 8a0b2ac..ce971f3 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -1831,8 +1831,11 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                         {
                             const SwPageFrame* pCurrPage = mrSh.GetLayout()->GetPageAtPos(aSnapRect.Center());
                             Rectangle aPDFRect(SwRectToPDFRect(pCurrPage, aSnapRect.SVRect()));
-                            sal_Int32 nScreenId = pPDFExtOutDevData->CreateScreen(aPDFRect);
-                            pPDFExtOutDevData->SetScreenURL(nScreenId, aMediaURL);
+                            for (sal_Int32 nScreenPageNum : aScreenPageNums)
+                            {
+                                sal_Int32 nScreenId = pPDFExtOutDevData->CreateScreen(aPDFRect, nScreenPageNum);
+                                pPDFExtOutDevData->SetScreenURL(nScreenId, aMediaURL);
+                            }
                         }
                     }
                 }
diff --git a/vcl/source/gdi/pdfextoutdevdata.cxx b/vcl/source/gdi/pdfextoutdevdata.cxx
index f85c981..0649b45 100644
--- a/vcl/source/gdi/pdfextoutdevdata.cxx
+++ b/vcl/source/gdi/pdfextoutdevdata.cxx
@@ -695,12 +695,12 @@ sal_Int32 PDFExtOutDevData::CreateLink( const Rectangle& rRect, sal_Int32 nPageN
     return mpGlobalSyncData->mCurId++;
 }
 
-sal_Int32 PDFExtOutDevData::CreateScreen(const Rectangle& rRect)
+sal_Int32 PDFExtOutDevData::CreateScreen(const Rectangle& rRect, sal_Int32 nPageNr)
 {
     mpGlobalSyncData->mActions.push_back(PDFExtOutDevDataSync::CreateScreen);
     mpGlobalSyncData->mParaRects.push_back(rRect);
     mpGlobalSyncData->mParaMapModes.push_back(mrOutDev.GetMapMode());
-    mpGlobalSyncData->mParaInts.push_back(mnPage);
+    mpGlobalSyncData->mParaInts.push_back(nPageNr);
     return mpGlobalSyncData->mCurId++;
 }
 
commit 23bdcd6247675da0bb1f455177441a28f8200c83
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Jan 3 12:06:56 2017 +0100

    Related: tdf#104841 sw PDF export: handle linked videos
    
    This is the sw-specific part only, the real work is done by the common
    CreateScreen() / SetScreenURL() API added for sd earlier.
    
    Change-Id: Ief9fd80082960ddd1f92f413eac79577621551ce
    Reviewed-on: https://gerrit.libreoffice.org/32687
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 81aef113056270ce65f9dee5fe31b6f60617973c)

diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index 7780321..8a0b2ac 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -75,6 +75,7 @@
 #include <stack>
 
 #include <tools/globname.hxx>
+#include <svx/svdobj.hxx>
 
 using namespace ::com::sun::star;
 
@@ -1735,11 +1736,11 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
 
         // HYPERLINKS (Graphics, Frames, OLEs )
 
-        const SwFrameFormats* pTable = pDoc->GetSpzFrameFormats();
+        SwFrameFormats* pTable = pDoc->GetSpzFrameFormats();
         const size_t nSpzFrameFormatsCount = pTable->size();
         for( size_t n = 0; n < nSpzFrameFormatsCount; ++n )
         {
-            const SwFrameFormat* pFrameFormat = (*pTable)[n];
+            SwFrameFormat* pFrameFormat = (*pTable)[n];
             const SfxPoolItem* pItem;
             if ( RES_DRAWFRMFMT != pFrameFormat->Which() &&
                  SfxItemState::SET == pFrameFormat->GetAttrSet().GetItemState( RES_URL, true, &pItem ) )
@@ -1810,6 +1811,32 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                     }
                 }
             }
+            else if (pFrameFormat->Which() == RES_DRAWFRMFMT)
+            {
+                // Handle linked videos.
+                if (SdrObject* pObject = pFrameFormat->FindRealSdrObject())
+                {
+                    SwRect aSnapRect = pObject->GetSnapRect();
+                    std::vector<sal_Int32> aScreenPageNums = CalcOutputPageNums(aSnapRect);
+                    if (aScreenPageNums.empty())
+                        continue;
+
+                    uno::Reference<drawing::XShape> xShape(pObject->getUnoShape(), uno::UNO_QUERY);
+                    if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape")
+                    {
+                        uno::Reference<beans::XPropertySet> xShapePropSet(xShape, uno::UNO_QUERY);
+                        OUString aMediaURL;
+                        xShapePropSet->getPropertyValue("MediaURL") >>= aMediaURL;
+                        if (!aMediaURL.isEmpty())
+                        {
+                            const SwPageFrame* pCurrPage = mrSh.GetLayout()->GetPageAtPos(aSnapRect.Center());
+                            Rectangle aPDFRect(SwRectToPDFRect(pCurrPage, aSnapRect.SVRect()));
+                            sal_Int32 nScreenId = pPDFExtOutDevData->CreateScreen(aPDFRect);
+                            pPDFExtOutDevData->SetScreenURL(nScreenId, aMediaURL);
+                        }
+                    }
+                }
+            }
             mrSh.SwCursorShell::ClearMark();
         }
 
commit f96f3ccdeedf0ab488cc2b9fba4a63218d6ba6c0
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Mon Jan 2 17:28:57 2017 +0100

    tdf#104841 sd PDF export: handle linked videos
    
    Use the screen annotation markup for this purpose.
    
    Change-Id: I129111cbe08c19c2f3b3ae046408ff9b2a28520c
    Reviewed-on: https://gerrit.libreoffice.org/32654
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 9d6a749bc664f1876c938afb9eba4adc9f6ee09a)

diff --git a/include/vcl/pdfextoutdevdata.hxx b/include/vcl/pdfextoutdevdata.hxx
index 7095b90..1a0c941 100644
--- a/include/vcl/pdfextoutdevdata.hxx
+++ b/include/vcl/pdfextoutdevdata.hxx
@@ -262,6 +262,10 @@ public:
     -1 if page id does not exist
     */
     sal_Int32 CreateLink( const Rectangle& rRect, sal_Int32 nPageNr = -1 );
+
+    /// Create a Screen annotation.
+    sal_Int32 CreateScreen(const Rectangle& rRect);
+
     /** Set the destination for a link
         <p>will change a URL type link to a dest link if necessary</p>
 
@@ -293,6 +297,10 @@ public:
         -1 in case the link id does not exist
     */
     sal_Int32 SetLinkURL( sal_Int32 nLinkId, const OUString& rURL );
+
+    /// Set URL for a Screen annotation.
+    void SetScreenURL(sal_Int32 nScreenId, const OUString& rURL);
+
     /** Create a new outline item
 
         @param nParent
diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index 8db01f8..2c2f8a2 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -928,6 +928,9 @@ The following structure describes the permissions used in PDF security
     */
     sal_Int32           CreateLink( const Rectangle& rRect, sal_Int32 nPageNr );
 
+    /// Creates a screen annotation.
+    sal_Int32 CreateScreen(const Rectangle& rRect, sal_Int32 nPageNr);
+
     /** creates a destination which is not intended to be referred to by a link, but by a public destination Id.
 
         Form widgets, for instance, might refer to a destination, without ever actually creating a source link to
@@ -974,6 +977,10 @@ The following structure describes the permissions used in PDF security
         service; the result will then appear literally in the PDF file produced
     */
     void           SetLinkURL( sal_Int32 nLinkId, const OUString& rURL );
+
+    /// Sets the URL of a linked screen annotation.
+    void SetScreenURL(sal_Int32 nScreenId, const OUString& rURL);
+
     /** Resolve link in logical structure
 
         If a link is created after the corresponding visual appearance was drawn
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index 3199294..338df9a 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -1668,6 +1668,18 @@ void ImplPDFExportShapeInteraction( const uno::Reference< drawing::XShape >& xSh
             awt::Size   aShapeSize( xShape->getSize() );
             Rectangle   aLinkRect( Point( aShapePos.X, aShapePos.Y ), Size( aShapeSize.Width, aShapeSize.Height ) );
 
+            // Handle linked videos.
+            if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape")
+            {
+                OUString aMediaURL;
+                xShapePropSet->getPropertyValue("MediaURL") >>= aMediaURL;
+                if (!aMediaURL.isEmpty())
+                {
+                    sal_Int32 nScreenId = rPDFExtOutDevData.CreateScreen(aLinkRect);
+                    rPDFExtOutDevData.SetScreenURL(nScreenId, aMediaURL);
+                }
+            }
+
             presentation::ClickAction eCa;
             uno::Any aAny( xShapePropSet->getPropertyValue( "OnClick" ) );
             if ( aAny >>= eCa )
diff --git a/vcl/source/gdi/pdfextoutdevdata.cxx b/vcl/source/gdi/pdfextoutdevdata.cxx
index 73d9232..f85c981 100644
--- a/vcl/source/gdi/pdfextoutdevdata.cxx
+++ b/vcl/source/gdi/pdfextoutdevdata.cxx
@@ -36,8 +36,10 @@ struct PDFExtOutDevDataSync
     enum Action{    CreateNamedDest,
                     CreateDest,
                     CreateLink,
+                    CreateScreen,
                     SetLinkDest,
                     SetLinkURL,
+                    SetScreenURL,
                     RegisterDest,
                     CreateOutlineItem,
                     SetOutlineItemParent,
@@ -183,6 +185,17 @@ void GlobalSyncData::PlayGlobalActions( PDFWriter& rWriter )
                 rWriter.Pop();
             }
             break;
+            case PDFExtOutDevDataSync::CreateScreen:
+            {
+                rWriter.Push(PushFlags::MAPMODE);
+                rWriter.SetMapMode(mParaMapModes.front());
+                mParaMapModes.pop_front();
+                mParaIds.push_back(rWriter.CreateScreen(mParaRects.front(), mParaInts.front()));
+                mParaRects.pop_front();
+                mParaInts.pop_front();
+                rWriter.Pop();
+            }
+            break;
             case PDFExtOutDevDataSync::SetLinkDest :
             {
                 sal_Int32 nLinkId = GetMappedId();
@@ -197,6 +210,13 @@ void GlobalSyncData::PlayGlobalActions( PDFWriter& rWriter )
                 mParaOUStrings.pop_front();
             }
             break;
+            case PDFExtOutDevDataSync::SetScreenURL:
+            {
+                sal_Int32 nScreenId = GetMappedId();
+                rWriter.SetScreenURL(nScreenId, mParaOUStrings.front());
+                mParaOUStrings.pop_front();
+            }
+            break;
             case PDFExtOutDevDataSync::RegisterDest :
             {
                 const sal_Int32 nDestId = mParaInts.front();
@@ -494,8 +514,10 @@ bool PageSyncData::PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAc
             case PDFExtOutDevDataSync::CreateNamedDest:
             case PDFExtOutDevDataSync::CreateDest:
             case PDFExtOutDevDataSync::CreateLink:
+            case PDFExtOutDevDataSync::CreateScreen:
             case PDFExtOutDevDataSync::SetLinkDest:
             case PDFExtOutDevDataSync::SetLinkURL:
+            case PDFExtOutDevDataSync::SetScreenURL:
             case PDFExtOutDevDataSync::RegisterDest:
             case PDFExtOutDevDataSync::CreateOutlineItem:
             case PDFExtOutDevDataSync::SetOutlineItemParent:
@@ -672,6 +694,16 @@ sal_Int32 PDFExtOutDevData::CreateLink( const Rectangle& rRect, sal_Int32 nPageN
     mpGlobalSyncData->mParaInts.push_back( nPageNr == -1 ? mnPage : nPageNr );
     return mpGlobalSyncData->mCurId++;
 }
+
+sal_Int32 PDFExtOutDevData::CreateScreen(const Rectangle& rRect)
+{
+    mpGlobalSyncData->mActions.push_back(PDFExtOutDevDataSync::CreateScreen);
+    mpGlobalSyncData->mParaRects.push_back(rRect);
+    mpGlobalSyncData->mParaMapModes.push_back(mrOutDev.GetMapMode());
+    mpGlobalSyncData->mParaInts.push_back(mnPage);
+    return mpGlobalSyncData->mCurId++;
+}
+
 sal_Int32 PDFExtOutDevData::SetLinkDest( sal_Int32 nLinkId, sal_Int32 nDestId )
 {
     mpGlobalSyncData->mActions.push_back( PDFExtOutDevDataSync::SetLinkDest );
@@ -686,6 +718,14 @@ sal_Int32 PDFExtOutDevData::SetLinkURL( sal_Int32 nLinkId, const OUString& rURL
     mpGlobalSyncData->mParaOUStrings.push_back( rURL );
     return 0;
 }
+
+void PDFExtOutDevData::SetScreenURL(sal_Int32 nScreenId, const OUString& rURL)
+{
+    mpGlobalSyncData->mActions.push_back(PDFExtOutDevDataSync::SetScreenURL);
+    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 741df80..7463e77 100644
--- a/vcl/source/gdi/pdfwriter.cxx
+++ b/vcl/source/gdi/pdfwriter.cxx
@@ -343,6 +343,12 @@ sal_Int32 PDFWriter::CreateLink( const Rectangle& rRect, sal_Int32 nPageNr )
 {
     return xImplementation->createLink( rRect, nPageNr );
 }
+
+sal_Int32 PDFWriter::CreateScreen(const Rectangle& rRect, sal_Int32 nPageNr)
+{
+    return xImplementation->createScreen(rRect, nPageNr);
+}
+
 sal_Int32 PDFWriter::RegisterDestReference( sal_Int32 nDestId, const Rectangle& rRect, sal_Int32 nPageNr, DestAreaType eType )
 {
     return xImplementation->registerDestReference( nDestId, rRect, nPageNr, eType );
@@ -367,6 +373,11 @@ void PDFWriter::SetLinkURL( sal_Int32 nLinkId, const OUString& rURL )
     xImplementation->setLinkURL( nLinkId, rURL );
 }
 
+void PDFWriter::SetScreenURL(sal_Int32 nScreenId, const OUString& rURL)
+{
+    xImplementation->setScreenURL(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 34d5e34..25f245d 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -104,6 +104,7 @@
 #endif
 
 using namespace vcl;
+using namespace::com::sun::star;
 
 static bool g_bDebugDisableCompression = getenv("VCL_DEBUG_DISABLE_PDFCOMPRESSION");
 
@@ -4417,6 +4418,64 @@ bool PDFWriterImpl::appendDest( sal_Int32 nDestID, OStringBuffer& rBuffer )
     return true;
 }
 
+bool PDFWriterImpl::emitScreenAnnotations()
+{
+    int nAnnots = m_aScreens.size();
+    for (int i = 0; i < nAnnots; i++)
+    {
+        const PDFScreen& rScreen = m_aScreens[i];
+        if (!updateObject(rScreen.m_nObject))
+            continue;
+
+        // Annot dictionary.
+        OStringBuffer aLine;
+        aLine.append(rScreen.m_nObject);
+        aLine.append(" 0 obj\n");
+        aLine.append("<</Type/Annot");
+        aLine.append("/Subtype/Screen/Rect[");
+        appendFixedInt(rScreen.m_aRect.Left(), aLine);
+        aLine.append(' ');
+        appendFixedInt(rScreen.m_aRect.Top(), aLine);
+        aLine.append(' ');
+        appendFixedInt(rScreen.m_aRect.Right(), aLine);
+        aLine.append(' ');
+        appendFixedInt(rScreen.m_aRect.Bottom(), aLine);
+        aLine.append("]");
+
+        // Action dictionary.
+        aLine.append("/A<</Type/Action /S/Rendition /AN ");
+        aLine.append(rScreen.m_nObject);
+        aLine.append(" 0 R ");
+
+        // Rendition dictionary.
+        aLine.append("/R<</Type/Rendition /S/MR ");
+
+        // 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)");
+        aLine.append(">>");
+
+        // End Rendition dictionary by requesting play/pause/stop controls.
+        aLine.append("/P<</BE<</C true >>>>");
+        aLine.append(">>");
+
+        // End Action dictionary.
+        aLine.append("/OP 0 >>");
+
+        // End Annot dictionary.
+        aLine.append("/P ");
+        aLine.append(m_aPages[rScreen.m_nPage].m_nPageObject);
+        aLine.append(" 0 R\n>>\nendobj\n\n");
+        CHECK_RETURN(writeBuffer(aLine.getStr(), aLine.getLength()));
+    }
+
+    return true;
+}
+
 bool PDFWriterImpl::emitLinkAnnotations()
 {
     int nAnnots = m_aLinks.size();
@@ -5547,6 +5606,7 @@ bool PDFWriterImpl::emitAnnotations()
         return false;
 
     CHECK_RETURN( emitLinkAnnotations() );
+    CHECK_RETURN(emitScreenAnnotations());
     CHECK_RETURN( emitNoteAnnotations() );
     CHECK_RETURN( emitWidgetAnnotations() );
 
@@ -12619,6 +12679,29 @@ sal_Int32 PDFWriterImpl::createLink( const Rectangle& rRect, sal_Int32 nPageNr )
     return nRet;
 }
 
+sal_Int32 PDFWriterImpl::createScreen(const Rectangle& rRect, sal_Int32 nPageNr)
+{
+    if (nPageNr < 0)
+        nPageNr = m_nCurrentPage;
+
+    if (nPageNr < 0 || nPageNr >= static_cast<sal_Int32>(m_aPages.size()))
+        return -1;
+
+    sal_Int32 nRet = m_aScreens.size();
+
+    m_aScreens.push_back(PDFScreen());
+    m_aScreens.back().m_nObject = createObject();
+    m_aScreens.back().m_nPage = nPageNr;
+    m_aScreens.back().m_aRect = rRect;
+    // Convert to default user space now, since the mapmode may change.
+    m_aPages[nPageNr].convertRect(m_aScreens.back().m_aRect);
+
+    // Insert link to page's annotation list.
+    m_aPages[nPageNr].m_aAnnotations.push_back(m_aScreens.back().m_nObject);
+
+    return nRet;
+}
+
 //--->i56629
 sal_Int32 PDFWriterImpl::createNamedDest( const OUString& sDestName, const Rectangle& rRect, sal_Int32 nPageNr, PDFWriter::DestAreaType eType )
 {
@@ -12700,6 +12783,14 @@ void PDFWriterImpl::setLinkURL( sal_Int32 nLinkId, const OUString& rURL )
     m_aLinks[ nLinkId ].m_aURL  = aURL.Complete;
 }
 
+void PDFWriterImpl::setScreenURL(sal_Int32 nScreenId, const OUString& rURL)
+{
+    if (nScreenId < 0 || nScreenId >= static_cast<sal_Int32>(m_aScreens.size()))
+        return;
+
+    m_aScreens[nScreenId].m_aURL = rURL;
+}
+
 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 de2327d..fa8244e 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -395,6 +395,12 @@ public:
         {}
     };
 
+    /// A PDF Screen annotation.
+    struct PDFScreen : public PDFAnnotation
+    {
+        OUString m_aURL;
+    };
+
     struct PDFNoteEntry : public PDFAnnotation
     {
         PDFNote                     m_aContents;
@@ -582,6 +588,8 @@ private:
        link id is always the link's position in this vector
     */
     std::vector<PDFLink>                m_aLinks;
+    /// Contains all screen annotations.
+    std::vector<PDFScreen> m_aScreens;
     /* makes correctly encoded for export to PDF URLS
     */
     css::uno::Reference< css::util::XURLTransformer > m_xTrans;
@@ -845,6 +853,8 @@ i12626
     bool appendDest( sal_Int32 nDestID, OStringBuffer& rBuffer );
     // write all links
     bool emitLinkAnnotations();
+    /// Write all screen annotations.
+    bool emitScreenAnnotations();
     // write all notes
     bool emitNoteAnnotations();
     // write the appearance streams of a widget
@@ -1182,6 +1192,10 @@ public:
     void      setLinkURL( sal_Int32 nLinkId, const OUString& rURL );
     void      setLinkPropertyId( sal_Int32 nLinkId, sal_Int32 nPropertyId );
 
+    // screens
+    sal_Int32 createScreen(const Rectangle& rRect, sal_Int32 nPageNr);
+    void setScreenURL(sal_Int32 nScreenId, const OUString& rURL);
+
     // outline
     sal_Int32 createOutlineItem( sal_Int32 nParent, const OUString& rText, sal_Int32 nDestID );
     void      setOutlineItemParent( sal_Int32 nItem, sal_Int32 nNewParent );
commit 1cfd5eba46f36625a1632d372d9aa7e236161585
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Mon Jan 2 12:33:41 2017 +0100

    vcl PDF export: enable MARK() in dbglevel<2 builds as well
    
    Instead of mandating dbglevel=2, use the already existing environment
    variable to avoid additional rebuilds.
    
    Change-Id: I9ac543522e0e79dd2be74e12d0dd0551be63988f
    Reviewed-on: https://gerrit.libreoffice.org/32638
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 49968942a62f6feb6db4dcf385ddee925a57b497)

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 9e592a7..34d5e34 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -13847,4 +13847,11 @@ void PDFWriterImpl::addStream( const OUString& rMimeType, PDFOutputStream* pStre
     }
 }
 
+void PDFWriterImpl::MARK( const char* pString )
+{
+    beginStructureElementMCSeq();
+    if (g_bDebugDisableCompression)
+        emitComment( pString );
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index 16f1fbd..de2327d 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -1212,17 +1212,7 @@ public:
 
     // helper: eventually begin marked content sequence and
     // emit a comment in debug case
-    void MARK( const char*
-#if OSL_DEBUG_LEVEL > 1
-        pString
-#endif
-        )
-    {
-        beginStructureElementMCSeq();
-#if OSL_DEBUG_LEVEL > 1
-        emitComment( pString );
-#endif
-    }
+    void MARK( const char* pString );
 };
 
 class PdfBuiltinFontFace : public PhysicalFontFace


More information about the Libreoffice-commits mailing list