diff options
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/drawingml/fillproperties.cxx | 92 |
1 files changed, 39 insertions, 53 deletions
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<graphic::XGraphic> const & return aReturnGraphic.GetXGraphic(); } -void lclCalculateCropPercentage(uno::Reference<graphic::XGraphic> const & xGraphic, geometry::IntegerRectangle2D &aFillRect) +using Quotients = std::tuple<double, double, double, double>; +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; - } + return { aRelRect.X1 / hDiv, aRelRect.Y1 / vDiv, aRelRect.X2 / hDiv, aRelRect.Y2 / vDiv }; +} - 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; +// ECMA-376 Part 1 20.1.8.55 srcRect (Source Rectangle) +std::optional<Quotients> 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); +} - aFillRect.X1 = -nLeftPercentage; - aFillRect.X2 = -nRightPercentage; - aFillRect.Y1 = -nTopPercentage; - aFillRect.Y2 = -nBottomPercentage; +// ECMA-376 Part 1 20.1.8.30 fillRect (Fill Rectangle) +std::optional<Quotients> 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. 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<graphic::XGraphic> const & xGraphic, geometry::IntegerRectangle2D aFillRect) +// Crops a piece of the bitmap. lclCropGraphic doesn't handle growing. +Reference<XGraphic> lclCropGraphic(uno::Reference<graphic::XGraphic> const& xGraphic, + std::optional<Quotients> quotients) { ::Graphic aGraphic(xGraphic); - ::Graphic aReturnGraphic; - assert (aGraphic.GetType() == GraphicType::Bitmap); - BitmapEx aBitmapEx(aGraphic.GetBitmapEx()); - - sal_Int32 nOrigHeight = aBitmapEx.GetSizePixel().Height(); - sal_Int32 nHeight = nOrigHeight; - sal_Int32 nTopCorr = nOrigHeight * -1 * static_cast<double>(aFillRect.Y1) / 100000; - nHeight += nTopCorr; - sal_Int32 nBottomCorr = nOrigHeight * -1 * static_cast<double>(aFillRect.Y2) / 100000; - nHeight += nBottomCorr; + BitmapEx aBitmapEx; + if (quotients) + { + aBitmapEx = aGraphic.GetBitmapEx(); - sal_Int32 nOrigWidth = aBitmapEx.GetSizePixel().Width(); - sal_Int32 nWidth = nOrigWidth; - sal_Int32 nLeftCorr = nOrigWidth * -1 * static_cast<double>(aFillRect.X1) / 100000; - nWidth += nLeftCorr; - sal_Int32 nRightCorr = nOrigWidth * -1 * static_cast<double>(aFillRect.X2) / 100000; - nWidth += nRightCorr; + 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); - aBitmapEx.Scale(Size(nWidth, nHeight)); - aBitmapEx.Crop(tools::Rectangle(Point(nLeftCorr, nTopCorr), Size(nOrigWidth, nOrigHeight))); + aBitmapEx.Crop({ l, t, bmpSize.Width() - r - 1, bmpSize.Height() - b - 1 }); + } - 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)); } } } |