summaryrefslogtreecommitdiff
path: root/vcl/headless
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2023-01-03 19:47:32 +0000
committerCaolán McNamara <caolanm@redhat.com>2023-01-05 10:49:01 +0000
commitfa0ecf2a61c24c6485693d81ff820693f21a5ec8 (patch)
treed22273c6017eca60c7f774b9a00daa3f40807d2c /vcl/headless
parent8549d6e26f5116b1fcf5e066252cc987a3f2574f (diff)
move drawGradient into CairoCommon and reuse from X11CairoSalGraphicsImpl
Change-Id: I249afbc4cf6318fd9ed42fef0a2aa71d1a76d9ce Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145024 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/headless')
-rw-r--r--vcl/headless/CairoCommon.cxx78
-rw-r--r--vcl/headless/SvpGraphicsBackend.cxx75
2 files changed, 82 insertions, 71 deletions
diff --git a/vcl/headless/CairoCommon.cxx b/vcl/headless/CairoCommon.cxx
index cfd463da41e3..14932adc6470 100644
--- a/vcl/headless/CairoCommon.cxx
+++ b/vcl/headless/CairoCommon.cxx
@@ -888,6 +888,84 @@ bool CairoCommon::drawPolyLine(cairo_t* cr, basegfx::B2DRange* pExtents, const C
return true;
}
+bool CairoCommon::drawGradient(cairo_t* cr, basegfx::B2DRange* pExtents, bool bAntiAlias,
+ 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.
+
+ 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,
+ !bAntiAlias, false);
+ }
+ else
+ {
+ basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPolygon.getB2DPolyPolygon());
+ for (auto const& rPolygon : std::as_const(aB2DPolyPolygon))
+ {
+ basegfx::B2DHomMatrix rObjectToDevice;
+ AddPolygonToPath(cr, rPolygon, rObjectToDevice, !bAntiAlias, 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);
+
+ if (pExtents)
+ *pExtents = getClippedFillDamage(cr);
+ cairo_fill_preserve(cr);
+
+ return true;
+}
+
bool CairoCommon::implDrawGradient(cairo_t* cr, basegfx::B2DRange* pExtents, bool bAntiAlias,
basegfx::B2DPolyPolygon const& rPolyPolygon,
SalGradient const& rGradient)
diff --git a/vcl/headless/SvpGraphicsBackend.cxx b/vcl/headless/SvpGraphicsBackend.cxx
index 6f527f350760..cedf105a2e94 100644
--- a/vcl/headless/SvpGraphicsBackend.cxx
+++ b/vcl/headless/SvpGraphicsBackend.cxx
@@ -876,83 +876,16 @@ bool SvpGraphicsBackend::drawAlphaRect(tools::Long nX, tools::Long nY, tools::Lo
bool SvpGraphicsBackend::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_rCairoCommon.getCairoContext(true, getAntiAlias());
+ basegfx::B2DRange extents;
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);
+ const bool bRetval(
+ CairoCommon::drawGradient(cr, &extents, getAntiAlias(), rPolyPolygon, rGradient));
m_rCairoCommon.releaseCairoContext(cr, true, extents);
- return true;
+ return bRetval;
}
bool SvpGraphicsBackend::implDrawGradient(basegfx::B2DPolyPolygon const& rPolyPolygon,