SkRect.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Copyright 2006 The Android Open Source Project
  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 "include/core/SkRect.h"
  8. #include "include/private/SkMalloc.h"
  9. void SkIRect::join(int32_t left, int32_t top, int32_t right, int32_t bottom) {
  10. // do nothing if the params are empty
  11. if (left >= right || top >= bottom) {
  12. return;
  13. }
  14. // if we are empty, just assign
  15. if (fLeft >= fRight || fTop >= fBottom) {
  16. this->set(left, top, right, bottom);
  17. } else {
  18. if (left < fLeft) fLeft = left;
  19. if (top < fTop) fTop = top;
  20. if (right > fRight) fRight = right;
  21. if (bottom > fBottom) fBottom = bottom;
  22. }
  23. }
  24. /////////////////////////////////////////////////////////////////////////////
  25. void SkRect::toQuad(SkPoint quad[4]) const {
  26. SkASSERT(quad);
  27. quad[0].set(fLeft, fTop);
  28. quad[1].set(fRight, fTop);
  29. quad[2].set(fRight, fBottom);
  30. quad[3].set(fLeft, fBottom);
  31. }
  32. #include "include/private/SkNx.h"
  33. bool SkRect::setBoundsCheck(const SkPoint pts[], int count) {
  34. SkASSERT((pts && count > 0) || count == 0);
  35. if (count <= 0) {
  36. this->setEmpty();
  37. return true;
  38. }
  39. Sk4s min, max;
  40. if (count & 1) {
  41. min = max = Sk4s(pts->fX, pts->fY,
  42. pts->fX, pts->fY);
  43. pts += 1;
  44. count -= 1;
  45. } else {
  46. min = max = Sk4s::Load(pts);
  47. pts += 2;
  48. count -= 2;
  49. }
  50. Sk4s accum = min * 0;
  51. while (count) {
  52. Sk4s xy = Sk4s::Load(pts);
  53. accum = accum * xy;
  54. min = Sk4s::Min(min, xy);
  55. max = Sk4s::Max(max, xy);
  56. pts += 2;
  57. count -= 2;
  58. }
  59. bool all_finite = (accum * 0 == 0).allTrue();
  60. if (all_finite) {
  61. this->set(SkTMin(min[0], min[2]), SkTMin(min[1], min[3]),
  62. SkTMax(max[0], max[2]), SkTMax(max[1], max[3]));
  63. } else {
  64. this->setEmpty();
  65. }
  66. return all_finite;
  67. }
  68. void SkRect::setBoundsNoCheck(const SkPoint pts[], int count) {
  69. if (!this->setBoundsCheck(pts, count)) {
  70. this->set(SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN);
  71. }
  72. }
  73. #define CHECK_INTERSECT(al, at, ar, ab, bl, bt, br, bb) \
  74. SkScalar L = SkMaxScalar(al, bl); \
  75. SkScalar R = SkMinScalar(ar, br); \
  76. SkScalar T = SkMaxScalar(at, bt); \
  77. SkScalar B = SkMinScalar(ab, bb); \
  78. do { if (!(L < R && T < B)) return false; } while (0)
  79. // do the !(opposite) check so we return false if either arg is NaN
  80. bool SkRect::intersect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) {
  81. CHECK_INTERSECT(left, top, right, bottom, fLeft, fTop, fRight, fBottom);
  82. this->setLTRB(L, T, R, B);
  83. return true;
  84. }
  85. bool SkRect::intersect(const SkRect& r) {
  86. return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom);
  87. }
  88. bool SkRect::intersect(const SkRect& a, const SkRect& b) {
  89. CHECK_INTERSECT(a.fLeft, a.fTop, a.fRight, a.fBottom, b.fLeft, b.fTop, b.fRight, b.fBottom);
  90. this->setLTRB(L, T, R, B);
  91. return true;
  92. }
  93. void SkRect::join(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) {
  94. // do nothing if the params are empty
  95. if (left >= right || top >= bottom) {
  96. return;
  97. }
  98. // if we are empty, just assign
  99. if (fLeft >= fRight || fTop >= fBottom) {
  100. this->set(left, top, right, bottom);
  101. } else {
  102. fLeft = SkMinScalar(fLeft, left);
  103. fTop = SkMinScalar(fTop, top);
  104. fRight = SkMaxScalar(fRight, right);
  105. fBottom = SkMaxScalar(fBottom, bottom);
  106. }
  107. }
  108. ////////////////////////////////////////////////////////////////////////////////////////////////
  109. #include "include/core/SkString.h"
  110. #include "src/core/SkStringUtils.h"
  111. static const char* set_scalar(SkString* storage, SkScalar value, SkScalarAsStringType asType) {
  112. storage->reset();
  113. SkAppendScalar(storage, value, asType);
  114. return storage->c_str();
  115. }
  116. void SkRect::dump(bool asHex) const {
  117. SkScalarAsStringType asType = asHex ? kHex_SkScalarAsStringType : kDec_SkScalarAsStringType;
  118. SkString line;
  119. if (asHex) {
  120. SkString tmp;
  121. line.printf( "SkRect::MakeLTRB(%s, /* %f */\n", set_scalar(&tmp, fLeft, asType), fLeft);
  122. line.appendf(" %s, /* %f */\n", set_scalar(&tmp, fTop, asType), fTop);
  123. line.appendf(" %s, /* %f */\n", set_scalar(&tmp, fRight, asType), fRight);
  124. line.appendf(" %s /* %f */);", set_scalar(&tmp, fBottom, asType), fBottom);
  125. } else {
  126. SkString strL, strT, strR, strB;
  127. SkAppendScalarDec(&strL, fLeft);
  128. SkAppendScalarDec(&strT, fTop);
  129. SkAppendScalarDec(&strR, fRight);
  130. SkAppendScalarDec(&strB, fBottom);
  131. line.printf("SkRect::MakeLTRB(%s, %s, %s, %s);",
  132. strL.c_str(), strT.c_str(), strR.c_str(), strB.c_str());
  133. }
  134. SkDebugf("%s\n", line.c_str());
  135. }