[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - include/basegfx svgio/source vcl/headless vcl/inc vcl/source

Tomaž Vajngerl (via logerrit) logerrit at kemper.freedesktop.org
Wed Nov 13 20:45:58 UTC 2019


 include/basegfx/DrawCommands.hxx            |   51 ++++++++++++++++++++++++++++
 svgio/source/svgreader/svgvisitor.cxx       |   37 ++++++++++++++++++++
 vcl/headless/svpgdi.cxx                     |   34 ++++++++++++++++++
 vcl/inc/SalGradient.hxx                     |   36 +++++++++++++++++++
 vcl/inc/headless/svpgdi.hxx                 |    2 +
 vcl/inc/salgdi.hxx                          |    9 ++++
 vcl/source/gdi/FileDefinitionWidgetDraw.cxx |   46 +++++++++++++++++++++++++
 vcl/source/gdi/salgdilayout.cxx             |    5 ++
 8 files changed, 220 insertions(+)

New commits:
commit a8dad3673f746ec9874f9b1d0780a13c4ac124a6
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Mon Nov 4 18:36:51 2019 +0100
Commit:     Tomaž Vajngerl <quikee at gmail.com>
CommitDate: Wed Nov 13 21:45:15 2019 +0100

    widget theme: Gradient support when drawing widgets
    
    Reviewed-on: https://gerrit.libreoffice.org/82207
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
    (cherry picked from commit 389c8239c93663fa5546b2f0227a118a3ad091bf)
    
    Change-Id: I29239348e36e4963d9708a22ac649b2b1d68bf02
    Reviewed-on: https://gerrit.libreoffice.org/82382
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/include/basegfx/DrawCommands.hxx b/include/basegfx/DrawCommands.hxx
index 92747c5af4d2..d7d861f9effd 100644
--- a/include/basegfx/DrawCommands.hxx
+++ b/include/basegfx/DrawCommands.hxx
@@ -11,6 +11,13 @@
 #define INCLUDED_BASEGFX_DRAWCOMMANDS_H
 
 #include <memory>
+#include <vector>
+
+#include <basegfx/color/bcolor.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/color/bcolor.hxx>
 
 namespace gfx
 {
@@ -29,6 +36,48 @@ enum class DrawCommandType
     Path
 };
 
+enum class GradientType
+{
+    Linear
+};
+
+class GradientStop
+{
+public:
+    float mfOffset;
+    basegfx::BColor maColor;
+    float mfOpacity;
+};
+
+class GradientInfo
+{
+public:
+    GradientType meType;
+
+    std::vector<GradientStop> maGradientStops;
+
+    GradientInfo(GradientType eType)
+        : meType(eType)
+    {
+    }
+};
+
+class LinearGradientInfo : public GradientInfo
+{
+public:
+    LinearGradientInfo()
+        : GradientInfo(GradientType::Linear)
+    {
+    }
+
+    double x1;
+    double y1;
+    double x2;
+    double y2;
+
+    basegfx::B2DHomMatrix maMatrix;
+};
+
 class DrawBase : public DrawCommand
 {
 private:
@@ -65,6 +114,7 @@ public:
     double mnOpacity;
     std::shared_ptr<basegfx::BColor> mpFillColor;
     std::shared_ptr<basegfx::BColor> mpStrokeColor;
+    std::shared_ptr<GradientInfo> mpFillGradient;
 
     DrawRectangle(basegfx::B2DRange const& rRectangle)
         : DrawBase(DrawCommandType::Rectangle)
@@ -86,6 +136,7 @@ public:
     double mnOpacity;
     std::shared_ptr<basegfx::BColor> mpFillColor;
     std::shared_ptr<basegfx::BColor> mpStrokeColor;
+    std::shared_ptr<GradientInfo> mpFillGradient;
 
     DrawPath(basegfx::B2DPolyPolygon const& rPolyPolygon)
         : DrawBase(DrawCommandType::Path)
diff --git a/svgio/source/svgreader/svgvisitor.cxx b/svgio/source/svgreader/svgvisitor.cxx
index 011ce5492fa3..52247be8dd43 100644
--- a/svgio/source/svgreader/svgvisitor.cxx
+++ b/svgio/source/svgreader/svgvisitor.cxx
@@ -16,6 +16,7 @@
 #include <svgsvgnode.hxx>
 #include <svggnode.hxx>
 #include <svgpathnode.hxx>
+#include <svggradientnode.hxx>
 
 #include <svgvisitor.hxx>
 #include <tools/color.hxx>
@@ -77,8 +78,44 @@ void SvgDrawVisitor::visit(svgio::svgreader::SvgNode const& rNode)
             pRectangle->mnOpacity = rRectNode.getSvgStyleAttributes()->getOpacity().getNumber();
 
             const basegfx::BColor* pFillColor = rRectNode.getSvgStyleAttributes()->getFill();
+            const SvgGradientNode* pFillGradient
+                = rRectNode.getSvgStyleAttributes()->getSvgGradientNodeFill();
             if (pFillColor)
+            {
                 pRectangle->mpFillColor = std::make_shared<basegfx::BColor>(*pFillColor);
+            }
+            else if (pFillGradient)
+            {
+                drawinglayer::primitive2d::SvgGradientEntryVector aSvgGradientEntryVector;
+                pFillGradient->collectGradientEntries(aSvgGradientEntryVector);
+                if (!aSvgGradientEntryVector.empty())
+                {
+                    auto aGradientInfo = std::make_shared<gfx::LinearGradientInfo>();
+
+                    aGradientInfo->x1 = pFillGradient->getX1().getNumber();
+                    aGradientInfo->y1 = pFillGradient->getY1().getNumber();
+                    aGradientInfo->x2 = pFillGradient->getX2().getNumber();
+                    aGradientInfo->y2 = pFillGradient->getY2().getNumber();
+
+                    const basegfx::B2DHomMatrix* pGradientTransform
+                        = pFillGradient->getGradientTransform();
+                    if (pGradientTransform)
+                    {
+                        aGradientInfo->maMatrix = *pGradientTransform;
+                    }
+
+                    pRectangle->mpFillGradient = aGradientInfo;
+
+                    for (auto const& rEntry : aSvgGradientEntryVector)
+                    {
+                        gfx::GradientStop aStop;
+                        aStop.maColor = rEntry.getColor();
+                        aStop.mfOffset = rEntry.getOffset();
+                        aStop.mfOpacity = rEntry.getOpacity();
+                        pRectangle->mpFillGradient->maGradientStops.push_back(aStop);
+                    }
+                }
+            }
 
             const basegfx::BColor* pStrokeColor = rRectNode.getSvgStyleAttributes()->getStroke();
             if (pStrokeColor)
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index 9c8a4bb97900..ae605252abe7 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -30,6 +30,7 @@
 #include <sal/log.hxx>
 #include <o3tl/safeint.hxx>
 #include <vcl/sysdata.hxx>
+#include <vcl/gradient.hxx>
 #include <config_cairo_canvas.h>
 #include <basegfx/numeric/ftools.hxx>
 #include <basegfx/range/b2drange.hxx>
@@ -1479,6 +1480,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 c33dd9dfb827..d4f03355258b 100644
--- a/vcl/inc/headless/svpgdi.hxx
+++ b/vcl/inc/headless/svpgdi.hxx
@@ -233,6 +233,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 9be773cfbeef..1106a1eed981 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"
 
@@ -276,6 +277,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(
@@ -498,6 +501,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 393fab87c7b0..9243035ec1e7 100644
--- a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
+++ b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
@@ -18,11 +18,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 <vcl/pngwrite.hxx>
 
@@ -222,6 +224,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 35d4009ffb1f..61c510a363d8 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -653,6 +653,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,


More information about the Libreoffice-commits mailing list