Index: src/core/SkScan_Antihair.cpp |
diff --git a/src/core/SkScan_Antihair.cpp b/src/core/SkScan_Antihair.cpp |
index c48ad2c3f4246f46b6abfeb9414149fab76af828..3073434f980b53e04a01e71e46a6eb7a69113c0f 100644 |
--- a/src/core/SkScan_Antihair.cpp |
+++ b/src/core/SkScan_Antihair.cpp |
@@ -588,7 +588,8 @@ static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1, |
} |
} |
-void SkScan::AntiHairLineRgn(SkPoint pt0, SkPoint pt1, const SkRegion* clip, SkBlitter* blitter) { |
+void SkScan::AntiHairLineRgn(const SkPoint array[], int arrayCount, const SkRegion* clip, |
+ SkBlitter* blitter) { |
if (clip && clip->isEmpty()) { |
return; |
} |
@@ -599,86 +600,83 @@ void SkScan::AntiHairLineRgn(SkPoint pt0, SkPoint pt1, const SkRegion* clip, SkB |
build_gamma_table(); |
#endif |
- SkPoint pts[2] = { pt0, pt1 }; |
- |
- // We have to pre-clip the line to fit in a SkFixed, so we just chop |
- // the line. TODO find a way to actually draw beyond that range. |
- { |
- SkRect fixedBounds; |
- const SkScalar max = SkIntToScalar(32767); |
- fixedBounds.set(-max, -max, max, max); |
- if (!SkLineClipper::IntersectLine(pts, fixedBounds, pts)) { |
- return; |
- } |
- } |
+ const SkScalar max = SkIntToScalar(32767); |
+ const SkRect fixedBounds = SkRect::MakeLTRB(-max, -max, max, max); |
+ SkRect clipBounds; |
if (clip) { |
- SkRect clipBounds; |
clipBounds.set(clip->getBounds()); |
/* We perform integral clipping later on, but we do a scalar clip first |
- to ensure that our coordinates are expressible in fixed/integers. |
- |
- antialiased hairlines can draw up to 1/2 of a pixel outside of |
- their bounds, so we need to outset the clip before calling the |
- clipper. To make the numerics safer, we outset by a whole pixel, |
- since the 1/2 pixel boundary is important to the antihair blitter, |
- we don't want to risk numerical fate by chopping on that edge. |
+ to ensure that our coordinates are expressible in fixed/integers. |
+ |
+ antialiased hairlines can draw up to 1/2 of a pixel outside of |
+ their bounds, so we need to outset the clip before calling the |
+ clipper. To make the numerics safer, we outset by a whole pixel, |
+ since the 1/2 pixel boundary is important to the antihair blitter, |
+ we don't want to risk numerical fate by chopping on that edge. |
*/ |
clipBounds.outset(SK_Scalar1, SK_Scalar1); |
- |
- if (!SkLineClipper::IntersectLine(pts, clipBounds, pts)) { |
- return; |
- } |
} |
- SkFDot6 x0 = SkScalarToFDot6(pts[0].fX); |
- SkFDot6 y0 = SkScalarToFDot6(pts[0].fY); |
- SkFDot6 x1 = SkScalarToFDot6(pts[1].fX); |
- SkFDot6 y1 = SkScalarToFDot6(pts[1].fY); |
+ for (int i = 0; i < arrayCount - 1; ++i) { |
+ SkPoint pts[2]; |
- if (clip) { |
- SkFDot6 left = SkMin32(x0, x1); |
- SkFDot6 top = SkMin32(y0, y1); |
- SkFDot6 right = SkMax32(x0, x1); |
- SkFDot6 bottom = SkMax32(y0, y1); |
- SkIRect ir; |
- |
- ir.set( SkFDot6Floor(left) - 1, |
- SkFDot6Floor(top) - 1, |
- SkFDot6Ceil(right) + 1, |
- SkFDot6Ceil(bottom) + 1); |
- |
- if (clip->quickReject(ir)) { |
- return; |
+ // We have to pre-clip the line to fit in a SkFixed, so we just chop |
+ // the line. TODO find a way to actually draw beyond that range. |
+ if (!SkLineClipper::IntersectLine(&array[i], fixedBounds, pts)) { |
+ continue; |
+ } |
+ |
+ if (clip && !SkLineClipper::IntersectLine(pts, clipBounds, pts)) { |
+ continue; |
} |
- if (!clip->quickContains(ir)) { |
- SkRegion::Cliperator iter(*clip, ir); |
- const SkIRect* r = &iter.rect(); |
- while (!iter.done()) { |
- do_anti_hairline(x0, y0, x1, y1, r, blitter); |
- iter.next(); |
+ SkFDot6 x0 = SkScalarToFDot6(pts[0].fX); |
+ SkFDot6 y0 = SkScalarToFDot6(pts[0].fY); |
+ SkFDot6 x1 = SkScalarToFDot6(pts[1].fX); |
+ SkFDot6 y1 = SkScalarToFDot6(pts[1].fY); |
+ |
+ if (clip) { |
+ SkFDot6 left = SkMin32(x0, x1); |
+ SkFDot6 top = SkMin32(y0, y1); |
+ SkFDot6 right = SkMax32(x0, x1); |
+ SkFDot6 bottom = SkMax32(y0, y1); |
+ SkIRect ir; |
+ |
+ ir.set( SkFDot6Floor(left) - 1, |
+ SkFDot6Floor(top) - 1, |
+ SkFDot6Ceil(right) + 1, |
+ SkFDot6Ceil(bottom) + 1); |
+ |
+ if (clip->quickReject(ir)) { |
+ continue; |
} |
- return; |
+ if (!clip->quickContains(ir)) { |
+ SkRegion::Cliperator iter(*clip, ir); |
+ const SkIRect* r = &iter.rect(); |
+ |
+ while (!iter.done()) { |
+ do_anti_hairline(x0, y0, x1, y1, r, blitter); |
+ iter.next(); |
+ } |
+ continue; |
+ } |
+ // fall through to no-clip case |
} |
- // fall through to no-clip case |
+ do_anti_hairline(x0, y0, x1, y1, NULL, blitter); |
} |
- do_anti_hairline(x0, y0, x1, y1, NULL, blitter); |
} |
void SkScan::AntiHairRect(const SkRect& rect, const SkRasterClip& clip, |
SkBlitter* blitter) { |
- SkPoint p0, p1; |
- |
- p0.set(rect.fLeft, rect.fTop); |
- p1.set(rect.fRight, rect.fTop); |
- SkScan::AntiHairLine(p0, p1, clip, blitter); |
- p0.set(rect.fRight, rect.fBottom); |
- SkScan::AntiHairLine(p0, p1, clip, blitter); |
- p1.set(rect.fLeft, rect.fBottom); |
- SkScan::AntiHairLine(p0, p1, clip, blitter); |
- p0.set(rect.fLeft, rect.fTop); |
- SkScan::AntiHairLine(p0, p1, clip, blitter); |
+ SkPoint pts[5]; |
+ |
+ pts[0].set(rect.fLeft, rect.fTop); |
+ pts[1].set(rect.fRight, rect.fTop); |
+ pts[2].set(rect.fRight, rect.fBottom); |
+ pts[3].set(rect.fLeft, rect.fBottom); |
+ pts[4] = pts[0]; |
+ SkScan::AntiHairLine(pts, 5, clip, blitter); |
} |
/////////////////////////////////////////////////////////////////////////////// |