diff options
Diffstat (limited to 'vcl/source/gdi/pdfwriter_impl.cxx')
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 115 |
1 files changed, 64 insertions, 51 deletions
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 3cf733449d31..5d2fbf6a6b13 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -45,6 +45,7 @@ #include <osl/thread.h> #include <rtl/digest.h> #include <rtl/ustrbuf.hxx> +#include <rtl/xmlencode.hxx> #include <sal/log.hxx> #include <svl/urihelper.hxx> #include <tools/fract.hxx> @@ -75,6 +76,7 @@ #include <bitmapwriteaccess.hxx> #include <impglyphitem.hxx> #include <pdf/objectcopier.hxx> +#include <pdf/PdfConfig.hxx> #include "pdfwriter_impl.hxx" @@ -4155,9 +4157,6 @@ void PDFWriterImpl::createDefaultRadioButtonAppearance( PDFWidget& rBox, const P pop(); - OStringBuffer aDA( 256 ); - appendNonStrokingColor( replaceColor( rWidget.TextColor, rSettings.GetRadioCheckTextColor() ), aDA ); - rBox.m_aDAString = aDA.makeStringAndClear(); //to encrypt this (el) rBox.m_aMKDict = "/CA"; //after this assignment, to m_aMKDic cannot be added anything @@ -4170,6 +4169,7 @@ void PDFWriterImpl::createDefaultRadioButtonAppearance( PDFWidget& rBox, const P SvMemoryStream* pCheckStream = new SvMemoryStream( 256, 256 ); beginRedirect( pCheckStream, aCheckRect ); + OStringBuffer aDA( 256 ); aDA.append( "/Tx BMC\nq BT\n" ); appendNonStrokingColor( replaceColor( rWidget.TextColor, rSettings.GetRadioCheckTextColor() ), aDA ); aDA.append( ' ' ); @@ -5326,37 +5326,6 @@ sal_Int32 PDFWriterImpl::emitOutputIntent() return nOIObject; } -// formats the string for the XML stream -static void escapeStringXML( const OUString& rStr, OUString &rValue) -{ - const sal_Unicode* pUni = rStr.getStr(); - int nLen = rStr.getLength(); - for( ; nLen; nLen--, pUni++ ) - { - switch( *pUni ) - { - case u'&': - rValue += "&"; - break; - case u'<': - rValue += "<"; - break; - case u'>': - rValue += ">"; - break; - case u'\'': - rValue += "'"; - break; - case u'"': - rValue += """; - break; - default: - rValue += OUStringChar( *pUni ); - break; - } - } -} - // emits the document metadata sal_Int32 PDFWriterImpl::emitDocumentMetadata() { @@ -5405,8 +5374,7 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() aMetadataStream.append( " <dc:title>\n" ); aMetadataStream.append( " <rdf:Alt>\n" ); aMetadataStream.append( " <rdf:li xml:lang=\"x-default\">" ); - OUString aTitle; - escapeStringXML( m_aContext.DocumentInfo.Title, aTitle ); + OUString aTitle = rtl::encodeForXml( m_aContext.DocumentInfo.Title ); aMetadataStream.append( OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "</rdf:li>\n" ); aMetadataStream.append( " </rdf:Alt>\n" ); @@ -5417,8 +5385,7 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() aMetadataStream.append( " <dc:creator>\n" ); aMetadataStream.append( " <rdf:Seq>\n" ); aMetadataStream.append( " <rdf:li>" ); - OUString aAuthor; - escapeStringXML( m_aContext.DocumentInfo.Author, aAuthor ); + OUString aAuthor = rtl::encodeForXml( m_aContext.DocumentInfo.Author ); aMetadataStream.append( OUStringToOString( aAuthor , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "</rdf:li>\n" ); aMetadataStream.append( " </rdf:Seq>\n" ); @@ -5430,8 +5397,7 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() aMetadataStream.append( " <dc:description>\n" ); aMetadataStream.append( " <rdf:Alt>\n" ); aMetadataStream.append( " <rdf:li xml:lang=\"x-default\">" ); - OUString aSubject; - escapeStringXML( m_aContext.DocumentInfo.Subject, aSubject ); + OUString aSubject = rtl::encodeForXml( m_aContext.DocumentInfo.Subject ); aMetadataStream.append( OUStringToOString( aSubject , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "</rdf:li>\n" ); aMetadataStream.append( " </rdf:Alt>\n" ); @@ -5449,16 +5415,14 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() if( !m_aContext.DocumentInfo.Producer.isEmpty() ) { aMetadataStream.append( " <pdf:Producer>" ); - OUString aProducer; - escapeStringXML( m_aContext.DocumentInfo.Producer, aProducer ); + OUString aProducer = rtl::encodeForXml( m_aContext.DocumentInfo.Producer ); aMetadataStream.append( OUStringToOString( aProducer , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "</pdf:Producer>\n" ); } if( !m_aContext.DocumentInfo.Keywords.isEmpty() ) { aMetadataStream.append( " <pdf:Keywords>" ); - OUString aKeywords; - escapeStringXML( m_aContext.DocumentInfo.Keywords, aKeywords ); + OUString aKeywords = rtl::encodeForXml( m_aContext.DocumentInfo.Keywords ); aMetadataStream.append( OUStringToOString( aKeywords , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "</pdf:Keywords>\n" ); } @@ -5470,8 +5434,7 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() if( !m_aContext.DocumentInfo.Creator.isEmpty() ) { aMetadataStream.append( " <xmp:CreatorTool>" ); - OUString aCreator; - escapeStringXML( m_aContext.DocumentInfo.Creator, aCreator ); + OUString aCreator = rtl::encodeForXml( m_aContext.DocumentInfo.Creator ); aMetadataStream.append( OUStringToOString( aCreator , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "</xmp:CreatorTool>\n" ); } @@ -8668,11 +8631,14 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit) return; // Count /Matrix and /BBox. - // vcl::ImportPDF() works with 96 DPI so use the same values here, too. + // vcl::ImportPDF() uses getDefaultPdfResolutionDpi to set the desired + // rendering DPI so we have to take into account that here too. + static const double fResolutionDPI = vcl::pdf::getDefaultPdfResolutionDpi(); + sal_Int32 nOldDPIX = GetDPIX(); - SetDPIX(96); sal_Int32 nOldDPIY = GetDPIY(); - SetDPIY(96); + SetDPIX(fResolutionDPI); + SetDPIY(fResolutionDPI); Size aSize = PixelToLogic(rEmit.m_aPixelSize, MapMode(m_aMapMode.GetMapUnit())); SetDPIX(nOldDPIX); SetDPIY(nOldDPIY); @@ -8736,6 +8702,53 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit) return; } + // Merge link annotations from pPage to our page. + std::vector<filter::PDFObjectElement*> aAnnots; + if (auto pArray = dynamic_cast<filter::PDFArrayElement*>(pPage->Lookup("Annots"))) + { + for (const auto pElement : pArray->GetElements()) + { + auto pReference = dynamic_cast<filter::PDFReferenceElement*>(pElement); + if (!pReference) + { + continue; + } + + filter::PDFObjectElement* pObject = pReference->LookupObject(); + if (!pObject) + { + continue; + } + + auto pType = dynamic_cast<filter::PDFNameElement*>(pObject->Lookup("Type")); + if (!pType || pType->GetValue() != "Annot") + { + continue; + } + + auto pSubtype = dynamic_cast<filter::PDFNameElement*>(pObject->Lookup("Subtype")); + if (!pSubtype || pSubtype->GetValue() != "Link") + { + continue; + } + + // Reference to a link annotation object, remember it. + aAnnots.push_back(pObject); + } + } + if (!aAnnots.empty()) + { + PDFObjectCopier aCopier(*this); + SvMemoryStream& rDocBuffer = pPage->GetDocument().GetEditBuffer(); + std::map<sal_Int32, sal_Int32> aMap; + for (const auto& pAnnot : aAnnots) + { + // Copy over the annotation and refer to its new id. + sal_Int32 nNewId = aCopier.copyExternalResource(rDocBuffer, *pAnnot, aMap); + m_aPages.back().m_aAnnotations.push_back(nNewId); + } + } + nWrappedFormObject = createObject(); // Write the form XObject wrapped below. This is a separate object from // the wrapper, this way there is no need to alter the stream contents. @@ -8833,9 +8846,9 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit) aLine.append(">> >>"); aLine.append(" /Matrix [ "); - appendDouble(fScaleX, aLine); + appendDouble(fScaleX, aLine, /*nPrecision=*/10); aLine.append(" 0 0 "); - appendDouble(fScaleY, aLine); + appendDouble(fScaleY, aLine, /*nPrecision=*/10); aLine.append(" 0 0 ]"); aLine.append(" /BBox [ 0 0 "); aLine.append(aSize.Width()); |