vcl/headless/SvpGraphicsBackend.cxx | 128 ++++++++++++++++++++++++++++++++++-- vcl/headless/svpgdi.cxx | 126 ----------------------------------- vcl/inc/headless/svpgdi.hxx | 6 - 3 files changed, 121 insertions(+), 139 deletions(-)
New commits: commit c065f342a0f2a0eb694b787096ed3bd600671cf1 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Tue Dec 28 08:52:05 2021 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Sat Jan 1 16:05:31 2022 +0100 vcl: move drawGradient to SvpGraphicsBackend Change-Id: Ifc3d0b0a693113b0cfbd763bf6ac0bd34eb6c872 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127824 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/vcl/headless/SvpGraphicsBackend.cxx b/vcl/headless/SvpGraphicsBackend.cxx index e5d449c57222..10c02d4644f9 100644 --- a/vcl/headless/SvpGraphicsBackend.cxx +++ b/vcl/headless/SvpGraphicsBackend.cxx @@ -438,16 +438,122 @@ bool SvpGraphicsBackend::drawAlphaRect(tools::Long /*nX*/, tools::Long /*nY*/, return false; } -bool SvpGraphicsBackend::drawGradient(const tools::PolyPolygon& /*rPolyPolygon*/, - const Gradient& /*rGradient*/) +bool SvpGraphicsBackend::drawGradient(const tools::PolyPolygon& rPolyPolygon, + const Gradient& rGradient) { - return false; + if (rGradient.GetStyle() != GradientStyle::Linear + && rGradient.GetStyle() != GradientStyle::Radial) + return false; // unsupported + if (rGradient.GetSteps() != 0) + return false; // We can't tell cairo how many colors to use in the gradient. + + cairo_t* cr = m_rCairoCommon.getCairoContext(true, getAntiAlias()); + m_rCairoCommon.clipRegion(cr); + + tools::Rectangle aInputRect(rPolyPolygon.GetBoundRect()); + if (rPolyPolygon.IsRect()) + { + // Rect->Polygon conversion loses the right and bottom edge, fix that. + aInputRect.AdjustRight(1); + aInputRect.AdjustBottom(1); + basegfx::B2DHomMatrix rObjectToDevice; + AddPolygonToPath(cr, tools::Polygon(aInputRect).getB2DPolygon(), rObjectToDevice, + !getAntiAlias(), false); + } + else + { + basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPolygon.getB2DPolyPolygon()); + for (auto const& rPolygon : std::as_const(aB2DPolyPolygon)) + { + basegfx::B2DHomMatrix rObjectToDevice; + AddPolygonToPath(cr, rPolygon, rObjectToDevice, !getAntiAlias(), false); + } + } + + Gradient aGradient(rGradient); + + tools::Rectangle aBoundRect; + Point aCenter; + + aGradient.SetAngle(aGradient.GetAngle() + 2700_deg10); + aGradient.GetBoundRect(aInputRect, aBoundRect, aCenter); + Color aStartColor = aGradient.GetStartColor(); + Color aEndColor = aGradient.GetEndColor(); + + cairo_pattern_t* pattern; + if (rGradient.GetStyle() == GradientStyle::Linear) + { + tools::Polygon aPoly(aBoundRect); + aPoly.Rotate(aCenter, aGradient.GetAngle() % 3600_deg10); + pattern + = cairo_pattern_create_linear(aPoly[0].X(), aPoly[0].Y(), aPoly[1].X(), aPoly[1].Y()); + } + else + { + double radius = std::max(aBoundRect.GetWidth() / 2.0, aBoundRect.GetHeight() / 2.0); + // Move the center a bit to the top-left (the default VCL algorithm is a bit off-center that way, + // cairo is the opposite way). + pattern = cairo_pattern_create_radial(aCenter.X() - 0.5, aCenter.Y() - 0.5, 0, + aCenter.X() - 0.5, aCenter.Y() - 0.5, radius); + std::swap(aStartColor, aEndColor); + } + + cairo_pattern_add_color_stop_rgba( + pattern, aGradient.GetBorder() / 100.0, + aStartColor.GetRed() * aGradient.GetStartIntensity() / 25500.0, + aStartColor.GetGreen() * aGradient.GetStartIntensity() / 25500.0, + aStartColor.GetBlue() * aGradient.GetStartIntensity() / 25500.0, 1.0); + + cairo_pattern_add_color_stop_rgba( + pattern, 1.0, aEndColor.GetRed() * aGradient.GetEndIntensity() / 25500.0, + aEndColor.GetGreen() * aGradient.GetEndIntensity() / 25500.0, + aEndColor.GetBlue() * aGradient.GetEndIntensity() / 25500.0, 1.0); + + cairo_set_source(cr, pattern); + cairo_pattern_destroy(pattern); + + basegfx::B2DRange extents = getClippedFillDamage(cr); + cairo_fill_preserve(cr); + + m_rCairoCommon.releaseCairoContext(cr, true, extents); + + return true; } -bool SvpGraphicsBackend::implDrawGradient(basegfx::B2DPolyPolygon const& /*rPolyPolygon*/, - SalGradient const& /*rGradient*/) +bool SvpGraphicsBackend::implDrawGradient(basegfx::B2DPolyPolygon const& rPolyPolygon, + SalGradient const& rGradient) { - return false; + cairo_t* cr = m_rCairoCommon.getCairoContext(true, getAntiAlias()); + m_rCairoCommon.clipRegion(cr); + + basegfx::B2DHomMatrix rObjectToDevice; + + for (auto const& rPolygon : rPolyPolygon) + AddPolygonToPath(cr, rPolygon, rObjectToDevice, !getAntiAlias(), false); + + cairo_pattern_t* pattern + = cairo_pattern_create_linear(rGradient.maPoint1.getX(), rGradient.maPoint1.getY(), + rGradient.maPoint2.getX(), rGradient.maPoint2.getY()); + + for (SalGradientStop const& rStop : rGradient.maStops) + { + double r = rStop.maColor.GetRed() / 255.0; + double g = rStop.maColor.GetGreen() / 255.0; + double b = rStop.maColor.GetBlue() / 255.0; + double a = rStop.maColor.GetAlpha() / 255.0; + double offset = rStop.mfOffset; + + cairo_pattern_add_color_stop_rgba(pattern, offset, r, g, b, a); + } + cairo_set_source(cr, pattern); + cairo_pattern_destroy(pattern); + + basegfx::B2DRange extents = getClippedFillDamage(cr); + cairo_fill_preserve(cr); + + m_rCairoCommon.releaseCairoContext(cr, true, extents); + + return true; } bool SvpGraphicsBackend::supportsOperation(OutDevSupportType eType) const diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index ff39f19b1030..523a76fbb530 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -852,119 +852,6 @@ void SvpSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ) rDPIX = rDPIY = 96; } -bool SvpSalGraphics::drawGradient(const tools::PolyPolygon& rPolyPolygon, const Gradient& rGradient) -{ - if (rGradient.GetStyle() != GradientStyle::Linear - && rGradient.GetStyle() != GradientStyle::Radial) - return false; // unsupported - if (rGradient.GetSteps() != 0) - return false; // We can't tell cairo how many colors to use in the gradient. - - cairo_t* cr = m_aCairoCommon.getCairoContext(true, getAntiAlias()); - clipRegion(cr); - - tools::Rectangle aInputRect(rPolyPolygon.GetBoundRect()); - if( rPolyPolygon.IsRect()) - { - // Rect->Polygon conversion loses the right and bottom edge, fix that. - aInputRect.AdjustRight( 1 ); - aInputRect.AdjustBottom( 1 ); - basegfx::B2DHomMatrix rObjectToDevice; - AddPolygonToPath(cr, tools::Polygon(aInputRect).getB2DPolygon(), rObjectToDevice, !getAntiAlias(), false); - } - else - { - basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPolygon.getB2DPolyPolygon()); - for (auto const & rPolygon : std::as_const(aB2DPolyPolygon)) - { - basegfx::B2DHomMatrix rObjectToDevice; - AddPolygonToPath(cr, rPolygon, rObjectToDevice, !getAntiAlias(), false); - } - } - - Gradient aGradient(rGradient); - - tools::Rectangle aBoundRect; - Point aCenter; - - aGradient.SetAngle(aGradient.GetAngle() + 2700_deg10); - aGradient.GetBoundRect(aInputRect, aBoundRect, aCenter); - Color aStartColor = aGradient.GetStartColor(); - Color aEndColor = aGradient.GetEndColor(); - - cairo_pattern_t* pattern; - if (rGradient.GetStyle() == GradientStyle::Linear) - { - tools::Polygon aPoly(aBoundRect); - aPoly.Rotate(aCenter, aGradient.GetAngle() % 3600_deg10); - pattern = cairo_pattern_create_linear(aPoly[0].X(), aPoly[0].Y(), aPoly[1].X(), aPoly[1].Y()); - } - else - { - double radius = std::max(aBoundRect.GetWidth() / 2.0, aBoundRect.GetHeight() / 2.0); - // Move the center a bit to the top-left (the default VCL algorithm is a bit off-center that way, - // cairo is the opposite way). - pattern = cairo_pattern_create_radial(aCenter.X() - 0.5, aCenter.Y() - 0.5, 0, - aCenter.X() - 0.5, aCenter.Y() - 0.5, radius); - std::swap( aStartColor, aEndColor ); - } - - cairo_pattern_add_color_stop_rgba(pattern, aGradient.GetBorder() / 100.0, - aStartColor.GetRed() * aGradient.GetStartIntensity() / 25500.0, - aStartColor.GetGreen() * aGradient.GetStartIntensity() / 25500.0, - aStartColor.GetBlue() * aGradient.GetStartIntensity() / 25500.0, - 1.0); - - cairo_pattern_add_color_stop_rgba(pattern, 1.0, - aEndColor.GetRed() * aGradient.GetEndIntensity() / 25500.0, - aEndColor.GetGreen() * aGradient.GetEndIntensity() / 25500.0, - aEndColor.GetBlue() * aGradient.GetEndIntensity() / 25500.0, - 1.0); - - cairo_set_source(cr, pattern); - cairo_pattern_destroy(pattern); - - basegfx::B2DRange extents = getClippedFillDamage(cr); - cairo_fill_preserve(cr); - - m_aCairoCommon.releaseCairoContext(cr, true, extents); - - return true; -} - -bool SvpSalGraphics::implDrawGradient(basegfx::B2DPolyPolygon const & rPolyPolygon, SalGradient const & rGradient) -{ - cairo_t* cr = m_aCairoCommon.getCairoContext(true, getAntiAlias()); - clipRegion(cr); - - basegfx::B2DHomMatrix rObjectToDevice; - - for (auto const & rPolygon : rPolyPolygon) - AddPolygonToPath(cr, rPolygon, rObjectToDevice, !getAntiAlias(), false); - - cairo_pattern_t* pattern = cairo_pattern_create_linear(rGradient.maPoint1.getX(), rGradient.maPoint1.getY(), rGradient.maPoint2.getX(), rGradient.maPoint2.getY()); - - for (SalGradientStop const & rStop : rGradient.maStops) - { - double r = rStop.maColor.GetRed() / 255.0; - double g = rStop.maColor.GetGreen() / 255.0; - double b = rStop.maColor.GetBlue() / 255.0; - double a = rStop.maColor.GetAlpha() / 255.0; - double offset = rStop.mfOffset; - - cairo_pattern_add_color_stop_rgba(pattern, offset, r, g, b, a); - } - cairo_set_source(cr, pattern); - cairo_pattern_destroy(pattern); - - basegfx::B2DRange extents = getClippedFillDamage(cr); - cairo_fill_preserve(cr); - - m_aCairoCommon.releaseCairoContext(cr, true, extents); - - return true; -} - void SvpSalGraphics::copyArea( tools::Long nDestX, tools::Long nDestY, tools::Long nSrcX, diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index 462482f907a4..0d36a2cf8442 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -119,10 +119,6 @@ public: virtual void DrawTextLayout( const GenericSalLayout& ) override; virtual bool supportsOperation( OutDevSupportType ) const override; - virtual bool drawGradient(tools::PolyPolygon const & rPolyPolygon, Gradient const & rGradient) override; - - virtual bool implDrawGradient(basegfx::B2DPolyPolygon const & rPolyPolygon, SalGradient const & rGradient) override; - virtual void copyArea( tools::Long nDestX, tools::Long nDestY, tools::Long nSrcX, commit 27856da9b43cd475922f57fec32bdef60dd21720 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Wed Dec 15 12:50:55 2021 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Sat Jan 1 16:05:16 2022 +0100 vcl: move (legacy) drawPolygon(.., Point*) to SvpGraphicsBackend Change-Id: I5b3b915712921fbbdaa0b0d7ad9b9c39291e00f2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127823 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/vcl/headless/SvpGraphicsBackend.cxx b/vcl/headless/SvpGraphicsBackend.cxx index e955790bd247..e5d449c57222 100644 --- a/vcl/headless/SvpGraphicsBackend.cxx +++ b/vcl/headless/SvpGraphicsBackend.cxx @@ -201,7 +201,15 @@ void SvpGraphicsBackend::drawPolyLine(sal_uInt32 nPoints, const Point* pPtAry) basegfx::deg2rad(15.0) /*default*/, false); } -void SvpGraphicsBackend::drawPolygon(sal_uInt32 /*nPoints*/, const Point* /*pPtAry*/) {} +void SvpGraphicsBackend::drawPolygon(sal_uInt32 nPoints, const Point* pPtAry) +{ + basegfx::B2DPolygon aPoly; + aPoly.append(basegfx::B2DPoint(pPtAry->getX(), pPtAry->getY()), nPoints); + for (sal_uInt32 i = 1; i < nPoints; ++i) + aPoly.setB2DPoint(i, basegfx::B2DPoint(pPtAry[i].getX(), pPtAry[i].getY())); + + drawPolyPolygon(basegfx::B2DHomMatrix(), basegfx::B2DPolyPolygon(aPoly), 0.0); +} void SvpGraphicsBackend::drawPolyPolygon(sal_uInt32 nPoly, const sal_uInt32* pPointCounts, const Point** pPtAry) diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index ce9f7928a1bb..ff39f19b1030 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -852,19 +852,6 @@ void SvpSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ) rDPIX = rDPIY = 96; } -void SvpSalGraphics::drawPolygon(sal_uInt32 nPoints, const Point* pPtAry) -{ - basegfx::B2DPolygon aPoly; - aPoly.append(basegfx::B2DPoint(pPtAry->getX(), pPtAry->getY()), nPoints); - for (sal_uInt32 i = 1; i < nPoints; ++i) - aPoly.setB2DPoint(i, basegfx::B2DPoint(pPtAry[i].getX(), pPtAry[i].getY())); - - GetImpl()->drawPolyPolygon( - basegfx::B2DHomMatrix(), - basegfx::B2DPolyPolygon(aPoly), - 0.0); -} - bool SvpSalGraphics::drawGradient(const tools::PolyPolygon& rPolyPolygon, const Gradient& rGradient) { if (rGradient.GetStyle() != GradientStyle::Linear diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index e38aa3be55a4..462482f907a4 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -119,8 +119,6 @@ public: virtual void DrawTextLayout( const GenericSalLayout& ) override; virtual bool supportsOperation( OutDevSupportType ) const override; - virtual void drawPolygon( sal_uInt32 nPoints, const Point* pPtAry ) override; - virtual bool drawGradient(tools::PolyPolygon const & rPolyPolygon, Gradient const & rGradient) override; virtual bool implDrawGradient(basegfx::B2DPolyPolygon const & rPolyPolygon, SalGradient const & rGradient) override;