[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - 2 commits - filter/source include/vcl officecfg/registry vcl/qa vcl/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Tue May 5 08:36:10 UTC 2020
filter/source/pdf/pdfexport.cxx | 5
include/vcl/pdfwriter.hxx | 2
officecfg/registry/schema/org/openoffice/Office/Common.xcs | 7 +
vcl/qa/cppunit/pdfexport/data/6m-wide.odg |binary
vcl/qa/cppunit/pdfexport/pdfexport.cxx | 77 +++++++++++++
vcl/source/filter/ipdf/pdfread.cxx | 8 -
vcl/source/gdi/pdfwriter_impl.cxx | 63 +++++++++-
vcl/source/gdi/pdfwriter_impl.hxx | 7 +
8 files changed, 154 insertions(+), 15 deletions(-)
New commits:
commit 969bafd6a41b73608396e608df998aa425a5d81a
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Apr 17 17:28:58 2020 +0200
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue May 5 10:23:32 2020 +0200
Change default PDF version to 1.6 (released in 2004)
We already write markup which is newer than 1.5, but the PDF version was
not changed. Fix the one violation I'm aware of.
Printing is left unchanged, similar to how commit
99ac4ee05b039166eedfe361fb985682fd92dd13 (Change default PDF version to
1.5, 2018-04-24) updated the default last time.
(cherry picked from commit 141e0449fdab89384564659191492b698e4b13d8)
Conflicts:
filter/source/pdf/pdfexport.cxx
include/vcl/pdfwriter.hxx
Change-Id: I9598dc46fe7db428bd2eff98bebff8b3c873b4ff
diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx
index c24e3e6581f4..d5c282053a98 100644
--- a/filter/source/pdf/pdfexport.cxx
+++ b/filter/source/pdf/pdfexport.cxx
@@ -601,7 +601,7 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
{
default:
case 0:
- aContext.Version = vcl::PDFWriter::PDFVersion::PDF_1_5;
+ aContext.Version = vcl::PDFWriter::PDFVersion::PDF_1_6;
break;
case 1:
aContext.Version = vcl::PDFWriter::PDFVersion::PDF_A_1;
@@ -617,6 +617,9 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
mbEncrypt = false; // no encryption
xEnc.clear();
break;
+ case 15:
+ aContext.Version = vcl::PDFWriter::PDFVersion::PDF_1_5;
+ break;
case 16:
aContext.Version = vcl::PDFWriter::PDFVersion::PDF_1_6;
break;
diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index e109cf6a76eb..858d8a36dec1 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -609,7 +609,7 @@ The following structure describes the permissions used in PDF security
DefaultLinkAction( PDFWriter::URIAction ),
ConvertOOoTargetToPDFTarget( false ),
ForcePDFAction( false ),
- Version( PDFWriter::PDFVersion::PDF_1_5 ),
+ Version( PDFWriter::PDFVersion::PDF_1_6 ),
Tagged( false ),
SubmitFormat( PDFWriter::FDF ),
AllowDuplicateFieldNames( false ),
diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
index cebb7d7ec0ef..61186edc8298 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
@@ -5294,7 +5294,12 @@
<constraints>
<enumeration oor:value="0">
<info>
- <desc>PDF 1.5 (default selection).</desc>
+ <desc>PDF 1.6 (default selection).</desc>
+ </info>
+ </enumeration>
+ <enumeration oor:value="15">
+ <info>
+ <desc>PDF 1.5</desc>
</info>
</enumeration>
<enumeration oor:value="16">
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 28b0b693e426..1076128b0775 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -139,6 +139,8 @@ public:
void testPdfImageResourceInlineXObjectRef();
void testLinkWrongPage();
void testLargePage();
+ void testVersion15();
+ void testDefaultVersion();
CPPUNIT_TEST_SUITE(PdfExportTest);
CPPUNIT_TEST(testTdf106059);
@@ -178,6 +180,8 @@ public:
CPPUNIT_TEST(testPdfImageResourceInlineXObjectRef);
CPPUNIT_TEST(testLinkWrongPage);
CPPUNIT_TEST(testLargePage);
+ CPPUNIT_TEST(testVersion15);
+ CPPUNIT_TEST(testDefaultVersion);
CPPUNIT_TEST_SUITE_END();
};
@@ -2006,6 +2010,55 @@ void PdfExportTest::testPdfImageResourceInlineXObjectRef()
CPPUNIT_ASSERT_EQUAL(-90, nRotateDeg);
}
+void PdfExportTest::testDefaultVersion()
+{
+ // Create an empty document.
+ mxComponent = loadFromDesktop("private:factory/swriter");
+ CPPUNIT_ASSERT(mxComponent.is());
+
+ // Save as PDF.
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export");
+ xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+
+ // Parse the export result.
+ SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ);
+ maMemory.WriteStream(aFile);
+ DocumentHolder pPdfDocument(
+ FPDF_LoadMemDocument(maMemory.GetData(), maMemory.GetSize(), /*password=*/nullptr));
+ CPPUNIT_ASSERT(pPdfDocument.get());
+ int nFileVersion = 0;
+ FPDF_GetFileVersion(pPdfDocument.get(), &nFileVersion);
+ CPPUNIT_ASSERT_EQUAL(16, nFileVersion);
+}
+
+void PdfExportTest::testVersion15()
+{
+ // Create an empty document.
+ mxComponent = loadFromDesktop("private:factory/swriter");
+ CPPUNIT_ASSERT(mxComponent.is());
+
+ // Save as PDF.
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValue> aFilterData(comphelper::InitPropertySequence(
+ { { "SelectPdfVersion", uno::makeAny(static_cast<sal_Int32>(15)) } }));
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export");
+ aMediaDescriptor["FilterData"] <<= aFilterData;
+ xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+
+ // Parse the export result.
+ SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ);
+ maMemory.WriteStream(aFile);
+ DocumentHolder pPdfDocument(
+ FPDF_LoadMemDocument(maMemory.GetData(), maMemory.GetSize(), /*password=*/nullptr));
+ CPPUNIT_ASSERT(pPdfDocument.get());
+ int nFileVersion = 0;
+ FPDF_GetFileVersion(pPdfDocument.get(), &nFileVersion);
+ CPPUNIT_ASSERT_EQUAL(15, nFileVersion);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest);
}
diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx
index 6ace744ec1eb..c5c542a35aad 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -79,7 +79,7 @@ bool isCompatible(SvStream& rInStream, sal_uInt64 nPos, sal_uInt64 nSize)
sal_Int32 nMajor = OString(aFirstBytes[5]).toInt32();
sal_Int32 nMinor = OString(aFirstBytes[7]).toInt32();
- return !(nMajor > 1 || (nMajor == 1 && nMinor > 5));
+ return !(nMajor > 1 || (nMajor == 1 && nMinor > 6));
}
/// Takes care of transparently downgrading the version of the PDF stream in
@@ -94,7 +94,7 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream, sal_uInt64 n
rOutStream.WriteStream(rInStream, nSize);
else
{
- // Downconvert to PDF-1.5.
+ // Downconvert to PDF-1.6.
FPDF_LIBRARY_CONFIG aConfig;
aConfig.version = 2;
aConfig.m_pUserFontPaths = nullptr;
@@ -116,8 +116,8 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream, sal_uInt64 n
aWriter.version = 1;
aWriter.WriteBlock = &CompatibleWriterCallback;
- // 15 means PDF-1.5.
- if (!FPDF_SaveWithVersion(pPdfDocument, &aWriter, 0, 15))
+ // 16 means PDF-1.6.
+ if (!FPDF_SaveWithVersion(pPdfDocument, &aWriter, 0, 16))
return false;
FPDF_CloseDocument(pPdfDocument);
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 27f5042e5f1c..35ac2e7dc6e0 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -726,6 +726,7 @@ PDFWriterImpl::PDFPage::PDFPage( PDFWriterImpl* pWriter, double nPageWidth, doub
m_pWriter( pWriter ),
m_nPageWidth( nPageWidth ),
m_nPageHeight( nPageHeight ),
+ m_nUserUnit( 1 ),
m_eOrientation( eOrientation ),
m_nPageObject( 0 ), // invalid object number
m_nStreamLengthObject( 0 ),
@@ -735,7 +736,16 @@ PDFWriterImpl::PDFPage::PDFPage( PDFWriterImpl* pWriter, double nPageWidth, doub
{
// object ref must be only ever updated in emit()
m_nPageObject = m_pWriter->createObject();
- m_nUserUnit = std::ceil(std::max(nPageWidth, nPageHeight) / 14400.0);
+
+ switch (m_pWriter->m_aContext.Version)
+ {
+ case PDFWriter::PDFVersion::PDF_1_6:
+ m_nUserUnit = std::ceil(std::max(nPageWidth, nPageHeight) / 14400.0);
+ break;
+ default:
+ // 1.2 -> 1.5
+ break;
+ }
}
PDFWriterImpl::PDFPage::~PDFPage()
@@ -1394,8 +1404,8 @@ double PDFWriterImpl::PDFPage::getHeight() const
case PDFWriter::PDFVersion::PDF_1_3: aBuffer.append( "1.3" );break;
case PDFWriter::PDFVersion::PDF_A_1:
case PDFWriter::PDFVersion::PDF_1_4: aBuffer.append( "1.4" );break;
- default:
case PDFWriter::PDFVersion::PDF_1_5: aBuffer.append( "1.5" );break;
+ default:
case PDFWriter::PDFVersion::PDF_1_6: aBuffer.append( "1.6" );break;
}
// append something binary as comment (suggested in PDF Reference)
commit eaafd7378bd3a06d2d99360667858a3b6106d0de
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Apr 16 18:13:01 2020 +0200
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue May 5 10:21:52 2020 +0200
PDF export: fix handling of page sizes larger than 508 cm
The value of these coordinates are not allowed to be larger than 14 400,
and Adobe Reader complains about them.
Use UserUnit to declare in case we won't work with points anymore, but
with a larger unit. This will mean UserUnit=2 in practice, since e.g.
Draw has is page size limited to 600x600cm, so larger values won't
happen, at least not for now.
(cherry picked from commit 4830592b780833cf5eee2aef30bc9c5d444dfb24)
Conflicts:
vcl/source/gdi/pdfwriter_impl.cxx
vcl/source/gdi/pdfwriter_impl.hxx
Change-Id: I8ee159f2571f4070aded85388792a215de86f7ff
diff --git a/vcl/qa/cppunit/pdfexport/data/6m-wide.odg b/vcl/qa/cppunit/pdfexport/data/6m-wide.odg
new file mode 100644
index 000000000000..49fb9bfff92e
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/6m-wide.odg differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 48f12080f74b..28b0b693e426 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -138,6 +138,7 @@ public:
void testTocLink();
void testPdfImageResourceInlineXObjectRef();
void testLinkWrongPage();
+ void testLargePage();
CPPUNIT_TEST_SUITE(PdfExportTest);
CPPUNIT_TEST(testTdf106059);
@@ -176,6 +177,7 @@ public:
CPPUNIT_TEST(testTocLink);
CPPUNIT_TEST(testPdfImageResourceInlineXObjectRef);
CPPUNIT_TEST(testLinkWrongPage);
+ CPPUNIT_TEST(testLargePage);
CPPUNIT_TEST_SUITE_END();
};
@@ -1895,6 +1897,28 @@ void PdfExportTest::testLinkWrongPage()
CPPUNIT_ASSERT(!HasLinksOnPage(pPdfPage2));
}
+void PdfExportTest::testLargePage()
+{
+ // Import the bugdoc and export as PDF.
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "6m-wide.odg";
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= OUString("draw_pdf_Export");
+ DocumentHolder pPdfDocument = exportAndParse(aURL, aMediaDescriptor);
+
+ // The document has 1 page.
+ CPPUNIT_ASSERT_EQUAL(1, FPDF_GetPageCount(pPdfDocument.get()));
+
+ // Check the value (not the unit) of the page size.
+ double fWidth = 0;
+ double fHeight = 0;
+ FPDF_GetPageSizeByIndex(pPdfDocument.get(), 0, &fWidth, &fHeight);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 8503.94
+ // - Actual : 17007.875
+ // i.e. the value for 600 cm was larger than the 14 400 limit set in the spec.
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(8503.94, fWidth, 0.01);
+}
+
void PdfExportTest::testPdfImageResourceInlineXObjectRef()
{
// Create an empty document.
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index a2a3f5ca9a5b..27f5042e5f1c 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -735,6 +735,7 @@ PDFWriterImpl::PDFPage::PDFPage( PDFWriterImpl* pWriter, double nPageWidth, doub
{
// object ref must be only ever updated in emit()
m_nPageObject = m_pWriter->createObject();
+ m_nUserUnit = std::ceil(std::max(nPageWidth, nPageHeight) / 14400.0);
}
PDFWriterImpl::PDFPage::~PDFPage()
@@ -816,10 +817,15 @@ bool PDFWriterImpl::PDFPage::emit(sal_Int32 nParentObject )
if( m_nPageWidth && m_nPageHeight )
{
aLine.append( "/MediaBox[0 0 " );
- aLine.append( m_nPageWidth );
+ aLine.append(m_nPageWidth / m_nUserUnit);
aLine.append( ' ' );
- aLine.append( m_nPageHeight );
+ aLine.append(m_nPageHeight / m_nUserUnit);
aLine.append( "]" );
+ if (m_nUserUnit > 1)
+ {
+ aLine.append("\n/UserUnit ");
+ aLine.append(m_nUserUnit);
+ }
}
switch( m_eOrientation )
{
@@ -1284,6 +1290,18 @@ void PDFWriterImpl::PDFPage::appendWaveLine( sal_Int32 nWidth, sal_Int32 nY, sal
rBuffer.append( "S\n" );
}
+double PDFWriterImpl::PDFPage::getHeight() const
+{
+ double fRet = m_nPageHeight ? m_nPageHeight : PDFWriterImpl::g_nInheritedPageHeight;
+
+ if (m_nUserUnit > 1)
+ {
+ fRet /= m_nUserUnit;
+ }
+
+ return fRet;
+}
+
PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext,
const css::uno::Reference< css::beans::XMaterialHolder >& xEnc,
PDFWriter& i_rOuterFace)
@@ -1768,6 +1786,14 @@ void PDFWriterImpl::newPage( double nPageWidth, double nPageHeight, PDFWriter::O
endPage();
m_nCurrentPage = m_aPages.size();
m_aPages.emplace_back(this, nPageWidth, nPageHeight, eOrientation );
+
+ sal_Int32 nUserUnit = m_aPages.back().m_nUserUnit;
+ if (nUserUnit > 1)
+ {
+ m_aMapMode = MapMode(MapUnit::MapPoint, Point(), Fraction(nUserUnit, pointToPixel(1)),
+ Fraction(nUserUnit, pointToPixel(1)));
+ }
+
m_aPages.back().beginStream();
// setup global graphics state
@@ -4564,6 +4590,7 @@ bool PDFWriterImpl::emitCatalog()
sal_Int32 nMediaBoxWidth = 0;
sal_Int32 nMediaBoxHeight = 0;
+ sal_Int32 nUserUnit = 1;
if( m_aPages.empty() ) // sanity check, this should not happen
{
nMediaBoxWidth = g_nInheritedPageWidth;
@@ -4574,17 +4601,29 @@ bool PDFWriterImpl::emitCatalog()
for (auto const& page : m_aPages)
{
if( page.m_nPageWidth > nMediaBoxWidth )
+ {
nMediaBoxWidth = page.m_nPageWidth;
+ nUserUnit = page.m_nUserUnit;
+ }
if( page.m_nPageHeight > nMediaBoxHeight )
+ {
nMediaBoxHeight = page.m_nPageHeight;
+ nUserUnit = page.m_nUserUnit;
+ }
}
}
aLine.append( "/MediaBox[ 0 0 " );
- aLine.append( nMediaBoxWidth );
+ aLine.append(nMediaBoxWidth / nUserUnit);
aLine.append( ' ' );
- aLine.append( nMediaBoxHeight );
- aLine.append( " ]\n"
- "/Kids[ " );
+ aLine.append(nMediaBoxHeight / nUserUnit);
+ aLine.append(" ]\n");
+ if (nUserUnit > 1)
+ {
+ aLine.append("/UserUnit ");
+ aLine.append(nUserUnit);
+ aLine.append("\n");
+ }
+ aLine.append("/Kids[ ");
unsigned int i = 0;
for (const auto & page : m_aPages)
{
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index 7e07d9e0d472..8c88ed6fb172 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -117,6 +117,11 @@ public:
VclPtr<PDFWriterImpl> m_pWriter;
double const m_nPageWidth; // in inch/72
double const m_nPageHeight; // in inch/72
+ /**
+ * A positive number that gives the size of default user space units, in multiples of points.
+ * Typically 1, larger if page size is > 508 cm.
+ */
+ sal_Int32 m_nUserUnit;
PDFWriter::Orientation const m_eOrientation;
sal_Int32 m_nPageObject;
std::vector<sal_Int32> m_aStreamObjects;
@@ -168,7 +173,7 @@ public:
// appends a horizontal waveline with vertical offset (helper for drawWaveLine)
void appendWaveLine( sal_Int32 nLength, sal_Int32 nYOffset, sal_Int32 nDelta, OStringBuffer& rBuffer ) const;
- double getHeight() const { return m_nPageHeight ? m_nPageHeight : PDFWriterImpl::g_nInheritedPageHeight; }
+ double getHeight() const;
};
friend struct PDFPage;
More information about the Libreoffice-commits
mailing list