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.
This commit is contained in:
@@ -272,9 +272,9 @@ Painter::Bounds() const
|
|||||||
|
|
||||||
// SetDrawState
|
// SetDrawState
|
||||||
void
|
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
|
// been taken into account elsewhere
|
||||||
|
|
||||||
// NOTE: Usually this function is only used when the "current view"
|
// 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
|
// and messed up the state. For other graphics state changes, the
|
||||||
// Painter methods are used directly, so this function is much less
|
// Painter methods are used directly, so this function is much less
|
||||||
// speed critical than it used to be.
|
// 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)
|
if (state->GetAlphaMask() != NULL)
|
||||||
fMaskedUnpackedScanline = data->GetAlphaMask()->Generate();
|
fMaskedUnpackedScanline = state->GetAlphaMask()->Generate();
|
||||||
else
|
else
|
||||||
fMaskedUnpackedScanline = NULL;
|
fMaskedUnpackedScanline = NULL;
|
||||||
|
|
||||||
// any of these conditions means we need to use a different drawing
|
// any of these conditions means we need to use a different drawing
|
||||||
// mode instance
|
// mode instance
|
||||||
bool updateDrawingMode
|
bool updateDrawingMode
|
||||||
= !(data->GetPattern() == fPatternHandler.GetPattern())
|
= !(state->GetPattern() == fPatternHandler.GetPattern())
|
||||||
|| data->GetDrawingMode() != fDrawingMode
|
|| state->GetDrawingMode() != fDrawingMode
|
||||||
|| (data->GetDrawingMode() == B_OP_ALPHA
|
|| (state->GetDrawingMode() == B_OP_ALPHA
|
||||||
&& (data->AlphaSrcMode() != fAlphaSrcMode
|
&& (state->AlphaSrcMode() != fAlphaSrcMode
|
||||||
|| data->AlphaFncMode() != fAlphaFncMode));
|
|| state->AlphaFncMode() != fAlphaFncMode));
|
||||||
|
|
||||||
fDrawingMode = data->GetDrawingMode();
|
fDrawingMode = state->GetDrawingMode();
|
||||||
fAlphaSrcMode = data->AlphaSrcMode();
|
fAlphaSrcMode = state->AlphaSrcMode();
|
||||||
fAlphaFncMode = data->AlphaFncMode();
|
fAlphaFncMode = state->AlphaFncMode();
|
||||||
fPatternHandler.SetPattern(data->GetPattern());
|
fPatternHandler.SetPattern(state->GetPattern());
|
||||||
fPatternHandler.SetOffsets(xOffset, yOffset);
|
fPatternHandler.SetOffsets(xOffset, yOffset);
|
||||||
fLineCapMode = data->LineCapMode();
|
fLineCapMode = state->LineCapMode();
|
||||||
fLineJoinMode = data->LineJoinMode();
|
fLineJoinMode = state->LineJoinMode();
|
||||||
fMiterLimit = data->MiterLimit();
|
fMiterLimit = state->MiterLimit();
|
||||||
|
|
||||||
// adopt the color *after* the pattern is set
|
// adopt the color *after* the pattern is set
|
||||||
// to set the renderers to the correct color
|
// to set the renderers to the correct color
|
||||||
SetHighColor(data->HighColor());
|
SetHighColor(state->HighColor());
|
||||||
SetLowColor(data->LowColor());
|
SetLowColor(state->LowColor());
|
||||||
|
|
||||||
if (updateDrawingMode || fPixelFormat.UsesOpCopyForText())
|
if (updateDrawingMode || fPixelFormat.UsesOpCopyForText())
|
||||||
_UpdateDrawingMode();
|
_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
|
// SetHighColor
|
||||||
void
|
void
|
||||||
Painter::SetHighColor(const rgb_color& color)
|
Painter::SetHighColor(const rgb_color& color)
|
||||||
@@ -460,7 +475,7 @@ Painter::StrokeLine(BPoint a, BPoint b)
|
|||||||
_Transform(&b, false);
|
_Transform(&b, false);
|
||||||
|
|
||||||
// first, try an optimized version
|
// first, try an optimized version
|
||||||
if (fPenSize == 1.0
|
if (fPenSize == 1.0 && fIdentityTransform
|
||||||
&& (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)
|
&& (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)
|
||||||
&& fMaskedUnpackedScanline == NULL) {
|
&& fMaskedUnpackedScanline == NULL) {
|
||||||
pattern pat = *fPatternHandler.GetR5Pattern();
|
pattern pat = *fPatternHandler.GetR5Pattern();
|
||||||
@@ -477,7 +492,7 @@ Painter::StrokeLine(BPoint a, BPoint b)
|
|||||||
|
|
||||||
if (a == b) {
|
if (a == b) {
|
||||||
// special case dots
|
// special case dots
|
||||||
if (fPenSize == 1.0 && !fSubpixelPrecise) {
|
if (fPenSize == 1.0 && !fSubpixelPrecise && fIdentityTransform) {
|
||||||
if (fClippingRegion->Contains(a)) {
|
if (fClippingRegion->Contains(a)) {
|
||||||
fPixelFormat.blend_pixel((int)a.x, (int)a.y, fRenderer.color(),
|
fPixelFormat.blend_pixel((int)a.x, (int)a.y, fRenderer.color(),
|
||||||
255);
|
255);
|
||||||
@@ -495,7 +510,7 @@ Painter::StrokeLine(BPoint a, BPoint b)
|
|||||||
// tweak ends to "include" the pixel at the index,
|
// tweak ends to "include" the pixel at the index,
|
||||||
// we need to do this in order to produce results like R5,
|
// we need to do this in order to produce results like R5,
|
||||||
// where coordinates were inclusive
|
// where coordinates were inclusive
|
||||||
if (!fSubpixelPrecise) {
|
if (!fSubpixelPrecise && fIdentityTransform) {
|
||||||
bool centerOnLine = fmodf(fPenSize, 2.0) != 0.0;
|
bool centerOnLine = fmodf(fPenSize, 2.0) != 0.0;
|
||||||
if (a.x == b.x) {
|
if (a.x == b.x) {
|
||||||
// shift to pixel center vertically
|
// shift to pixel center vertically
|
||||||
@@ -870,7 +885,7 @@ Painter::StrokeRect(const BRect& r) const
|
|||||||
_Transform(&b, false);
|
_Transform(&b, false);
|
||||||
|
|
||||||
// first, try an optimized version
|
// first, try an optimized version
|
||||||
if (fPenSize == 1.0
|
if (fPenSize == 1.0 && fIdentityTransform
|
||||||
&& (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)
|
&& (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)
|
||||||
&& fMaskedUnpackedScanline == NULL) {
|
&& fMaskedUnpackedScanline == NULL) {
|
||||||
pattern p = *fPatternHandler.GetR5Pattern();
|
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
|
// shift coords to center of pixels
|
||||||
a.x += 0.5;
|
a.x += 0.5;
|
||||||
a.y += 0.5;
|
a.y += 0.5;
|
||||||
@@ -934,7 +949,7 @@ Painter::FillRect(const BRect& r) const
|
|||||||
|
|
||||||
// first, try an optimized version
|
// first, try an optimized version
|
||||||
if ((fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)
|
if ((fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)
|
||||||
&& fMaskedUnpackedScanline == NULL) {
|
&& fMaskedUnpackedScanline == NULL && fIdentityTransform) {
|
||||||
pattern p = *fPatternHandler.GetR5Pattern();
|
pattern p = *fPatternHandler.GetR5Pattern();
|
||||||
if (p == B_SOLID_HIGH) {
|
if (p == B_SOLID_HIGH) {
|
||||||
BRect rect(a, b);
|
BRect rect(a, b);
|
||||||
@@ -946,7 +961,8 @@ Painter::FillRect(const BRect& r) const
|
|||||||
return _Clipped(rect);
|
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();
|
pattern p = *fPatternHandler.GetR5Pattern();
|
||||||
if (p == B_SOLID_HIGH) {
|
if (p == B_SOLID_HIGH) {
|
||||||
BRect rect(a, b);
|
BRect rect(a, b);
|
||||||
@@ -994,7 +1010,7 @@ Painter::FillRect(const BRect& r, const BGradient& gradient) const
|
|||||||
// first, try an optimized version
|
// first, try an optimized version
|
||||||
if (gradient.GetType() == BGradient::TYPE_LINEAR
|
if (gradient.GetType() == BGradient::TYPE_LINEAR
|
||||||
&& (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)
|
&& (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)
|
||||||
&& fMaskedUnpackedScanline == NULL) {
|
&& fMaskedUnpackedScanline == NULL && fIdentityTransform) {
|
||||||
const BGradientLinear* linearGradient
|
const BGradientLinear* linearGradient
|
||||||
= dynamic_cast<const BGradientLinear*>(&gradient);
|
= dynamic_cast<const BGradientLinear*>(&gradient);
|
||||||
if (linearGradient->Start().x == linearGradient->End().x
|
if (linearGradient->Start().x == linearGradient->End().x
|
||||||
@@ -1067,7 +1083,8 @@ Painter::FillRect(const BRect& r, const rgb_color& c) const
|
|||||||
|
|
||||||
// FillRectVerticalGradient
|
// FillRectVerticalGradient
|
||||||
void
|
void
|
||||||
Painter::FillRectVerticalGradient(BRect r, const BGradientLinear& gradient) const
|
Painter::FillRectVerticalGradient(BRect r,
|
||||||
|
const BGradientLinear& gradient) const
|
||||||
{
|
{
|
||||||
if (!fValidClipping)
|
if (!fValidClipping)
|
||||||
return;
|
return;
|
||||||
@@ -1153,97 +1170,15 @@ Painter::StrokeRoundRect(const BRect& r, float xRadius, float yRadius) const
|
|||||||
|
|
||||||
BPoint lt(r.left, r.top);
|
BPoint lt(r.left, r.top);
|
||||||
BPoint rb(r.right, r.bottom);
|
BPoint rb(r.right, r.bottom);
|
||||||
bool centerOffset = fPenSize == 1.0;
|
bool centerOffset = fmodf(fPenSize, 2.0) != 0.0;
|
||||||
// TODO: use this when using _StrokePath()
|
|
||||||
// bool centerOffset = fmodf(fPenSize, 2.0) != 0.0;
|
|
||||||
_Transform(<, centerOffset);
|
_Transform(<, centerOffset);
|
||||||
_Transform(&rb, centerOffset);
|
_Transform(&rb, centerOffset);
|
||||||
|
|
||||||
if (fPenSize == 1.0) {
|
agg::rounded_rect rect;
|
||||||
agg::rounded_rect rect;
|
rect.rect(lt.x, lt.y, rb.x, rb.y);
|
||||||
rect.rect(lt.x, lt.y, rb.x, rb.y);
|
rect.radius(xRadius, yRadius);
|
||||||
rect.radius(xRadius, yRadius);
|
|
||||||
|
|
||||||
return _StrokePath(rect);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _Clipped(_BoundingBox(outer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1334,61 +1269,12 @@ Painter::DrawEllipse(BRect r, bool fill) const
|
|||||||
if (divisions > 4096)
|
if (divisions > 4096)
|
||||||
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);
|
return _FillPath(path);
|
||||||
}
|
else
|
||||||
|
return _StrokePath(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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2908,30 +2794,14 @@ Painter::_StrokePath(VertexSource& path) const
|
|||||||
stroke.line_join(agg_line_join_mode_for(fLineJoinMode));
|
stroke.line_join(agg_line_join_mode_for(fLineJoinMode));
|
||||||
stroke.miter_limit(fMiterLimit);
|
stroke.miter_limit(fMiterLimit);
|
||||||
|
|
||||||
if (fMaskedUnpackedScanline != NULL) {
|
if (fIdentityTransform)
|
||||||
// TODO: we can't do both alpha-masking and subpixel AA.
|
return _RasterizePath(stroke);
|
||||||
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,
|
stroke.approximation_scale(fTransform.scale());
|
||||||
fSubpixPackedScanline, fSubpixRenderer);
|
|
||||||
} else {
|
|
||||||
fRasterizer.reset();
|
|
||||||
fRasterizer.add_path(stroke);
|
|
||||||
|
|
||||||
agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer);
|
agg::conv_transform<agg::conv_stroke<VertexSource> > transformedStroke(
|
||||||
}
|
stroke, fTransform);
|
||||||
|
return _RasterizePath(transformedStroke);
|
||||||
BRect touched = _BoundingBox(path);
|
|
||||||
float penSize = ceilf(fPenSize / 2.0);
|
|
||||||
touched.InsetBy(-penSize, -penSize);
|
|
||||||
|
|
||||||
return _Clipped(touched);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2939,6 +2809,19 @@ Painter::_StrokePath(VertexSource& path) const
|
|||||||
template<class VertexSource>
|
template<class VertexSource>
|
||||||
BRect
|
BRect
|
||||||
Painter::_FillPath(VertexSource& path) const
|
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) {
|
if (fMaskedUnpackedScanline != NULL) {
|
||||||
// TODO: we can't do both alpha-masking and subpixel AA.
|
// TODO: we can't do both alpha-masking and subpixel AA.
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <agg_conv_curve.h>
|
#include <agg_conv_curve.h>
|
||||||
#include <agg_path_storage.h>
|
#include <agg_path_storage.h>
|
||||||
|
|
||||||
|
#include <AffineTransform.h>
|
||||||
#include <Font.h>
|
#include <Font.h>
|
||||||
#include <Rect.h>
|
#include <Rect.h>
|
||||||
|
|
||||||
@@ -51,15 +52,19 @@ public:
|
|||||||
void DetachFromBuffer();
|
void DetachFromBuffer();
|
||||||
BRect Bounds() const;
|
BRect Bounds() const;
|
||||||
|
|
||||||
void ConstrainClipping(const BRegion* region);
|
|
||||||
const BRegion* ClippingRegion() const
|
|
||||||
{ return fClippingRegion; }
|
|
||||||
|
|
||||||
void SetDrawState(const DrawState* data,
|
void SetDrawState(const DrawState* data,
|
||||||
int32 xOffset = 0,
|
int32 xOffset = 0,
|
||||||
int32 yOffset = 0);
|
int32 yOffset = 0);
|
||||||
|
|
||||||
|
void ConstrainClipping(const BRegion* region);
|
||||||
|
const BRegion* ClippingRegion() const
|
||||||
|
{ return fClippingRegion; }
|
||||||
|
|
||||||
// object settings
|
// object settings
|
||||||
|
void SetTransform(BAffineTransform transform,
|
||||||
|
int32 xOffset = 0,
|
||||||
|
int32 yOffset = 0);
|
||||||
|
|
||||||
void SetHighColor(const rgb_color& color);
|
void SetHighColor(const rgb_color& color);
|
||||||
inline rgb_color HighColor() const
|
inline rgb_color HighColor() const
|
||||||
{ return fPatternHandler.HighColor(); }
|
{ return fPatternHandler.HighColor(); }
|
||||||
@@ -295,6 +300,8 @@ private:
|
|||||||
BRect _StrokePath(VertexSource& path) const;
|
BRect _StrokePath(VertexSource& path) const;
|
||||||
template<class VertexSource>
|
template<class VertexSource>
|
||||||
BRect _FillPath(VertexSource& path) const;
|
BRect _FillPath(VertexSource& path) const;
|
||||||
|
template<class VertexSource>
|
||||||
|
BRect _RasterizePath(VertexSource& path) const;
|
||||||
void _CalcLinearGradientTransform(BPoint startPoint,
|
void _CalcLinearGradientTransform(BPoint startPoint,
|
||||||
BPoint endPoint, agg::trans_affine& mtx,
|
BPoint endPoint, agg::trans_affine& mtx,
|
||||||
float gradient_d2 = 100.0f) const;
|
float gradient_d2 = 100.0f) const;
|
||||||
@@ -358,7 +365,9 @@ private:
|
|||||||
bool fValidClipping : 1;
|
bool fValidClipping : 1;
|
||||||
bool fDrawingText : 1;
|
bool fDrawingText : 1;
|
||||||
bool fAttached : 1;
|
bool fAttached : 1;
|
||||||
|
bool fIdentityTransform : 1;
|
||||||
|
|
||||||
|
agg::trans_affine fTransform;
|
||||||
float fPenSize;
|
float fPenSize;
|
||||||
const BRegion* fClippingRegion;
|
const BRegion* fClippingRegion;
|
||||||
drawing_mode fDrawingMode;
|
drawing_mode fDrawingMode;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <agg_span_gradient.h>
|
#include <agg_span_gradient.h>
|
||||||
#include <agg_span_interpolator_linear.h>
|
#include <agg_span_interpolator_linear.h>
|
||||||
#include <agg_rendering_buffer.h>
|
#include <agg_rendering_buffer.h>
|
||||||
|
#include <agg_trans_affine.h>
|
||||||
|
|
||||||
#include "agg_clipped_alpha_mask.h"
|
#include "agg_clipped_alpha_mask.h"
|
||||||
#include "agg_rasterizer_scanline_aa_subpix.h"
|
#include "agg_rasterizer_scanline_aa_subpix.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user