[haiku-commits] haiku: hrev46818 - src/servers/app/drawing/Painter

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 4 Feb 2014 23:57:50 +0100 (CET)

hrev46818 adds 3 changesets to branch 'master'
old head: a6db6bd40fe3492fd3104dba560f0e3ff61d388d
new head: 63a30a4744428d78a1bdce296e7ebf180fadbd8f
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=63a30a4+%5Ea6db6bd

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

897f556: Remove transform again from drawing coord conversion

2e7da84: Fixed execute bits of AGG headers.

63a30a4: Implemented using the transformation in Painter (incomplete)
  
   * Also removed wonky BeOS rendering of stroked round rects and ellipses.
     Nobody would expect it to work like this. This affects stroked round rects
     and ellipsis with a pensize greater than 1.
   * Refactored common code from _StrokePath() and _FillPath().
   * _StrokePath() returned a curious bounding box that didn't take into
     acount the miter width. Now the bounding box is computed from the actual
     stroke conversion of the path.

                                      [ Stephan Aßmus <superstippi@xxxxxx> ]

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

26 files changed, 88 insertions(+), 209 deletions(-)
headers/libs/agg/agg_alpha_mask_u8.h          |   0
headers/libs/agg/agg_conv_adaptor_vcgen.h     |   0
headers/libs/agg/agg_conv_adaptor_vpgen.h     |   0
headers/libs/agg/agg_conv_segmentator.h       |   0
headers/libs/agg/agg_font_cache_manager.h     |   0
headers/libs/agg/agg_path_storage_integer.h   |   0
headers/libs/agg/agg_rasterizer_cells_aa.h    |   0
headers/libs/agg/agg_rasterizer_compound_aa.h |   0
headers/libs/agg/agg_scanline_p.h             |   0
headers/libs/agg/agg_scanline_u.h             |   0
headers/libs/agg/agg_trans_affine.h           |   0
headers/libs/agg/agg_trans_double_path.h      |   0
headers/libs/agg/agg_trans_single_path.h      |   0
headers/libs/agg/agg_trans_viewport.h         |   0
headers/libs/agg/agg_trans_warp_magnifier.h   |   0
headers/libs/agg/agg_vcgen_contour.h          |   0
headers/libs/agg/agg_vcgen_dash.h             |   0
headers/libs/agg/agg_vcgen_markers_term.h     |   0
headers/libs/agg/agg_vcgen_smooth_poly1.h     |   0
headers/libs/agg/agg_vcgen_stroke.h           |   0
headers/libs/agg/agg_vcgen_vertex_sequence.h  |   0
headers/libs/agg/agg_vpgen_segmentator.h      |   0
src/servers/app/DrawState.cpp                 |  14 --
src/servers/app/drawing/Painter/Painter.cpp   | 269 ++++++----------------
src/servers/app/drawing/Painter/Painter.h     |  13 +-
src/servers/app/drawing/Painter/defines.h     |   1 +

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

Commit:      897f5562f9dfb213805d8a84c7de3b668a1380ee
URL:         http://cgit.haiku-os.org/haiku/commit/?id=897f556
Author:      Stephan Aßmus <superstippi@xxxxxx>
Date:        Tue Feb  4 21:54:54 2014 UTC

Remove transform again from drawing coord conversion

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

diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp
index a673aea4..3b0f3ef 100644
--- a/src/servers/app/DrawState.cpp
+++ b/src/servers/app/DrawState.cpp
@@ -457,26 +457,12 @@ DrawState::Transform(float* x, float* y) const
        *y *= fCombinedScale;
        *x += fCombinedOrigin.x;
        *y += fCombinedOrigin.y;
