[haiku-commits] haiku: hrev46838 - in src/servers/app/drawing/Painter: . src/servers/app/drawing

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 8 Feb 2014 11:39:37 +0100 (CET)

hrev46838 adds 2 changesets to branch 'master'
old head: b8f01fee6077245ee530dce98dfc7babcdbe413d
new head: 89f8b7a12d16a16388e45a4708c033cfb3993df7
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=89f8b7a+%5Eb8f01fe

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

13e393d: app_server::Transforable: Cleanup
  
   * No need to implement operator== and !=
   * Fix operator=() to be efficent, declare agg::trans_affine version, too.

89f8b7a: app_server: Fix computing bounding boxes for transformed stuff.
  
   * In DrawingEngine, clipping is computed before drawing happens. This did not
     take into account when drawing primitives can now be transformed. Fixes
     drawing glitches in the Transformation test when the round rect is scrolled
     into view and it was previously prevented to draw.
   * Fixed clipping rect computation for the sanitized StrokeRoundRect()
     implementation which centers the stroke on the rect.

                                      [ Stephan Aßmus <superstippi@xxxxxx> ]

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

4 files changed, 107 insertions(+), 83 deletions(-)
src/servers/app/drawing/DrawingEngine.cpp        | 48 +++++-----
src/servers/app/drawing/Painter/Painter.h        | 42 ++++++++-
.../app/drawing/Painter/Transformable.cpp        | 95 +++++++++-----------
src/servers/app/drawing/Painter/Transformable.h  |  5 +-

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

Commit:      13e393dfc18797b29ea7a07c3b94cadae4b330ee
URL:         http://cgit.haiku-os.org/haiku/commit/?id=13e393d
Author:      Stephan Aßmus <superstippi@xxxxxx>
Date:        Sat Feb  8 10:35:05 2014 UTC

app_server::Transforable: Cleanup

 * No need to implement operator== and !=
 * Fix operator=() to be efficent, declare agg::trans_affine version, too.

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

diff --git a/src/servers/app/drawing/Painter/Transformable.cpp 
b/src/servers/app/drawing/Painter/Transformable.cpp
index 07769d9..ca7eb66 100644
--- a/src/servers/app/drawing/Painter/Transformable.cpp
+++ b/src/servers/app/drawing/Painter/Transformable.cpp
@@ -13,37 +13,37 @@
 
 #include "Transformable.h"
 
-// min4
+
 inline float
 min4(float a, float b, float c, float d)
 {
        return min_c(a, min_c(b, min_c(c, d)));
 } 
 
-// max4
+
 inline float
 max4(float a, float b, float c, float d)
 {
        return max_c(a, max_c(b, max_c(c, d)));
 } 
 
-// constructor
+
 Transformable::Transformable()
        : agg::trans_affine()
 {
 }
 
-// copy constructor
+
 Transformable::Transformable(const Transformable& other)
        : agg::trans_affine(other)
 {
 }
 
