[Libreoffice-commits] core.git: vcl/CppunitTest_vcl_pdfexport.mk vcl/qa vcl/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Wed Nov 6 16:58:28 UTC 2019


 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 <vmiklos at collabora.com>
AuthorDate: Wed Nov 6 16:48:55 2019 +0100
Commit:     Miklos Vajna <vmiklos at 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 <vmiklos at 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)


More information about the Libreoffice-commits mailing list