[Libreoffice-commits] core.git: include/vcl sd/source vcl/source
Miklos Vajna
vmiklos at collabora.co.uk
Mon Jan 2 17:42:23 UTC 2017
include/vcl/pdfextoutdevdata.hxx | 8 +++
include/vcl/pdfwriter.hxx | 7 ++
sd/source/ui/unoidl/unomodel.cxx | 12 ++++
vcl/source/gdi/pdfextoutdevdata.cxx | 40 +++++++++++++++
vcl/source/gdi/pdfwriter.cxx | 11 ++++
vcl/source/gdi/pdfwriter_impl.cxx | 91 ++++++++++++++++++++++++++++++++++++
vcl/source/gdi/pdfwriter_impl.hxx | 14 +++++
7 files changed, 183 insertions(+)
New commits:
commit 9d6a749bc664f1876c938afb9eba4adc9f6ee09a
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>
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 67eee15..888cddb 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 0da6543..cb269d6 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 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 d75bdeb..83672f1 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 d974442..8f9a9d6 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 );
More information about the Libreoffice-commits
mailing list