Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1169)

Unified Diff: skia/ext/analysis_canvas.cc

Issue 2449583002: Support rrect clips in analysis canvas (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | skia/ext/analysis_canvas_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: skia/ext/analysis_canvas.cc
diff --git a/skia/ext/analysis_canvas.cc b/skia/ext/analysis_canvas.cc
index 2caa73d00dd2cbad35493532d6de1b9ade8cd84d..8ff2bf9f1a5b3ccc2ff164f0fb5fc146f1b85fb4 100644
--- a/skia/ext/analysis_canvas.cc
+++ b/skia/ext/analysis_canvas.cc
@@ -410,9 +410,103 @@ void AnalysisCanvas::onClipPath(const SkPath& path,
INHERITED::onClipRect(path.getBounds(), op, edge_style);
}
+SkRect toDeviceSpace(const SkVector& scale,
f(malita) 2016/10/25 13:26:25 SkMatrix::mapRectScaleTranslate()? (see below)
+ const SkVector& translate,
+ const SkRect& src) {
+ SkRect result = SkRect::MakeLTRB(src.fLeft * scale.fX + translate.fX,
+ src.fTop * scale.fY + translate.fY,
+ src.fRight * scale.fX + translate.fX,
+ src.fBottom * scale.fY + translate.fY);
+
+ if (result.fLeft > result.fRight)
+ std::swap(result.fLeft, result.fRight);
+
+ if (result.fTop > result.fBottom)
+ std::swap(result.fTop, result.fBottom);
+
+ return result;
+}
+
+bool doesCoverCanvas(const SkRRect& rr,
+ const SkMatrix& total_matrix,
+ const SkIRect& clip_device_bounds) {
+ // We cannot handle non axis aligned rectangles at the moment.
+ if (!total_matrix.isScaleTranslate()) {
+ return false;
+ }
+
+ const SkRect& bounding_rect = rr.rect();
+
+ // We inline the implementation of mapping and scaling to device space for
+ // the fast path. We also inline here so that we can reuse intermediate
+ // results for scaling multiple rects.
+ float sx = total_matrix.getScaleX();
+ float sy = total_matrix.getScaleY();
+ float tx = total_matrix.getTranslateX();
+ float ty = total_matrix.getTranslateY();
+
+ SkVector scale =
+ SkVector::Make(total_matrix.getScaleX(), total_matrix.getScaleY());
+ SkVector translate = SkVector::Make(total_matrix.getTranslateX(),
+ total_matrix.getTranslateY());
+
+ const SkVector& ul_radii = rr.radii(SkRRect::kUpperLeft_Corner);
+ const SkVector& ur_radii = rr.radii(SkRRect::kUpperRight_Corner);
+ const SkVector& ll_radii = rr.radii(SkRRect::kLowerLeft_Corner);
+ const SkVector& lr_radii = rr.radii(SkRRect::kLowerRight_Corner);
+
+ SkRect ul_device_rect =
+ toDeviceSpace(scale, translate,
f(malita) 2016/10/25 13:26:25 total_matrix.mapRectScaleTranslate(&ul_device_rect
+ SkRect::MakeLTRB(bounding_rect.fLeft, bounding_rect.fTop,
+ bounding_rect.fLeft + ul_radii.fX,
+ bounding_rect.fTop + ul_radii.fY));
+
+ SkRect ur_device_rect =
+ toDeviceSpace(scale, translate,
f(malita) 2016/10/25 13:26:25 ditto
+ SkRect::MakeLTRB(bounding_rect.fRight - ur_radii.fX,
+ bounding_rect.fTop, bounding_rect.fRight,
+ bounding_rect.fTop + ur_radii.fY));
+
+ SkRect ll_device_rect = toDeviceSpace(
f(malita) 2016/10/25 13:26:25 ditto
+ scale, translate,
+ SkRect::MakeLTRB(bounding_rect.fLeft, bounding_rect.fBottom - ll_radii.fY,
+ bounding_rect.fLeft + ll_radii.fX,
+ bounding_rect.fBottom));
+
+ SkRect lr_device_rect = toDeviceSpace(
f(malita) 2016/10/25 13:26:25 ditto
+ scale, translate,
+ SkRect::MakeLTRB(bounding_rect.fRight - lr_radii.fX,
+ bounding_rect.fBottom - lr_radii.fY,
+ bounding_rect.fRight, bounding_rect.fBottom));
+
+ SkRect bounding_device_rect = toDeviceSpace(scale, translate, bounding_rect);
f(malita) 2016/10/25 13:26:25 ditto
+
+ if (!bounding_device_rect.isFinite() || !ul_device_rect.isFinite() ||
+ !ur_device_rect.isFinite() || !ll_device_rect.isFinite() ||
+ !lr_device_rect.isFinite()) {
+ return false;
+ }
+
+ SkRect clip_device_rect = SkRect::MakeFromIRect(clip_device_bounds);
+
+ return bounding_device_rect.contains(clip_device_rect) &&
+ !SkRect::Intersects(ul_device_rect, clip_device_rect) &&
+ !SkRect::Intersects(ur_device_rect, clip_device_rect) &&
+ !SkRect::Intersects(ll_device_rect, clip_device_rect) &&
+ !SkRect::Intersects(lr_device_rect, clip_device_rect);
f(malita) 2016/10/25 13:26:25 Not quite the same thing, but wouldn't it be suffi
+}
+
void AnalysisCanvas::onClipRRect(const SkRRect& rrect,
SkRegion::Op op,
ClipEdgeStyle edge_style) {
+ SkIRect clip_device_bounds;
+ if (getClipDeviceBounds(&clip_device_bounds) &&
+ doesCoverCanvas(rrect, getTotalMatrix(), clip_device_bounds)) {
+ // If the canvas is fully contained within the clip, it is as if we weren't
+ // clipped at all, so bail early.
+ return;
+ }
+
OnComplexClip();
INHERITED::onClipRect(rrect.getBounds(), op, edge_style);
}
« no previous file with comments | « no previous file | skia/ext/analysis_canvas_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698