diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2019-11-04 18:36:51 +0100 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2019-11-08 12:09:48 +0100 |
commit | 389c8239c93663fa5546b2f0227a118a3ad091bf (patch) | |
tree | 283ca215c088c682aeb1d492d6f5b7be21921965 /vcl | |
parent | 456300d4fbea0f27453973b50d148753d0315b80 (diff) |
widget theme: Gradient support when drawing widgets
Change-Id: I29239348e36e4963d9708a22ac649b2b1d68bf02
Reviewed-on: https://gerrit.libreoffice.org/82207
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/headless/svpgdi.cxx | 34 | ||||
-rw-r--r-- | vcl/inc/SalGradient.hxx | 36 | ||||
-rw-r--r-- | vcl/inc/headless/svpgdi.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/salgdi.hxx | 9 | ||||
-rw-r--r-- | vcl/source/gdi/FileDefinitionWidgetDraw.cxx | 46 | ||||
-rw-r--r-- | vcl/source/gdi/salgdilayout.cxx | 5 |
6 files changed, 132 insertions, 0 deletions
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index 5c1f0daab194..57f66d4fabf6 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -32,6 +32,7 @@ #include <o3tl/safeint.hxx> #include <vcl/BitmapTools.hxx> #include <vcl/sysdata.hxx> +#include <vcl/gradient.hxx> #include <config_cairo_canvas.h> #include <basegfx/numeric/ftools.hxx> #include <basegfx/range/b2drange.hxx> @@ -1494,6 +1495,39 @@ bool SvpSalGraphics::drawPolyPolygon( return true; } +bool SvpSalGraphics::implDrawGradient(basegfx::B2DPolyPolygon const & rPolyPolygon, SalGradient const & rGradient) +{ + cairo_t* cr = getCairoContext(true); + clipRegion(cr); + + basegfx::B2DHomMatrix rObjectToDevice; + + for (auto const & rPolygon : rPolyPolygon) + AddPolygonToPath(cr, rPolygon, rObjectToDevice, !getAntiAliasB2DDraw(), false); + + cairo_pattern_t* pattern; + 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 = (0xFF - rStop.maColor.GetTransparency()) / 255.0; + double offset = rStop.mfOffset; + + cairo_pattern_add_color_stop_rgba(pattern, offset, r, g, b, a); + } + cairo_set_source(cr, pattern); + + basegfx::B2DRange extents = getClippedFillDamage(cr); + cairo_fill_preserve(cr); + + releaseCairoContext(cr, true, extents); + + return true; +} + void SvpSalGraphics::applyColor(cairo_t *cr, Color aColor, double fTransparency) { if (cairo_surface_get_content(m_pSurface) == CAIRO_CONTENT_COLOR_ALPHA) diff --git a/vcl/inc/SalGradient.hxx b/vcl/inc/SalGradient.hxx new file mode 100644 index 000000000000..1b4a47f9a6ff --- /dev/null +++ b/vcl/inc/SalGradient.hxx @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_VCL_INC_SALGRADIENT_HXX +#define INCLUDED_VCL_INC_SALGRADIENT_HXX + +#include <basegfx/point/b2dpoint.hxx> + +struct SalGradientStop +{ + Color maColor; + float mfOffset; + + SalGradientStop(Color const& rColor, float fOffset) + : maColor(rColor) + , mfOffset(fOffset) + { + } +}; + +struct SalGradient +{ + basegfx::B2DPoint maPoint1; + basegfx::B2DPoint maPoint2; + std::vector<SalGradientStop> maStops; +}; + +#endif // INCLUDED_VCL_INC_SALGRADIENT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index b0e4aac4adad..d06c138a0284 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -232,6 +232,8 @@ public: const PolyFlags* const* pFlgAry ) override; virtual bool drawGradient( const tools::PolyPolygon&, const Gradient& ) override { return false; }; + virtual bool implDrawGradient(basegfx::B2DPolyPolygon const & rPolyPolygon, SalGradient const & rGradient) override; + virtual void copyArea( long nDestX, long nDestY, long nSrcX, diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index d61c00cd9654..6b5899a4ce10 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -25,6 +25,7 @@ #include "impfontmetricdata.hxx" #include "salgdiimpl.hxx" #include "sallayout.hxx" +#include "SalGradient.hxx" #include <basegfx/matrix/b2dhommatrix.hxx> #include "WidgetDrawInterface.hxx" @@ -275,6 +276,8 @@ public: const tools::PolyPolygon& rPolyPoly, const Gradient& rGradient ); + bool DrawGradient(basegfx::B2DPolyPolygon const & rPolyPolygon, + SalGradient const & rGradient); // CopyArea --> No RasterOp, but ClipRegion void CopyArea( @@ -486,6 +489,12 @@ protected: const tools::PolyPolygon& rPolyPoly, const Gradient& rGradient ) = 0; + virtual bool implDrawGradient(basegfx::B2DPolyPolygon const & /*rPolyPolygon*/, + SalGradient const & /*rGradient*/) + { + return false; + } + // CopyArea --> No RasterOp, but ClipRegion virtual void copyArea( long nDestX, long nDestY, diff --git a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx index 653a369a1e3d..40d443bb0edf 100644 --- a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx +++ b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx @@ -19,11 +19,13 @@ #include <basegfx/range/b2drectangle.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/tuple/b2dtuple.hxx> #include <basegfx/matrix/b2dhommatrixtools.hxx> #include <tools/stream.hxx> #include <vcl/bitmapex.hxx> #include <vcl/BitmapTools.hxx> +#include <vcl/gradient.hxx> #include <comphelper/seqstream.hxx> #include <comphelper/processfactory.hxx> @@ -221,6 +223,50 @@ void drawFromDrawCommands(gfx::DrawRoot const& rDrawRoot, SalGraphics& rGraphics basegfx::B2DPolyPolygon(aB2DPolygon), 1.0 - rRectangle.mnOpacity, nullptr); } + else if (rRectangle.mpFillGradient) + { + rGraphics.SetLineColor(); + rGraphics.SetFillColor(); + if (rRectangle.mpFillGradient->meType == gfx::GradientType::Linear) + { + auto* pLinearGradient = static_cast<gfx::LinearGradientInfo*>( + rRectangle.mpFillGradient.get()); + SalGradient aGradient; + double x, y; + + x = pLinearGradient->x1; + y = pLinearGradient->y1; + + if (x > aSVGRect.getCenterX()) + x = x + fDeltaX; + if (y > aSVGRect.getCenterY()) + y = y + fDeltaY; + + aGradient.maPoint1 = basegfx::B2DPoint(x, y); + aGradient.maPoint1 *= basegfx::utils::createTranslateB2DHomMatrix( + aTargetSurface.getMinX() - 0.5, aTargetSurface.getMinY() - 0.5); + + x = pLinearGradient->x2; + y = pLinearGradient->y2; + + if (x > aSVGRect.getCenterX()) + x = x + fDeltaX; + if (y > aSVGRect.getCenterY()) + y = y + fDeltaY; + + aGradient.maPoint2 = basegfx::B2DPoint(x, y); + aGradient.maPoint2 *= basegfx::utils::createTranslateB2DHomMatrix( + aTargetSurface.getMinX() - 0.5, aTargetSurface.getMinY() - 0.5); + + for (gfx::GradientStop const& rStop : pLinearGradient->maGradientStops) + { + Color aColor(rStop.maColor); + aColor.SetTransparency(rStop.mfOpacity * (1.0f - rRectangle.mnOpacity)); + aGradient.maStops.emplace_back(aColor, rStop.mfOffset); + } + rGraphics.DrawGradient(basegfx::B2DPolyPolygon(aB2DPolygon), aGradient); + } + } if (rRectangle.mpStrokeColor) { rGraphics.SetLineColor(Color(*rRectangle.mpStrokeColor)); diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx index c3c3c306d19e..b0fefa665bd5 100644 --- a/vcl/source/gdi/salgdilayout.cxx +++ b/vcl/source/gdi/salgdilayout.cxx @@ -652,6 +652,11 @@ bool SalGraphics::DrawGradient( const tools::PolyPolygon& rPolyPoly, const Gradi return drawGradient( rPolyPoly, rGradient ); } +bool SalGraphics::DrawGradient(basegfx::B2DPolyPolygon const & rPolyPolygon, SalGradient const & rSalGradient) +{ + return implDrawGradient(rPolyPolygon, rSalGradient); +} + void SalGraphics::CopyArea( long nDestX, long nDestY, long nSrcX, long nSrcY, long nSrcWidth, long nSrcHeight, |