-// constructor
+
 Transformable::Transformable(const BMessage* archive)
        : agg::trans_affine()
 {
-       if (archive) {
+       if (archive != NULL) {
                double storage[6];
                status_t ret = B_OK;
                for (int32 i = 0; i < 6; i++) {
@@ -56,17 +56,17 @@ Transformable::Transformable(const BMessage* archive)
        }
 }
 
-// destructor
+
 Transformable::~Transformable()
 {
 }
 
-// Archive
+
 status_t
 Transformable::Archive(BMessage* into, bool deep) const
 {
        status_t ret = BArchivable::Archive(into, deep);
-       if (ret >= B_OK) {
+       if (ret == B_OK) {
                double storage[6];
                store_to(storage);
                for (int32 i = 0; i < 6; i++) {
@@ -75,24 +75,24 @@ Transformable::Archive(BMessage* into, bool deep) const
                                break;
                }
                // finish off
-               if (ret >= B_OK)
+               if (ret == B_OK)
                        ret = into->AddString("class", "Transformable");
        }
        return ret;
 }
 
-// StoreTo
+
 void
 Transformable::StoreTo(double matrix[6]) const
 {
        store_to(matrix);
 }
 
-// LoadFrom
+
 void
 Transformable::LoadFrom(double matrix[6])
 {
-       // before calling the potentially heavy TransformationChanged()
+       // Before calling the potentially heavy TransformationChanged()
        // hook function, we make sure that it is actually true
        Transformable t;
        t.load_from(matrix);
@@ -102,7 +102,7 @@ Transformable::LoadFrom(double matrix[6])
        }
 }
 
-// SetTransformable
+
 void
 Transformable::SetTransformable(const Transformable& other)
 {
@@ -112,19 +112,29 @@ Transformable::SetTransformable(const Transformable& 
other)
        }
 }
 
-// operator=
+
 Transformable&
 Transformable::operator=(const Transformable& other)
 {
        if (other != *this) {
-               reset();
-               multiply(other);
+               agg::trans_affine::operator=(other);
+               TransformationChanged();
+       }
+       return *this;
+}
+
+
+Transformable&
+Transformable::operator=(const agg::trans_affine& other)
+{
+       if (other != *this) {
+               agg::trans_affine::operator=(other);
                TransformationChanged();
        }
        return *this;
 }
 
-// Multiply
+
 Transformable&
 Transformable::Multiply(const Transformable& other)
 {
@@ -135,14 +145,14 @@ Transformable::Multiply(const Transformable& other)
        return *this;
 }
 
-// Reset
+
 void
 Transformable::Reset()
 {
        reset();
 }
 
-// IsIdentity
+
 bool
 Transformable::IsIdentity() const
 {
@@ -158,39 +168,14 @@ Transformable::IsIdentity() const
        return false;
 }
 
-// operator==
-bool
-Transformable::operator==(const Transformable& other) const
-{
-       double m1[6];
-       other.store_to(m1);
-       double m2[6];
-       store_to(m2);
-       if (m1[0] == m2[0] &&
-               m1[1] == m2[1] &&
-               m1[2] == m2[2] &&
-               m1[3] == m2[3] &&
-               m1[4] == m2[4] &&
-               m1[5] == m2[5])
-               return true;
-       return false;
-}
-
-// operator!=
-bool
-Transformable::operator!=(const Transformable& other) const
-{
-       return !(*this == other);
-}
 
-// Transform
 void
 Transformable::Transform(double* x, double* y) const
 {
        transform(x, y);
 }
 
-// Transform
+
 void
 Transformable::Transform(BPoint* point) const
 {
@@ -205,7 +190,7 @@ Transformable::Transform(BPoint* point) const
        }
 }
 
-// Transform
+
 BPoint
 Transformable::Transform(const BPoint& point) const
 {
@@ -214,14 +199,14 @@ Transformable::Transform(const BPoint& point) const
        return p;
 }
 
-// InverseTransform
+
 void
 Transformable::InverseTransform(double* x, double* y) const
 {
        inverse_transform(x, y);
 }
 
-// InverseTransform
+
 void
 Transformable::InverseTransform(BPoint* point) const
 {
@@ -236,7 +221,7 @@ Transformable::InverseTransform(BPoint* point) const
        }
 }
 
-// InverseTransform
+
 BPoint
 Transformable::InverseTransform(const BPoint& point) const
 {
@@ -245,7 +230,7 @@ Transformable::InverseTransform(const BPoint& point) const
        return p;
 }
 
-// TransformBounds
+
 BRect
 Transformable::TransformBounds(const BRect& bounds) const
 {
@@ -279,7 +264,7 @@ Transformable::IsTranslationOnly() const
 }
 
 
-// TranslateBy
+
 void
 Transformable::TranslateBy(BPoint offset)
 {
@@ -289,7 +274,7 @@ Transformable::TranslateBy(BPoint offset)
        }
 }
 
