chop hairlines against 32K bounds, since that is our limit (currently)
for a fixedpoint implementation.
git-svn-id: http://skia.googlecode.com/svn/trunk@3713 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkScan_Antihair.cpp b/src/core/SkScan_Antihair.cpp
index 6c920ad..ec23a2b 100644
--- a/src/core/SkScan_Antihair.cpp
+++ b/src/core/SkScan_Antihair.cpp
@@ -230,6 +230,11 @@
}
#endif
+static bool canConvertFDot6ToFixed(SkFDot6 x) {
+ const int maxDot6 = SK_MaxS32 >> (16 - 6);
+ return SkAbs32(x) <= maxDot6;
+}
+
static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1,
const SkIRect* clip, SkBlitter* blitter) {
// check for integer NaN (0x80000000) which we can't handle (can't negate it)
@@ -239,6 +244,13 @@
return;
}
+ // The caller must clip the line to [-32767.0 ... 32767.0] ahead of time
+ // (in dot6 format)
+ SkASSERT(canConvertFDot6ToFixed(x0));
+ SkASSERT(canConvertFDot6ToFixed(y0));
+ SkASSERT(canConvertFDot6ToFixed(x1));
+ SkASSERT(canConvertFDot6ToFixed(y1));
+
if (SkAbs32(x1 - x0) > SkIntToFDot6(511) || SkAbs32(y1 - y0) > SkIntToFDot6(511)) {
/* instead of (x0 + x1) >> 1, we shift each separately. This is less
precise, but avoids overflowing the intermediate result if the
@@ -428,6 +440,19 @@
SkPoint pts[2] = { pt0, pt1 };
+#ifdef SK_SCALAR_IS_FLOAT
+ // 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;
+ }
+ }
+#endif
+
if (clip) {
SkRect clipBounds;
clipBounds.set(clip->getBounds());