[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - drawinglayer/source vcl/headless vcl/inc

Tomaž Vajngerl (via logerrit) logerrit at kemper.freedesktop.org
Mon Sep 28 11:25:18 UTC 2020


 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx |   72 ++++++++++++++++
 drawinglayer/source/processor2d/vclpixelprocessor2d.hxx |    2 
 vcl/headless/svpgdi.cxx                                 |   49 ++++++++++
 vcl/inc/headless/svpgdi.hxx                             |    3 
 4 files changed, 125 insertions(+), 1 deletion(-)

New commits:
commit 556df847ce677b6b32d15a153c5bbf400db27b75
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Tue Sep 22 15:20:57 2020 +0200
Commit:     Tomaž Vajngerl <quikee at gmail.com>
CommitDate: Mon Sep 28 13:24:43 2020 +0200

    use vcl lin. gradient drawing in drawinglayer + cairo impl.
    
    This adds a divert for drawing of linear gradients drawing, which
    can be implemented natively with a much higher quality and speed.
    
    This also adds a implementation of drawing linear gradients with
    cairo.
    
    Change-Id: I8c39915c3579e6eb88cdce8ae4ac9694ffdb4957
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103374
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>
    (cherry picked from commit 20c09d351ee060bdde13d92d2bf86dd998cdb0cb)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103425
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 0cc87e6eaa20..10d8e69e51fa 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -36,6 +36,7 @@
 #include <drawinglayer/primitive2d/controlprimitive2d.hxx>
 #include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
 #include <com/sun/star/awt/XWindow2.hpp>
+#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
 #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
 #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx>
 #include "helperwrongspellrenderer.hxx"
@@ -58,6 +59,13 @@
 
 #include <com/sun/star/table/BorderLineStyle.hpp>
 
+#include <vcl/window.hxx>
+#include <vcl/gradient.hxx>
+#include <svtools/borderhelper.hxx>
+#include <editeng/borderline.hxx>
+
+#include <com/sun/star/table/BorderLineStyle.hpp>
+
 using namespace com::sun::star;
 
 namespace drawinglayer
@@ -213,6 +221,30 @@ namespace drawinglayer
                 /* false bBypassAACheck, default*/);
         }
 
+namespace
+{
+GradientStyle convertGradientStyle(drawinglayer::attribute::GradientStyle eGradientStyle)
+{
+    switch (eGradientStyle)
+    {
+        case drawinglayer::attribute::GradientStyle::Axial:
+            return GradientStyle::Axial;
+        case drawinglayer::attribute::GradientStyle::Radial:
+            return GradientStyle::Radial;
+        case drawinglayer::attribute::GradientStyle::Elliptical:
+            return GradientStyle::Elliptical;
+        case drawinglayer::attribute::GradientStyle::Square:
+            return GradientStyle::Square;
+        case drawinglayer::attribute::GradientStyle::Rect:
+            return GradientStyle::Rect;
+        case drawinglayer::attribute::GradientStyle::Linear:
+        default:
+            return GradientStyle::Linear;
+    }
+}
+
+} // end anonymous namespace
+
         void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
         {
             switch(rCandidate.getPrimitive2DID())
@@ -373,6 +405,12 @@ namespace drawinglayer
                     processBorderLinePrimitive2D(static_cast<const drawinglayer::primitive2d::BorderLinePrimitive2D&>(rCandidate));
                     break;
                 }
+                case PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D:
+                {
+                    processFillGradientPrimitive2D(
+                        static_cast<const drawinglayer::primitive2d::FillGradientPrimitive2D&>(rCandidate));
+                    break;
+                }
                 default :
                 {
                     SAL_INFO("drawinglayer", "default case for " << drawinglayer::primitive2d::idToString(rCandidate.getPrimitive2DID()));
@@ -857,6 +895,40 @@ namespace drawinglayer
                 mpOutputDevice->SetAntialiasing(nOldAntiAliase);
             }
         }