-// RotateBy
+
 void
 Transformable::RotateBy(BPoint origin, double radians)
 {
@@ -301,7 +286,7 @@ Transformable::RotateBy(BPoint origin, double radians)
        }
 }
 
-// ScaleBy
+
 void
 Transformable::ScaleBy(BPoint origin, double xScale, double yScale)
 {
@@ -313,7 +298,7 @@ Transformable::ScaleBy(BPoint origin, double xScale, double 
yScale)
        }
 }
 
-// ShearBy
+
 void
 Transformable::ShearBy(BPoint origin, double xShear, double yShear)
 {
diff --git a/src/servers/app/drawing/Painter/Transformable.h 
b/src/servers/app/drawing/Painter/Transformable.h
index 9854020..ac8dc0b 100644
--- a/src/servers/app/drawing/Painter/Transformable.h
+++ b/src/servers/app/drawing/Painter/Transformable.h
@@ -32,13 +32,14 @@ class Transformable : public BArchivable,
 
                                                                // set to or 
combine with other matrix
                        void                            SetTransformable(const 
Transformable& other);
+                       Transformable&          operator=(const 
agg::trans_affine& other);
                        Transformable&          operator=(const Transformable& 
other);
                        Transformable&          Multiply(const Transformable& 
other);
                        void                            Reset();
 
                        bool                            IsIdentity() const;
-                       bool                            operator==(const 
Transformable& other) const;
-                       bool                            operator!=(const 
Transformable& other) const;
+//                     bool                            operator==(const 
Transformable& other) const;
+//                     bool                            operator!=(const 
Transformable& other) const;
 
                                                                // transforms 
coordiantes
                        void                            Transform(double* x, 
double* y) const;

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

Revision:    hrev46838
Commit:      89f8b7a12d16a16388e45a4708c033cfb3993df7
URL:         http://cgit.haiku-os.org/haiku/commit/?id=89f8b7a
Author:      Stephan Aßmus <superstippi@xxxxxx>
Date:        Sat Feb  8 10:36:13 2014 UTC

app_server: Fix computing bounding boxes for transformed stuff.

 * In DrawingEngine, clipping is computed before drawing happens. This did not
   take into account when drawing primitives can now be transformed. Fixes
   drawing glitches in the Transformation test when the round rect is scrolled
   into view and it was previously prevented to draw.
 * Fixed clipping rect computation for the sanitized StrokeRoundRect()
   implementation which centers the stroke on the rect.

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

diff --git a/src/servers/app/drawing/DrawingEngine.cpp 
b/src/servers/app/drawing/DrawingEngine.cpp
index 6ef0b85..3fdc48f 100644
--- a/src/servers/app/drawing/DrawingEngine.cpp
+++ b/src/servers/app/drawing/DrawingEngine.cpp
@@ -583,6 +583,7 @@ DrawingEngine::InvertRect(BRect r)
        ASSERT_PARALLEL_LOCKED();
 
        make_rect_valid(r);
+       // NOTE: Currently ignores view transformation, so no 
TransformAndClipRect()
        r = fPainter->ClipRect(r);
        if (!r.IsValid())
                return;
