drawinglayer/source/attribute/fillgradientattribute.cxx  |   35 ++++
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx  |   63 +++-----
 include/drawinglayer/attribute/fillgradientattribute.hxx |    7 
 svx/source/sdr/primitive2d/sdrattributecreator.cxx       |  106 ++++++++-------
 4 files changed, 129 insertions(+), 82 deletions(-)

New commits:
commit 9331d2d333feb911e16f20ce899f2de220bee2f1
Author:     Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de>
AuthorDate: Wed Mar 22 11:44:52 2023 +0100
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Wed Mar 22 14:28:19 2023 +0000

    MCGR: Corrected error with Case16 wrong gradient shortcut
    
    Also simplified using the test cases, these now depend on
    an ENV VAR called MCGR_TEST. Fallback is no test. For
    seeing a multi-color gradient use 1, for Case16 use 16.
    If active, all gradients are replaced with the one active
    for the test, 2D and 3D. This is temporary but also for
    pro build to check for speed there.
    
    Change-Id: I90f3c7e59d9d0a3e070a849af3f9ea1c9e5462a0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149316
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>

diff --git a/drawinglayer/source/attribute/fillgradientattribute.cxx 
b/drawinglayer/source/attribute/fillgradientattribute.cxx
index 62bde03a29f6..b25a4dab2f25 100644
--- a/drawinglayer/source/attribute/fillgradientattribute.cxx
+++ b/drawinglayer/source/attribute/fillgradientattribute.cxx
@@ -154,6 +154,41 @@ namespace drawinglayer::attribute
             return mpFillGradientAttribute->hasSingleColor();
         }
 
+        // MCGR: Check if rendering cannot be handled by old vcl stuff
+        bool FillGradientAttribute::cannotBeHandledByVCL() const
+        {
+            // MCGR: If GradientStops are used, use decomposition since vcl is 
not able
+            // to render multi-color gradients
+            if (getColorStops().size() != 2)
+            {
+                return true;
+            }
+
+            // MCGR: If GradientStops do not start and stop at traditional 
Start/EndColor,
+            // use decomposition since vcl is not able to render this
+            if (!getColorStops().empty())
+            {
+                if 
(!basegfx::fTools::equalZero(getColorStops().front().getStopOffset())
+                    || 
!basegfx::fTools::equal(getColorStops().back().getStopOffset(), 1.0))
+                {
+                    return true;
+                }
+            }
+
+            // VCL should be able to handle all styles, but for tdf#133477 the 
VCL result
+            // is different from processing the gradient manually by 
drawinglayer
+            // (and the Writer unittest for it fails). Keep using the 
drawinglayer code
+            // until somebody founds out what's wrong and fixes it.
+            if (getStyle() != drawinglayer::attribute::GradientStyle::Linear
+                && getStyle() != drawinglayer::attribute::GradientStyle::Axial
+                && getStyle() != 
drawinglayer::attribute::GradientStyle::Radial)
+            {
+                return true;
+            }
+
+            return false;
+        }
+
         FillGradientAttribute& FillGradientAttribute::operator=(const 
FillGradientAttribute&) = default;
 
         FillGradientAttribute& 