+
+        void VclPixelProcessor2D::processFillGradientPrimitive2D(
+            const primitive2d::FillGradientPrimitive2D& rPrimitive)
+        {
+            const attribute::FillGradientAttribute& rFillGradient = rPrimitive.getFillGradient();
+
+            if (rFillGradient.getSteps() > 0
+                || rFillGradient.getStyle() != drawinglayer::attribute::GradientStyle::Linear)
+            {
+                process(rPrimitive);
+                return;
+            }
+
+            GradientStyle eGradientStyle = convertGradientStyle(rFillGradient.getStyle());
+
+            basegfx::B2DRange aRange(rPrimitive.getOutputRange());
+            aRange.transform(maCurrentTransformation);
+
+            const tools::Rectangle aRectangle(
+                sal_Int32(std::floor(aRange.getMinX())), sal_Int32(std::floor(aRange.getMinY())),
+                sal_Int32(std::ceil(aRange.getMaxX())), sal_Int32(std::ceil(aRange.getMaxY())));
+
+            Gradient aGradient(eGradientStyle, Color(rFillGradient.getStartColor()),
+                               Color(rFillGradient.getEndColor()));
+
+            aGradient.SetAngle(rFillGradient.getAngle() / F_PI1800);
+            aGradient.SetBorder(rFillGradient.getBorder() * 100);
+            aGradient.SetOfsX(rFillGradient.getOffsetX() * 100.0);
+            aGradient.SetOfsY(rFillGradient.getOffsetY() * 100.0);
+            aGradient.SetSteps(rFillGradient.getSteps());
+
+            mpOutputDevice->DrawGradient(aRectangle, aGradient);
+        }
+
     } // end of namespace processor2d
 } // end of namespace drawinglayer
 
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx
index 1111943a62c8..7fbcd7954dca 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx
@@ -44,6 +44,7 @@ namespace drawinglayer { namespace primitive2d {
     class FillHatchPrimitive2D;
     class BackgroundColorPrimitive2D;
     class BorderLinePrimitive2D;
+    class FillGradientPrimitive2D;
 }}
 
 namespace drawinglayer
@@ -86,6 +87,7 @@ namespace drawinglayer
             void processBorderLinePrimitive2D(const drawinglayer::primitive2d::BorderLinePrimitive2D& rBorder);
             void processInvertPrimitive2D(const primitive2d::BasePrimitive2D& rCandidate);
             void processMetaFilePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate);
+            void processFillGradientPrimitive2D(const primitive2d::FillGradientPrimitive2D& rPrimitive);
 
         public:
             /// constructor/destructor
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index feaaa671e67e..e196c3b8b2cc 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -1600,6 +1600,55 @@ bool SvpSalGraphics::drawPolyPolygon(
     return true;
 }
 
+bool SvpSalGraphics::drawGradient(const tools::PolyPolygon& rPolyPolygon, const Gradient& rGradient)
+{
+    cairo_t* cr = getCairoContext(true);
+    clipRegion(cr);
+
+    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);
+
+    cairo_pattern_t* pattern;
+    pattern = cairo_pattern_create_linear(aPoly[0].X(), aPoly[0].Y(), aPoly[1].X(), aPoly[1].Y());
+
+    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);
+
+    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);
+    cairo_set_source(cr, pattern);
+
+    basegfx::B2DRange extents = getClippedFillDamage(cr);
+    cairo_fill_preserve(cr);
+
+    releaseCairoContext(cr, true, extents);
+
+    return true;
+}
+
 bool SvpSalGraphics::implDrawGradient(basegfx::B2DPolyPolygon const & rPolyPolygon, SalGradient const & rGradient)
 {
     cairo_t* cr = getCairoContext(true);
diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx
index ef64d5b241c9..21c1ebe64a54 100644
--- a/vcl/inc/headless/svpgdi.hxx
+++ b/vcl/inc/headless/svpgdi.hxx
@@ -234,7 +234,8 @@ public:
                                                    const sal_uInt32* pPoints,
                                                    const SalPoint* const* pPtAry,
                                                    const PolyFlags* const* pFlgAry ) override;
-    virtual bool            drawGradient( const tools::PolyPolygon&, const Gradient& ) override { return false; };
+
+    virtual bool drawGradient(tools::PolyPolygon const & rPolyPolygon, Gradient const & rGradient) override;
 
     virtual bool implDrawGradient(basegfx::B2DPolyPolygon const & rPolyPolygon, SalGradient const & rGradient) override;
 


More information about the Libreoffice-commits mailing list