SkClipStackDevice.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * Copyright 2017 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "src/core/SkClipStackDevice.h"
  8. #include "src/core/SkDraw.h"
  9. #include "src/core/SkRasterClip.h"
  10. SkIRect SkClipStackDevice::devClipBounds() const {
  11. SkIRect r = fClipStack.bounds(this->imageInfo().bounds()).roundOut();
  12. if (!r.isEmpty()) {
  13. SkASSERT(this->imageInfo().bounds().contains(r));
  14. }
  15. return r;
  16. }
  17. ///////////////////////////////////////////////////////////////////////////////////////////////////
  18. void SkClipStackDevice::onSave() {
  19. fClipStack.save();
  20. }
  21. void SkClipStackDevice::onRestore() {
  22. fClipStack.restore();
  23. }
  24. void SkClipStackDevice::onClipRect(const SkRect& rect, SkClipOp op, bool aa) {
  25. fClipStack.clipRect(rect, this->ctm(), op, aa);
  26. }
  27. void SkClipStackDevice::onClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) {
  28. fClipStack.clipRRect(rrect, this->ctm(), op, aa);
  29. }
  30. void SkClipStackDevice::onClipPath(const SkPath& path, SkClipOp op, bool aa) {
  31. fClipStack.clipPath(path, this->ctm(), op, aa);
  32. }
  33. void SkClipStackDevice::onClipRegion(const SkRegion& rgn, SkClipOp op) {
  34. SkIPoint origin = this->getOrigin();
  35. SkRegion tmp;
  36. const SkRegion* ptr = &rgn;
  37. if (origin.fX | origin.fY) {
  38. // translate from "global/canvas" coordinates to relative to this device
  39. rgn.translate(-origin.fX, -origin.fY, &tmp);
  40. ptr = &tmp;
  41. }
  42. fClipStack.clipDevRect(ptr->getBounds(), op);
  43. }
  44. void SkClipStackDevice::onSetDeviceClipRestriction(SkIRect* clipRestriction) {
  45. if (clipRestriction->isEmpty()) {
  46. fClipStack.setDeviceClipRestriction(*clipRestriction);
  47. } else {
  48. SkIPoint origin = this->getOrigin();
  49. SkIRect rect = clipRestriction->makeOffset(-origin.x(), -origin.y());
  50. fClipStack.setDeviceClipRestriction(rect);
  51. fClipStack.clipDevRect(rect, SkClipOp::kIntersect);
  52. }
  53. }
  54. bool SkClipStackDevice::onClipIsAA() const {
  55. SkClipStack::B2TIter iter(fClipStack);
  56. const SkClipStack::Element* element;
  57. while ((element = iter.next()) != nullptr) {
  58. if (element->isAA()) {
  59. return true;
  60. }
  61. }
  62. return false;
  63. }
  64. void SkClipStackDevice::onAsRgnClip(SkRegion* rgn) const {
  65. SkClipStack::BoundsType boundType;
  66. bool isIntersectionOfRects;
  67. SkRect bounds;
  68. fClipStack.getBounds(&bounds, &boundType, &isIntersectionOfRects);
  69. if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
  70. rgn->setRect(bounds.round());
  71. } else {
  72. SkPath path;
  73. fClipStack.asPath(&path);
  74. rgn->setPath(path, SkRegion(SkIRect::MakeWH(this->width(), this->height())));
  75. }
  76. }
  77. SkBaseDevice::ClipType SkClipStackDevice::onGetClipType() const {
  78. if (fClipStack.isWideOpen()) {
  79. return kRect_ClipType;
  80. }
  81. if (fClipStack.isEmpty(SkIRect::MakeWH(this->width(), this->height()))) {
  82. return kEmpty_ClipType;
  83. } else {
  84. SkClipStack::BoundsType boundType;
  85. bool isIntersectionOfRects;
  86. SkRect bounds;
  87. fClipStack.getBounds(&bounds, &boundType, &isIntersectionOfRects);
  88. if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
  89. return kRect_ClipType;
  90. } else {
  91. return kComplex_ClipType;
  92. }
  93. }
  94. }