FillGradientAttribute::operator=(FillGradientAttribute&&) = default;
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index c49deaf3f369..9f0875e2f489 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -497,16 +497,30 @@ void VclPixelProcessor2D::processBitmapPrimitive2D(
 void VclPixelProcessor2D::processPolyPolygonGradientPrimitive2D(
     const primitive2d::PolyPolygonGradientPrimitive2D& rPolygonCandidate)
 {
-    // direct draw of gradient
+    basegfx::B2DPolyPolygon 
aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon());
+
+    // no geometry, no need to render, done
+    if (!aLocalPolyPolygon.count())
+        return;
+
+    // *try* direct draw (AKA using old VCL stuff) to render gradient
     const attribute::FillGradientAttribute& 
rGradient(rPolygonCandidate.getFillGradient());
+
+    // MCGR: *many* - and not only GradientStops - cases cannot be handled by 
VCL
+    // so use decomposition
+    // NOTE: There may be even more reasons to detect, e.g. a 
ViewTransformation
+    // that uses shear/rotate/mirror (what VCL cannot handle at all), see
+    // other checks already in processFillGradientPrimitive2D
+    if (rGradient.cannotBeHandledByVCL())
+    {
+        process(rPolygonCandidate);
+        return;
+    }
+
     basegfx::BColor aStartColor(
         
maBColorModifierStack.getModifiedColor(rGradient.getColorStops().front().getStopColor()));
     basegfx::BColor aEndColor(
         
maBColorModifierStack.getModifiedColor(rGradient.getColorStops().back().getStopColor()));
-    basegfx::B2DPolyPolygon 
aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon());
-
-    if (!aLocalPolyPolygon.count())
-        return;
 
     if (aStartColor == aEndColor)
     {
@@ -515,12 +529,11 @@ void 
VclPixelProcessor2D::processPolyPolygonGradientPrimitive2D(
         mpOutputDevice->SetLineColor();
         mpOutputDevice->SetFillColor(Color(aStartColor));
         mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
+        return;
     }
-    else
-    {
-        // use the primitive decomposition of the metafile
-        process(rPolygonCandidate);
-    }
+
+    // use the primitive decomposition
+    process(rPolygonCandidate);
 }
 
 void VclPixelProcessor2D::processPolyPolygonColorPrimitive2D(
@@ -938,33 +951,9 @@ void VclPixelProcessor2D::processFillGradientPrimitive2D(
 {
     const attribute::FillGradientAttribute& rFillGradient = 
rPrimitive.getFillGradient();
 
-    // MCGR: If GradientStops are used, use decomposition since vcl is not able
-    // to render multi-color gradients
-    if (rFillGradient.getColorStops().size() != 2)
-    {
-        process(rPrimitive);
-        return;
-    }
-
-    // MCGR: If GradientStops do not start and stop at traditional 
Start/EndColor,
-    // use decomposition since vcl is not able to render this
-    if (!rFillGradient.getColorStops().empty())
-    {
-        if 
(!basegfx::fTools::equalZero(rFillGradient.getColorStops().front().getStopOffset())
-            || 
!basegfx::fTools::equal(rFillGradient.getColorStops().back().getStopOffset(), 
1.0))
-        {
-            process(rPrimitive);
-            return;
-        }
-    }
-
-    // VCL should be able to handle all styles, but for tdf#133477 the VCL 
result
-    // is different from processing the gradient manually by drawinglayer
-    // (and the Writer unittest for it fails). Keep using the drawinglayer code
-    // until somebody founds out what's wrong and fixes it.
-    if (rFillGradient.getStyle() != 
drawinglayer::attribute::GradientStyle::Linear
-        && rFillGradient.getStyle() != 
drawinglayer::attribute::GradientStyle::Axial
-        && rFillGradient.getStyle() != 
drawinglayer::attribute::GradientStyle::Radial)
+    // MCGR: *many* - and not only GradientStops - cases cannot be handled by 
VCL
+    // so use decomposition
+    if (rFillGradient.cannotBeHandledByVCL())
     {
         process(rPrimitive);
         return;
diff --git a/include/drawinglayer/attribute/fillgradientattribute.hxx 
b/include/drawinglayer/attribute/fillgradientattribute.hxx
index 8a2df4d6baaf..eab442644be3 100644
--- a/include/drawinglayer/attribute/fillgradientattribute.hxx
+++ b/include/drawinglayer/attribute/fillgradientattribute.hxx
@@ -89,6 +89,13 @@ public:
     // check if it is defined by a single color, then it is no gradient at all
     bool hasSingleColor() const;
 
+    // MCGR: Check if rendering cannot be handled by old vcl stuff
+    // due to various restrictions, based on local parameters. There
+    // may be even more reasons on caller's side, e.g. a
+    // ViewTransformation that uses shear/rotate/mirror (what VCL
+    // cannot do at all)
+    bool cannotBeHandledByVCL() const;
+
     // compare operator
     bool operator==(const FillGradientAttribute& rCandidate) const;
 
diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx 
b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
index 475a0916f444..344e16e95a8e 100644
--- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx
+++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
@@ -475,7 +475,8 @@ namespace drawinglayer::primitive2d
                             basegfx::ColorStops 
aColorStops(aXGradient.GetColorStops());
 
                             // test code here, can/will be removed later
-                            static sal_uInt32 nUseGradientSteps(0);
+                            static const char* 
pUseGradientSteps(std::getenv("MCGR_TEST"));
+                            static int nUseGradientSteps(pUseGradientSteps ? 
std::atoi(pUseGradientSteps) : 0);
 
                             switch(nUseGradientSteps)
                             {
@@ -483,11 +484,11 @@ namespace drawinglayer::primitive2d
                                 {
                                     // just test a nice valid gradient
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.0, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(0.25, 
basegfx::BColor(0.0, 1.0, 0.0)); // green@25%
-                                    aColorStops.emplace_back(0.50, 
basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
-                                    aColorStops.emplace_back(0.75, 
basegfx::BColor(1.0, 0.0, 1.0)); // pink@75%
-                                    aColorStops.emplace_back(1.0, 
basegfx::BColor(0.0, 0.0, 1.0)); // blue
+                                    aColorStops.emplace_back(0.0, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(0.25, 
COL_LIGHTGREEN.getBColor()); // green@25%
+                                    aColorStops.emplace_back(0.50, 
COL_YELLOW.getBColor()); // yellow@50%
+                                    aColorStops.emplace_back(0.75, 
COL_LIGHTMAGENTA.getBColor()); // pink@75%
+                                    aColorStops.emplace_back(1.0, 
COL_LIGHTBLUE.getBColor()); // blue
                                     break;
                                 }
 
@@ -495,9 +496,9 @@ namespace drawinglayer::primitive2d
                                 {
                                     // single added in-between, no change of 
start/end
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.0, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(0.5, 
basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
-                                    aColorStops.emplace_back(1.0, 
basegfx::BColor(0.0, 0.0, 1.0)); // blue
+                                    aColorStops.emplace_back(0.0, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(0.5, 
COL_YELLOW.getBColor()); // yellow@50%
+                                    aColorStops.emplace_back(1.0, 
COL_LIGHTBLUE.getBColor()); // blue
                                     break;
                                 }
 
@@ -505,9 +506,9 @@ namespace drawinglayer::primitive2d
                                 {
                                     // check additional StartColor, the second 
one has to win
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.0, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(0.0, 
basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
-                                    aColorStops.emplace_back(1.0, 
basegfx::BColor(0.0, 0.0, 1.0)); // blue
+                                    aColorStops.emplace_back(0.0, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(0.0, 
COL_YELLOW.getBColor()); // yellow@50%
+                                    aColorStops.emplace_back(1.0, 
COL_LIGHTBLUE.getBColor()); // blue
                                     break;
                                 }
 
@@ -515,9 +516,9 @@ namespace drawinglayer::primitive2d
                                 {
                                     // check additional EndColor, the first 
one has to win
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.0, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(1.0, 
basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
-                                    aColorStops.emplace_back(1.0, 
basegfx::BColor(0.0, 0.0, 1.0)); // blue
+                                    aColorStops.emplace_back(0.0, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(1.0, 
COL_YELLOW.getBColor()); // yellow@50%
+                                    aColorStops.emplace_back(1.0, 
COL_LIGHTBLUE.getBColor()); // blue
                                     break;
                                 }
 
@@ -525,9 +526,9 @@ namespace drawinglayer::primitive2d
                                 {
                                     // check invalid color (too low index), 
has to be ignored
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.0, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(1.0, 
basegfx::BColor(0.0, 0.0, 1.0)); // blue
-                                    aColorStops.emplace_back(-1.0, 
basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
+                                    aColorStops.emplace_back(0.0, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(1.0, 
COL_LIGHTBLUE.getBColor()); // blue
+                                    aColorStops.emplace_back(-1.0, 
COL_YELLOW.getBColor()); // yellow@50%
                                     break;
                                 }
 
@@ -535,9 +536,9 @@ namespace drawinglayer::primitive2d
                                 {
                                     // check invalid color (too high index), 
has to be ignored
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.0, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(1.0, 
basegfx::BColor(0.0, 0.0, 1.0)); // blue
-                                    aColorStops.emplace_back(2.0, 
basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
+                                    aColorStops.emplace_back(0.0, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(1.0, 
COL_LIGHTBLUE.getBColor()); // blue
+                                    aColorStops.emplace_back(2.0, 
COL_YELLOW.getBColor()); // yellow@50%
                                     break;
                                 }
 
@@ -545,10 +546,10 @@ namespace drawinglayer::primitive2d
                                 {
                                     // check in-between single-color section
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.0, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(0.3, 
basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
-                                    aColorStops.emplace_back(0.7, 
basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
-                                    aColorStops.emplace_back(1.0, 
basegfx::BColor(0.0, 0.0, 1.0)); // blue
+                                    aColorStops.emplace_back(0.0, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(0.3, 
COL_YELLOW.getBColor()); // yellow@50%
+                                    aColorStops.emplace_back(0.7, 
COL_YELLOW.getBColor()); // yellow@50%
+                                    aColorStops.emplace_back(1.0, 
COL_LIGHTBLUE.getBColor()); // blue
                                     break;
                                 }
 
@@ -556,13 +557,13 @@ namespace drawinglayer::primitive2d
                                 {
                                     // check in-between single-color sections
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.0, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(0.2, 
basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
-                                    aColorStops.emplace_back(0.4, 
basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
-                                    aColorStops.emplace_back(0.5, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(0.6, 
basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
-                                    aColorStops.emplace_back(0.8, 
basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
-                                    aColorStops.emplace_back(1.0, 
basegfx::BColor(0.0, 0.0, 1.0)); // blue
+                                    aColorStops.emplace_back(0.0, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(0.2, 
COL_YELLOW.getBColor()); // yellow@50%
+                                    aColorStops.emplace_back(0.4, 
COL_YELLOW.getBColor()); // yellow@50%
+                                    aColorStops.emplace_back(0.5, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(0.6, 
COL_YELLOW.getBColor()); // yellow@50%
+                                    aColorStops.emplace_back(0.8, 
COL_YELLOW.getBColor()); // yellow@50%
+                                    aColorStops.emplace_back(1.0, 
COL_LIGHTBLUE.getBColor()); // blue
                                     break;
                                 }
 
@@ -570,9 +571,9 @@ namespace drawinglayer::primitive2d
                                 {
                                     // check single-color start area
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.0, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(0.6, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(1.0, 
basegfx::BColor(0.0, 0.0, 1.0)); // blue
+                                    aColorStops.emplace_back(0.0, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(0.6, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(1.0, 
COL_LIGHTBLUE.getBColor()); // blue
                                     break;
                                 }
 
@@ -580,9 +581,9 @@ namespace drawinglayer::primitive2d
                                 {
                                     // check single-color end area
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.0, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(0.4, 
basegfx::BColor(0.0, 0.0, 1.0)); // blue
-                                    aColorStops.emplace_back(1.0, 
basegfx::BColor(0.0, 0.0, 1.0)); // blue
+                                    aColorStops.emplace_back(0.0, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(0.4, 
COL_LIGHTBLUE.getBColor()); // blue
+                                    aColorStops.emplace_back(1.0, 
COL_LIGHTBLUE.getBColor()); // blue
                                     break;
                                 }
 
@@ -590,8 +591,8 @@ namespace drawinglayer::primitive2d
                                 {
                                     // check case without direct Start/EndColor
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.4, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(0.6, 
basegfx::BColor(0.0, 0.0, 1.0)); // blue
+                                    aColorStops.emplace_back(0.4, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(0.6, 
COL_LIGHTBLUE.getBColor()); // blue
                                     break;
                                 }
 
@@ -606,7 +607,7 @@ namespace drawinglayer::primitive2d
                                 {
                                     // check case with single stop
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.5, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
+                                    aColorStops.emplace_back(0.5, 
COL_LIGHTRED.getBColor()); // red
                                     break;
                                 }
 
@@ -614,8 +615,8 @@ namespace drawinglayer::primitive2d
                                 {
                                     // check case with single-double stop
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.5, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(0.5, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
+                                    aColorStops.emplace_back(0.5, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(0.5, 
COL_LIGHTRED.getBColor()); // red
                                     break;
                                 }
 
@@ -623,8 +624,23 @@ namespace drawinglayer::primitive2d
                                 {
                                     // check case with single stop diff colors
                                     aColorStops.clear();
-                                    aColorStops.emplace_back(0.5, 
basegfx::BColor(1.0, 0.0, 0.0)); // red
-                                    aColorStops.emplace_back(0.5, 
basegfx::BColor(0.0, 0.0, 1.0)); // blue
+                                    aColorStops.emplace_back(0.5, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(0.5, 
COL_LIGHTBLUE.getBColor()); // blue
+                                    break;
+                                }
+
+                                case 16:
+                                {
+                                    // check case with gradient, hard change, 
gradient
+                                    aColorStops.clear();
+                                    aColorStops.emplace_back(0.0, 
COL_LIGHTGREEN.getBColor()); // green
+                                    aColorStops.emplace_back(0.2, 
COL_LIGHTGREEN.getBColor()); // green
+                                    aColorStops.emplace_back(0.2, 
COL_LIGHTBLUE.getBColor()); // blue
+                                    aColorStops.emplace_back(0.5, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(0.5, 
COL_LIGHTBLUE.getBColor()); // blue
+                                    aColorStops.emplace_back(0.8, 
COL_LIGHTRED.getBColor()); // red
+                                    aColorStops.emplace_back(0.8, 
COL_LIGHTGREEN.getBColor()); // green
+                                    aColorStops.emplace_back(1.0, 
COL_LIGHTGREEN.getBColor()); // green
                                     break;
                                 }
 

Reply via email to