diff options
-rw-r--r-- | src/core/SkDraw.cpp | 37 | ||||
-rw-r--r-- | src/core/SkMathPriv.h | 5 | ||||
-rw-r--r-- | src/core/SkRectPriv.h | 7 |
3 files changed, 30 insertions, 19 deletions
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 77af440caf..70cb485f73 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -380,36 +380,35 @@ bool PtProcRec::init(SkCanvas::PointMode mode, const SkPaint& paint, if ((unsigned)mode > (unsigned)SkCanvas::kPolygon_PointMode) { return false; } - if (paint.getPathEffect()) { return false; } SkScalar width = paint.getStrokeWidth(); + SkScalar radius = -1; // sentinel value, a "valid" value must be > 0 + if (0 == width) { + radius = 0.5f; + } else if (paint.getStrokeCap() != SkPaint::kRound_Cap && + matrix->isScaleTranslate() && SkCanvas::kPoints_PointMode == mode) { + SkScalar sx = matrix->get(SkMatrix::kMScaleX); + SkScalar sy = matrix->get(SkMatrix::kMScaleY); + if (SkScalarNearlyZero(sx - sy)) { + radius = SkScalarHalf(width * SkScalarAbs(sx)); + } + } + if (radius > 0) { + // if we return true, the caller may assume that the constructed shapes can be represented + // using SkFixed, so we preflight that here, looking at the radius and clip-bounds + if (!SkRectPriv::FitsInFixed(SkRect::Make(rc->getBounds()).makeOutset(radius, radius))) { + return false; + } fMode = mode; fPaint = &paint; fClip = nullptr; fRC = rc; - fRadius = SK_FixedHalf; + fRadius = SkScalarToFixed(radius); return true; } - if (paint.getStrokeCap() != SkPaint::kRound_Cap && - matrix->isScaleTranslate() && SkCanvas::kPoints_PointMode == mode) { - SkScalar sx = matrix->get(SkMatrix::kMScaleX); - SkScalar sy = matrix->get(SkMatrix::kMScaleY); - if (SkScalarNearlyZero(sx - sy)) { - if (sx < 0) { - sx = -sx; - } - - fMode = mode; - fPaint = &paint; - fClip = nullptr; - fRC = rc; - fRadius = SkScalarToFixed(width * sx) >> 1; - return true; - } - } return false; } diff --git a/src/core/SkMathPriv.h b/src/core/SkMathPriv.h index 6c33e36747..dcdd81fd41 100644 --- a/src/core/SkMathPriv.h +++ b/src/core/SkMathPriv.h @@ -215,4 +215,9 @@ static inline size_t GrNextSizePow2(size_t n) { return n + 1; } +// conservative check. will return false for very large values that "could" fit +template <typename T> static inline bool SkFitsInFixed(T x) { + return SkTAbs(x) <= 32767.0f; +} + #endif diff --git a/src/core/SkRectPriv.h b/src/core/SkRectPriv.h index 16c9535cc8..d2a2ce4665 100644 --- a/src/core/SkRectPriv.h +++ b/src/core/SkRectPriv.h @@ -9,6 +9,7 @@ #define SkRectPriv_DEFINED #include "SkRect.h" +#include "SkMathPriv.h" class SkRectPriv { public: @@ -45,6 +46,12 @@ public: r->fTop = SkMinScalar(pt.fY, r->fTop); r->fBottom = SkMaxScalar(pt.fY, r->fBottom); } + + // conservative check. will return false for very large values that "could" fit + static bool FitsInFixed(const SkRect& r) { + return SkFitsInFixed(r.fLeft) && SkFitsInFixed(r.fTop) && + SkFitsInFixed(r.fRight) && SkFitsInFixed(r.fBottom); + } }; |