aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkScan_Hairline.cpp
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2015-04-14 10:40:44 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-04-14 10:40:44 -0700
commit5dc6b7d1a8bc591d62366ff83c434ff74f3e10fc (patch)
tree25b4f701bfc2b56e28a2ed03cd5a0eecc2aefba9 /src/core/SkScan_Hairline.cpp
parentb5de630d10982c0e650b842fe15cee2eb9efabbd (diff)
change hairline procs to take array of points
Diffstat (limited to 'src/core/SkScan_Hairline.cpp')
-rw-r--r--src/core/SkScan_Hairline.cpp199
1 files changed, 102 insertions, 97 deletions
diff --git a/src/core/SkScan_Hairline.cpp b/src/core/SkScan_Hairline.cpp
index 8cce57b8c9..0f2308b1f7 100644
--- a/src/core/SkScan_Hairline.cpp
+++ b/src/core/SkScan_Hairline.cpp
@@ -40,102 +40,105 @@ static bool canConvertFDot6ToFixed(SkFDot6 x) {
}
#endif
-void SkScan::HairLineRgn(SkPoint pt0, SkPoint pt1, const SkRegion* clip, SkBlitter* blitter) {
+void SkScan::HairLineRgn(const SkPoint array[], int arrayCount, const SkRegion* clip,
+ SkBlitter* origBlitter) {
SkBlitterClipper clipper;
- SkRect r;
SkIRect clipR, ptsR;
- 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) {
- // Perform a clip in scalar space, so we catch huge values which might
- // be missed after we convert to SkFDot6 (overflow)
- r.set(clip->getBounds());
- if (!SkLineClipper::IntersectLine(pts, r, pts)) {
- return;
- }
+ clipBounds.set(clip->getBounds());
}
- 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) {
+ SkBlitter* blitter = origBlitter;
- SkASSERT(canConvertFDot6ToFixed(x0));
- SkASSERT(canConvertFDot6ToFixed(y0));
- SkASSERT(canConvertFDot6ToFixed(x1));
- SkASSERT(canConvertFDot6ToFixed(y1));
+ SkPoint pts[2];
- if (clip) {
- // now perform clipping again, as the rounding to dot6 can wiggle us
- // our rects are really dot6 rects, but since we've already used
- // lineclipper, we know they will fit in 32bits (26.6)
- const SkIRect& bounds = clip->getBounds();
-
- clipR.set(SkIntToFDot6(bounds.fLeft), SkIntToFDot6(bounds.fTop),
- SkIntToFDot6(bounds.fRight), SkIntToFDot6(bounds.fBottom));
- ptsR.set(x0, y0, x1, y1);
- ptsR.sort();
-
- // outset the right and bottom, to account for how hairlines are
- // actually drawn, which may hit the pixel to the right or below of
- // the coordinate
- ptsR.fRight += SK_FDot6One;
- ptsR.fBottom += SK_FDot6One;
-
- if (!SkIRect::Intersects(ptsR, clipR)) {
- return;
- }
- if (clip->isRect() && clipR.contains(ptsR)) {
- clip = NULL;
- } else {
- blitter = clipper.apply(blitter, clip);
+ // 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;
}
- }
- SkFDot6 dx = x1 - x0;
- SkFDot6 dy = y1 - y0;
-
- if (SkAbs32(dx) > SkAbs32(dy)) { // mostly horizontal
- if (x0 > x1) { // we want to go left-to-right
- SkTSwap<SkFDot6>(x0, x1);
- SkTSwap<SkFDot6>(y0, y1);
+ // Perform a clip in scalar space, so we catch huge values which might
+ // be missed after we convert to SkFDot6 (overflow)
+ if (clip && !SkLineClipper::IntersectLine(pts, clipBounds, pts)) {
+ continue;
}
- int ix0 = SkFDot6Round(x0);
- int ix1 = SkFDot6Round(x1);
- if (ix0 == ix1) {// too short to draw
- 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);
+
+ SkASSERT(canConvertFDot6ToFixed(x0));
+ SkASSERT(canConvertFDot6ToFixed(y0));
+ SkASSERT(canConvertFDot6ToFixed(x1));
+ SkASSERT(canConvertFDot6ToFixed(y1));
+
+ if (clip) {
+ // now perform clipping again, as the rounding to dot6 can wiggle us
+ // our rects are really dot6 rects, but since we've already used
+ // lineclipper, we know they will fit in 32bits (26.6)
+ const SkIRect& bounds = clip->getBounds();
+
+ clipR.set(SkIntToFDot6(bounds.fLeft), SkIntToFDot6(bounds.fTop),
+ SkIntToFDot6(bounds.fRight), SkIntToFDot6(bounds.fBottom));
+ ptsR.set(x0, y0, x1, y1);
+ ptsR.sort();
+
+ // outset the right and bottom, to account for how hairlines are
+ // actually drawn, which may hit the pixel to the right or below of
+ // the coordinate
+ ptsR.fRight += SK_FDot6One;
+ ptsR.fBottom += SK_FDot6One;
+
+ if (!SkIRect::Intersects(ptsR, clipR)) {
+ continue;
+ }
+ if (!clip->isRect() || !clipR.contains(ptsR)) {
+ blitter = clipper.apply(origBlitter, clip);
+ }
}
- SkFixed slope = SkFixedDiv(dy, dx);
- SkFixed startY = SkFDot6ToFixed(y0) + (slope * ((32 - x0) & 63) >> 6);
+ SkFDot6 dx = x1 - x0;
+ SkFDot6 dy = y1 - y0;
- horiline(ix0, ix1, startY, slope, blitter);
- } else { // mostly vertical
- if (y0 > y1) { // we want to go top-to-bottom
- SkTSwap<SkFDot6>(x0, x1);
- SkTSwap<SkFDot6>(y0, y1);
- }
- int iy0 = SkFDot6Round(y0);
- int iy1 = SkFDot6Round(y1);
- if (iy0 == iy1) { // too short to draw
- return;
- }
+ if (SkAbs32(dx) > SkAbs32(dy)) { // mostly horizontal
+ if (x0 > x1) { // we want to go left-to-right
+ SkTSwap<SkFDot6>(x0, x1);
+ SkTSwap<SkFDot6>(y0, y1);
+ }
+ int ix0 = SkFDot6Round(x0);
+ int ix1 = SkFDot6Round(x1);
+ if (ix0 == ix1) {// too short to draw
+ continue;
+ }
- SkFixed slope = SkFixedDiv(dx, dy);
- SkFixed startX = SkFDot6ToFixed(x0) + (slope * ((32 - y0) & 63) >> 6);
+ SkFixed slope = SkFixedDiv(dy, dx);
+ SkFixed startY = SkFDot6ToFixed(y0) + (slope * ((32 - x0) & 63) >> 6);
- vertline(iy0, iy1, startX, slope, blitter);
+ horiline(ix0, ix1, startY, slope, blitter);
+ } else { // mostly vertical
+ if (y0 > y1) { // we want to go top-to-bottom
+ SkTSwap<SkFDot6>(x0, x1);
+ SkTSwap<SkFDot6>(y0, y1);
+ }
+ int iy0 = SkFDot6Round(y0);
+ int iy1 = SkFDot6Round(y1);
+ if (iy0 == iy1) { // too short to draw
+ continue;
+ }
+
+ SkFixed slope = SkFixedDiv(dx, dy);
+ SkFixed startX = SkFDot6ToFixed(x0) + (slope * ((32 - y0) & 63) >> 6);
+
+ vertline(iy0, iy1, startX, slope, blitter);
+ }
}
}
@@ -209,10 +212,8 @@ static int compute_int_quad_dist(const SkPoint pts[3]) {
}
}
-typedef void (*LineProc)(SkPoint, SkPoint, const SkRegion*, SkBlitter*);
-
static void hairquad(const SkPoint pts[3], const SkRegion* clip,
- SkBlitter* blitter, int level, LineProc lineproc) {
+ SkBlitter* blitter, int level, SkScan::HairRgnProc lineproc) {
if (level > 0) {
SkPoint tmp[5];
@@ -220,12 +221,13 @@ static void hairquad(const SkPoint pts[3], const SkRegion* clip,
hairquad(tmp, clip, blitter, level - 1, lineproc);
hairquad(&tmp[2], clip, blitter, level - 1, lineproc);
} else {
- lineproc(pts[0], pts[2], clip, blitter);
+ SkPoint tmp[] = { pts[0], pts[2] };
+ lineproc(tmp, 2, clip, blitter);
}
}
static void haircubic(const SkPoint pts[4], const SkRegion* clip,
- SkBlitter* blitter, int level, LineProc lineproc) {
+ SkBlitter* blitter, int level, SkScan::HairRgnProc lineproc) {
if (level > 0) {
SkPoint tmp[7];
@@ -233,7 +235,8 @@ static void haircubic(const SkPoint pts[4], const SkRegion* clip,
haircubic(tmp, clip, blitter, level - 1, lineproc);
haircubic(&tmp[3], clip, blitter, level - 1, lineproc);
} else {
- lineproc(pts[0], pts[3], clip, blitter);
+ SkPoint tmp[] = { pts[0], pts[3] };
+ lineproc(tmp, 2, clip, blitter);
}
}
@@ -256,7 +259,7 @@ static int compute_quad_level(const SkPoint pts[3]) {
}
static void hair_path(const SkPath& path, const SkRasterClip& rclip, SkBlitter* blitter,
- LineProc lineproc) {
+ SkScan::HairRgnProc lineproc) {
if (path.isEmpty()) {
return;
}
@@ -291,7 +294,7 @@ static void hair_path(const SkPath& path, const SkRasterClip& rclip, SkBlitter*
case SkPath::kMove_Verb:
break;
case SkPath::kLine_Verb:
- lineproc(pts[0], pts[1], clip, blitter);
+ lineproc(pts, 2, clip, blitter);
break;
case SkPath::kQuad_Verb:
hairquad(pts, clip, blitter, compute_quad_level(pts), lineproc);
@@ -364,14 +367,15 @@ void SkScan::FrameRect(const SkRect& r, const SkPoint& strokeSize,
SkScan::FillRect(tmp, clip, blitter);
}
-void SkScan::HairLine(SkPoint p0, SkPoint p1, const SkRasterClip& clip, SkBlitter* blitter) {
+void SkScan::HairLine(const SkPoint pts[], int count, const SkRasterClip& clip,
+ SkBlitter* blitter) {
if (clip.isBW()) {
- HairLineRgn(p0, p1, &clip.bwRgn(), blitter);
+ HairLineRgn(pts, count, &clip.bwRgn(), blitter);
} else {
const SkRegion* clipRgn = NULL;
+
SkRect r;
- r.set(p0.fX, p0.fY, p1.fX, p1.fY);
- r.sort();
+ r.set(pts, count);
r.outset(SK_ScalarHalf, SK_ScalarHalf);
SkAAClipBlitterWrapper wrap;
@@ -380,18 +384,19 @@ void SkScan::HairLine(SkPoint p0, SkPoint p1, const SkRasterClip& clip, SkBlitte
blitter = wrap.getBlitter();
clipRgn = &wrap.getRgn();
}
- HairLineRgn(p0, p1, clipRgn, blitter);
+ HairLineRgn(pts, count, clipRgn, blitter);
}
}
-void SkScan::AntiHairLine(SkPoint p0, SkPoint p1, const SkRasterClip& clip, SkBlitter* blitter) {
+void SkScan::AntiHairLine(const SkPoint pts[], int count, const SkRasterClip& clip,
+ SkBlitter* blitter) {
if (clip.isBW()) {
- AntiHairLineRgn(p0, p1, &clip.bwRgn(), blitter);
+ AntiHairLineRgn(pts, count, &clip.bwRgn(), blitter);
} else {
const SkRegion* clipRgn = NULL;
+
SkRect r;
- r.set(p0.fX, p0.fY, p1.fX, p1.fY);
- r.sort();
+ r.set(pts, count);
SkAAClipBlitterWrapper wrap;
if (!clip.quickContains(r.roundOut().makeOutset(1, 1))) {
@@ -399,6 +404,6 @@ void SkScan::AntiHairLine(SkPoint p0, SkPoint p1, const SkRasterClip& clip, SkBl
blitter = wrap.getBlitter();
clipRgn = &wrap.getRgn();
}
- AntiHairLineRgn(p0, p1, clipRgn, blitter);
+ AntiHairLineRgn(pts, count, clipRgn, blitter);
}
}