[haiku-commits] haiku: hrev46828 - in src: servers/app/drawing/Painter tests/servers/app/transformation

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 6 Feb 2014 17:18:38 +0100 (CET)

hrev46828 adds 2 changesets to branch 'master'
old head: d091cdec92947211c7675329c370ffad0e9c91a0
new head: d0477fb6730fcd57d0e354b93c83bca8493841aa
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=d0477fb+%5Ed091cde

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

e966330: Transformation: Added gradient test.

d0477fb: Painter: Support transformation in gradient code paths.
  
  Clipping paths (or rather alpha masks) and affine view transformations
  seem to be generally supported for all drawing operations now. There might
  still be bugs that have not yet been exposed by the current set of tests.
  These could be related to scrolling, origin and scale as well as stacked
  view states.

                                      [ Stephan Aßmus <superstippi@xxxxxx> ]

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

3 files changed, 154 insertions(+), 277 deletions(-)
src/servers/app/drawing/Painter/Painter.cpp   | 353 ++++++----------------
src/servers/app/drawing/Painter/Painter.h     |  36 +--
src/tests/servers/app/transformation/main.cpp |  42 ++-

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

Commit:      e966330c991c5e3a605c8e0e9dc48e152a7cd9ae
URL:         http://cgit.haiku-os.org/haiku/commit/?id=e966330
Author:      Stephan Aßmus <superstippi@xxxxxx>
Date:        Thu Feb  6 16:13:08 2014 UTC

Transformation: Added gradient test.

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

diff --git a/src/tests/servers/app/transformation/main.cpp 
b/src/tests/servers/app/transformation/main.cpp
index 09b3007..610df0a 100644
--- a/src/tests/servers/app/transformation/main.cpp
+++ b/src/tests/servers/app/transformation/main.cpp
@@ -4,11 +4,13 @@
  */
 
 
+#include <algorithm>
 #include <stdio.h>
 #include <string.h>
 
 #include <Application.h>
 #include <Bitmap.h>
+#include <GradientLinear.h>
 #include <Message.h>
 #include <Picture.h>
 #include <LayoutBuilder.h>
@@ -361,6 +363,43 @@ private:
 };
 
 
+// #pragma mark - Gradient
+
+
+class GradientTest : public Test {
+public:
+       GradientTest()
+               :
+               Test("Gradient")
+       {
+       }
+       
+       virtual void Draw(BView* view, BRect updateRect)
+       {
+               BRect rect(view->Bounds());
+               rect.InsetBy(rect.Width() / 3, rect.Height() / 3);
+               BPoint center(
+                       rect.left + rect.Width() / 2,
+                       rect.top + rect.Height() / 2);
+
+               BAffineTransform transform;
+               transform.RotateBy(center, 30.0 * M_PI / 180.0);
+               view->SetTransform(transform);
+
+               rgb_color top = (rgb_color){ 255, 255, 0, 255 };
+               rgb_color bottom = (rgb_color){ 0, 255, 255, 255 };
+
+               BGradientLinear gradient;
+               gradient.AddColor(top, 0.0f);
+               gradient.AddColor(bottom, 255.0f);
+               gradient.SetStart(rect.LeftTop());
+               gradient.SetEnd(rect.LeftBottom());
+
+               float radius = std::min(rect.Width() / 5, rect.Height() / 5);
+
+               view->FillRoundRect(rect, radius, radius, gradient);
+       }
+};
 
 
 // #pragma mark -
@@ -375,8 +414,9 @@ main(int argc, char** argv)
 
        window->AddTest(new RectsTest());
        window->AddTest(new BitmapTest());
+       window->AddTest(new GradientTest());
 
-       window->SetToTest(0);
+       window->SetToTest(2);
        window->Show();
 
        app.Run();

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

Revision:    hrev46828
Commit:      d0477fb6730fcd57d0e354b93c83bca8493841aa
URL:         http://cgit.haiku-os.org/haiku/commit/?id=d0477fb
Author:      Stephan Aßmus <superstippi@xxxxxx>
Date:        Thu Feb  6 16:13:36 2014 UTC

Painter: Support transformation in gradient code paths.

