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 /vcl | |
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>
Diffstat (limited to 'vcl')
-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 |
4 files changed, 86 insertions, 6 deletions
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 ); |