sw/source/uibase/app/docstyle.cxx | 18 +++++--- vcl/qa/cppunit/pdfexport/data/bitmap-scaledown.odt |binary vcl/qa/cppunit/pdfexport/pdfexport.cxx | 47 ++++++++++++++++++--- vcl/source/outdev/bitmapex.cxx | 10 ---- 4 files changed, 53 insertions(+), 22 deletions(-)
New commits: commit 8a3548eb859553a930a6120105cd30b3cc0ffeb3 Author: Miklos Vajna <[email protected]> AuthorDate: Wed Aug 3 09:44:03 2022 +0200 Commit: Xisco Fauli <[email protected]> CommitDate: Mon Aug 8 15:59:24 2022 +0200 tdf#149943 vcl: fix pixelated PDF export and print for a rotated image The bugdoc has a barcode which looks good in Writer, but it's quite blurry in the PDF export result. This is a problem since commit dd4a67084853a030bf4b9f1f85d728620e0604a5 (vcl: avoid downscale && upscale in DrawTransformedBitmapEx(), 2019-10-08), where the motivation was to not downscale a bitmap in case it has a larger amount of pixels but a smaller logic size. This went wrong here and resulted in a blurry bitmap for a not so small image. Fix the problem by mostly reverting the above commit, because it's no longer necessary: 68549e00d5e23aa22bc974a8151d93cd948444b3 (vcl, BitmapEx transformed draw: special-case simple rotations, 2019-10-10) already made sure that the rotation case doesn't use scaling from the transform. testTdf128630 has been adapted to pass again (after manually verifying that the bugdoc export result is still OK), now the bad case there simply produces a smaller bitmap. (cherry picked from commit 7c94d7267bc8b5f43185204ab4953c4b188214bf) Change-Id: Ib28881c129a0cf037a96eecd065e5cadede97051 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137743 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137950 diff --git a/vcl/qa/cppunit/pdfexport/data/bitmap-scaledown.odt b/vcl/qa/cppunit/pdfexport/data/bitmap-scaledown.odt new file mode 100644 index 000000000000..da9b167fd9d7 Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/bitmap-scaledown.odt differ diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index a3b351056228..5701fe613a35 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -1513,7 +1513,7 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf128630) // The document has one page. CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount()); - // Assert the aspect ratio of the only bitmap on the page. + // Assert the size of the only bitmap on the page. std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(/*nIndex=*/0); CPPUNIT_ASSERT(pPdfPage); int nPageObjectCount = pPdfPage->getObjectCount(); @@ -1526,12 +1526,13 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf128630) std::unique_ptr<vcl::pdf::PDFiumBitmap> pBitmap = pPageObject->getImageBitmap(); CPPUNIT_ASSERT(pBitmap); int nWidth = pBitmap->getWidth(); - int nHeight = pBitmap->getHeight(); // Without the accompanying fix in place, this test would have failed with: - // assertion failed - // - Expression: nWidth != nHeight - // i.e. the bitmap lost its custom aspect ratio during export. - CPPUNIT_ASSERT(nWidth != nHeight); + // - Expected: 466 + // - Actual : 289 + // i.e. the rotated + scaled arrow was more thin than it should be. + CPPUNIT_ASSERT_EQUAL(466, nWidth); + int nHeight = pBitmap->getHeight(); + CPPUNIT_ASSERT_EQUAL(466, nHeight); } } @@ -3183,6 +3184,40 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testPdfImageAnnots) // i.e. not only the hyperlink but also the 2 comments were exported, leading to duplication. CPPUNIT_ASSERT_EQUAL(1, pPdfPage->getAnnotationCount()); } + +CPPUNIT_TEST_FIXTURE(PdfExportTest, testBitmapScaledown) +{ + // Given a document with an upscaled and rotated barcode bitmap in it: + aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); + + // When saving as PDF: + saveAsPDF(u"bitmap-scaledown.odt"); + + // Then verify that the bitmap is not downscaled: + std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = parseExport(); + CPPUNIT_ASSERT(pPdfDocument); + CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount()); + std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(/*nIndex=*/0); + CPPUNIT_ASSERT(pPdfPage); + int nPageObjectCount = pPdfPage->getObjectCount(); + for (int i = 0; i < nPageObjectCount; ++i) + { + std::unique_ptr<vcl::pdf::PDFiumPageObject> pPageObject = pPdfPage->getObject(i); + if (pPageObject->getType() != vcl::pdf::PDFPageObjectType::Image) + continue; + + std::unique_ptr<vcl::pdf::PDFiumBitmap> pBitmap = pPageObject->getImageBitmap(); + CPPUNIT_ASSERT(pBitmap); + // In-file sizes: good is 2631x380, bad is 1565x14. + int nWidth = pBitmap->getWidth(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 2616 + // - Actual : 1565 + // i.e. the bitmap in the pdf result was small enough to be blurry. + CPPUNIT_ASSERT_EQUAL(2616, nWidth); + } +} + } // end anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/vcl/source/outdev/bitmapex.cxx b/vcl/source/outdev/bitmapex.cxx index 7855d1ae5613..bf84bb35d963 100644 --- a/vcl/source/outdev/bitmapex.cxx +++ b/vcl/source/outdev/bitmapex.cxx @@ -624,19 +624,9 @@ void OutputDevice::DrawTransformedBitmapEx( aTransformed = BitmapEx(aContent, aMaskBmp); } - // Remove scaling from aFulltransform: we transform due to shearing or rotation, scaling - // will happen according to aDestSize. basegfx::B2DVector aFullScale, aFullTranslate; double fFullRotate, fFullShearX; aFullTransform.decompose(aFullScale, aFullTranslate, fFullRotate, fFullShearX); - // Require positive scaling, negative scaling would loose horizontal or vertical flip. - if (aFullScale.getX() > 0 && aFullScale.getY() > 0) - { - basegfx::B2DHomMatrix aTransform = basegfx::utils::createScaleB2DHomMatrix( - rOriginalSizePixel.getWidth() / aFullScale.getX(), - rOriginalSizePixel.getHeight() / aFullScale.getY()); - aFullTransform *= aTransform; - } double fSourceRatio = 1.0; if (rOriginalSizePixel.getHeight() != 0) commit b87c3e7ecb7e9f1914cc81a1758f9f2aa5170f78 Author: Mike Kaganski <[email protected]> AuthorDate: Wed Aug 3 09:47:40 2022 +0300 Commit: Xisco Fauli <[email protected]> CommitDate: Mon Aug 8 15:59:11 2022 +0200 tdf#150241: a blind fix attempt I can't repro it locally (the report misses clear repro steps), but the three changed OUString assignment operators use rtl::str::assign internally, and the unconditional dereference of the value returned from SwDoc::GetDocPattern (that may return a nullptr) is suspicious, especially compared to the checks made in SwDocStyleSheet::GetHelpId later in the same file. All four calls to GetDocPattern in the file were introduced in commit 7b0b5cdfeed656b279bc32cd929630d5fc25878b Author Jens-Heiner Rechtien <[email protected]> Date Mon Sep 18 16:15:01 2000 +0000 initial import Change-Id: If9d4cff921443e5af71b7d541b79d00ea77e853b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137734 Tested-by: Jenkins Reviewed-by: Mike Kaganski <[email protected]> (cherry picked from commit 4afb80eaa0df58b78e2bfad892f9e7ce5e1bce7a) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137962 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/sw/source/uibase/app/docstyle.cxx b/sw/source/uibase/app/docstyle.cxx index 398f8775ba47..8ab68590c1a9 100644 --- a/sw/source/uibase/app/docstyle.cxx +++ b/sw/source/uibase/app/docstyle.cxx @@ -1986,8 +1986,10 @@ bool SwDocStyleSheet::FillStyleSheet( { nPoolId = m_pDesc->GetPoolFormatId(); nHelpId = m_pDesc->GetPoolHelpId(); - if( m_pDesc->GetPoolHlpFileId() != UCHAR_MAX ) - aHelpFile = *m_rDoc.GetDocPattern( m_pDesc->GetPoolHlpFileId() ); + if (const OUString* pattern = m_pDesc->GetPoolHlpFileId() != UCHAR_MAX + ? m_rDoc.GetDocPattern(m_pDesc->GetPoolHlpFileId()) + : nullptr) + aHelpFile = *pattern; else aHelpFile.clear(); } @@ -2015,8 +2017,10 @@ bool SwDocStyleSheet::FillStyleSheet( { nPoolId = m_pNumRule->GetPoolFormatId(); nHelpId = m_pNumRule->GetPoolHelpId(); - if( m_pNumRule->GetPoolHlpFileId() != UCHAR_MAX ) - aHelpFile = *m_rDoc.GetDocPattern( m_pNumRule->GetPoolHlpFileId() ); + if (const OUString* pattern = m_pNumRule->GetPoolHlpFileId() != UCHAR_MAX + ? m_rDoc.GetDocPattern(m_pNumRule->GetPoolHlpFileId()) + : nullptr) + aHelpFile = *pattern; else aHelpFile.clear(); } @@ -2071,8 +2075,10 @@ bool SwDocStyleSheet::FillStyleSheet( OSL_ENSURE( m_bPhysical, "Format not found" ); nHelpId = pFormat->GetPoolHelpId(); - if( pFormat->GetPoolHlpFileId() != UCHAR_MAX ) - aHelpFile = *m_rDoc.GetDocPattern( pFormat->GetPoolHlpFileId() ); + if (const OUString* pattern = pFormat->GetPoolHlpFileId() != UCHAR_MAX + ? m_rDoc.GetDocPattern(pFormat->GetPoolHlpFileId()) + : nullptr) + aHelpFile = *pattern; else aHelpFile.clear();
