[Libreoffice-commits] core.git: Branch 'distro/vector/vector-5.4' - vcl/qa vcl/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Mon Apr 20 13:14:10 UTC 2020
vcl/qa/cppunit/pdfexport/data/6m-wide.odg |binary
vcl/qa/cppunit/pdfexport/pdfexport.cxx | 32 ++++++++++++++++++
vcl/source/gdi/pdfwriter_impl.cxx | 51 ++++++++++++++++++++++++++----
vcl/source/gdi/pdfwriter_impl.hxx | 7 +++-
4 files changed, 83 insertions(+), 7 deletions(-)
New commits:
commit 4b52ba8e61e121ac92c21861c5f2755e892f888d
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Apr 16 18:13:01 2020 +0200
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon Apr 20 11:25:14 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/qa/cppunit/pdfexport/pdfexport.cxx
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 d578f3a27207..e997379ca3e5 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -97,6 +97,7 @@ public:
void testTdf99680_2();
#endif
void testTocLink();
+ void testLargePage();
CPPUNIT_TEST_SUITE(PdfExportTest);
#if HAVE_FEATURE_PDFIUM
@@ -115,6 +116,7 @@ public:
CPPUNIT_TEST(testTdf99680_2);
#endif
CPPUNIT_TEST(testTocLink);
+ CPPUNIT_TEST(testLargePage);
CPPUNIT_TEST_SUITE_END();
};
@@ -752,6 +754,36 @@ void PdfExportTest::testTocLink()
CPPUNIT_ASSERT(FPDFLink_Enumerate(pPdfPage.get(), &nStartPos, &pLinkAnnot));
}
+void PdfExportTest::testLargePage()
+{
+ // Import the bugdoc and export as PDF.
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "6m-wide.odg";
+ mxComponent = loadFromDesktop(aURL);
+ CPPUNIT_ASSERT(mxComponent.is());
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= OUString("draw_pdf_Export");
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+
+ SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ);
+ maMemory.WriteStream(aFile);
+ DocumentHolder pPdfDocument(
+ FPDF_LoadMemDocument(maMemory.GetData(), maMemory.GetSize(), /*password=*/nullptr));
+
+ // 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.92
+ // - 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.92, fWidth, 0.01);
+}
+
#endif
CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest);
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 7a341f8d10b2..2ef2a002fd90 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -1141,6 +1141,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()
@@ -1224,10 +1225,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 )
{
@@ -1699,6 +1705,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 : m_pWriter->m_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)
@@ -2262,6 +2280,14 @@ void PDFWriterImpl::newPage( double nPageWidth, double nPageHeight, PDFWriter::O
endPage();
m_nCurrentPage = m_aPages.size();
m_aPages.push_back( PDFPage(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
@@ -5048,6 +5074,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 = m_nInheritedPageWidth;
@@ -5058,17 +5085,29 @@ bool PDFWriterImpl::emitCatalog()
for( std::vector<PDFPage>::const_iterator iter = m_aPages.begin(); iter != m_aPages.end(); ++iter )
{
if( iter->m_nPageWidth > nMediaBoxWidth )
+ {
nMediaBoxWidth = iter->m_nPageWidth;
+ nUserUnit = iter->m_nUserUnit;
+ }
if( iter->m_nPageHeight > nMediaBoxHeight )
+ {
nMediaBoxHeight = iter->m_nPageHeight;
+ nUserUnit = iter->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( std::vector<PDFPage>::const_iterator iter = m_aPages.begin(); iter != m_aPages.end(); ++iter, i++ )
{
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index 850ea559bc0c..847aac8a3382 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -137,6 +137,11 @@ public:
PDFWriterImpl* m_pWriter;
double m_nPageWidth; // in inch/72
double 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 m_eOrientation;
sal_Int32 m_nPageObject;
std::vector<sal_Int32> m_aStreamObjects;
@@ -189,7 +194,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 : m_pWriter->m_nInheritedPageHeight; }
+ double getHeight() const;
};
friend struct PDFPage;
More information about the Libreoffice-commits
mailing list