diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2020-09-25 10:41:27 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2020-09-25 19:36:06 +0200 |
commit | 141dfd653f1413cc5fae5a7b9ef356c095f21d3b (patch) | |
tree | bb872faaec6f16a7c10d3ef6850008a744358fc0 /vcl/headless | |
parent | 20c09d351ee060bdde13d92d2bf86dd998cdb0cb (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.cxx | 64 |
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); |