diff options
Diffstat (limited to 'src/core/SkPaint.cpp')
-rw-r--r-- | src/core/SkPaint.cpp | 89 |
1 files changed, 74 insertions, 15 deletions
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index cf25dbf9ee..7d418f4b1c 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -9,7 +9,6 @@ #include "SkPaint.h" #include "SkColorFilter.h" -#include "SkDrawLooper.h" #include "SkFontHost.h" #include "SkImageFilter.h" #include "SkMaskFilter.h" @@ -1847,23 +1846,38 @@ bool SkPaint::getFillPath(const SkPath& src, SkPath* dst) const { return width != 0; // return true if we're filled, or false if we're hairline (width == 0) } -const SkRect& SkPaint::computeStrokeFastBounds(const SkRect& src, - SkRect* storage) const { +const SkRect& SkPaint::doComputeFastBounds(const SkRect& src, + SkRect* storage) const { SkASSERT(storage); - SkASSERT(this->getStyle() != SkPaint::kFill_Style); - - // since we're stroked, outset the rect by the radius (and join type) - SkScalar radius = SkScalarHalf(this->getStrokeWidth()); - if (0 == radius) { // hairline - radius = SK_Scalar1; - } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) { - SkScalar scale = this->getStrokeMiter(); - if (scale > SK_Scalar1) { - radius = SkScalarMul(radius, scale); + + if (this->getLooper()) { + SkASSERT(this->getLooper()->canComputeFastBounds(*this)); + this->getLooper()->computeFastBounds(*this, src, storage); + return *storage; + } + + if (this->getStyle() != SkPaint::kFill_Style) { + // since we're stroked, outset the rect by the radius (and join type) + SkScalar radius = SkScalarHalf(this->getStrokeWidth()); + if (0 == radius) { // hairline + radius = SK_Scalar1; + } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) { + SkScalar scale = this->getStrokeMiter(); + if (scale > SK_Scalar1) { + radius = SkScalarMul(radius, scale); + } } + storage->set(src.fLeft - radius, src.fTop - radius, + src.fRight + radius, src.fBottom + radius); + } else { + *storage = src; } - storage->set(src.fLeft - radius, src.fTop - radius, - src.fRight + radius, src.fBottom + radius); + + // check the mask filter + if (this->getMaskFilter()) { + this->getMaskFilter()->computeFastBounds(*storage, storage); + } + return *storage; } @@ -2021,3 +2035,48 @@ bool SkImageFilter::asABlur(SkSize* sigma) const { return false; } +////// + +bool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) { + SkCanvas canvas; + + this->init(&canvas); + for (;;) { + SkPaint p(paint); + if (this->next(&canvas, &p)) { + p.setLooper(NULL); + if (!p.canComputeFastBounds()) { + return false; + } + } else { + break; + } + } + return true; +} + +void SkDrawLooper::computeFastBounds(const SkPaint& paint, const SkRect& src, + SkRect* dst) { + SkCanvas canvas; + + this->init(&canvas); + for (bool firstTime = true;; firstTime = false) { + SkPaint p(paint); + if (this->next(&canvas, &p)) { + SkRect r(src); + + p.setLooper(NULL); + p.computeFastBounds(r, &r); + canvas.getTotalMatrix().mapRect(&r); + + if (firstTime) { + *dst = r; + } else { + dst->join(r); + } + } else { + break; + } + } +} + |