[haiku-commits] haiku: hrev48447 - in src: tests/servers/app/gradients servers/app servers/app/drawing/Painter

  • From: pulkomandy@xxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 5 Dec 2014 14:55:05 +0100 (CET)

hrev48447 adds 2 changesets to branch 'master'
old head: 336c69d9c4dfc80a6d9450e51d64b0569bbba603
new head: c4e8d88f7c53179606b32acb0cab1265eaa47bf3
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=c4e8d88+%5E336c69d

----------------------------------------------------------------------------

96bac1b: Add a test for #2945.

c4e8d88: app_server: fix gradients with no stops at the ends
  
  When a gradient has no stop at offset 0 or 255, the drawing code will
  not automatically complete the gradiet with the first or last color,
  instead agg interpolation generated invalid random colors.
  
  To avoid this, insert extra stops at the start and end in the
  DrawingEngine when we prepare the gradient for drawing. We just copy the
  first and last stops to new stops at offsets 0 and 255, which makes sure
  the gradients covers the whole range and gives the expected result.
  
  Fixes #2945.

                                 [ Adrien Destugues <pulkomandy@xxxxxxxxx> ]

----------------------------------------------------------------------------

3 files changed, 56 insertions(+), 8 deletions(-)
src/servers/app/DrawingContext.cpp          | 24 ++++++++++++----
src/servers/app/drawing/Painter/Painter.cpp |  2 +-
src/tests/servers/app/gradients/main.cpp    | 38 ++++++++++++++++++++++++-

############################################################################

Commit:      96bac1b30b7608c473264dfa7d234d6ef95667e5
URL:         http://cgit.haiku-os.org/haiku/commit/?id=96bac1b
Author:      Adrien Destugues <pulkomandy@xxxxxxxxx>
Date:        Fri Dec  5 13:51:47 2014 UTC

Ticket:      https://dev.haiku-os.org/ticket/2945

Add a test for #2945.

----------------------------------------------------------------------------

diff --git a/src/tests/servers/app/gradients/main.cpp 
b/src/tests/servers/app/gradients/main.cpp
index 52c684a..47810a8 100644
--- a/src/tests/servers/app/gradients/main.cpp
+++ b/src/tests/servers/app/gradients/main.cpp
@@ -42,7 +42,7 @@ public:
                Test("Radial Gradient")
        {
        }
-       
+
        virtual void Draw(BView* view, BRect updateRect)
        {
                // Draws two radial gradients with the same stops and different 
radiis,
@@ -157,6 +157,41 @@ public:
 };
 
 
+// Test for https://dev.haiku-os.org/ticket/2945
+// Gradients with no stop at offset 0 or 255 draw random colors
+class OutOfBoundsGradientTest : public Test {
+public:
+       OutOfBoundsGradientTest()
+               :
+               Test("Out of bounds gradients")
+       {
+       }
+
+       virtual void Draw(BView* view, BRect updateRect)
+       {
+               {
+                       // Linear gradient - Vertical
+                       BPoint from(275, 10);
+                       BPoint to(275, 138);
+                       BGradientLinear l(from, to);
+                       l.AddColor((rgb_color){ 255, 0, 0, 255 }, 100.0);
+                       l.AddColor((rgb_color){ 255, 255, 0, 255 }, 156.0);
+                       view->FillRect(BRect(275, 10, 2*265, 265), l);
+               }
+
+               {
+                       // Linear gradient - Horizontal
+                       BPoint from(10, 10);
+                       BPoint to(138, 10);
+                       BGradientLinear l(from, to);
+                       l.AddColor((rgb_color){ 255, 0, 0, 255 }, 100.0);
+                       l.AddColor((rgb_color){ 255, 255, 0, 255 }, 156.0);
+                       view->FillRect(BRect(10, 10, 265, 265), l);
+               }
+       }
+};
+
+
 // #pragma mark -
 
 
@@ -169,6 +204,7 @@ main(int argc, char** argv)
 
        window->AddTest(new RadialGradientTest());
        window->AddTest(new AlphaGradientTest());
+       window->AddTest(new OutOfBoundsGradientTest());
 
        window->SetToTest(0);
        window->Show();

############################################################################

Revision:    hrev48447
Commit:      c4e8d88f7c53179606b32acb0cab1265eaa47bf3
URL:         http://cgit.haiku-os.org/haiku/commit/?id=c4e8d88
Author:      Adrien Destugues <pulkomandy@xxxxxxxxx>
Date:        Fri Dec  5 13:52:31 2014 UTC

Ticket:      https://dev.haiku-os.org/ticket/2945

app_server: fix gradients with no stops at the ends

