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

Side by Side Diff: skia/ext/analysis_canvas.cc

Issue 2449583002: Support rrect clips in analysis canvas (Closed)
Patch Set: Created 4 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « no previous file | skia/ext/analysis_canvas_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/logging.h" 5 #include "base/logging.h"
6 #include "base/trace_event/trace_event.h" 6 #include "base/trace_event/trace_event.h"
7 #include "skia/ext/analysis_canvas.h" 7 #include "skia/ext/analysis_canvas.h"
8 #include "third_party/skia/include/core/SkDraw.h" 8 #include "third_party/skia/include/core/SkDraw.h"
9 #include "third_party/skia/include/core/SkPath.h" 9 #include "third_party/skia/include/core/SkPath.h"
10 #include "third_party/skia/include/core/SkRRect.h" 10 #include "third_party/skia/include/core/SkRRect.h"
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 INHERITED::onClipRect(rect, op, edge_style); 403 INHERITED::onClipRect(rect, op, edge_style);
404 } 404 }
405 405
406 void AnalysisCanvas::onClipPath(const SkPath& path, 406 void AnalysisCanvas::onClipPath(const SkPath& path,
407 SkRegion::Op op, 407 SkRegion::Op op,
408 ClipEdgeStyle edge_style) { 408 ClipEdgeStyle edge_style) {
409 OnComplexClip(); 409 OnComplexClip();
410 INHERITED::onClipRect(path.getBounds(), op, edge_style); 410 INHERITED::onClipRect(path.getBounds(), op, edge_style);
411 } 411 }
412 412
413 SkRect toDeviceSpace(const SkVector& scale,
f(malita) 2016/10/25 13:26:25 SkMatrix::mapRectScaleTranslate()? (see below)
414 const SkVector& translate,
415 const SkRect& src) {
416 SkRect result = SkRect::MakeLTRB(src.fLeft * scale.fX + translate.fX,
417 src.fTop * scale.fY + translate.fY,
418 src.fRight * scale.fX + translate.fX,
419 src.fBottom * scale.fY + translate.fY);
420
421 if (result.fLeft > result.fRight)
422 std::swap(result.fLeft, result.fRight);
423
424 if (result.fTop > result.fBottom)
425 std::swap(result.fTop, result.fBottom);
426
427 return result;
428 }
429
430 bool doesCoverCanvas(const SkRRect& rr,
431 const SkMatrix& total_matrix,
432 const SkIRect& clip_device_bounds) {
433 // We cannot handle non axis aligned rectangles at the moment.
434 if (!total_matrix.isScaleTranslate()) {
435 return false;
436 }
437
438 const SkRect& bounding_rect = rr.rect();
439
440 // We inline the implementation of mapping and scaling to device space for
441 // the fast path. We also inline here so that we can reuse intermediate
442 // results for scaling multiple rects.
443 float sx = total_matrix.getScaleX();
444 float sy = total_matrix.getScaleY();
445 float tx = total_matrix.getTranslateX();
446 float ty = total_matrix.getTranslateY();
447
448 SkVector scale =
449 SkVector::Make(total_matrix.getScaleX(), total_matrix.getScaleY());
450 SkVector translate = SkVector::Make(total_matrix.getTranslateX(),
451 total_matrix.getTranslateY());
452
453 const SkVector& ul_radii = rr.radii(SkRRect::kUpperLeft_Corner);
454 const SkVector& ur_radii = rr.radii(SkRRect::kUpperRight_Corner);
455 const SkVector& ll_radii = rr.radii(SkRRect::kLowerLeft_Corner);
456 const SkVector& lr_radii = rr.radii(SkRRect::kLowerRight_Corner);
457
458 SkRect ul_device_rect =
459 toDeviceSpace(scale, translate,
f(malita) 2016/10/25 13:26:25 total_matrix.mapRectScaleTranslate(&ul_device_rect
460 SkRect::MakeLTRB(bounding_rect.fLeft, bounding_rect.fTop,
461 bounding_rect.fLeft + ul_radii.fX,
462 bounding_rect.fTop + ul_radii.fY));
463
464 SkRect ur_device_rect =
465 toDeviceSpace(scale, translate,
f(malita) 2016/10/25 13:26:25 ditto
466 SkRect::MakeLTRB(bounding_rect.fRight - ur_radii.fX,
467 bounding_rect.fTop, bounding_rect.fRight,
468 bounding_rect.fTop + ur_radii.fY));
469
470 SkRect ll_device_rect = toDeviceSpace(
f(malita) 2016/10/25 13:26:25 ditto
471 scale, translate,
472 SkRect::MakeLTRB(bounding_rect.fLeft, bounding_rect.fBottom - ll_radii.fY,
473 bounding_rect.fLeft + ll_radii.fX,
474 bounding_rect.fBottom));
475
476 SkRect lr_device_rect = toDeviceSpace(
f(malita) 2016/10/25 13:26:25 ditto
477 scale, translate,
478 SkRect::MakeLTRB(bounding_rect.fRight - lr_radii.fX,
479 bounding_rect.fBottom - lr_radii.fY,
480 bounding_rect.fRight, bounding_rect.fBottom));
481
482 SkRect bounding_device_rect = toDeviceSpace(scale, translate, bounding_rect);
f(malita) 2016/10/25 13:26:25 ditto
483
484 if (!bounding_device_rect.isFinite() || !ul_device_rect.isFinite() ||
485 !ur_device_rect.isFinite() || !ll_device_rect.isFinite() ||
486 !lr_device_rect.isFinite()) {
487 return false;
488 }
489
490 SkRect clip_device_rect = SkRect::MakeFromIRect(clip_device_bounds);
491
492 return bounding_device_rect.contains(clip_device_rect) &&
493 !SkRect::Intersects(ul_device_rect, clip_device_rect) &&
494 !SkRect::Intersects(ur_device_rect, clip_device_rect) &&
495 !SkRect::Intersects(ll_device_rect, clip_device_rect) &&
496 !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
497 }
498
413 void AnalysisCanvas::onClipRRect(const SkRRect& rrect, 499 void AnalysisCanvas::onClipRRect(const SkRRect& rrect,
414 SkRegion::Op op, 500 SkRegion::Op op,
415 ClipEdgeStyle edge_style) { 501 ClipEdgeStyle edge_style) {
502 SkIRect clip_device_bounds;
503 if (getClipDeviceBounds(&clip_device_bounds) &&
504 doesCoverCanvas(rrect, getTotalMatrix(), clip_device_bounds)) {
505 // If the canvas is fully contained within the clip, it is as if we weren't
506 // clipped at all, so bail early.
507 return;
508 }
509
416 OnComplexClip(); 510 OnComplexClip();
417 INHERITED::onClipRect(rrect.getBounds(), op, edge_style); 511 INHERITED::onClipRect(rrect.getBounds(), op, edge_style);
418 } 512 }
419 513
420 void AnalysisCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { 514 void AnalysisCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) {
421 const ClipEdgeStyle edge_style = kHard_ClipEdgeStyle; 515 const ClipEdgeStyle edge_style = kHard_ClipEdgeStyle;
422 if (deviceRgn.isRect()) { 516 if (deviceRgn.isRect()) {
423 onClipRect(SkRect::MakeFromIRect(deviceRgn.getBounds()), op, edge_style); 517 onClipRect(SkRect::MakeFromIRect(deviceRgn.getBounds()), op, edge_style);
424 return; 518 return;
425 } 519 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 force_not_transparent_stack_level_ = kNoLayer; 580 force_not_transparent_stack_level_ = kNoLayer;
487 } 581 }
488 } 582 }
489 583
490 INHERITED::willRestore(); 584 INHERITED::willRestore();
491 } 585 }
492 586
493 } // namespace skia 587 } // namespace skia
494 588
495 589
OLDNEW
« 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