aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkDraw.cpp37
-rw-r--r--src/core/SkMathPriv.h5
-rw-r--r--src/core/SkRectPriv.h7
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);
+ }
};