diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2018-05-24 17:29:13 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2018-05-25 08:45:24 +0200 |
commit | 89dc667cebfec5315f0c0361e49d759e88458689 (patch) | |
tree | affbfc03e045e00bc983b7d4074d9051078876c7 /vcl | |
parent | 6b1b8ef51b752f9711d6581283d6c515d3c50d9b (diff) |
tdf#113143 PDF export: fix mis-scaled JPGs on Impress note pages
This is really similar to commit
4c2172a3e973bc6351107a3a1b554c77b40b75dd (tdf#106702 PDF export: fix
missing images from Writer headers/footers, 2018-05-22) just this one is
about the size of the output rectangle for JPG content, while the
previous problem was about the position of them.
Also extract PdfExportTest::exportAndParse() from the last two tests to
avoid duplication.
Change-Id: I9812924d505e9fdaca2a95b4990e7aaa5e44fd7f
Reviewed-on: https://gerrit.libreoffice.org/54773
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/qa/cppunit/pdfexport/data/tdf113143.odp | bin | 0 -> 100637 bytes | |||
-rw-r--r-- | vcl/qa/cppunit/pdfexport/pdfexport.cxx | 173 | ||||
-rw-r--r-- | vcl/source/gdi/pdfextoutdevdata.cxx | 6 |
3 files changed, 114 insertions, 65 deletions
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf113143.odp b/vcl/qa/cppunit/pdfexport/data/tdf113143.odp Binary files differnew file mode 100644 index 000000000000..5f8a1b10e2e5 --- /dev/null +++ b/vcl/qa/cppunit/pdfexport/data/tdf113143.odp diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index 28803f0fd1b2..849e87b90f4a 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -39,8 +39,13 @@ class PdfExportTest : public test::BootstrapFixture, public unotest::MacrosTest uno::Reference<lang::XComponent> mxComponent; FPDF_PAGE mpPdfPage = nullptr; FPDF_DOCUMENT mpPdfDocument = nullptr; + utl::TempFile maTempFile; + SvMemoryStream maMemory; + // Export the document as PDF, then parse it with PDFium. + void exportAndParse(const OUString& rURL, const utl::MediaDescriptor& rDescriptor); public: + PdfExportTest(); virtual void setUp() override; virtual void tearDown() override; void load(const OUString& rFile, vcl::filter::PDFDocument& rDocument); @@ -82,6 +87,7 @@ public: void testTdf109143(); void testTdf105954(); void testTdf106702(); + void testTdf113143(); CPPUNIT_TEST_SUITE(PdfExportTest); CPPUNIT_TEST(testTdf106059); @@ -110,9 +116,32 @@ public: CPPUNIT_TEST(testTdf109143); CPPUNIT_TEST(testTdf105954); CPPUNIT_TEST(testTdf106702); + CPPUNIT_TEST(testTdf113143); CPPUNIT_TEST_SUITE_END(); }; +PdfExportTest::PdfExportTest() +{ + maTempFile.EnableKillingFile(); +} + +void PdfExportTest::exportAndParse(const OUString& rURL, const utl::MediaDescriptor& rDescriptor) +{ + // Import the bugdoc and export as PDF. + mxComponent = loadFromDesktop(rURL); + CPPUNIT_ASSERT(mxComponent.is()); + + uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); + xStorable->storeToURL(maTempFile.GetURL(), rDescriptor.getAsConstPropertyValueList()); + + // Parse the export result with pdfium. + SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ); + maMemory.WriteStream(aFile); + mpPdfDocument + = FPDF_LoadMemDocument(maMemory.GetData(), maMemory.GetSize(), /*password=*/nullptr); + CPPUNIT_ASSERT(mpPdfDocument); +} + void PdfExportTest::setUp() { test::BootstrapFixture::setUp(); @@ -150,14 +179,12 @@ void PdfExportTest::load(const OUString& rFile, vcl::filter::PDFDocument& rDocum CPPUNIT_ASSERT(mxComponent.is()); uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); - utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); utl::MediaDescriptor aMediaDescriptor; aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); - xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); // Parse the export result. - SvFileStream aStream(aTempFile.GetURL(), StreamMode::READ); + SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ); CPPUNIT_ASSERT(rDocument.Read(aStream)); } @@ -169,8 +196,6 @@ void PdfExportTest::testTdf106059() CPPUNIT_ASSERT(mxComponent.is()); uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); - utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); utl::MediaDescriptor aMediaDescriptor; aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); // Explicitly enable the usage of the reference XObject markup. @@ -178,11 +203,11 @@ void PdfExportTest::testTdf106059() {"UseReferenceXObject", uno::Any(true) } })); aMediaDescriptor["FilterData"] <<= aFilterData; - xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); // Parse the export result. vcl::filter::PDFDocument aDocument; - SvFileStream aStream(aTempFile.GetURL(), StreamMode::READ); + SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ); CPPUNIT_ASSERT(aDocument.Read(aStream)); // Assert that the XObject in the page resources dictionary is a reference XObject. @@ -249,14 +274,12 @@ void PdfExportTest::testTdf105461() CPPUNIT_ASSERT(mxComponent.is()); uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); - utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); utl::MediaDescriptor aMediaDescriptor; aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); - xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); // Parse the export result with pdfium. - SvFileStream aFile(aTempFile.GetURL(), StreamMode::READ); + SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ); SvMemoryStream aMemory; aMemory.WriteStream(aFile); mpPdfDocument = FPDF_LoadMemDocument(aMemory.GetData(), aMemory.GetSize(), /*password=*/nullptr); @@ -298,19 +321,17 @@ void PdfExportTest::testTdf107868() CPPUNIT_ASSERT(mxComponent.is()); uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); - utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); uno::Reference<view::XPrintable> xPrintable(mxComponent, uno::UNO_QUERY); CPPUNIT_ASSERT(xPrintable.is()); uno::Sequence<beans::PropertyValue> aOptions(comphelper::InitPropertySequence( { - {"FileName", uno::makeAny(aTempFile.GetURL())}, + {"FileName", uno::makeAny(maTempFile.GetURL())}, {"Wait", uno::makeAny(true)} })); xPrintable->print(aOptions); // Parse the export result with pdfium. - SvFileStream aFile(aTempFile.GetURL(), StreamMode::READ); + SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ); SvMemoryStream aMemory; aMemory.WriteStream(aFile); mpPdfDocument = FPDF_LoadMemDocument(aMemory.GetData(), aMemory.GetSize(), /*password=*/nullptr); @@ -385,15 +406,13 @@ void PdfExportTest::testTdf106206() CPPUNIT_ASSERT(mxComponent.is()); uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); - utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); utl::MediaDescriptor aMediaDescriptor; aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); - xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); // Parse the export result. vcl::filter::PDFDocument aDocument; - SvFileStream aStream(aTempFile.GetURL(), StreamMode::READ); + SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ); CPPUNIT_ASSERT(aDocument.Read(aStream)); // The document has one page. @@ -436,15 +455,13 @@ void PdfExportTest::testTdf109143() CPPUNIT_ASSERT(mxComponent.is()); uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); - utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); utl::MediaDescriptor aMediaDescriptor; aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); - xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); // Parse the export result. vcl::filter::PDFDocument aDocument; - SvFileStream aStream(aTempFile.GetURL(), StreamMode::READ); + SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ); CPPUNIT_ASSERT(aDocument.Read(aStream)); // The document has one page. @@ -476,15 +493,13 @@ void PdfExportTest::testTdf106972() CPPUNIT_ASSERT(mxComponent.is()); uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); - utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); utl::MediaDescriptor aMediaDescriptor; aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); - xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); // Parse the export result. vcl::filter::PDFDocument aDocument; - SvFileStream aStream(aTempFile.GetURL(), StreamMode::READ); + SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ); CPPUNIT_ASSERT(aDocument.Read(aStream)); // Get access to the only form object on the only page. @@ -522,15 +537,13 @@ void PdfExportTest::testTdf106972Pdf17() CPPUNIT_ASSERT(mxComponent.is()); uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); - utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); utl::MediaDescriptor aMediaDescriptor; aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); - xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); // Parse the export result. vcl::filter::PDFDocument aDocument; - SvFileStream aStream(aTempFile.GetURL(), StreamMode::READ); + SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ); CPPUNIT_ASSERT(aDocument.Read(aStream)); // Get access to the only image on the only page. @@ -743,14 +756,12 @@ void PdfExportTest::testTdf108963() CPPUNIT_ASSERT(mxComponent.is()); uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); - utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); utl::MediaDescriptor aMediaDescriptor; aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); - xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); // Parse the export result with pdfium. - SvFileStream aFile(aTempFile.GetURL(), StreamMode::READ); + SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ); SvMemoryStream aMemory; aMemory.WriteStream(aFile); mpPdfDocument = FPDF_LoadMemDocument(aMemory.GetData(), aMemory.GetSize(), /*password=*/nullptr); @@ -941,14 +952,12 @@ void PdfExportTest::testTdf115117_1a() CPPUNIT_ASSERT(mxComponent.is()); uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); - utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); utl::MediaDescriptor aMediaDescriptor; aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); - xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); // Parse the export result with pdfium. - SvFileStream aFile(aTempFile.GetURL(), StreamMode::READ); + SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ); SvMemoryStream aMemory; aMemory.WriteStream(aFile); mpPdfDocument = FPDF_LoadMemDocument(aMemory.GetData(), aMemory.GetSize(), /*password=*/nullptr); @@ -986,14 +995,12 @@ void PdfExportTest::testTdf115117_2a() CPPUNIT_ASSERT(mxComponent.is()); uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); - utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); utl::MediaDescriptor aMediaDescriptor; aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); - xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); // Parse the export result with pdfium. - SvFileStream aFile(aTempFile.GetURL(), StreamMode::READ); + SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ); SvMemoryStream aMemory; aMemory.WriteStream(aFile); mpPdfDocument = FPDF_LoadMemDocument(aMemory.GetData(), aMemory.GetSize(), /*password=*/nullptr); @@ -1295,18 +1302,16 @@ void PdfExportTest::testTdf105954() CPPUNIT_ASSERT(mxComponent.is()); uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); - utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); utl::MediaDescriptor aMediaDescriptor; aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); uno::Sequence<beans::PropertyValue> aFilterData(comphelper::InitPropertySequence( { { "ReduceImageResolution", uno::Any(true) }, { "MaxImageResolution", uno::Any(static_cast<sal_Int32>(300)) } })); aMediaDescriptor["FilterData"] <<= aFilterData; - xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); // Parse the export result with pdfium. - SvFileStream aFile(aTempFile.GetURL(), StreamMode::READ); + SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ); SvMemoryStream aMemory; aMemory.WriteStream(aFile); mpPdfDocument @@ -1335,23 +1340,9 @@ void PdfExportTest::testTdf106702() { // Import the bugdoc and export as PDF. OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf106702.odt"; - mxComponent = loadFromDesktop(aURL); - CPPUNIT_ASSERT(mxComponent.is()); - - uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); - utl::TempFile aTempFile; - aTempFile.EnableKillingFile(); utl::MediaDescriptor aMediaDescriptor; aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); - xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); - - // Parse the export result with pdfium. - SvFileStream aFile(aTempFile.GetURL(), StreamMode::READ); - SvMemoryStream aMemory; - aMemory.WriteStream(aFile); - mpPdfDocument - = FPDF_LoadMemDocument(aMemory.GetData(), aMemory.GetSize(), /*password=*/nullptr); - CPPUNIT_ASSERT(mpPdfDocument); + exportAndParse(aURL, aMediaDescriptor); // The document has two pages. CPPUNIT_ASSERT_EQUAL(2, FPDF_GetPageCount(mpPdfDocument)); @@ -1396,6 +1387,62 @@ void PdfExportTest::testTdf106702() CPPUNIT_ASSERT_EQUAL(nExpected, nActual); } +void PdfExportTest::testTdf113143() +{ + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf113143.odp"; + utl::MediaDescriptor aMediaDescriptor; + aMediaDescriptor["FilterName"] <<= OUString("impress_pdf_Export"); + uno::Sequence<beans::PropertyValue> aFilterData(comphelper::InitPropertySequence({ + { "ExportNotesPages", uno::Any(true) }, + // ReduceImageResolution is on by default and that hides the bug we + // want to test. + { "ReduceImageResolution", uno::Any(false) }, + })); + aMediaDescriptor["FilterData"] <<= aFilterData; + exportAndParse(aURL, aMediaDescriptor); + + // The document has two pages. + CPPUNIT_ASSERT_EQUAL(2, FPDF_GetPageCount(mpPdfDocument)); + + // First has the original (larger) image. + mpPdfPage = FPDF_LoadPage(mpPdfDocument, /*page_index=*/0); + CPPUNIT_ASSERT(mpPdfPage); + int nLarger = 0; + int nPageObjectCount = FPDFPage_CountObjects(mpPdfPage); + for (int i = 0; i < nPageObjectCount; ++i) + { + FPDF_PAGEOBJECT pPageObject = FPDFPage_GetObject(mpPdfPage, i); + if (FPDFPageObj_GetType(pPageObject) != FPDF_PAGEOBJ_IMAGE) + continue; + + float fLeft = 0, fBottom = 0, fRight = 0, fTop = 0; + FPDFPageObj_GetBounds(pPageObject, &fLeft, &fBottom, &fRight, &fTop); + nLarger = fRight - fLeft; + break; + } + + // Second page has the scaled (smaller) image. + FPDF_ClosePage(mpPdfPage); + mpPdfPage = FPDF_LoadPage(mpPdfDocument, /*page_index=*/1); + CPPUNIT_ASSERT(mpPdfPage); + int nSmaller = 0; + nPageObjectCount = FPDFPage_CountObjects(mpPdfPage); + for (int i = 0; i < nPageObjectCount; ++i) + { + FPDF_PAGEOBJECT pPageObject = FPDFPage_GetObject(mpPdfPage, i); + if (FPDFPageObj_GetType(pPageObject) != FPDF_PAGEOBJ_IMAGE) + continue; + + float fLeft = 0, fBottom = 0, fRight = 0, fTop = 0; + FPDFPageObj_GetBounds(pPageObject, &fLeft, &fBottom, &fRight, &fTop); + nSmaller = fRight - fLeft; + break; + } + + // This failed, both were 319, now nSmaller is 169. + CPPUNIT_ASSERT_LESS(nLarger, nSmaller); +} + CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest); } diff --git a/vcl/source/gdi/pdfextoutdevdata.cxx b/vcl/source/gdi/pdfextoutdevdata.cxx index 05bb37a0c6c3..d36ab2844f17 100644 --- a/vcl/source/gdi/pdfextoutdevdata.cxx +++ b/vcl/source/gdi/pdfextoutdevdata.cxx @@ -466,8 +466,9 @@ bool PageSyncData::PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAc // Look up the output rectangle from the previous // bitmap scale action if possible. This has the - // correct position for images repeated in - // Writer headers/footers for non-first pages. + // correct position and size for images with a + // custom translation (Writer header) or scaling + // (Impress notes page). if (rCurGDIMtfAction > 0) { const MetaAction* pAction = rMtf.GetAction(rCurGDIMtfAction - 1); @@ -476,6 +477,7 @@ bool PageSyncData::PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAc const MetaBmpScaleAction* pA = static_cast<const MetaBmpScaleAction*>(pAction); aOutputRect.SetPos(pA->GetPoint()); + aOutputRect.SetSize(pA->GetSize()); } } |