diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkScan_Antihair.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/core/SkScan_Antihair.cpp b/src/core/SkScan_Antihair.cpp index 6c920adc07..ec23a2b525 100644 --- a/src/core/SkScan_Antihair.cpp +++ b/src/core/SkScan_Antihair.cpp @@ -230,6 +230,11 @@ static int any_bad_ints(int a, int b, int c, int d) { } #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 @@ static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1, 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 @@ void SkScan::AntiHairLineRgn(const SkPoint& pt0, const SkPoint& pt1, 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()); |