rrect.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * Copyright 2012 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 "gm/gm.h"
  8. #include "include/core/SkCanvas.h"
  9. #include "include/core/SkColor.h"
  10. #include "include/core/SkPaint.h"
  11. #include "include/core/SkPoint.h"
  12. #include "include/core/SkRRect.h"
  13. #include "include/core/SkRect.h"
  14. #include "include/core/SkScalar.h"
  15. #include "include/core/SkSize.h"
  16. #include "include/core/SkString.h"
  17. #include "include/core/SkTypes.h"
  18. #include "tools/ToolUtils.h"
  19. typedef void (*InsetProc)(const SkRRect&, SkScalar dx, SkScalar dy, SkRRect*);
  20. static void inset0(const SkRRect& src, SkScalar dx, SkScalar dy, SkRRect* dst) {
  21. SkRect r = src.rect();
  22. r.inset(dx, dy);
  23. if (r.isEmpty()) {
  24. dst->setEmpty();
  25. return;
  26. }
  27. SkVector radii[4];
  28. for (int i = 0; i < 4; ++i) {
  29. radii[i] = src.radii((SkRRect::Corner)i);
  30. }
  31. for (int i = 0; i < 4; ++i) {
  32. radii[i].fX -= dx;
  33. radii[i].fY -= dy;
  34. }
  35. dst->setRectRadii(r, radii);
  36. }
  37. static void inset1(const SkRRect& src, SkScalar dx, SkScalar dy, SkRRect* dst) {
  38. SkRect r = src.rect();
  39. r.inset(dx, dy);
  40. if (r.isEmpty()) {
  41. dst->setEmpty();
  42. return;
  43. }
  44. SkVector radii[4];
  45. for (int i = 0; i < 4; ++i) {
  46. radii[i] = src.radii((SkRRect::Corner)i);
  47. }
  48. dst->setRectRadii(r, radii);
  49. }
  50. static void inset2(const SkRRect& src, SkScalar dx, SkScalar dy, SkRRect* dst) {
  51. SkRect r = src.rect();
  52. r.inset(dx, dy);
  53. if (r.isEmpty()) {
  54. dst->setEmpty();
  55. return;
  56. }
  57. SkVector radii[4];
  58. for (int i = 0; i < 4; ++i) {
  59. radii[i] = src.radii((SkRRect::Corner)i);
  60. }
  61. for (int i = 0; i < 4; ++i) {
  62. if (radii[i].fX) {
  63. radii[i].fX -= dx;
  64. }
  65. if (radii[i].fY) {
  66. radii[i].fY -= dy;
  67. }
  68. }
  69. dst->setRectRadii(r, radii);
  70. }
  71. static SkScalar prop(SkScalar radius, SkScalar newSize, SkScalar oldSize) {
  72. return newSize * radius / oldSize;
  73. }
  74. static void inset3(const SkRRect& src, SkScalar dx, SkScalar dy, SkRRect* dst) {
  75. SkRect r = src.rect();
  76. r.inset(dx, dy);
  77. if (r.isEmpty()) {
  78. dst->setEmpty();
  79. return;
  80. }
  81. SkVector radii[4];
  82. for (int i = 0; i < 4; ++i) {
  83. radii[i] = src.radii((SkRRect::Corner)i);
  84. }
  85. for (int i = 0; i < 4; ++i) {
  86. radii[i].fX = prop(radii[i].fX, r.width(), src.rect().width());
  87. radii[i].fY = prop(radii[i].fY, r.height(), src.rect().height());
  88. }
  89. dst->setRectRadii(r, radii);
  90. }
  91. static void draw_rrect_color(SkCanvas* canvas, const SkRRect& rrect) {
  92. SkPaint paint;
  93. paint.setAntiAlias(true);
  94. paint.setStyle(SkPaint::kStroke_Style);
  95. if (rrect.isRect()) {
  96. paint.setColor(SK_ColorRED);
  97. } else if (rrect.isOval()) {
  98. paint.setColor(ToolUtils::color_to_565(0xFF008800));
  99. } else if (rrect.isSimple()) {
  100. paint.setColor(SK_ColorBLUE);
  101. } else {
  102. paint.setColor(SK_ColorBLACK);
  103. }
  104. canvas->drawRRect(rrect, paint);
  105. }
  106. static void drawrr(SkCanvas* canvas, const SkRRect& rrect, InsetProc proc) {
  107. SkRRect rr;
  108. for (SkScalar d = -30; d <= 30; d += 5) {
  109. proc(rrect, d, d, &rr);
  110. draw_rrect_color(canvas, rr);
  111. }
  112. }
  113. class RRectGM : public skiagm::GM {
  114. public:
  115. RRectGM() {}
  116. protected:
  117. SkString onShortName() override {
  118. return SkString("rrect");
  119. }
  120. SkISize onISize() override {
  121. return SkISize::Make(820, 710);
  122. }
  123. void onDraw(SkCanvas* canvas) override {
  124. constexpr InsetProc insetProcs[] = {
  125. inset0, inset1, inset2, inset3
  126. };
  127. SkRRect rrect[4];
  128. SkRect r = { 0, 0, 120, 100 };
  129. SkVector radii[4] = {
  130. { 0, 0 }, { 30, 1 }, { 10, 40 }, { 40, 40 }
  131. };
  132. rrect[0].setRect(r);
  133. rrect[1].setOval(r);
  134. rrect[2].setRectXY(r, 20, 20);
  135. rrect[3].setRectRadii(r, radii);
  136. canvas->translate(50.5f, 50.5f);
  137. for (size_t j = 0; j < SK_ARRAY_COUNT(insetProcs); ++j) {
  138. canvas->save();
  139. for (size_t i = 0; i < SK_ARRAY_COUNT(rrect); ++i) {
  140. drawrr(canvas, rrect[i], insetProcs[j]);
  141. canvas->translate(200, 0);
  142. }
  143. canvas->restore();
  144. canvas->translate(0, 170);
  145. }
  146. }
  147. private:
  148. typedef GM INHERITED;
  149. };
  150. DEF_GM( return new RRectGM; )