Clipping paths (or rather alpha masks) and affine view transformations
seem to be generally supported for all drawing operations now. There might
still be bugs that have not yet been exposed by the current set of tests.
These could be related to scrolling, origin and scale as well as stacked
view states.

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

diff --git a/src/servers/app/drawing/Painter/Painter.cpp 
b/src/servers/app/drawing/Painter/Painter.cpp
index e9f8132..3600901 100644
--- a/src/servers/app/drawing/Painter/Painter.cpp
+++ b/src/servers/app/drawing/Painter/Painter.cpp
@@ -2856,49 +2856,117 @@ template<class VertexSource>
 BRect
 Painter::_FillPath(VertexSource& path, const BGradient& gradient) const
 {
-       GTRACE("Painter::_FillPath\n");
+       if (fIdentityTransform)
+               return _RasterizePath(path, gradient);
+
+       agg::conv_transform<VertexSource> transformedPath(path, fTransform);
+       return _RasterizePath(transformedPath, gradient);
+}
+
+
+// _FillPath
+template<class VertexSource>
+BRect
+Painter::_RasterizePath(VertexSource& path, const BGradient& gradient) const
+{
+       GTRACE("Painter::_RasterizePath\n");
+
+       agg::trans_affine gradientTransform;
 
        switch(gradient.GetType()) {
-               case BGradient::TYPE_LINEAR: {
+               case BGradient::TYPE_LINEAR:
+               {
                        GTRACE(("Painter::_FillPath> type == TYPE_LINEAR\n"));
-                       _FillPathGradientLinear(path, *((const 
BGradientLinear*) &gradient));
+                       const BGradientLinear& linearGradient
+                               = (const BGradientLinear&) gradient;
+                       agg::gradient_x gradientFunction;
+                       _CalcLinearGradientTransform(linearGradient.Start(),
+                               linearGradient.End(), gradientTransform);
+                       _RasterizePath(path, gradient, gradientFunction, 
gradientTransform);
                        break;
                }
-               case BGradient::TYPE_RADIAL: {
+               case BGradient::TYPE_RADIAL:
+               {
                        GTRACE(("Painter::_FillPathGradient> type == 
TYPE_RADIAL\n"));
-                       _FillPathGradientRadial(path,
-                               *((const BGradientRadial*) &gradient));
+                       const BGradientRadial& radialGradient
+                               = (const BGradientRadial&) gradient;
+                       agg::gradient_radial gradientFunction;
+                       _CalcRadialGradientTransform(radialGradient.Center(),
+                               gradientTransform);
+                       _RasterizePath(path, gradient, gradientFunction, 
gradientTransform);
                        break;
                }
-               case BGradient::TYPE_RADIAL_FOCUS: {
+               case BGradient::TYPE_RADIAL_FOCUS:
+               {
                        GTRACE(("Painter::_FillPathGradient> type == 
TYPE_RADIAL_FOCUS\n"));
-                       _FillPathGradientRadialFocus(path,
-                               *((const BGradientRadialFocus*) &gradient));
+                       const BGradientRadialFocus& radialGradient
+                               = (const BGradientRadialFocus&) gradient;
+                       agg::gradient_radial_focus gradientFunction;
+                       _CalcRadialGradientTransform(radialGradient.Center(),
+                               gradientTransform);
+                       _RasterizePath(path, gradient, gradientFunction, 
gradientTransform);
                        break;
                }
-               case BGradient::TYPE_DIAMOND: {
+               case BGradient::TYPE_DIAMOND:
+               {
                        GTRACE(("Painter::_FillPathGradient> type == 
TYPE_DIAMOND\n"));
-                       _FillPathGradientDiamond(path,
-                               *((const BGradientDiamond*) &gradient));
+                       const BGradientDiamond& diamontGradient
+                               = (const BGradientDiamond&) gradient;
+                       agg::gradient_diamond gradientFunction;
+                       _CalcRadialGradientTransform(diamontGradient.Center(),
+                               gradientTransform);
+                       _RasterizePath(path, gradient, gradientFunction, 
gradientTransform);
                        break;
                }
-               case BGradient::TYPE_CONIC: {
+               case BGradient::TYPE_CONIC:
+               {
                        GTRACE(("Painter::_FillPathGradient> type == 
TYPE_CONIC\n"));
-                       _FillPathGradientConic(path,
-                               *((const BGradientConic*) &gradient));
+                       const BGradientConic& conicGradient
+                               = (const BGradientConic&) gradient;
+                       agg::gradient_conic gradientFunction;
+                       _CalcRadialGradientTransform(conicGradient.Center(),
+                               gradientTransform);
+                       _RasterizePath(path, gradient, gradientFunction, 
gradientTransform);
                        break;
                }
-               case BGradient::TYPE_NONE: {
-                       GTRACE(("Painter::_FillPathGradient> type == 
TYPE_NONE\n"));
+               
+               default:
+               case BGradient::TYPE_NONE:
+                       GTRACE(("Painter::_FillPathGradient> type == 
TYPE_NONE/unkown\n"));
                        break;
-               }
        }
 
        return _Clipped(_BoundingBox(path));
 }
 
 
-// _MakeGradient
+void
+Painter::_CalcLinearGradientTransform(BPoint startPoint, BPoint endPoint,
+       agg::trans_affine& matrix, float gradient_d2) const
+{
+       float dx = endPoint.x - startPoint.x;
+       float dy = endPoint.y - startPoint.y;
+
+       matrix.reset();
+       matrix *= agg::trans_affine_scaling(sqrt(dx * dx + dy * dy) / 
gradient_d2);
+       matrix *= agg::trans_affine_rotation(atan2(dy, dx));
+       matrix *= agg::trans_affine_translation(startPoint.x, startPoint.y);
+       matrix *= fTransform;
+       matrix.invert();
+}
+
+
+void
+Painter::_CalcRadialGradientTransform(BPoint center,
+       agg::trans_affine& matrix, float gradient_d2) const
+{
+       matrix.reset();
+       matrix *= agg::trans_affine_translation(center.x, center.y);
+       matrix *= fTransform;
+       matrix.invert();
+}
+
+
 void
 Painter::_MakeGradient(const BGradient& gradient, int32 colorCount,
        uint32* colors, int32 arrayOffset, int32 arraySize) const
@@ -2978,7 +3046,6 @@ Painter::_MakeGradient(const BGradient& gradient, int32 
colorCount,
 }
 
 
-// _MakeGradient
 template<class Array>
 void
 Painter::_MakeGradient(Array& array, const BGradient& gradient) const
@@ -3009,57 +3076,33 @@ Painter::_MakeGradient(Array& array, const BGradient& 
gradient) const
 }
 
 
-// _CalcLinearGradientTransform
-void Painter::_CalcLinearGradientTransform(BPoint startPoint, BPoint endPoint,
-       agg::trans_affine& matrix, float gradient_d2) const
-{
-       float dx = endPoint.x - startPoint.x;
-       float dy = endPoint.y - startPoint.y;
-
-       matrix.reset();
-       matrix *= agg::trans_affine_scaling(sqrt(dx * dx + dy * dy) / 
gradient_d2);
-       matrix *= agg::trans_affine_rotation(atan2(dy, dx));
-       matrix *= agg::trans_affine_translation(startPoint.x, startPoint.y);
-       matrix.invert();
-}
-
-
-// _FillPathGradientLinear
-template<class VertexSource>
+template<class VertexSource, typename GradientFunction>
 void
-Painter::_FillPathGradientLinear(VertexSource& path,
-       const BGradientLinear& linear) const
+Painter::_RasterizePath(VertexSource& path, const BGradient& gradient,
+       GradientFunction function, agg::trans_affine& gradientTransform) const
 {
-       GTRACE("Painter::_FillPathGradientLinear\n");
-
-       BPoint start = linear.Start();
-       BPoint end = linear.End();
+       GTRACE("Painter::_RasterizePath\n");
 
        typedef agg::span_interpolator_linear<> interpolator_type;
        typedef agg::pod_auto_array<agg::rgba8, 256> color_array_type;
        typedef agg::span_allocator<agg::rgba8> span_allocator_type;
-       typedef agg::gradient_x gradient_func_type;
        typedef agg::span_gradient<agg::rgba8, interpolator_type,
-                               gradient_func_type, color_array_type> 
span_gradient_type;
+                               GradientFunction, color_array_type> 
span_gradient_type;
        typedef agg::renderer_scanline_aa<renderer_base, span_allocator_type,
                                span_gradient_type> renderer_gradient_type;
 
-       gradient_func_type gradientFunc;
-       agg::trans_affine gradientMatrix;
-       interpolator_type spanInterpolator(gradientMatrix);
+       interpolator_type spanInterpolator(gradientTransform);
        span_allocator_type spanAllocator;
        color_array_type colorArray;
 
-       _MakeGradient(colorArray, linear);
+       _MakeGradient(colorArray, gradient);
 
-       span_gradient_type spanGradient(spanInterpolator, gradientFunc, 
colorArray,
+       span_gradient_type spanGradient(spanInterpolator, function, colorArray,
                0, 100);
 
        renderer_gradient_type gradientRenderer(fBaseRenderer, spanAllocator,
                spanGradient);
 
-       _CalcLinearGradientTransform(start, end, gradientMatrix);
-
        fRasterizer.reset();
        fRasterizer.add_path(path);
        if (fMaskedUnpackedScanline == NULL)
@@ -3070,209 +3113,3 @@ Painter::_FillPathGradientLinear(VertexSource& path,
        }
 }
 
-
-// _FillPathGradientRadial
-template<class VertexSource>
-void
-Painter::_FillPathGradientRadial(VertexSource& path,
-       const BGradientRadial& radial) const
-{
-       GTRACE("Painter::_FillPathGradientRadial\n");
-
-       BPoint center = radial.Center();
-// TODO: finish this
-//     float radius = radial.Radius();
-
-       typedef agg::span_interpolator_linear<> interpolator_type;
-       typedef agg::pod_auto_array<agg::rgba8, 256> color_array_type;
-       typedef agg::span_allocator<agg::rgba8> span_allocator_type;
-       typedef agg::gradient_radial gradient_func_type;
-       typedef agg::span_gradient<agg::rgba8, interpolator_type,
-       gradient_func_type, color_array_type> span_gradient_type;
-       typedef agg::renderer_scanline_aa<renderer_base, span_allocator_type,
-       span_gradient_type> renderer_gradient_type;
-
-       gradient_func_type gradientFunc;
-       agg::trans_affine gradientMatrix;
-       interpolator_type spanInterpolator(gradientMatrix);
-       span_allocator_type spanAllocator;
-       color_array_type colorArray;
-
-       _MakeGradient(colorArray, radial);
-
-       span_gradient_type spanGradient(spanInterpolator, gradientFunc, 
colorArray,
-               0, 100);
-
-       renderer_gradient_type gradientRenderer(fBaseRenderer, spanAllocator,
-               spanGradient);
-
-       gradientMatrix.reset();
-       gradientMatrix *= agg::trans_affine_translation(center.x, center.y);
-       gradientMatrix.invert();
-
-//     _CalcLinearGradientTransform(start, end, gradientMtx);
-
-       fRasterizer.reset();
-       fRasterizer.add_path(path);
-       if (fMaskedUnpackedScanline == NULL)
-               agg::render_scanlines(fRasterizer, fPackedScanline, 
gradientRenderer);
-       else {
-               agg::render_scanlines(fRasterizer, *fMaskedUnpackedScanline,
-                       gradientRenderer);
-       }
-}
-
-
-// _FillPathGradientRadialFocus
-template<class VertexSource>
-void
-Painter::_FillPathGradientRadialFocus(VertexSource& path,
-       const BGradientRadialFocus& focus) const
-{
-       GTRACE("Painter::_FillPathGradientRadialFocus\n");
-
-       BPoint center = focus.Center();
-// TODO: finish this.
-//     BPoint focal = focus.Focal();
-//     float radius = focus.Radius();
-
-       typedef agg::span_interpolator_linear<> interpolator_type;
-       typedef agg::pod_auto_array<agg::rgba8, 256> color_array_type;
-       typedef agg::span_allocator<agg::rgba8> span_allocator_type;
-       typedef agg::gradient_radial_focus gradient_func_type;
-       typedef agg::span_gradient<agg::rgba8, interpolator_type,
-       gradient_func_type, color_array_type> span_gradient_type;
-       typedef agg::renderer_scanline_aa<renderer_base, span_allocator_type,
-       span_gradient_type> renderer_gradient_type;
-
-       gradient_func_type gradientFunc;
-       agg::trans_affine gradientMatrix;
-       interpolator_type spanInterpolator(gradientMatrix);
-       span_allocator_type spanAllocator;
-       color_array_type colorArray;
-
-       _MakeGradient(colorArray, focus);
-
-       span_gradient_type spanGradient(spanInterpolator, gradientFunc, 
colorArray,
-               0, 100);
-
-       renderer_gradient_type gradientRenderer(fBaseRenderer, spanAllocator,
-               spanGradient);
-
-       gradientMatrix.reset();
-       gradientMatrix *= agg::trans_affine_translation(center.x, center.y);
-       gradientMatrix.invert();
-
-       //      _CalcLinearGradientTransform(start, end, gradientMatrix);
-
-       fRasterizer.reset();
-       fRasterizer.add_path(path);
-       if (fMaskedUnpackedScanline == NULL)
-               agg::render_scanlines(fRasterizer, fPackedScanline, 
gradientRenderer);
-       else {
-               agg::render_scanlines(fRasterizer, *fMaskedUnpackedScanline,
-                       gradientRenderer);
-       }
-}
-
-
-// _FillPathGradientDiamond
-template<class VertexSource>
-void
-Painter::_FillPathGradientDiamond(VertexSource& path,
-       const BGradientDiamond& diamond) const
-{
-       GTRACE("Painter::_FillPathGradientDiamond\n");
-
-       BPoint center = diamond.Center();
-//     float radius = diamond.Radius();
-
-       typedef agg::span_interpolator_linear<> interpolator_type;
-       typedef agg::pod_auto_array<agg::rgba8, 256> color_array_type;
-       typedef agg::span_allocator<agg::rgba8> span_allocator_type;
-       typedef agg::gradient_diamond gradient_func_type;
-       typedef agg::span_gradient<agg::rgba8, interpolator_type,
-       gradient_func_type, color_array_type> span_gradient_type;
-       typedef agg::renderer_scanline_aa<renderer_base, span_allocator_type,
-       span_gradient_type> renderer_gradient_type;
-
-       gradient_func_type gradientFunc;
-       agg::trans_affine gradientMatrix;
-       interpolator_type spanInterpolator(gradientMatrix);
-       span_allocator_type spanAllocator;
-       color_array_type colorArray;
-
-       _MakeGradient(colorArray, diamond);
-
-       span_gradient_type spanGradient(spanInterpolator, gradientFunc, 
colorArray,
-               0, 100);
-
-       renderer_gradient_type gradientRenderer(fBaseRenderer, spanAllocator,
-               spanGradient);
-
-       gradientMatrix.reset();
-       gradientMatrix *= agg::trans_affine_translation(center.x, center.y);
-       gradientMatrix.invert();
-
-       //      _CalcLinearGradientTransform(start, end, gradientMatrix);
-
-       fRasterizer.reset();
-       fRasterizer.add_path(path);
-       if (fMaskedUnpackedScanline == NULL)
-               agg::render_scanlines(fRasterizer, fPackedScanline, 
gradientRenderer);
-       else {
-               agg::render_scanlines(fRasterizer, *fMaskedUnpackedScanline,
-                       gradientRenderer);
-       }
-}
-
-
-// _FillPathGradientConic
-template<class VertexSource>
-void
-Painter::_FillPathGradientConic(VertexSource& path,
-       const BGradientConic& conic) const
-{
-       GTRACE("Painter::_FillPathGradientConic\n");
-
-       BPoint center = conic.Center();
-//     float radius = conic.Radius();
-
-       typedef agg::span_interpolator_linear<> interpolator_type;
-       typedef agg::pod_auto_array<agg::rgba8, 256> color_array_type;
-       typedef agg::span_allocator<agg::rgba8> span_allocator_type;
-       typedef agg::gradient_conic gradient_func_type;
-       typedef agg::span_gradient<agg::rgba8, interpolator_type,
-       gradient_func_type, color_array_type> span_gradient_type;
-       typedef agg::renderer_scanline_aa<renderer_base, span_allocator_type,
-       span_gradient_type> renderer_gradient_type;
-
-       gradient_func_type gradientFunc;
-       agg::trans_affine gradientMatrix;
-       interpolator_type spanInterpolator(gradientMatrix);
-       span_allocator_type spanAllocator;
-       color_array_type colorArray;
-
-       _MakeGradient(colorArray, conic);
-
-       span_gradient_type spanGradient(spanInterpolator, gradientFunc, 
colorArray,
-               0, 100);
-
-       renderer_gradient_type gradientRenderer(fBaseRenderer, spanAllocator,
-               spanGradient);
-
-       gradientMatrix.reset();
-       gradientMatrix *= agg::trans_affine_translation(center.x, center.y);
-       gradientMatrix.invert();
-
-       //      _CalcLinearGradientTransform(start, end, gradientMatrix);
-
-       fRasterizer.reset();
-       fRasterizer.add_path(path);
-       if (fMaskedUnpackedScanline == NULL)
-               agg::render_scanlines(fRasterizer, fPackedScanline, 
gradientRenderer);
-       else {
-               agg::render_scanlines(fRasterizer, *fMaskedUnpackedScanline,
-                       gradientRenderer);
-       }
-}
diff --git a/src/servers/app/drawing/Painter/Painter.h 
b/src/servers/app/drawing/Painter/Painter.h
index 2a24fdc..6e5a09e 100644
--- a/src/servers/app/drawing/Painter/Painter.h
+++ b/src/servers/app/drawing/Painter/Painter.h
@@ -302,9 +302,20 @@ private:
                        BRect                           _FillPath(VertexSource& 
path) const;
                        template<class VertexSource>
                        BRect                           
_RasterizePath(VertexSource& path) const;
+
+                       template<class VertexSource>
+                       BRect                           _FillPath(VertexSource& 
path,
+                                                                       const 
BGradient& gradient) const;
+                       template<class VertexSource>
+                       BRect                           
_RasterizePath(VertexSource& path,
+                                                                       const 
BGradient& gradient) const;
+
                        void                            
_CalcLinearGradientTransform(BPoint startPoint,
                                                                        BPoint 
endPoint, agg::trans_affine& mtx,
                                                                        float 
gradient_d2 = 100.0f) const;
+                       void                            
_CalcRadialGradientTransform(BPoint center,
+                                                                       
agg::trans_affine& mtx,
+                                                                       float 
gradient_d2 = 100.0f) const;
 
                        void                            _MakeGradient(const 
BGradient& gradient,
                                                                        int32 
colorCount, uint32* colors,
@@ -313,25 +324,14 @@ private:
                        template<class Array>
                        void                            _MakeGradient(Array& 
array,
                                                                        const 
BGradient& gradient) const;
-                       template<class VertexSource>
-                       BRect                           _FillPath(VertexSource& 
path,
-                                                                       const 
BGradient& gradient) const;
-                       template<class VertexSource>
-                       void                            
_FillPathGradientLinear(VertexSource& path,
-                                                                       const 
BGradientLinear& linear) const;
-                       template<class VertexSource>
-                       void                            
_FillPathGradientRadial(VertexSource& path,
-                                                                       const 
BGradientRadial& radial) const;
-                       template<class VertexSource>
-                       void                            
_FillPathGradientRadialFocus(VertexSource& path,
-                                                                       const 
BGradientRadialFocus& focus) const;
-                       template<class VertexSource>
-                       void                            
_FillPathGradientDiamond(VertexSource& path,
-                                                                       const 
BGradientDiamond& diamond) const;
-                       template<class VertexSource>
-                       void                            
_FillPathGradientConic(VertexSource& path,
-                                                                       const 
BGradientConic& conic) const;
 
+                       template<class VertexSource, typename GradientFunction>
+                       void                            
_RasterizePath(VertexSource& path,
+                                                                       const 
BGradient& gradient,
+                                                                       
GradientFunction function,
+                                                                       
agg::trans_affine& gradientTransform) const;
+
+private:
        mutable agg::rendering_buffer fBuffer;
 
        // AGG rendering and rasterization classes


Other related posts:

  • » [haiku-commits] haiku: hrev46828 - in src: servers/app/drawing/Painter tests/servers/app/transformation - superstippi