vcl/CppunitTest_vcl_pdfexport.mk | 1 vcl/qa/cppunit/pdfexport/data/pdf-image-resource-inline-xobject-ref.pdf |binary vcl/qa/cppunit/pdfexport/pdfexport.cxx | 28 ++++++++ vcl/source/gdi/pdfwriter_impl.cxx | 32 +++++++++- 4 files changed, 59 insertions(+), 2 deletions(-)
New commits: commit bd520b177637d4b7d9d93733103cff17a3c91b0a Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Nov 6 16:48:55 2019 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Nov 6 17:56:59 2019 +0100 vcl PDF export: fix re-exporting PDF images with page-level rotation PDF images are effectively 1 page PDF documents. The page object may have a /Rotate key, which was simply ignored before. We turn page objects into form XObjects on PDF export, such rotation can be expressed with a /Matrix key. Add support for the 90 degrees rotation case, this can be generalized later if wanted. Change-Id: I55a4f63e0b986637ccdeba0b783f1db9a85c4d93 Reviewed-on: https://gerrit.libreoffice.org/82154 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/vcl/CppunitTest_vcl_pdfexport.mk b/vcl/CppunitTest_vcl_pdfexport.mk index 45123e7c2811..2721d15e410b 100644 --- a/vcl/CppunitTest_vcl_pdfexport.mk +++ b/vcl/CppunitTest_vcl_pdfexport.mk @@ -16,6 +16,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,vcl_pdfexport, \ $(eval $(call gb_CppunitTest_use_sdk_api,vcl_pdfexport)) $(eval $(call gb_CppunitTest_use_libraries,vcl_pdfexport, \ + basegfx \ comphelper \ cppu \ cppuhelper \ diff --git a/vcl/qa/cppunit/pdfexport/data/pdf-image-resource-inline-xobject-ref.pdf b/vcl/qa/cppunit/pdfexport/data/pdf-image-resource-inline-xobject-ref.pdf index b62068eae9dd..739a80c4766d 100644 Binary files a/vcl/qa/cppunit/pdfexport/data/pdf-image-resource-inline-xobject-ref.pdf and b/vcl/qa/cppunit/pdfexport/data/pdf-image-resource-inline-xobject-ref.pdf differ diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index ba62f301bec4..22585a9827eb 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -36,6 +36,7 @@ #include <fpdf_doc.h> #include <fpdfview.h> #include <vcl/graphicfilter.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> using namespace ::com::sun::star; @@ -1877,6 +1878,33 @@ void PdfExportTest::testPdfImageResourceInlineXObjectRef() // - Actual : 0 // i.e. the sub-form was missing its image. CPPUNIT_ASSERT_EQUAL(1, FPDFFormObj_CountObjects(pFormObject)); + + // Check if the inner form object (original page object in the pdf image) has the correct + // rotation. + FPDF_PAGEOBJECT pInnerFormObject = FPDFFormObj_GetObject(pFormObject, 0); + CPPUNIT_ASSERT_EQUAL(FPDF_PAGEOBJ_FORM, FPDFPageObj_GetType(pInnerFormObject)); + CPPUNIT_ASSERT_EQUAL(1, FPDFFormObj_CountObjects(pInnerFormObject)); + FPDF_PAGEOBJECT pImage = FPDFFormObj_GetObject(pInnerFormObject, 0); + CPPUNIT_ASSERT_EQUAL(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(pImage)); + double fA = 0; + double fB = 0; + double fC = 0; + double fD = 0; + double fE = 0; + double fF = 0; + FPDFFormObj_GetMatrix(pInnerFormObject, &fA, &fB, &fC, &fD, &fE, &fF); + basegfx::B2DHomMatrix aMat{ fA, fC, fE, fB, fD, fF }; + basegfx::B2DTuple aScale; + basegfx::B2DTuple aTranslate; + double fRotate = 0; + double fShearX = 0; + aMat.decompose(aScale, aTranslate, fRotate, fShearX); + int nRotateDeg = basegfx::rad2deg(fRotate); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: -90 + // - Actual : 0 + // i.e. rotation was lost on pdf export. + CPPUNIT_ASSERT_EQUAL(-90, nRotateDeg); } CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest); diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index faabdd8769f9..a63a2152e6b7 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -8842,6 +8842,34 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit) aLine.append(" 0 obj\n"); aLine.append("<< /Type /XObject"); aLine.append(" /Subtype /Form"); + + long nWidth = aSize.Width(); + long nHeight = aSize.Height(); + if (auto pRotate = dynamic_cast<filter::PDFNumberElement*>(pPage->Lookup("Rotate"))) + { + // The original page was rotated, then construct a transformation matrix which does the + // same with our form object. + if (rtl::math::approxEqual(pRotate->GetValue(), 90)) + { + std::swap(nWidth, nHeight); + basegfx::B2DHomMatrix aMat; + aMat.rotate(basegfx::deg2rad(pRotate->GetValue())); + // Rotate around the origo (bottom left corner) counter-clockwise, then translate + // horizontally to effectively keep the bottom left corner unchanged. + aLine.append(" /Matrix [ "); + aLine.append(aMat.get(0, 0)); + aLine.append(" "); + aLine.append(aMat.get(0, 1)); + aLine.append(" "); + aLine.append(aMat.get(1, 0)); + aLine.append(" "); + aLine.append(aMat.get(1, 1)); + aLine.append(" 0 "); + aLine.append(nWidth); + aLine.append(" ] "); + } + } + aLine.append(" /Resources <<"); static const std::initializer_list<OString> aKeys = { @@ -8855,9 +8883,9 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit) aLine.append(copyExternalResources(*pPage, rKey, aCopiedResources)); aLine.append(">>"); aLine.append(" /BBox [ 0 0 "); - aLine.append(aSize.Width()); + aLine.append(nWidth); aLine.append(" "); - aLine.append(aSize.Height()); + aLine.append(nHeight); aLine.append(" ]"); if (!g_bDebugDisableCompression) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits