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(<, 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"