GrRect.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * Copyright 2010 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. #ifndef GrRect_DEFINED
  8. #define GrRect_DEFINED
  9. #include "include/core/SkMatrix.h"
  10. #include "include/core/SkRect.h"
  11. #include "include/core/SkTypes.h"
  12. #include "include/private/SkTo.h"
  13. struct GrIRect16 {
  14. int16_t fLeft, fTop, fRight, fBottom;
  15. static GrIRect16 SK_WARN_UNUSED_RESULT MakeEmpty() {
  16. GrIRect16 r;
  17. r.setEmpty();
  18. return r;
  19. }
  20. static GrIRect16 SK_WARN_UNUSED_RESULT MakeWH(int16_t w, int16_t h) {
  21. GrIRect16 r;
  22. r.set(0, 0, w, h);
  23. return r;
  24. }
  25. static GrIRect16 SK_WARN_UNUSED_RESULT MakeXYWH(int16_t x, int16_t y, int16_t w, int16_t h) {
  26. GrIRect16 r;
  27. r.set(x, y, x + w, y + h);
  28. return r;
  29. }
  30. static GrIRect16 SK_WARN_UNUSED_RESULT Make(const SkIRect& ir) {
  31. GrIRect16 r;
  32. r.set(ir);
  33. return r;
  34. }
  35. int width() const { return fRight - fLeft; }
  36. int height() const { return fBottom - fTop; }
  37. int area() const { return this->width() * this->height(); }
  38. bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
  39. void setEmpty() { memset(this, 0, sizeof(*this)); }
  40. void set(int16_t left, int16_t top, int16_t right, int16_t bottom) {
  41. fLeft = left;
  42. fTop = top;
  43. fRight = right;
  44. fBottom = bottom;
  45. }
  46. void set(const SkIRect& r) {
  47. fLeft = SkToS16(r.fLeft);
  48. fTop = SkToS16(r.fTop);
  49. fRight = SkToS16(r.fRight);
  50. fBottom = SkToS16(r.fBottom);
  51. }
  52. };
  53. /** Returns true if the rectangles have a nonzero area of overlap. It assumed that rects can be
  54. infinitely small but not "inverted". */
  55. static inline bool GrRectsOverlap(const SkRect& a, const SkRect& b) {
  56. // See skbug.com/6607 about the isFinite() checks.
  57. SkASSERT(!a.isFinite() || (a.fLeft <= a.fRight && a.fTop <= a.fBottom));
  58. SkASSERT(!b.isFinite() || (b.fLeft <= b.fRight && b.fTop <= b.fBottom));
  59. return a.fRight > b.fLeft && a.fBottom > b.fTop && b.fRight > a.fLeft && b.fBottom > a.fTop;
  60. }
  61. /** Returns true if the rectangles overlap or share an edge or corner. It assumed that rects can be
  62. infinitely small but not "inverted". */
  63. static inline bool GrRectsTouchOrOverlap(const SkRect& a, const SkRect& b) {
  64. // See skbug.com/6607 about the isFinite() checks.
  65. SkASSERT(!a.isFinite() || (a.fLeft <= a.fRight && a.fTop <= a.fBottom));
  66. SkASSERT(!b.isFinite() || (b.fLeft <= b.fRight && b.fTop <= b.fBottom));
  67. return a.fRight >= b.fLeft && a.fBottom >= b.fTop && b.fRight >= a.fLeft && b.fBottom >= a.fTop;
  68. }
  69. /**
  70. * Apply the transform from 'inRect' to 'outRect' to each point in 'inPts', storing the mapped point
  71. * into the parallel index of 'outPts'.
  72. */
  73. static inline void GrMapRectPoints(const SkRect& inRect, const SkRect& outRect,
  74. const SkPoint inPts[], SkPoint outPts[], int ptCount) {
  75. SkMatrix rectTransform = SkMatrix::MakeRectToRect(inRect, outRect, SkMatrix::kFill_ScaleToFit);
  76. rectTransform.mapPoints(outPts, inPts, ptCount);
  77. }
  78. /**
  79. * Clips the srcRect and the dstPoint to the bounds of the srcSize and dstSize respectively. Returns
  80. * true if the srcRect and dstRect intersect the srcRect and dst rect (dstPoint with srcRect
  81. * width/height). Returns false otherwise. The clipped values are returned in clippedSrcRect and
  82. * clippedDstPoint.
  83. */
  84. static inline bool GrClipSrcRectAndDstPoint(const SkISize& dstSize,
  85. const SkISize& srcSize,
  86. const SkIRect& srcRect,
  87. const SkIPoint& dstPoint,
  88. SkIRect* clippedSrcRect,
  89. SkIPoint* clippedDstPoint) {
  90. *clippedSrcRect = srcRect;
  91. *clippedDstPoint = dstPoint;
  92. // clip the left edge to src and dst bounds, adjusting dstPoint if necessary
  93. if (clippedSrcRect->fLeft < 0) {
  94. clippedDstPoint->fX -= clippedSrcRect->fLeft;
  95. clippedSrcRect->fLeft = 0;
  96. }
  97. if (clippedDstPoint->fX < 0) {
  98. clippedSrcRect->fLeft -= clippedDstPoint->fX;
  99. clippedDstPoint->fX = 0;
  100. }
  101. // clip the top edge to src and dst bounds, adjusting dstPoint if necessary
  102. if (clippedSrcRect->fTop < 0) {
  103. clippedDstPoint->fY -= clippedSrcRect->fTop;
  104. clippedSrcRect->fTop = 0;
  105. }
  106. if (clippedDstPoint->fY < 0) {
  107. clippedSrcRect->fTop -= clippedDstPoint->fY;
  108. clippedDstPoint->fY = 0;
  109. }
  110. // clip the right edge to the src and dst bounds.
  111. if (clippedSrcRect->fRight > srcSize.width()) {
  112. clippedSrcRect->fRight = srcSize.width();
  113. }
  114. if (clippedDstPoint->fX + clippedSrcRect->width() > dstSize.width()) {
  115. clippedSrcRect->fRight = clippedSrcRect->fLeft + dstSize.width() - clippedDstPoint->fX;
  116. }
  117. // clip the bottom edge to the src and dst bounds.
  118. if (clippedSrcRect->fBottom > srcSize.height()) {
  119. clippedSrcRect->fBottom = srcSize.height();
  120. }
  121. if (clippedDstPoint->fY + clippedSrcRect->height() > dstSize.height()) {
  122. clippedSrcRect->fBottom = clippedSrcRect->fTop + dstSize.height() - clippedDstPoint->fY;
  123. }
  124. // The above clipping steps may have inverted the rect if it didn't intersect either the src or
  125. // dst bounds.
  126. return !clippedSrcRect->isEmpty();
  127. }
  128. #endif