aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar tomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-08-10 14:10:45 +0000
committerGravatar tomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-08-10 14:10:45 +0000
commited02c4d05e3f2ed86dbf4276a69827ab23810598 (patch)
tree9bde04de3b9bcac97197b85910ee1135ab227b65 /src/core
parenta37a517b5419c4faf1799b0b2b9b6a559ee6af4d (diff)
Fix handling of infinite bounds during "fast transforms".
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkPath.cpp32
1 files changed, 26 insertions, 6 deletions
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 4483388f5a..1127e956ea 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -1341,13 +1341,30 @@ void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const {
dst->swap(tmp);
matrix.mapPoints(dst->fPts.begin(), dst->fPts.count());
} else {
- // remember that dst might == this, so be sure to check
- // fBoundsIsDirty before we set it
+ /*
+ * If we're not in perspective, we can transform all of the points at
+ * once.
+ *
+ * Here we also want to optimize bounds, by noting if the bounds are
+ * already known, and if so, we just transform those as well and mark
+ * them as "known", rather than force the transformed path to have to
+ * recompute them.
+ *
+ * Special gotchas if the path is effectively empty (<= 1 point) or
+ * if it is non-finite. In those cases bounds need to stay empty,
+ * regardless of the matrix.
+ */
if (!fBoundsIsDirty && matrix.rectStaysRect() && fPts.count() > 1) {
- // if we're empty, fastbounds should not be mapped
- matrix.mapRect(&dst->fBounds, fBounds);
dst->fBoundsIsDirty = false;
- dst->fIsFinite = dst->fBounds.isFinite();
+ if (fIsFinite) {
+ matrix.mapRect(&dst->fBounds, fBounds);
+ if (!(dst->fIsFinite = dst->fBounds.isFinite())) {
+ dst->fBounds.setEmpty();
+ }
+ } else {
+ dst->fIsFinite = false;
+ dst->fBounds.setEmpty();
+ }
} else {
GEN_ID_PTR_INC(dst);
dst->fBoundsIsDirty = true;
@@ -1795,7 +1812,10 @@ void SkPath::validate() const {
if (!fBoundsIsDirty) {
SkRect bounds;
- compute_pt_bounds(&bounds, fPts);
+
+ bool isFinite = compute_pt_bounds(&bounds, fPts);
+ SkASSERT(fIsFinite == isFinite);
+
if (fPts.count() <= 1) {
// if we're empty, fBounds may be empty but translated, so we can't
// necessarily compare to bounds directly