Chromium Code Reviews| 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); |
| } |