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 <[email protected]> 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 <[email protected]> Tested-by: Jenkins <[email protected]> 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 ); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