-       if (!fCombinedTransform.IsIdentity()) {
-               double _x = *x;
-               double _y = *y;
-               fCombinedTransform.Apply(&_x, &_y);
-               *x = _x;
-               *y = _y;
-       }
 }
 
 
 void
 DrawState::InverseTransform(float* x, float* y) const
 {
-       if (!fCombinedTransform.IsIdentity()) {
-               double _x = *x;
-               double _y = *y;
-               fCombinedTransform.ApplyInverse(&_x, &_y);
-               *x = _x;
-               *y = _y;
-       }
        *x -= fCombinedOrigin.x;
        *y -= fCombinedOrigin.y;
        if (fCombinedScale != 0.0) {

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

Commit:      2e7da8455a92f61db667fdaf602308344c4426d6
URL:         http://cgit.haiku-os.org/haiku/commit/?id=2e7da84
Author:      Stephan Aßmus <superstippi@xxxxxx>
Date:        Tue Feb  4 22:51:49 2014 UTC

Fixed execute bits of AGG headers.

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

diff --git a/headers/libs/agg/agg_alpha_mask_u8.h 
b/headers/libs/agg/agg_alpha_mask_u8.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_conv_adaptor_vcgen.h 
b/headers/libs/agg/agg_conv_adaptor_vcgen.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_conv_adaptor_vpgen.h 
b/headers/libs/agg/agg_conv_adaptor_vpgen.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_conv_segmentator.h 
b/headers/libs/agg/agg_conv_segmentator.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_font_cache_manager.h 
b/headers/libs/agg/agg_font_cache_manager.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_path_storage_integer.h 
b/headers/libs/agg/agg_path_storage_integer.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_rasterizer_cells_aa.h 
b/headers/libs/agg/agg_rasterizer_cells_aa.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_rasterizer_compound_aa.h 
b/headers/libs/agg/agg_rasterizer_compound_aa.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_scanline_p.h 
b/headers/libs/agg/agg_scanline_p.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_scanline_u.h 
b/headers/libs/agg/agg_scanline_u.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_trans_affine.h 
b/headers/libs/agg/agg_trans_affine.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_trans_double_path.h 
b/headers/libs/agg/agg_trans_double_path.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_trans_single_path.h 
b/headers/libs/agg/agg_trans_single_path.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_trans_viewport.h 
b/headers/libs/agg/agg_trans_viewport.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_trans_warp_magnifier.h 
b/headers/libs/agg/agg_trans_warp_magnifier.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_vcgen_contour.h 
b/headers/libs/agg/agg_vcgen_contour.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_vcgen_dash.h 
b/headers/libs/agg/agg_vcgen_dash.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_vcgen_markers_term.h 
b/headers/libs/agg/agg_vcgen_markers_term.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_vcgen_smooth_poly1.h 
b/headers/libs/agg/agg_vcgen_smooth_poly1.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_vcgen_stroke.h 
b/headers/libs/agg/agg_vcgen_stroke.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_vcgen_vertex_sequence.h 
b/headers/libs/agg/agg_vcgen_vertex_sequence.h
old mode 100755
new mode 100644
diff --git a/headers/libs/agg/agg_vpgen_segmentator.h 
b/headers/libs/agg/agg_vpgen_segmentator.h
old mode 100755
new mode 100644

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

Revision:    hrev46818
Commit:      63a30a4744428d78a1bdce296e7ebf180fadbd8f
URL:         http://cgit.haiku-os.org/haiku/commit/?id=63a30a4
Author:      Stephan Aßmus <superstippi@xxxxxx>
Date:        Tue Feb  4 22:52:32 2014 UTC

Implemented using the transformation in Painter (incomplete)

 * Also removed wonky BeOS rendering of stroked round rects and ellipses.
   Nobody would expect it to work like this. This affects stroked round rects
   and ellipsis with a pensize greater than 1.
 * Refactored common code from _StrokePath() and _FillPath().
 * _StrokePath() returned a curious bounding box that didn't take into
   acount the miter width. Now the bounding box is computed from the actual
   stroke conversion of the path.

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

diff --git a/src/servers/app/drawing/Painter/Painter.cpp 
b/src/servers/app/drawing/Painter/Painter.cpp
index 8f2765f..7b45d9e 100644
--- a/src/servers/app/drawing/Painter/Painter.cpp
+++ b/src/servers/app/drawing/Painter/Painter.cpp
@@ -272,9 +272,9 @@ Painter::Bounds() const
 
 // SetDrawState
 void
-Painter::SetDrawState(const DrawState* data, int32 xOffset, int32 yOffset)
+Painter::SetDrawState(const DrawState* state, int32 xOffset, int32 yOffset)
 {
-       // NOTE: The custom clipping in "data" is ignored, because it has 
already
+       // NOTE: The custom clipping in "state" is ignored, because it has 
already
        // been taken into account elsewhere
 
        // NOTE: Usually this function is only used when the "current view"
@@ -282,40 +282,41 @@ Painter::SetDrawState(const DrawState* data, int32 
xOffset, int32 yOffset)
        // and messed up the state. For other graphics state changes, the
        // Painter methods are used directly, so this function is much less
        // speed critical than it used to be.
+       SetTransform(state->CombinedTransform(), xOffset, yOffset);
 
-       SetPenSize(data->PenSize());
+       SetPenSize(state->PenSize());
 
-       SetFont(data);
+       SetFont(state);
 
-       fSubpixelPrecise = data->SubPixelPrecise();
+       fSubpixelPrecise = state->SubPixelPrecise();
 
-       if (data->GetAlphaMask() != NULL)
-               fMaskedUnpackedScanline = data->GetAlphaMask()->Generate();
+       if (state->GetAlphaMask() != NULL)
+               fMaskedUnpackedScanline = state->GetAlphaMask()->Generate();
        else
                fMaskedUnpackedScanline = NULL;
 
        // any of these conditions means we need to use a different drawing
        // mode instance
        bool updateDrawingMode
-               = !(data->GetPattern() == fPatternHandler.GetPattern())
-                       || data->GetDrawingMode() != fDrawingMode
-                       || (data->GetDrawingMode() == B_OP_ALPHA
-                               && (data->AlphaSrcMode() != fAlphaSrcMode
-                                       || data->AlphaFncMode() != 
fAlphaFncMode));
-
-       fDrawingMode = data->GetDrawingMode();
-       fAlphaSrcMode = data->AlphaSrcMode();
-       fAlphaFncMode = data->AlphaFncMode();
-       fPatternHandler.SetPattern(data->GetPattern());
+               = !(state->GetPattern() == fPatternHandler.GetPattern())
+                       || state->GetDrawingMode() != fDrawingMode
+                       || (state->GetDrawingMode() == B_OP_ALPHA
+                               && (state->AlphaSrcMode() != fAlphaSrcMode
+                                       || state->AlphaFncMode() != 
fAlphaFncMode));
+
+       fDrawingMode = state->GetDrawingMode();
+       fAlphaSrcMode = state->AlphaSrcMode();
+       fAlphaFncMode = state->AlphaFncMode();
+       fPatternHandler.SetPattern(state->GetPattern());
        fPatternHandler.SetOffsets(xOffset, yOffset);
-       fLineCapMode = data->LineCapMode();
-       fLineJoinMode = data->LineJoinMode();
-       fMiterLimit = data->MiterLimit();
+       fLineCapMode = state->LineCapMode();
+       fLineJoinMode = state->LineJoinMode();
+       fMiterLimit = state->MiterLimit();
 
        // adopt the color *after* the pattern is set
        // to set the renderers to the correct color
-       SetHighColor(data->HighColor());
-       SetLowColor(data->LowColor());
+       SetHighColor(state->HighColor());
+       SetLowColor(state->LowColor());
 
        if (updateDrawingMode || fPixelFormat.UsesOpCopyForText())
                _UpdateDrawingMode();
@@ -341,6 +342,20 @@ Painter::ConstrainClipping(const BRegion* region)
 }
 
 
+void
+Painter::SetTransform(BAffineTransform transform, int32 xOffset, int32 yOffset)
+{
+       fIdentityTransform = transform.IsIdentity();
+       if (!fIdentityTransform) {
+               fTransform = agg::trans_affine(transform.sx, transform.shy,
+                       transform.shx, transform.sy, transform.tx/* + xOffset*/,
+                       transform.ty/* + yOffset*/);
+       } else {
+               fTransform.reset();
+       }
+}
+
+
 // SetHighColor
 void
 Painter::SetHighColor(const rgb_color& color)
@@ -460,7 +475,7 @@ Painter::StrokeLine(BPoint a, BPoint b)
        _Transform(&b, false);
 
        // first, try an optimized version
-       if (fPenSize == 1.0
+       if (fPenSize == 1.0 && fIdentityTransform
                && (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)
                && fMaskedUnpackedScanline == NULL) {
                pattern pat = *fPatternHandler.GetR5Pattern();
@@ -477,7 +492,7 @@ Painter::StrokeLine(BPoint a, BPoint b)
 
        if (a == b) {
                // special case dots
-               if (fPenSize == 1.0 && !fSubpixelPrecise) {
+               if (fPenSize == 1.0 && !fSubpixelPrecise && fIdentityTransform) 
{
                        if (fClippingRegion->Contains(a)) {
                                fPixelFormat.blend_pixel((int)a.x, (int)a.y, 
fRenderer.color(),
                                        255);
@@ -495,7 +510,7 @@ Painter::StrokeLine(BPoint a, BPoint b)
                // tweak ends to "include" the pixel at the index,
                // we need to do this in order to produce results like R5,
                // where coordinates were inclusive
-               if (!fSubpixelPrecise) {
+               if (!fSubpixelPrecise && fIdentityTransform) {
                        bool centerOnLine = fmodf(fPenSize, 2.0) != 0.0;
                        if (a.x == b.x) {
                                // shift to pixel center vertically
@@ -870,7 +885,7 @@ Painter::StrokeRect(const BRect& r) const
        _Transform(&b, false);
 
        // first, try an optimized version
-       if (fPenSize == 1.0
+       if (fPenSize == 1.0 && fIdentityTransform
                        && (fDrawingMode == B_OP_COPY || fDrawingMode == 
B_OP_OVER)
                        && fMaskedUnpackedScanline == NULL) {
                pattern p = *fPatternHandler.GetR5Pattern();
@@ -885,7 +900,7 @@ Painter::StrokeRect(const BRect& r) const
                }
        }
 
-       if (fmodf(fPenSize, 2.0) != 0.0) {
+       if (fIdentityTransform && fmodf(fPenSize, 2.0) != 0.0) {
                // shift coords to center of pixels
                a.x += 0.5;
                a.y += 0.5;
@@ -934,7 +949,7 @@ Painter::FillRect(const BRect& r) const
 
        // first, try an optimized version
        if ((fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)
-                       && fMaskedUnpackedScanline == NULL) {
+               && fMaskedUnpackedScanline == NULL && fIdentityTransform) {
                pattern p = *fPatternHandler.GetR5Pattern();
                if (p == B_SOLID_HIGH) {
                        BRect rect(a, b);
@@ -946,7 +961,8 @@ Painter::FillRect(const BRect& r) const
                        return _Clipped(rect);
                }
        }
-       if (fDrawingMode == B_OP_ALPHA && fAlphaFncMode == B_ALPHA_OVERLAY) {
+       if (fDrawingMode == B_OP_ALPHA && fAlphaFncMode == B_ALPHA_OVERLAY
+               && fMaskedUnpackedScanline == NULL && fIdentityTransform) {
                pattern p = *fPatternHandler.GetR5Pattern();
                if (p == B_SOLID_HIGH) {
                        BRect rect(a, b);
@@ -994,7 +1010,7 @@ Painter::FillRect(const BRect& r, const BGradient& 
gradient) const
        // first, try an optimized version
        if (gradient.GetType() == BGradient::TYPE_LINEAR
                && (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)
-               && fMaskedUnpackedScanline == NULL) {
+               && fMaskedUnpackedScanline == NULL && fIdentityTransform) {
                const BGradientLinear* linearGradient
                        = dynamic_cast<const BGradientLinear*>(&gradient);
                if (linearGradient->Start().x == linearGradient->End().x
@@ -1067,7 +1083,8 @@ Painter::FillRect(const BRect& r, const rgb_color& c) 
const
 
 // FillRectVerticalGradient
 void
-Painter::FillRectVerticalGradient(BRect r, const BGradientLinear& gradient) 
const
+Painter::FillRectVerticalGradient(BRect r,
+       const BGradientLinear& gradient) const
 {
        if (!fValidClipping)
                return;
@@ -1153,97 +1170,15 @@ Painter::StrokeRoundRect(const BRect& r, float xRadius, 
float yRadius) const
 
        BPoint lt(r.left, r.top);
        BPoint rb(r.right, r.bottom);
-       bool centerOffset = fPenSize == 1.0;
-       // TODO: use this when using _StrokePath()
-       // bool centerOffset = fmodf(fPenSize, 2.0) != 0.0;
+       bool centerOffset = fmodf(fPenSize, 2.0) != 0.0;
        _Transform(&lt, centerOffset);
        _Transform(&rb, centerOffset);
 
-       if (fPenSize == 1.0) {
-               agg::rounded_rect rect;
-               rect.rect(lt.x, lt.y, rb.x, rb.y);
-               rect.radius(xRadius, yRadius);
-
-               return _StrokePath(rect);
-       }
-
-       // NOTE: This implementation might seem a little strange, but it makes
-       // stroked round rects look like on R5. A more correct way would be to
-       // use _StrokePath() as above (independent from fPenSize).
-       // The fact that the bounding box of the round rect is not enlarged
-       // by fPenSize/2 is actually on purpose, though one could argue it is
-       // unexpected.
-
-       // enclose the right and bottom edge
-       rb.x++;
-       rb.y++;
-
-       agg::rounded_rect outer;
-       outer.rect(lt.x, lt.y, rb.x, rb.y);
-       outer.radius(xRadius, yRadius);
-
-       if (gSubpixelAntialiasing) {
-               fSubpixRasterizer.reset();
-               fSubpixRasterizer.add_path(outer);
-
-               // don't add an inner hole if the "size is negative", this 
avoids
-               // some defects that can be observed on R5 and could be regarded
-               // as a bug.
-               if (2 * fPenSize < rb.x - lt.x && 2 * fPenSize < rb.y - lt.y) {
-                       agg::rounded_rect inner;
-                       inner.rect(lt.x + fPenSize, lt.y + fPenSize, rb.x - 
fPenSize,
-                               rb.y - fPenSize);
-                       inner.radius(max_c(0.0, xRadius - fPenSize),
-                               max_c(0.0, yRadius - fPenSize));
-
-                       fSubpixRasterizer.add_path(inner);
-               }
-
-               // make the inner rect work as a hole
-               fSubpixRasterizer.filling_rule(agg::fill_even_odd);
-
-               if (fPenSize > 2) {
-                       agg::render_scanlines(fSubpixRasterizer, 
fSubpixPackedScanline,
-                               fSubpixRenderer);
-               } else {
-                       agg::render_scanlines(fSubpixRasterizer, 
fSubpixUnpackedScanline,
-                               fSubpixRenderer);
-               }
-
-               fSubpixRasterizer.filling_rule(agg::fill_non_zero);
-       } else {
-               fRasterizer.reset();
-               fRasterizer.add_path(outer);
-
-               // don't add an inner hole if the "size is negative", this 
avoids
-               // some defects that can be observed on R5 and could be 
regarded as
-               // a bug.
-               if (2 * fPenSize < rb.x - lt.x && 2 * fPenSize < rb.y - lt.y) {
-                       agg::rounded_rect inner;
-                       inner.rect(lt.x + fPenSize, lt.y + fPenSize, rb.x - 
fPenSize,
-                               rb.y - fPenSize);
-                       inner.radius(max_c(0.0, xRadius - fPenSize),
-                               max_c(0.0, yRadius - fPenSize));
-
-                       fRasterizer.add_path(inner);
-               }
-
-               // make the inner rect work as a hole
-               fRasterizer.filling_rule(agg::fill_even_odd);
-
-               if (fMaskedUnpackedScanline != NULL) {
-                       agg::render_scanlines(fRasterizer, 
*fMaskedUnpackedScanline,
-                               fRenderer);
-               } else if (fPenSize > 2)
-                       agg::render_scanlines(fRasterizer, fPackedScanline, 
fRenderer);
-               else
-                       agg::render_scanlines(fRasterizer, fUnpackedScanline, 
fRenderer);
-
-               // reset to default
-               fRasterizer.filling_rule(agg::fill_non_zero);
-       }
+       agg::rounded_rect rect;
+       rect.rect(lt.x, lt.y, rb.x, rb.y);
+       rect.radius(xRadius, yRadius);
 
-       return _Clipped(_BoundingBox(outer));
+       return _StrokePath(rect);
 }
 
 
@@ -1334,61 +1269,12 @@ Painter::DrawEllipse(BRect r, bool fill) const
        if (divisions > 4096)
                divisions = 4096;
 
-       if (fill) {
-               agg::ellipse path(center.x, center.y, xRadius, yRadius, 
divisions);
+       agg::ellipse path(center.x, center.y, xRadius, yRadius, divisions);
 
+       if (fill)
                return _FillPath(path);
-       }
-
-       // NOTE: This implementation might seem a little strange, but it makes
-       // stroked ellipses look like on R5. A more correct way would be to use
-       // _StrokePath(), but it currently has its own set of problems with
-       // narrow ellipses (for small xRadii or yRadii).
-       float inset = fPenSize / 2.0;
-       agg::ellipse inner(center.x, center.y, max_c(0.0, xRadius - inset),
-               max_c(0.0, yRadius - inset), divisions);
-       agg::ellipse outer(center.x, center.y, xRadius + inset, yRadius + inset,
-               divisions);
-
-       if (gSubpixelAntialiasing) {
-               fSubpixRasterizer.reset();
-               fSubpixRasterizer.add_path(outer);
-               fSubpixRasterizer.add_path(inner);
-
-               // make the inner ellipse work as a hole
-               fSubpixRasterizer.filling_rule(agg::fill_even_odd);
-
-               if (fPenSize > 4) {
-                       agg::render_scanlines(fSubpixRasterizer, 
fSubpixPackedScanline,
-                               fSubpixRenderer);
-               } else {
-                       agg::render_scanlines(fSubpixRasterizer, 
fSubpixUnpackedScanline,
-                               fSubpixRenderer);
-               }
-
-               // reset to default
-               fSubpixRasterizer.filling_rule(agg::fill_non_zero);
-       } else {
-               fRasterizer.reset();
-               fRasterizer.add_path(outer);
-               fRasterizer.add_path(inner);
-
-               // make the inner ellipse work as a hole
-               fRasterizer.filling_rule(agg::fill_even_odd);
-
-               if (fMaskedUnpackedScanline != NULL) {
-                       agg::render_scanlines(fRasterizer, 
*fMaskedUnpackedScanline,
-                               fRenderer);
-               } else if (fPenSize > 4)
-                       agg::render_scanlines(fRasterizer, fPackedScanline, 
fRenderer);
-               else
-                       agg::render_scanlines(fRasterizer, fUnpackedScanline, 
fRenderer);
-
-               // reset to default
-               fRasterizer.filling_rule(agg::fill_non_zero);
-       }
-
-       return _Clipped(_BoundingBox(outer));
+       else
+               return _StrokePath(path);
 }
 
 
@@ -2908,30 +2794,14 @@ Painter::_StrokePath(VertexSource& path) const
        stroke.line_join(agg_line_join_mode_for(fLineJoinMode));
        stroke.miter_limit(fMiterLimit);
 
-       if (fMaskedUnpackedScanline != NULL) {
-               // TODO: we can't do both alpha-masking and subpixel AA.
-               fRasterizer.reset();
-               fRasterizer.add_path(path);
-               agg::render_scanlines(fRasterizer, *fMaskedUnpackedScanline,
-                       fRenderer);
-       } else if (gSubpixelAntialiasing) {
-               fSubpixRasterizer.reset();
-               fSubpixRasterizer.add_path(stroke);
-
-               agg::render_scanlines(fSubpixRasterizer,
-                       fSubpixPackedScanline, fSubpixRenderer);
-       } else {
-               fRasterizer.reset();
-               fRasterizer.add_path(stroke);
+       if (fIdentityTransform)
+               return _RasterizePath(stroke);
 
-               agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer);
-       }
-
-       BRect touched = _BoundingBox(path);
-       float penSize = ceilf(fPenSize / 2.0);
-       touched.InsetBy(-penSize, -penSize);
+       stroke.approximation_scale(fTransform.scale());
 
-       return _Clipped(touched);
+       agg::conv_transform<agg::conv_stroke<VertexSource> > transformedStroke(
+               stroke, fTransform);
+       return _RasterizePath(transformedStroke);
 }
 
 
@@ -2940,6 +2810,19 @@ template<class VertexSource>
 BRect
 Painter::_FillPath(VertexSource& path) const
 {
+       if (fIdentityTransform)
+               return _RasterizePath(path);
+
+       agg::conv_transform<VertexSource> transformedPath(path, fTransform);
+       return _RasterizePath(transformedPath);
+}
+
+
+// _RasterizePath
+template<class VertexSource>
+BRect
+Painter::_RasterizePath(VertexSource& path) const
+{
        if (fMaskedUnpackedScanline != NULL) {
                // TODO: we can't do both alpha-masking and subpixel AA.
                fRasterizer.reset();
diff --git a/src/servers/app/drawing/Painter/Painter.h 
b/src/servers/app/drawing/Painter/Painter.h
index 2cd5d6e..2a24fdc 100644
--- a/src/servers/app/drawing/Painter/Painter.h
+++ b/src/servers/app/drawing/Painter/Painter.h
@@ -21,6 +21,7 @@
 #include <agg_conv_curve.h>
 #include <agg_path_storage.h>
 
+#include <AffineTransform.h>
 #include <Font.h>
 #include <Rect.h>
 
@@ -51,15 +52,19 @@ public:
                        void                            DetachFromBuffer();
                        BRect                           Bounds() const;
 
+                       void                            SetDrawState(const 
DrawState* data,
+                                                                       int32 
xOffset = 0,
+                                                                       int32 
yOffset = 0);
+
                        void                            ConstrainClipping(const 
BRegion* region);
                        const BRegion*          ClippingRegion() const
                                                                        { 
return fClippingRegion; }
 
-                       void                            SetDrawState(const 
DrawState* data,
+                                                               // object 
settings
+                       void                            
SetTransform(BAffineTransform transform,
                                                                        int32 
xOffset = 0,
                                                                        int32 
yOffset = 0);
 
-                                                               // object 
settings
                        void                            SetHighColor(const 
rgb_color& color);
        inline  rgb_color                       HighColor() const
                                                                        { 
return fPatternHandler.HighColor(); }
@@ -295,6 +300,8 @@ private:
                        BRect                           
_StrokePath(VertexSource& path) const;
                        template<class VertexSource>
                        BRect                           _FillPath(VertexSource& 
path) const;
+                       template<class VertexSource>
+                       BRect                           
_RasterizePath(VertexSource& path) const;
                        void                            
_CalcLinearGradientTransform(BPoint startPoint,
                                                                        BPoint 
endPoint, agg::trans_affine& mtx,
                                                                        float 
gradient_d2 = 100.0f) const;
@@ -358,7 +365,9 @@ private:
                        bool                            fValidClipping : 1;
                        bool                            fDrawingText : 1;
                        bool                            fAttached : 1;
+                       bool                            fIdentityTransform : 1;
 
+                       agg::trans_affine       fTransform;
                        float                           fPenSize;
                        const BRegion*          fClippingRegion;
                        drawing_mode            fDrawingMode;
diff --git a/src/servers/app/drawing/Painter/defines.h 
b/src/servers/app/drawing/Painter/defines.h
index d23e67a..e614b7c 100644
--- a/src/servers/app/drawing/Painter/defines.h
+++ b/src/servers/app/drawing/Painter/defines.h
@@ -25,6 +25,7 @@
 #include <agg_span_gradient.h>
 #include <agg_span_interpolator_linear.h>
 #include <agg_rendering_buffer.h>
+#include <agg_trans_affine.h>
 
 #include "agg_clipped_alpha_mask.h"
 #include "agg_rasterizer_scanline_aa_subpix.h"


Other related posts:

  • » [haiku-commits] haiku: hrev46818 - src/servers/app/drawing/Painter - superstippi