diff options
-rw-r--r-- | include/vcl/pdfextoutdevdata.hxx | 8 | ||||
-rw-r--r-- | include/vcl/pdfwriter.hxx | 7 | ||||
-rw-r--r-- | sd/source/ui/unoidl/unomodel.cxx | 12 | ||||
-rw-r--r-- | vcl/source/gdi/pdfextoutdevdata.cxx | 40 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter.cxx | 11 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 91 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.hxx | 14 |
7 files changed, 183 insertions, 0 deletions
diff --git a/include/vcl/pdfextoutdevdata.hxx b/include/vcl/pdfextoutdevdata.hxx index 7095b9092dea..1a0c941eaef7 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 67eee153f384..888cddb2380f 100644 --- a/include/vcl/pdfwriter.hxx +++ b/include/vcl/pdfwriter.hxx @@ -927,6 +927,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 @@ -973,6 +976,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 0da6543f542e..cb269d6e6758 100644 --- a/sd/source/ui/unoidl/unomodel.cxx +++ b/sd/source/ui/unoidl/unomodel.cxx @@ -1652,6 +1652,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 73d923267a64..f85c981010a1 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 741df80f2fe5..7463e7764c5c 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 d75bdeb36d23..83672f139029 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -106,6 +106,7 @@ #endif using namespace vcl; +using namespace::com::sun::star; static bool g_bDebugDisableCompression = getenv("VCL_DEBUG_DISABLE_PDFCOMPRESSION"); @@ -3765,6 +3766,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(); @@ -4895,6 +4954,7 @@ bool PDFWriterImpl::emitAnnotations() return false; CHECK_RETURN( emitLinkAnnotations() ); + CHECK_RETURN(emitScreenAnnotations()); CHECK_RETURN( emitNoteAnnotations() ); CHECK_RETURN( emitWidgetAnnotations() ); @@ -11814,6 +11874,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 ) { @@ -11895,6 +11978,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 d974442aae29..8f9a9d69bf58 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -414,6 +414,12 @@ public: {} }; + /// A PDF Screen annotation. + struct PDFScreen : public PDFAnnotation + { + OUString m_aURL; + }; + struct PDFNoteEntry : public PDFAnnotation { PDFNote m_aContents; @@ -604,6 +610,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; @@ -852,6 +860,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 @@ -1189,6 +1199,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 ); |