diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-01-04 15:28:41 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-01-04 16:27:44 +0000 |
commit | 4ad249af88d15f2c8a09f0721a59d82718fcc201 (patch) | |
tree | 84676573811a2d1fcfc1f3ef33465b0995add950 | |
parent | 3bacb560c60e6484f217b3edc251d91725b64b84 (diff) |
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@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
-rw-r--r-- | include/vcl/pdfextoutdevdata.hxx | 4 | ||||
-rw-r--r-- | include/vcl/pdfwriter.hxx | 2 | ||||
-rw-r--r-- | sd/source/ui/unoidl/unomodel.cxx | 9 | ||||
-rw-r--r-- | vcl/source/gdi/pdfextoutdevdata.cxx | 16 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter.cxx | 5 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 60 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.hxx | 11 |
7 files changed, 99 insertions, 8 deletions
diff --git a/include/vcl/pdfextoutdevdata.hxx b/include/vcl/pdfextoutdevdata.hxx index e3a05d9afa61..566ff2abbfc8 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 888cddb2380f..29aecc7ce749 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 073e70d8deaa..d305a293c5a1 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 0649b450bde5..386e6837c459 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 7463e7764c5c..cda66dd642db 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 83672f139029..d1987dc3544e 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 8f9a9d69bf58..b50dc4da26d7 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 ); |