@@ -608,7 +609,7 @@ DrawingEngine::DrawBitmap(ServerBitmap* bitmap, const 
BRect& bitmapRect,
 {
        ASSERT_PARALLEL_LOCKED();
 
-       BRect clipped = fPainter->ClipRect(viewRect);
+       BRect clipped = fPainter->TransformAndClipRect(viewRect);
        if (clipped.IsValid()) {
                AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
 
@@ -632,7 +633,7 @@ DrawingEngine::DrawArc(BRect r, const float& angle, const 
float& span,
        if (!filled)
                extend_by_stroke_width(clipped, fPainter->PenSize());
 
-       clipped = fPainter->ClipRect(r);
+       clipped = fPainter->TransformAndClipRect(r);
 
        if (clipped.IsValid()) {
                AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
@@ -662,7 +663,7 @@ DrawingEngine::FillArc(BRect r, const float& angle, const 
float& span,
        fPainter->AlignEllipseRect(&r, true);
        BRect clipped(r);
 
-       clipped = fPainter->ClipRect(r);
+       clipped = fPainter->TransformAndClipRect(r);
 
        if (clipped.IsValid()) {
                AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
@@ -724,7 +725,7 @@ DrawingEngine::DrawEllipse(BRect r, bool filled)
        clipped.right = ceilf(clipped.right);
        clipped.bottom = ceilf(clipped.bottom);
 
-       clipped = fPainter->ClipRect(clipped);
+       clipped = fPainter->TransformAndClipRect(clipped);
 
        if (clipped.IsValid()) {
                AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
@@ -750,7 +751,7 @@ DrawingEngine::FillEllipse(BRect r, const BGradient& 
gradient)
        clipped.right = ceilf(clipped.right);
        clipped.bottom = ceilf(clipped.bottom);
 
-       clipped = fPainter->ClipRect(clipped);
+       clipped = fPainter->TransformAndClipRect(clipped);
 
        if (clipped.IsValid()) {
                AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
@@ -771,7 +772,7 @@ DrawingEngine::DrawPolygon(BPoint* ptlist, int32 numpts, 
BRect bounds,
        make_rect_valid(bounds);
        if (!filled)
                extend_by_stroke_width(bounds, fPainter->PenSize());
-       bounds = fPainter->ClipRect(bounds);
+       bounds = fPainter->TransformAndClipRect(bounds);
        if (bounds.IsValid()) {
                AutoFloatingOverlaysHider _(fGraphicsCard, bounds);
 
@@ -789,7 +790,7 @@ DrawingEngine::FillPolygon(BPoint* ptlist, int32 numpts, 
BRect bounds,
        ASSERT_PARALLEL_LOCKED();
 
        make_rect_valid(bounds);
-       bounds = fPainter->ClipRect(bounds);
+       bounds = fPainter->TransformAndClipRect(bounds);
        if (bounds.IsValid()) {
                AutoFloatingOverlaysHider _(fGraphicsCard, bounds);
 
@@ -938,7 +939,7 @@ DrawingEngine::StrokeRect(BRect r)
        make_rect_valid(r);
        BRect clipped(r);
        extend_by_stroke_width(clipped, fPainter->PenSize());
-       clipped = fPainter->ClipRect(clipped);
+       clipped = fPainter->TransformAndClipRect(clipped);
        if (clipped.IsValid()) {
                AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
 
@@ -955,7 +956,7 @@ DrawingEngine::FillRect(BRect r)
        ASSERT_PARALLEL_LOCKED();
 
        make_rect_valid(r);
-       r = fPainter->AlignAndClipRect(r);
+       r = fPainter->TransformAlignAndClipRect(r);
        if (!r.IsValid())
                return;
 
@@ -1007,7 +1008,7 @@ DrawingEngine::FillRect(BRect r, const BGradient& 
gradient)
        ASSERT_PARALLEL_LOCKED();
 
        make_rect_valid(r);
-       r = fPainter->AlignAndClipRect(r);
+       r = fPainter->TransformAlignAndClipRect(r);
        if (!r.IsValid())
                return;
 
@@ -1024,7 +1025,7 @@ DrawingEngine::FillRegion(BRegion& r)
 {
        ASSERT_PARALLEL_LOCKED();
 
-       BRect clipped = fPainter->ClipRect(r.Frame());
+       BRect clipped = fPainter->TransformAndClipRect(r.Frame());
        if (!clipped.IsValid())
                return;
 
@@ -1095,10 +1096,10 @@ DrawingEngine::DrawRoundRect(BRect r, float xrad, float 
yrad, bool filled)
 {
        ASSERT_PARALLEL_LOCKED();
 
-       // NOTE: the stroke does not extend past "r" in R5,
-       // though I consider this unexpected behaviour.
        make_rect_valid(r);
-       BRect clipped = fPainter->ClipRect(r);
+       if (!filled)
+               extend_by_stroke_width(r, fPainter->PenSize());
+       BRect clipped = fPainter->TransformAndClipRect(r);
 
        clipped.left = floorf(clipped.left);
        clipped.top = floorf(clipped.top);
@@ -1122,10 +1123,8 @@ DrawingEngine::FillRoundRect(BRect r, float xrad, float 
yrad,
 {
        ASSERT_PARALLEL_LOCKED();
 
-       // NOTE: the stroke does not extend past "r" in R5,
-       // though I consider this unexpected behaviour.
        make_rect_valid(r);
-       BRect clipped = fPainter->ClipRect(r);
+       BRect clipped = fPainter->TransformAndClipRect(r);
 
        clipped.left = floorf(clipped.left);
        clipped.top = floorf(clipped.top);
@@ -1210,7 +1209,7 @@ DrawingEngine::DrawTriangle(BPoint* pts, const BRect& 
bounds, bool filled)
        BRect clipped(bounds);
        if (!filled)
                extend_by_stroke_width(clipped, fPainter->PenSize());
-       clipped = fPainter->ClipRect(clipped);
+       clipped = fPainter->TransformAndClipRect(clipped);
        if (clipped.IsValid()) {
                AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
 
@@ -1231,7 +1230,7 @@ DrawingEngine::FillTriangle(BPoint* pts, const BRect& 
bounds,
        ASSERT_PARALLEL_LOCKED();
 
        BRect clipped(bounds);
-       clipped = fPainter->ClipRect(clipped);
+       clipped = fPainter->TransformAndClipRect(clipped);
        if (clipped.IsValid()) {
                AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
 
@@ -1250,7 +1249,7 @@ DrawingEngine::StrokeLine(const BPoint& start, const 
BPoint& end)
        BRect touched(start, end);
        make_rect_valid(touched);
        extend_by_stroke_width(touched, fPainter->PenSize());
-       touched = fPainter->ClipRect(touched);
+       touched = fPainter->TransformAndClipRect(touched);
        if (touched.IsValid()) {
                AutoFloatingOverlaysHider _(fGraphicsCard, touched);
 
@@ -1286,7 +1285,7 @@ DrawingEngine::StrokeLineArray(int32 numLines,
                touched = touched | box;
        }
        extend_by_stroke_width(touched, fPainter->PenSize());
-       touched = fPainter->ClipRect(touched);
+       touched = fPainter->TransformAndClipRect(touched);
        if (touched.IsValid()) {
                AutoFloatingOverlaysHider _(fGraphicsCard, touched);
 
@@ -1328,7 +1327,8 @@ DrawingEngine::DrawString(const char* string, int32 
length,
        BPoint penLocation = pt;
 
        // try a fast clipping path
-       if (fPainter->ClippingRegion() && fPainter->Font().Rotation() == 0.0f) {
+       if (fPainter->ClippingRegion() && fPainter->Font().Rotation() == 0.0f
+               && fPainter->IsIdentityTransform()) {
                float fontSize = fPainter->Font().Size();
                BRect clippingFrame = fPainter->ClippingRegion()->Frame();
                if (pt.x - fontSize > clippingFrame.right
@@ -1354,7 +1354,7 @@ DrawingEngine::DrawString(const char* string, int32 
length,
        BRect b = fPainter->BoundingBox(string, length, pt, &penLocation, delta,
                &cacheReference);
        // stop here if we're supposed to render outside of the clipping
-       b = fPainter->ClipRect(b);
+       b = fPainter->TransformAndClipRect(b);
        if (b.IsValid()) {
 //printf("bounding box '%s': %lld µs\n", string, system_time() - now);
                AutoFloatingOverlaysHider _(fGraphicsCard, b);
@@ -1385,7 +1385,7 @@ DrawingEngine::DrawString(const char* string, int32 
length,
        BRect b = fPainter->BoundingBox(string, length, offsets, &penLocation,
                &cacheReference);
        // stop here if we're supposed to render outside of the clipping
-       b = fPainter->ClipRect(b);
+       b = fPainter->TransformAndClipRect(b);
        if (b.IsValid()) {
 //printf("bounding box '%s': %lld µs\n", string, system_time() - now);
                AutoFloatingOverlaysHider _(fGraphicsCard, b);
diff --git a/src/servers/app/drawing/Painter/Painter.h 
b/src/servers/app/drawing/Painter/Painter.h
index 6e5a09e..bb9f200 100644
--- a/src/servers/app/drawing/Painter/Painter.h
+++ b/src/servers/app/drawing/Painter/Painter.h
@@ -15,6 +15,7 @@
 #include "FontManager.h"
 #include "PatternHandler.h"
 #include "ServerFont.h"
+#include "Transformable.h"
 
 #include "defines.h"
 
@@ -39,7 +40,6 @@ class FontCacheReference;
 class RenderingBuffer;
 class ServerBitmap;
 class ServerFont;
-class Transformable;
 
 
 class Painter {
@@ -65,6 +65,9 @@ public:
                                                                        int32 
xOffset = 0,
                                                                        int32 
yOffset = 0);
 
+       inline  bool                            IsIdentityTransform() const
+                                                                       { 
return fIdentityTransform; }
+
                        void                            SetHighColor(const 
rgb_color& color);
        inline  rgb_color                       HighColor() const
                                                                        { 
return fPatternHandler.HighColor(); }
@@ -233,7 +236,9 @@ public:
 
                        BRect                           InvertRect(const BRect& 
r) const;
 
+       inline  BRect                           TransformAndClipRect(BRect 
rect) const;
        inline  BRect                           ClipRect(BRect rect) const;
+       inline  BRect                           TransformAlignAndClipRect(BRect 
rect) const;
        inline  BRect                           AlignAndClipRect(BRect rect) 
const;
 
 
@@ -367,7 +372,7 @@ private:
                        bool                            fAttached : 1;
                        bool                            fIdentityTransform : 1;
 
-                       agg::trans_affine       fTransform;
+                       Transformable           fTransform;
                        float                           fPenSize;
                        const BRegion*          fClippingRegion;
                        drawing_mode            fDrawingMode;
@@ -387,6 +392,21 @@ private:
 
 
 inline BRect
+Painter::TransformAndClipRect(BRect rect) const
+{
+       rect.left = floorf(rect.left);
+       rect.top = floorf(rect.top);
+       rect.right = ceilf(rect.right);
+       rect.bottom = ceilf(rect.bottom);
+
+       if (!fIdentityTransform)
+               rect = fTransform.TransformBounds(rect);
+
+       return _Clipped(rect);
+}
+
+
+inline BRect
 Painter::ClipRect(BRect rect) const
 {
        rect.left = floorf(rect.left);
@@ -413,4 +433,22 @@ Painter::AlignAndClipRect(BRect rect) const
 }
 
 
+inline BRect
+Painter::TransformAlignAndClipRect(BRect rect) const
+{
+       rect.left = floorf(rect.left);
+       rect.top = floorf(rect.top);
+       if (fSubpixelPrecise) {
+               rect.right = ceilf(rect.right);
+               rect.bottom = ceilf(rect.bottom);
+       } else {
+               rect.right = floorf(rect.right);
+               rect.bottom = floorf(rect.bottom);
+       }
+       if (!fIdentityTransform)
+               rect = fTransform.TransformBounds(rect);
+       return _Clipped(rect);
+}
+
+
 #endif // PAINTER_H


Other related posts:

  • » [haiku-commits] haiku: hrev46838 - in src/servers/app/drawing/Painter: . src/servers/app/drawing - superstippi