When a gradient has no stop at offset 0 or 255, the drawing code will
not automatically complete the gradiet with the first or last color,
instead agg interpolation generated invalid random colors.

To avoid this, insert extra stops at the start and end in the
DrawingEngine when we prepare the gradient for drawing. We just copy the
first and last stops to new stops at offsets 0 and 255, which makes sure
the gradients covers the whole range and gives the expected result.

Fixes #2945.

----------------------------------------------------------------------------

diff --git a/src/servers/app/DrawingContext.cpp 
b/src/servers/app/DrawingContext.cpp
index b259f5e..8a61f9b 100644
--- a/src/servers/app/DrawingContext.cpp
+++ b/src/servers/app/DrawingContext.cpp
@@ -185,7 +185,7 @@ DrawingContext::ConvertToScreenForDrawing(BRegion* region) 
const
 void
 DrawingContext::ConvertToScreenForDrawing(BGradient* gradient) const
 {
-       switch(gradient->GetType()) {
+       switch (gradient->GetType()) {
                case BGradient::TYPE_LINEAR:
                {
                        BGradientLinear* linear = (BGradientLinear*) gradient;
@@ -197,7 +197,6 @@ DrawingContext::ConvertToScreenForDrawing(BGradient* 
gradient) const
                        ConvertToScreen(&end);
                        linear->SetStart(start);
                        linear->SetEnd(end);
-                       linear->SortColorStopsByOffset();
                        break;
                }
                case BGradient::TYPE_RADIAL:
@@ -207,7 +206,6 @@ DrawingContext::ConvertToScreenForDrawing(BGradient* 
gradient) const
                        fDrawState->Transform(&center);
                        ConvertToScreen(&center);
                        radial->SetCenter(center);
-                       radial->SortColorStopsByOffset();
                        break;
                }
                case BGradient::TYPE_RADIAL_FOCUS:
@@ -221,7 +219,6 @@ DrawingContext::ConvertToScreenForDrawing(BGradient* 
gradient) const
                        ConvertToScreen(&focal);
                        radialFocus->SetCenter(center);
                        radialFocus->SetFocal(focal);
-                       radialFocus->SortColorStopsByOffset();
                        break;
                }
                case BGradient::TYPE_DIAMOND:
@@ -231,7 +228,6 @@ DrawingContext::ConvertToScreenForDrawing(BGradient* 
gradient) const
                        fDrawState->Transform(&center);
                        ConvertToScreen(&center);
                        diamond->SetCenter(center);
-                       diamond->SortColorStopsByOffset();
                        break;
                }
                case BGradient::TYPE_CONIC:
@@ -241,7 +237,6 @@ DrawingContext::ConvertToScreenForDrawing(BGradient* 
gradient) const
                        fDrawState->Transform(&center);
                        ConvertToScreen(&center);
                        conic->SetCenter(center);
-                       conic->SortColorStopsByOffset();
                        break;
                }
                case BGradient::TYPE_NONE:
@@ -249,6 +244,23 @@ DrawingContext::ConvertToScreenForDrawing(BGradient* 
gradient) const
                        break;
                }
        }
+
+       // Make sure the gradient is fully padded so that out of bounds access
+       // get the correct colors
+       gradient->SortColorStopsByOffset();
+
+       BGradient::ColorStop* end = gradient->ColorStopAtFast(
+               gradient->CountColorStops() - 1);
+
+       if (end->offset != 255)
+               gradient->AddColor(end->color, 255);
+
+       BGradient::ColorStop* start = gradient->ColorStopAtFast(0);
+
+       if (start->offset != 0)
+               gradient->AddColor(start->color, 0);
+
+       gradient->SortColorStopsByOffset();
 }
 
 
diff --git a/src/servers/app/drawing/Painter/Painter.cpp 
b/src/servers/app/drawing/Painter/Painter.cpp
index 97f1a1f..9ac646e 100644
--- a/src/servers/app/drawing/Painter/Painter.cpp
+++ b/src/servers/app/drawing/Painter/Painter.cpp
@@ -2881,7 +2881,7 @@ Painter::_RasterizePath(VertexSource& path, const 
BGradient& gradient) const
 
        agg::trans_affine gradientTransform;
 
-       switch(gradient.GetType()) {
+       switch (gradient.GetType()) {
                case BGradient::TYPE_LINEAR:
                {
                        GTRACE(("Painter::_FillPath> type == TYPE_LINEAR\n"));


Other related posts:

  • » [haiku-commits] haiku: hrev48447 - in src: tests/servers/app/gradients servers/app servers/app/drawing/Painter - pulkomandy