summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2022-08-21 19:51:58 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2022-08-22 09:27:53 +0200
commitb2b3b4e833484aa70cb73b296bb62cdb0304eac9 (patch)
tree0b6044f46f5aa8c625c289698dcd8fab72cae3aa /drawinglayer
parentf1adf4e4672b805fbda5682f4e0e6f08aed5ce79 (diff)
flatten logic in RenderFillGraphicPrimitive2D a little
splitting part of it out into a helper function Change-Id: I135ba5c6c823eec9f708b4652900e06fa06bbba7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138641 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/source/processor2d/vclprocessor2d.cxx389
-rw-r--r--drawinglayer/source/processor2d/vclprocessor2d.hxx4
2 files changed, 191 insertions, 202 deletions
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index 112ac2b591c7..5c4b15a906c9 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -450,243 +450,228 @@ void VclProcessor2D::RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2
void VclProcessor2D::RenderFillGraphicPrimitive2D(
const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate)
{
+ bool bPrimitiveAccepted = RenderFillGraphicPrimitive2DImpl(rFillBitmapCandidate);
+
+ if (!bPrimitiveAccepted)
+ {
+ // do not accept, use decomposition
+ process(rFillBitmapCandidate);
+ }
+}
+
+bool VclProcessor2D::RenderFillGraphicPrimitive2DImpl(
+ const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate)
+{
const attribute::FillGraphicAttribute& rFillGraphicAttribute(
rFillBitmapCandidate.getFillGraphic());
- bool bPrimitiveAccepted(false);
// #121194# when tiling is used and content is bitmap-based, do direct tiling in the
// renderer on pixel base to ensure tight fitting. Do not do this when
// the fill is rotated or sheared.
- if (rFillGraphicAttribute.getTiling())
- {
- // content is bitmap(ex)
- //
- // for Vector Graphic Data (SVG, EMF+) support, force decomposition when present. This will lead to use
- // the primitive representation of the vector data directly.
- //
- // when graphic is animated, force decomposition to use the correct graphic, else
- // fill style will not be animated
- if (GraphicType::Bitmap == rFillGraphicAttribute.getGraphic().GetType()
- && !rFillGraphicAttribute.getGraphic().getVectorGraphicData()
- && !rFillGraphicAttribute.getGraphic().IsAnimated())
- {
- // decompose matrix to check for shear, rotate and mirroring
- basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation
- * rFillBitmapCandidate.getTransformation());
- basegfx::B2DVector aScale, aTranslate;
- double fRotate, fShearX;
- aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX);
-
- // when nopt rotated/sheared
- if (basegfx::fTools::equalZero(fRotate) && basegfx::fTools::equalZero(fShearX))
- {
- // no shear or rotate, draw direct in pixel coordinates
- bPrimitiveAccepted = true;
+ if (!rFillGraphicAttribute.getTiling())
+ return false;
+
+ // content is bitmap(ex)
+ //
+ // for Vector Graphic Data (SVG, EMF+) support, force decomposition when present. This will lead to use
+ // the primitive representation of the vector data directly.
+ //
+ // when graphic is animated, force decomposition to use the correct graphic, else
+ // fill style will not be animated
+ if (GraphicType::Bitmap != rFillGraphicAttribute.getGraphic().GetType()
+ || rFillGraphicAttribute.getGraphic().getVectorGraphicData()
+ || rFillGraphicAttribute.getGraphic().IsAnimated())
+ return false;
+
+ // decompose matrix to check for shear, rotate and mirroring
+ basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation
+ * rFillBitmapCandidate.getTransformation());
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX);
- // transform object range to device coordinates (pixels). Use
- // the device transformation for better accuracy
- basegfx::B2DRange aObjectRange(aTranslate, aTranslate + aScale);
- aObjectRange.transform(mpOutputDevice->GetViewTransformation());
+ // when nopt rotated/sheared
+ if (!basegfx::fTools::equalZero(fRotate) || !basegfx::fTools::equalZero(fShearX))
+ return false;
- // extract discrete size of object
- const sal_Int32 nOWidth(basegfx::fround(aObjectRange.getWidth()));
- const sal_Int32 nOHeight(basegfx::fround(aObjectRange.getHeight()));
+ // no shear or rotate, draw direct in pixel coordinates
- // only do something when object has a size in discrete units
- if (nOWidth > 0 && nOHeight > 0)
- {
- // transform graphic range to device coordinates (pixels). Use
- // the device transformation for better accuracy
- basegfx::B2DRange aGraphicRange(rFillGraphicAttribute.getGraphicRange());
- aGraphicRange.transform(mpOutputDevice->GetViewTransformation()
- * aLocalTransform);
-
- // extract discrete size of graphic
- // caution: when getting to zero, nothing would be painted; thus, do not allow this
- const sal_Int32 nBWidth(
- std::max(sal_Int32(1), basegfx::fround(aGraphicRange.getWidth())));
- const sal_Int32 nBHeight(
- std::max(sal_Int32(1), basegfx::fround(aGraphicRange.getHeight())));
-
- // only do something when bitmap fill has a size in discrete units
- if (nBWidth > 0 && nBHeight > 0)
- {
- // nBWidth, nBHeight is the pixel size of the needed bitmap. To not need to scale it
- // in vcl many times, create a size-optimized version
- const Size aNeededBitmapSizePixel(nBWidth, nBHeight);
- BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx());
- const bool bPreScaled(nBWidth * nBHeight < (250 * 250));
-
- // ... but only up to a maximum size, else it gets too expensive
- if (bPreScaled)
- {
- // if color depth is below 24bit, expand before scaling for better quality.
- // This is even needed for low colors, else the scale will produce
- // a bitmap in gray or Black/White (!)
- if (isPalettePixelFormat(aBitmapEx.getPixelFormat()))
- {
- aBitmapEx.Convert(BmpConversion::N24Bit);
- }
+ // transform object range to device coordinates (pixels). Use
+ // the device transformation for better accuracy
+ basegfx::B2DRange aObjectRange(aTranslate, aTranslate + aScale);
+ aObjectRange.transform(mpOutputDevice->GetViewTransformation());
- aBitmapEx.Scale(aNeededBitmapSizePixel, BmpScaleFlag::Interpolate);
- }
+ // extract discrete size of object
+ const sal_Int32 nOWidth(basegfx::fround(aObjectRange.getWidth()));
+ const sal_Int32 nOHeight(basegfx::fround(aObjectRange.getHeight()));
- bool bPainted(false);
+ // only do something when object has a size in discrete units
+ if (nOWidth <= 0 || nOHeight <= 0)
+ return true;
- if (maBColorModifierStack.count())
- {
- // when color modifier, apply to bitmap
- aBitmapEx = aBitmapEx.ModifyBitmapEx(maBColorModifierStack);
+ // transform graphic range to device coordinates (pixels). Use
+ // the device transformation for better accuracy
+ basegfx::B2DRange aGraphicRange(rFillGraphicAttribute.getGraphicRange());
+ aGraphicRange.transform(mpOutputDevice->GetViewTransformation() * aLocalTransform);
- // impModifyBitmapEx uses empty bitmap as sign to return that
- // the content will be completely replaced to mono color, use shortcut
- if (aBitmapEx.IsEmpty())
- {
- // color gets completely replaced, get it
- const basegfx::BColor aModifiedColor(
- maBColorModifierStack.getModifiedColor(basegfx::BColor()));
- basegfx::B2DPolygon aPolygon(basegfx::utils::createUnitPolygon());
- aPolygon.transform(aLocalTransform);
+ // extract discrete size of graphic
+ // caution: when getting to zero, nothing would be painted; thus, do not allow this
+ const sal_Int32 nBWidth(std::max(sal_Int32(1), basegfx::fround(aGraphicRange.getWidth())));
+ const sal_Int32 nBHeight(std::max(sal_Int32(1), basegfx::fround(aGraphicRange.getHeight())));
- mpOutputDevice->SetFillColor(Color(aModifiedColor));
- mpOutputDevice->SetLineColor();
- mpOutputDevice->DrawPolygon(aPolygon);
+ // only do something when bitmap fill has a size in discrete units
+ if (nBWidth <= 0 || nBHeight <= 0)
+ return true;
- bPainted = true;
- }
- }
+ // nBWidth, nBHeight is the pixel size of the needed bitmap. To not need to scale it
+ // in vcl many times, create a size-optimized version
+ const Size aNeededBitmapSizePixel(nBWidth, nBHeight);
+ BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx());
+ const bool bPreScaled(nBWidth * nBHeight < (250 * 250));
- if (!bPainted)
- {
- sal_Int32 nBLeft(basegfx::fround(aGraphicRange.getMinX()));
- sal_Int32 nBTop(basegfx::fround(aGraphicRange.getMinY()));
- const sal_Int32 nOLeft(basegfx::fround(aObjectRange.getMinX()));
- const sal_Int32 nOTop(basegfx::fround(aObjectRange.getMinY()));
- sal_Int32 nPosX(0);
- sal_Int32 nPosY(0);
-
- if (nBLeft > nOLeft)
- {
- const sal_Int32 nDiff((nBLeft / nBWidth) + 1);
+ // ... but only up to a maximum size, else it gets too expensive
+ if (bPreScaled)
+ {
+ // if color depth is below 24bit, expand before scaling for better quality.
+ // This is even needed for low colors, else the scale will produce
+ // a bitmap in gray or Black/White (!)
+ if (isPalettePixelFormat(aBitmapEx.getPixelFormat()))
+ {
+ aBitmapEx.Convert(BmpConversion::N24Bit);
+ }
- nPosX -= nDiff;
- nBLeft -= nDiff * nBWidth;
- }
+ aBitmapEx.Scale(aNeededBitmapSizePixel, BmpScaleFlag::Interpolate);
+ }
- if (nBLeft + nBWidth <= nOLeft)
- {
- const sal_Int32 nDiff(-nBLeft / nBWidth);
+ if (maBColorModifierStack.count())
+ {
+ // when color modifier, apply to bitmap
+ aBitmapEx = aBitmapEx.ModifyBitmapEx(maBColorModifierStack);
- nPosX += nDiff;
- nBLeft += nDiff * nBWidth;
- }
+ // ModifyBitmapEx uses empty bitmap as sign to return that
+ // the content will be completely replaced to mono color, use shortcut
+ if (aBitmapEx.IsEmpty())
+ {
+ // color gets completely replaced, get it
+ const basegfx::BColor aModifiedColor(
+ maBColorModifierStack.getModifiedColor(basegfx::BColor()));
+ basegfx::B2DPolygon aPolygon(basegfx::utils::createUnitPolygon());
+ aPolygon.transform(aLocalTransform);
- if (nBTop > nOTop)
- {
- const sal_Int32 nDiff((nBTop / nBHeight) + 1);
+ mpOutputDevice->SetFillColor(Color(aModifiedColor));
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->DrawPolygon(aPolygon);
- nPosY -= nDiff;
- nBTop -= nDiff * nBHeight;
- }
+ return true;
+ }
+ }
- if (nBTop + nBHeight <= nOTop)
- {
- const sal_Int32 nDiff(-nBTop / nBHeight);
+ sal_Int32 nBLeft(basegfx::fround(aGraphicRange.getMinX()));
+ sal_Int32 nBTop(basegfx::fround(aGraphicRange.getMinY()));
+ const sal_Int32 nOLeft(basegfx::fround(aObjectRange.getMinX()));
+ const sal_Int32 nOTop(basegfx::fround(aObjectRange.getMinY()));
+ sal_Int32 nPosX(0);
+ sal_Int32 nPosY(0);
- nPosY += nDiff;
- nBTop += nDiff * nBHeight;
- }
+ if (nBLeft > nOLeft)
+ {
+ const sal_Int32 nDiff((nBLeft / nBWidth) + 1);
- // prepare OutDev
- const Point aEmptyPoint(0, 0);
- const ::tools::Rectangle aVisiblePixel(
- aEmptyPoint, mpOutputDevice->GetOutputSizePixel());
- const bool bWasEnabled(mpOutputDevice->IsMapModeEnabled());
- mpOutputDevice->EnableMapMode(false);
+ nPosX -= nDiff;
+ nBLeft -= nDiff * nBWidth;
+ }
- // check if offset is used
- const sal_Int32 nOffsetX(
- basegfx::fround(rFillGraphicAttribute.getOffsetX() * nBWidth));
+ if (nBLeft + nBWidth <= nOLeft)
+ {
+ const sal_Int32 nDiff(-nBLeft / nBWidth);
- if (nOffsetX)
- {
- // offset in X, so iterate over Y first and draw lines
- for (sal_Int32 nYPos(nBTop); nYPos < nOTop + nOHeight;
- nYPos += nBHeight, nPosY++)
- {
- for (sal_Int32 nXPos((nPosY % 2) ? nBLeft - nBWidth + nOffsetX
- : nBLeft);
- nXPos < nOLeft + nOWidth; nXPos += nBWidth)
- {
- const ::tools::Rectangle aOutRectPixel(
- Point(nXPos, nYPos), aNeededBitmapSizePixel);
-
- if (aOutRectPixel.Overlaps(aVisiblePixel))
- {
- if (bPreScaled)
- {
- mpOutputDevice->DrawBitmapEx(
- aOutRectPixel.TopLeft(), aBitmapEx);
- }
- else
- {
- mpOutputDevice->DrawBitmapEx(
- aOutRectPixel.TopLeft(), aNeededBitmapSizePixel,
- aBitmapEx);
- }
- }
- }
- }
- }
- else
- {
- // check if offset is used
- const sal_Int32 nOffsetY(
- basegfx::fround(rFillGraphicAttribute.getOffsetY() * nBHeight));
+ nPosX += nDiff;
+ nBLeft += nDiff * nBWidth;
+ }
- // possible offset in Y, so iterate over X first and draw columns
- for (sal_Int32 nXPos(nBLeft); nXPos < nOLeft + nOWidth;
- nXPos += nBWidth, nPosX++)
- {
- for (sal_Int32 nYPos((nPosX % 2) ? nBTop - nBHeight + nOffsetY
- : nBTop);
- nYPos < nOTop + nOHeight; nYPos += nBHeight)
- {
- const ::tools::Rectangle aOutRectPixel(
- Point(nXPos, nYPos), aNeededBitmapSizePixel);
-
- if (aOutRectPixel.Overlaps(aVisiblePixel))
- {
- if (bPreScaled)
- {
- mpOutputDevice->DrawBitmapEx(
- aOutRectPixel.TopLeft(), aBitmapEx);
- }
- else
- {
- mpOutputDevice->DrawBitmapEx(
- aOutRectPixel.TopLeft(), aNeededBitmapSizePixel,
- aBitmapEx);
- }
- }
- }
- }
- }
+ if (nBTop > nOTop)
+ {
+ const sal_Int32 nDiff((nBTop / nBHeight) + 1);
- // restore OutDev
- mpOutputDevice->EnableMapMode(bWasEnabled);
- }
+ nPosY -= nDiff;
+ nBTop -= nDiff * nBHeight;
+ }
+
+ if (nBTop + nBHeight <= nOTop)
+ {
+ const sal_Int32 nDiff(-nBTop / nBHeight);
+
+ nPosY += nDiff;
+ nBTop += nDiff * nBHeight;
+ }
+
+ // prepare OutDev
+ const Point aEmptyPoint(0, 0);
+ // the visible rect, in pixels
+ const ::tools::Rectangle aVisiblePixel(aEmptyPoint, mpOutputDevice->GetOutputSizePixel());
+ const bool bWasEnabled(mpOutputDevice->IsMapModeEnabled());
+ mpOutputDevice->EnableMapMode(false);
+
+ // check if offset is used
+ const sal_Int32 nOffsetX(basegfx::fround(rFillGraphicAttribute.getOffsetX() * nBWidth));
+
+ if (nOffsetX)
+ {
+ // offset in X, so iterate over Y first and draw lines
+ for (sal_Int32 nYPos(nBTop); nYPos < nOTop + nOHeight; nYPos += nBHeight, nPosY++)
+ {
+ for (sal_Int32 nXPos((nPosY % 2) ? nBLeft - nBWidth + nOffsetX : nBLeft);
+ nXPos < nOLeft + nOWidth; nXPos += nBWidth)
+ {
+ const ::tools::Rectangle aOutRectPixel(Point(nXPos, nYPos), aNeededBitmapSizePixel);
+
+ if (aOutRectPixel.Overlaps(aVisiblePixel))
+ {
+ if (bPreScaled)
+ {
+ mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx);
+ }
+ else
+ {
+ mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(),
+ aNeededBitmapSizePixel, aBitmapEx);
}
}
}
}
}
-
- if (!bPrimitiveAccepted)
+ else
{
- // do not accept, use decomposition
- process(rFillBitmapCandidate);
+ // check if offset is used
+ const sal_Int32 nOffsetY(basegfx::fround(rFillGraphicAttribute.getOffsetY() * nBHeight));
+
+ // possible offset in Y, so iterate over X first and draw columns
+ for (sal_Int32 nXPos(nBLeft); nXPos < nOLeft + nOWidth; nXPos += nBWidth, nPosX++)
+ {
+ for (sal_Int32 nYPos((nPosX % 2) ? nBTop - nBHeight + nOffsetY : nBTop);
+ nYPos < nOTop + nOHeight; nYPos += nBHeight)
+ {
+ const ::tools::Rectangle aOutRectPixel(Point(nXPos, nYPos), aNeededBitmapSizePixel);
+
+ if (aOutRectPixel.Overlaps(aVisiblePixel))
+ {
+ if (bPreScaled)
+ {
+ mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx);
+ }
+ else
+ {
+ mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(),
+ aNeededBitmapSizePixel, aBitmapEx);
+ }
+ }
+ }
+ }
}
+
+ // restore OutDev
+ mpOutputDevice->EnableMapMode(bWasEnabled);
+ return true;
}
// direct draw of Graphic
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.hxx b/drawinglayer/source/processor2d/vclprocessor2d.hxx
index 798c6659bd73..b7d0c65e9437 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.hxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.hxx
@@ -125,6 +125,10 @@ public:
{
return mpObjectInfoPrimitive2D;
}
+
+private:
+ bool RenderFillGraphicPrimitive2DImpl(
+ const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate);
};
} // end of namespace drawinglayer::processor2d