From 5772cef244dbee5834efbc693bc714d89ae6301d Mon Sep 17 00:00:00 2001 From: Mike Kaganski Date: Wed, 15 Jun 2022 18:33:38 +0300 Subject: [PATCH] tdf#134210: Reimplement cropping from srcRect and fillRect This avoids the scaling after the crop, since scaling is performed anyway when applying BitmapMode_STRETCH. This improves resulting bitmap quality. Also consider the "crop to zero" case (when the sum of cropped parts is equal to 100%). In that case, just use an empty graphic as the fill bitmap. This makes the differences between srcRect and fillRect processing explicit, simplifies the code, avoids extra rounding inaccuracies, and takes care of the edge cases that were considered in commit 2859ec288f2c1323ea3123d82cb1684b349ff598 Author Miklos Vajna Date Wed Jun 15 15:52:18 2022 +0200 oox: fix div by zero in lclCalculateCropPercentage() The change in SdImportTest2::testTdf134210 is because we now don't scale the cropped image. The previous value was an interpolated color, while the new value is the actual color of pixel [0, 41] of the original image. Change-Id: I24fa9928cff32bcaa6a7b3e34def14700fddd7ca Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135917 Tested-by: Jenkins Reviewed-by: Mike Kaganski --- oox/source/drawingml/fillproperties.cxx | 96 ++++++++++-------------- sd/qa/unit/data/pptx/croppedTo0.pptx | Bin 0 -> 32741 bytes sd/qa/unit/import-tests2.cxx | 10 ++- 3 files changed, 50 insertions(+), 56 deletions(-) create mode 100644 sd/qa/unit/data/pptx/croppedTo0.pptx diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx index 93fea51194ef..9270201920b3 100644 --- a/oox/source/drawingml/fillproperties.cxx +++ b/oox/source/drawingml/fillproperties.cxx @@ -88,67 +88,55 @@ Reference< XGraphic > lclRotateGraphic(uno::Reference const & return aReturnGraphic.GetXGraphic(); } -void lclCalculateCropPercentage(uno::Reference const & xGraphic, geometry::IntegerRectangle2D &aFillRect) +using Quotients = std::tuple; +Quotients getQuotients(geometry::IntegerRectangle2D aRelRect, double hDiv, double vDiv) { - ::Graphic aGraphic(xGraphic); - assert (aGraphic.GetType() == GraphicType::Bitmap); - - BitmapEx aBitmapEx(aGraphic.GetBitmapEx()); - - sal_Int32 nScaledWidth = aBitmapEx.GetSizePixel().Width(); - sal_Int32 nScaledHeight = aBitmapEx.GetSizePixel().Height(); - - sal_Int32 nOrigWidth = (nScaledWidth * (100000 - aFillRect.X1 - aFillRect.X2)) / 100000; - if (nOrigWidth == 0) - { - nOrigWidth = 1; - } - sal_Int32 nOrigHeight = (nScaledHeight * (100000 - aFillRect.Y1 - aFillRect.Y2)) / 100000; - if (nOrigHeight == 0) - { - nOrigHeight = 1; - } - - sal_Int32 nLeftPercentage = nScaledWidth * aFillRect.X1 / nOrigWidth; - sal_Int32 nRightPercentage = nScaledWidth * aFillRect.X2 / nOrigWidth; - sal_Int32 nTopPercentage = nScaledHeight * aFillRect.Y1 / nOrigHeight; - sal_Int32 nBottomPercentage = nScaledHeight * aFillRect.Y2 / nOrigHeight; - - aFillRect.X1 = -nLeftPercentage; - aFillRect.X2 = -nRightPercentage; - aFillRect.Y1 = -nTopPercentage; - aFillRect.Y2 = -nBottomPercentage; + return { aRelRect.X1 / hDiv, aRelRect.Y1 / vDiv, aRelRect.X2 / hDiv, aRelRect.Y2 / vDiv }; } -// Crops a piece of the bitmap. Takes negative aFillRect values. Negative values means "crop", -// positive values means "grow" bitmap with empty spaces. lclCropGraphic doesn't handle growing. -Reference< XGraphic > lclCropGraphic(uno::Reference const & xGraphic, geometry::IntegerRectangle2D aFillRect) +// ECMA-376 Part 1 20.1.8.55 srcRect (Source Rectangle) +std::optional CropQuotientsFromSrcRect(geometry::IntegerRectangle2D aSrcRect) +{ + // Currently the following precondition is guaranteed in GraphicProperties::pushToPropMap + assert(aSrcRect.X1 >= 0 && aSrcRect.X2 >= 0 && aSrcRect.Y1 >= 0 && aSrcRect.Y2 >= 0); + if (aSrcRect.X1 + aSrcRect.X2 >= 100'000 || aSrcRect.Y1 + aSrcRect.Y2 >= 100'000) + return {}; // Cropped everything + return getQuotients(aSrcRect, 100'000.0, 100'000.0); +} + +// ECMA-376 Part 1 20.1.8.30 fillRect (Fill Rectangle) +std::optional CropQuotientsFromFillRect(geometry::IntegerRectangle2D aFillRect) +{ + // Currently the following precondition is guaranteed in FillProperties::pushToPropMap + assert(aFillRect.X1 <= 0 && aFillRect.X2 <= 0 && aFillRect.Y1 <= 0 && aFillRect.Y2 <= 0); + // Negative divisor and negative relative offset give positive value wanted in lclCropGraphic + return getQuotients(aFillRect, -100'000.0 + aFillRect.X1 + aFillRect.X2, + -100'000.0 + aFillRect.Y1 + aFillRect.Y2); +} + +// Crops a piece of the bitmap. lclCropGraphic doesn't handle growing. +Reference lclCropGraphic(uno::Reference const& xGraphic, + std::optional quotients) { ::Graphic aGraphic(xGraphic); - ::Graphic aReturnGraphic; - assert (aGraphic.GetType() == GraphicType::Bitmap); - BitmapEx aBitmapEx(aGraphic.GetBitmapEx()); + BitmapEx aBitmapEx; + if (quotients) + { + aBitmapEx = aGraphic.GetBitmapEx(); - sal_Int32 nOrigHeight = aBitmapEx.GetSizePixel().Height(); - sal_Int32 nHeight = nOrigHeight; - sal_Int32 nTopCorr = nOrigHeight * -1 * static_cast(aFillRect.Y1) / 100000; - nHeight += nTopCorr; - sal_Int32 nBottomCorr = nOrigHeight * -1 * static_cast(aFillRect.Y2) / 100000; - nHeight += nBottomCorr; + const Size bmpSize = aBitmapEx.GetSizePixel(); + const auto& [qx1, qy1, qx2, qy2] = *quotients; + const tools::Long l = std::round(bmpSize.Width() * qx1); + const tools::Long t = std::round(bmpSize.Height() * qy1); + const tools::Long r = std::round(bmpSize.Width() * qx2); + const tools::Long b = std::round(bmpSize.Height() * qy2); - sal_Int32 nOrigWidth = aBitmapEx.GetSizePixel().Width(); - sal_Int32 nWidth = nOrigWidth; - sal_Int32 nLeftCorr = nOrigWidth * -1 * static_cast(aFillRect.X1) / 100000; - nWidth += nLeftCorr; - sal_Int32 nRightCorr = nOrigWidth * -1 * static_cast(aFillRect.X2) / 100000; - nWidth += nRightCorr; + aBitmapEx.Crop({ l, t, bmpSize.Width() - r - 1, bmpSize.Height() - b - 1 }); + } - aBitmapEx.Scale(Size(nWidth, nHeight)); - aBitmapEx.Crop(tools::Rectangle(Point(nLeftCorr, nTopCorr), Size(nOrigWidth, nOrigHeight))); - - aReturnGraphic = ::Graphic(aBitmapEx); + ::Graphic aReturnGraphic(aBitmapEx); aReturnGraphic.setOriginURL(aGraphic.getOriginURL()); return aReturnGraphic.GetXGraphic(); @@ -818,7 +806,7 @@ void FillProperties::pushToPropMap( ShapePropertyMap& rPropMap, if(bIsCustomShape && bHasCropValues && bNeedCrop) { - xGraphic = lclCropGraphic(xGraphic, aFillRect); + xGraphic = lclCropGraphic(xGraphic, CropQuotientsFromFillRect(aFillRect)); rPropMap.setProperty(ShapeProperty::FillBitmap, xGraphic); } } @@ -932,9 +920,7 @@ void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const GraphicHelpe if(mbIsCustomShape && bHasCropValues && bNeedCrop) { - geometry::IntegerRectangle2D aCropRect = oClipRect; - lclCalculateCropPercentage(xGraphic, aCropRect); - xGraphic = lclCropGraphic(xGraphic, aCropRect); + xGraphic = lclCropGraphic(xGraphic, CropQuotientsFromSrcRect(oClipRect)); } } } diff --git a/sd/qa/unit/data/pptx/croppedTo0.pptx b/sd/qa/unit/data/pptx/croppedTo0.pptx new file mode 100644 index 0000000000000000000000000000000000000000..fecf53559b1fb6c910f35b3367116a573def1443 GIT binary patch literal 32741 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 literal 0 HcmV?d00001 diff --git a/sd/qa/unit/import-tests2.cxx b/sd/qa/unit/import-tests2.cxx index 3bddc580c07d..8ada9e682f39 100644 --- a/sd/qa/unit/import-tests2.cxx +++ b/sd/qa/unit/import-tests2.cxx @@ -135,6 +135,7 @@ public: void testTdf112209(); void testTdf128596(); void testDefaultTabStop(); + void testCropToZero(); CPPUNIT_TEST_SUITE(SdImportTest2); @@ -204,6 +205,7 @@ public: CPPUNIT_TEST(testTdf112209); CPPUNIT_TEST(testTdf128596); CPPUNIT_TEST(testDefaultTabStop); + CPPUNIT_TEST(testCropToZero); CPPUNIT_TEST_SUITE_END(); }; @@ -1293,7 +1295,7 @@ void SdImportTest2::testTdf134210() Graphic aGraphic(xGraphic); BitmapEx aBitmap(aGraphic.GetBitmapEx()); - CPPUNIT_ASSERT_EQUAL(Color(0x60563e), aBitmap.GetPixelColor(0, 0)); + CPPUNIT_ASSERT_EQUAL(Color(0x605741), aBitmap.GetPixelColor(0, 0)); xDocShRef->DoClose(); } @@ -2035,6 +2037,12 @@ void SdImportTest2::testDefaultTabStop() xDocShRef->DoClose(); } +void SdImportTest2::testCropToZero() +{ + // Must not crash because of division by zero + loadURL(m_directories.getURLFromSrc(u"/sd/qa/unit/data/pptx/croppedTo0.pptx"), PPTX); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTest2); CPPUNIT_PLUGIN_IMPLEMENT();