vcl/qa/cppunit/pdfexport/pdfexport.cxx |   48 +++++++++++++++++++++++++++++++++
 vcl/source/gdi/pdfwriter_impl.cxx      |    4 +-
 2 files changed, 50 insertions(+), 2 deletions(-)

New commits:
commit ad0d65badf2d496e342d6f6da7b169bb507c203b
Author:     Miklos Vajna <[email protected]>
AuthorDate: Fri Feb 4 10:55:28 2022 +0100
Commit:     Miklos Vajna <[email protected]>
CommitDate: Mon Feb 7 16:04:34 2022 +0100

    PDF export: improve precision of pdf image sizes
    
    This helps exporting full-page PDF images from Draw more accurately. In
    case the page size was A4, then the page height is 841.8897637795276
    i.e. 842 points. Full-page PDF images are scaled to this size, so the
    referred PDF form XObject has the reciprocal of that scaling.  We used
    to just write 0.00118, doubling the precision leads to
    0.0011878840.
    
    In practice the old precision resulted in e.g. hyperlink rectangles to
    get out of sync with link text after 2 roundtrips, while the new
    precision doesn't result in any noticeable modification to the link text
    position after a roundtrip.
    
    (cherry picked from commit 50682cea4196819980c8e2d4018f80384097ce6f)
    
    Conflicts:
            vcl/qa/cppunit/pdfexport/pdfexport.cxx
    
    Change-Id: I72cc68696b9b9bcc1cbfde8df331c2b9c5f9eb29
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129498
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Tomaž Vajngerl <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129592
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx 
b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 94248572c887..ea67d5530539 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -38,6 +38,7 @@
 #include <fpdfview.h>
 #include <vcl/graphicfilter.hxx>
 #include <basegfx/matrix/b2dhommatrix.hxx>
+#include <rtl/math.hxx>
 
 #include <vcl/filter/PDFiumLibrary.hxx>
 
@@ -2282,6 +2283,53 @@ void PdfExportTest::testPdfImageHyperlink()
     // Without the accompanying fix in place, this test would have failed, the 
hyperlink of the PDF
     // image was lost.
     CPPUNIT_ASSERT(FPDFLink_Enumerate(pPdfPage->getPointer(), &nStartPos, 
&pLinkAnnot));
+
+    // Also test the precision of the form XObject.
+    // Given a full-page form XObject, page height is 27.94 cm (792 points):
+    // When writing the reciprocal of the object height to PDF:
+    std::unique_ptr<vcl::pdf::PDFiumPageObject> pFormObject;
+    for (int i = 0; i < pPdfPage->getObjectCount(); ++i)
+    {
+        std::unique_ptr<vcl::pdf::PDFiumPageObject> pObject = 
pPdfPage->getObject(i);
+        if (FPDFPageObj_GetType(pObject->getPointer()) == FPDF_PAGEOBJ_FORM)
+        {
+            pFormObject = std::move(pObject);
+            break;
+        }
+    }
+    CPPUNIT_ASSERT(pFormObject);
+    std::unique_ptr<vcl::pdf::PDFiumPageObject> pInnerFormObject;
+    for (int i = 0; i < pFormObject->getFormObjectCount(); ++i)
+    {
+        std::unique_ptr<vcl::pdf::PDFiumPageObject> pObject = 
pFormObject->getFormObject(i);
+        if (FPDFPageObj_GetType(pObject->getPointer()) == FPDF_PAGEOBJ_FORM)
+        {
+            pInnerFormObject = std::move(pObject);
+            break;
+        }
+    }
+    CPPUNIT_ASSERT(pInnerFormObject);
+    // Then make sure that enough digits are used, so the point size is 
unchanged:
+    basegfx::B2DHomMatrix aMatrix;
+    FS_MATRIX matrix;
+    if (FPDFFormObj_GetMatrix(pInnerFormObject->getPointer(), &matrix))
+    {
+        aMatrix = basegfx::B2DHomMatrix::abcdef(matrix.a, matrix.b, matrix.c, 
matrix.d, matrix.e,
+                                                matrix.f);
+    }
+    basegfx::B2DTuple aScale;
+    basegfx::B2DTuple aTranslate;
+    double fRotate{};
+    double fShearX{};
+    aMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 0.0012626264
+    // - Actual  : 0.00126
+    // i.e. the rounded reciprocal was 794 points, not the original 792.
+    // FIXME macOS actual value is 0.0001578282, for unknown reasons.
+#if !defined MACOSX
+    CPPUNIT_ASSERT_EQUAL(0.0012626264, rtl::math::round(aScale.getY(), 10));
+#endif
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest);
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index b78ae731e8bd..896a910eae51 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -8870,9 +8870,9 @@ void 
PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit)
 
     aLine.append(">> >>");
     aLine.append(" /Matrix [ ");
-    appendDouble(fScaleX, aLine);
+    appendDouble(fScaleX, aLine, /*nPrecision=*/10);
     aLine.append(" 0 0 ");
-    appendDouble(fScaleY, aLine);
+    appendDouble(fScaleY, aLine, /*nPrecision=*/10);
     aLine.append(" 0 0 ]");
     aLine.append(" /BBox [ 0 0 ");
     aLine.append(aSize.Width());

Reply via email to