From 389f338da025aa7bc26556a7167cd272b64b77fd Mon Sep 17 00:00:00 2001 From: "Armin Le Grand (Allotropia)" Date: Fri, 31 Mar 2023 16:05:28 +0200 Subject: [PATCH] SDPR: Use currently added lambda to render Gradients Change-Id: I9fba920c60690f136cae956dae17e2f5e5081f19 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149839 Tested-by: Jenkins Reviewed-by: Armin Le Grand --- .../processor2d/d2dpixelprocessor2d.cxx | 116 ++++++++++++------ .../processor2d/d2dpixelprocessor2d.hxx | 13 ++ 2 files changed, 94 insertions(+), 35 deletions(-) diff --git a/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx b/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx index 0670ad2febd8..783060c2be4c 100644 --- a/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -817,6 +818,47 @@ void D2DPixelProcessor2D::processPolygonHairlinePrimitive2D( increaseError(); } +bool D2DPixelProcessor2D::drawPolyPolygonColorTransformed( + const basegfx::B2DHomMatrix& rTansformation, const basegfx::B2DPolyPolygon& rPolyPolygon, + const basegfx::BColor& rColor) +{ + std::shared_ptr pSystemDependentData_ID2D1PathGeometry( + getOrCreateFillGeometry(rPolyPolygon)); + + if (pSystemDependentData_ID2D1PathGeometry) + { + sal::systools::COMReference pTransformedGeometry; + const double fAAOffset(getViewInformation2D().getUseAntiAliasing() ? 0.5 : 0.0); + basegfx::B2DHomMatrix aTansformation(getViewInformation2D().getObjectToViewTransformation() + * rTansformation); + HRESULT hr(aID2D1GlobalFactoryProvider.getID2D1Factory()->CreateTransformedGeometry( + pSystemDependentData_ID2D1PathGeometry->getID2D1PathGeometry(), + D2D1::Matrix3x2F(aTansformation.a(), aTansformation.b(), aTansformation.c(), + aTansformation.d(), aTansformation.e() + fAAOffset, + aTansformation.f() + fAAOffset), + &pTransformedGeometry)); + + if (SUCCEEDED(hr) && pTransformedGeometry) + { + const basegfx::BColor aFillColor(maBColorModifierStack.getModifiedColor(rColor)); + const D2D1::ColorF aD2DColor(aFillColor.getRed(), aFillColor.getGreen(), + aFillColor.getBlue()); + + sal::systools::COMReference pColorBrush; + hr = getRenderTarget()->CreateSolidColorBrush(aD2DColor, &pColorBrush); + + if (SUCCEEDED(hr) && pColorBrush) + { + getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); + getRenderTarget()->FillGeometry(pTransformedGeometry, pColorBrush); + return true; + } + } + } + + return false; +} + void D2DPixelProcessor2D::processPolyPolygonColorPrimitive2D( const primitive2d::PolyPolygonColorPrimitive2D& rPolyPolygonColorPrimitive2D) { @@ -829,41 +871,8 @@ void D2DPixelProcessor2D::processPolyPolygonColorPrimitive2D( return; } - bool bDone(false); - std::shared_ptr pSystemDependentData_ID2D1PathGeometry( - getOrCreateFillGeometry(rPolyPolygon)); - - if (pSystemDependentData_ID2D1PathGeometry) - { - sal::systools::COMReference pTransformedGeometry; - const double fAAOffset(getViewInformation2D().getUseAntiAliasing() ? 0.5 : 0.0); - const basegfx::B2DHomMatrix& rObjectToView( - getViewInformation2D().getObjectToViewTransformation()); - HRESULT hr(aID2D1GlobalFactoryProvider.getID2D1Factory()->CreateTransformedGeometry( - pSystemDependentData_ID2D1PathGeometry->getID2D1PathGeometry(), - D2D1::Matrix3x2F(rObjectToView.a(), rObjectToView.b(), rObjectToView.c(), - rObjectToView.d(), rObjectToView.e() + fAAOffset, - rObjectToView.f() + fAAOffset), - &pTransformedGeometry)); - - if (SUCCEEDED(hr) && pTransformedGeometry) - { - const basegfx::BColor aFillColor( - maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor())); - const D2D1::ColorF aD2DColor(aFillColor.getRed(), aFillColor.getGreen(), - aFillColor.getBlue()); - - sal::systools::COMReference pColorBrush; - hr = getRenderTarget()->CreateSolidColorBrush(aD2DColor, &pColorBrush); - - if (SUCCEEDED(hr) && pColorBrush) - { - getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); - getRenderTarget()->FillGeometry(pTransformedGeometry, pColorBrush); - bDone = true; - } - } - } + const bool bDone(drawPolyPolygonColorTransformed(basegfx::B2DHomMatrix(), rPolyPolygon, + rPolyPolygonColorPrimitive2D.getBColor())); if (!bDone) increaseError(); @@ -1912,6 +1921,37 @@ void D2DPixelProcessor2D::processFillGraphicPrimitive2D( increaseError(); } +void D2DPixelProcessor2D::processFillGradientPrimitive2D( + const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D) +{ + // draw all-covering initial BG polygon 1st + bool bDone(drawPolyPolygonColorTransformed( + basegfx::B2DHomMatrix(), + basegfx::B2DPolyPolygon( + basegfx::utils::createPolygonFromRect(rFillGradientPrimitive2D.getOutputRange())), + rFillGradientPrimitive2D.getOuterColor())); + + if (bDone) + { + const basegfx::B2DPolyPolygon aForm(rFillGradientPrimitive2D.getUnitPolygon()); + + // paint solid fill steps by providing callback as lambda + auto aCallback([&aForm, &bDone, this](const basegfx::B2DHomMatrix& rMatrix, + const basegfx::BColor& rColor) { + if (bDone) + { + bDone = drawPolyPolygonColorTransformed(rMatrix, aForm, rColor); + } + }); + + // call value generator to trigger callbacks + rFillGradientPrimitive2D.generateMatricesAndColors(aCallback); + } + + if (!bDone) + increaseError(); +} + void D2DPixelProcessor2D::processInvertPrimitive2D( const primitive2d::InvertPrimitive2D& rInvertPrimitive2D) { @@ -2124,6 +2164,12 @@ void D2DPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitiv static_cast(rCandidate)); break; } + case PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D: + { + processFillGradientPrimitive2D( + static_cast(rCandidate)); + break; + } // continue with decompose as fallback default: diff --git a/include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx b/include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx index d49dcba63ea1..b627bf2b164b 100644 --- a/include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx +++ b/include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx @@ -46,6 +46,14 @@ class FilledRectanglePrimitive2D; class SingleLinePrimitive2D; class FillGraphicPrimitive2D; class InvertPrimitive2D; +class FillGradientPrimitive2D; +} + +namespace basegfx +{ +class B2DHomMatrix; +class B2DPolyPolygon; +class BColor; } struct ID2D1RenderTarget; @@ -94,6 +102,8 @@ class DRAWINGLAYER_DLLPUBLIC D2DPixelProcessor2D : public BaseProcessor2D void processFillGraphicPrimitive2D( const primitive2d::FillGraphicPrimitive2D& rFillGraphicPrimitive2D); void processInvertPrimitive2D(const primitive2d::InvertPrimitive2D& rInvertPrimitive2D); + void processFillGradientPrimitive2D( + const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D); // common helpers sal::systools::COMReference @@ -102,6 +112,9 @@ class DRAWINGLAYER_DLLPUBLIC D2DPixelProcessor2D : public BaseProcessor2D implCreateAlpha_B2DBitmap(const primitive2d::TransparencePrimitive2D& rTransCandidate, const basegfx::B2DRange& rVisibleRange, D2D1_MATRIX_3X2_F& rMaskScale); + bool drawPolyPolygonColorTransformed(const basegfx::B2DHomMatrix& rTansformation, + const basegfx::B2DPolyPolygon& rPolyPolygon, + const basegfx::BColor& rColor); /* the local processor for BasePrimitive2D-Implementation based primitives, called from the common process()-implementation