summaryrefslogtreecommitdiff
path: root/vcl/headless
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2020-09-25 10:41:27 +0200
committerLuboš Luňák <l.lunak@collabora.com>2020-09-25 19:36:06 +0200
commit141dfd653f1413cc5fae5a7b9ef356c095f21d3b (patch)
treebb872faaec6f16a7c10d3ef6850008a744358fc0 /vcl/headless
parent20c09d351ee060bdde13d92d2bf86dd998cdb0cb (diff)
headless/cairo drawGradient() fixes
Change-Id: I53913262f8f856bf265ce50fc355244445499089 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103375 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'vcl/headless')
-rw-r--r--vcl/headless/svpgdi.cxx64
1 files changed, 47 insertions, 17 deletions
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index e769474c3dd5..1194148da235 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -1912,43 +1912,73 @@ bool SvpSalGraphics::drawPolyPolygon(
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 = getCairoContext(true);
clipRegion(cr);
- basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPolygon.getB2DPolyPolygon());
-
- for (auto const & rPolygon : aB2DPolyPolygon)
+ 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, rPolygon, rObjectToDevice, !getAntiAliasB2DDraw(), false);
+ AddPolygonToPath(cr, tools::Polygon(aInputRect).getB2DPolygon(), rObjectToDevice, !getAntiAliasB2DDraw(), false);
+ }
+ else
+ {
+ basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPolygon.getB2DPolyPolygon());
+ for (auto const & rPolygon : aB2DPolyPolygon)
+ {
+ basegfx::B2DHomMatrix rObjectToDevice;
+ AddPolygonToPath(cr, rPolygon, rObjectToDevice, !getAntiAliasB2DDraw(), false);
+ }
}
Gradient aGradient(rGradient);
- tools::Rectangle aInputRect(rPolyPolygon.GetBoundRect());
tools::Rectangle aBoundRect;
Point aCenter;
aGradient.SetAngle(aGradient.GetAngle() + 2700);
aGradient.GetBoundRect(aInputRect, aBoundRect, aCenter);
-
- tools::Polygon aPoly(aBoundRect);
- aPoly.Rotate(aCenter, aGradient.GetAngle() % 3600);
+ Color aStartColor = aGradient.GetStartColor();
+ Color aEndColor = aGradient.GetEndColor();
cairo_pattern_t* pattern;
- pattern = cairo_pattern_create_linear(aPoly[0].X(), aPoly[0].Y(), aPoly[1].X(), aPoly[1].Y());
+ if (rGradient.GetStyle() == GradientStyle::Linear)
+ {
+ tools::Polygon aPoly(aBoundRect);
+ aPoly.Rotate(aCenter, aGradient.GetAngle() % 3600);
+ 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,
- aGradient.GetStartColor().GetRed() / 255.0,
- aGradient.GetStartColor().GetGreen() / 255.0,
- aGradient.GetStartColor().GetBlue() / 255.0,
- 1.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,
- aGradient.GetEndColor().GetRed() / 255.0,
- aGradient.GetEndColor().GetGreen() / 255.0,
- aGradient.GetEndColor().GetBlue() / 255.0,
- 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);
basegfx::B2DRange extents = getClippedFillDamage(cr);