Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |