blurroundrect.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * Copyright 2013 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/SkBlendMode.h"
  9. #include "include/core/SkBlurTypes.h"
  10. #include "include/core/SkCanvas.h"
  11. #include "include/core/SkColor.h"
  12. #include "include/core/SkColorFilter.h"
  13. #include "include/core/SkDrawLooper.h"
  14. #include "include/core/SkMaskFilter.h"
  15. #include "include/core/SkMatrix.h"
  16. #include "include/core/SkPaint.h"
  17. #include "include/core/SkPoint.h"
  18. #include "include/core/SkRRect.h"
  19. #include "include/core/SkRect.h"
  20. #include "include/core/SkRefCnt.h"
  21. #include "include/core/SkScalar.h"
  22. #include "include/core/SkShader.h"
  23. #include "include/core/SkSize.h"
  24. #include "include/core/SkString.h"
  25. #include "include/core/SkTileMode.h"
  26. #include "include/core/SkTypes.h"
  27. #include "include/effects/SkGradientShader.h"
  28. #include "include/effects/SkLayerDrawLooper.h"
  29. #include "src/core/SkBlurMask.h"
  30. #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
  31. // This GM mimics a blurred RR seen in the wild.
  32. class BlurRoundRectGM : public skiagm::GM {
  33. public:
  34. BlurRoundRectGM(int w, int h) : fWidth(w), fHeight(h) {}
  35. private:
  36. SkString onShortName() override {
  37. return SkStringPrintf("blurroundrect-WH-%ix%i-unevenCorners", fWidth, fHeight);
  38. }
  39. SkISize onISize() override { return {fWidth, fHeight}; }
  40. void onOnceBeforeDraw() override {
  41. SkVector radii[4];
  42. radii[0].set(SkIntToScalar(30), SkIntToScalar(30));
  43. radii[1].set(SkIntToScalar(10), SkIntToScalar(10));
  44. radii[2].set(SkIntToScalar(30), SkIntToScalar(30));
  45. radii[3].set(SkIntToScalar(10), SkIntToScalar(10));
  46. SkRect r = SkRect::MakeWH(SkIntToScalar(fWidth), SkIntToScalar(fHeight));
  47. fRRect.setRectRadii(r, radii);
  48. }
  49. void onDraw(SkCanvas* canvas) override {
  50. SkLayerDrawLooper::Builder looperBuilder;
  51. {
  52. SkLayerDrawLooper::LayerInfo info;
  53. info.fPaintBits = SkLayerDrawLooper::kMaskFilter_Bit
  54. | SkLayerDrawLooper::kColorFilter_Bit;
  55. info.fColorMode = SkBlendMode::kSrc;
  56. info.fOffset = SkPoint::Make(SkIntToScalar(-1), SkIntToScalar(0));
  57. info.fPostTranslate = false;
  58. SkPaint* paint = looperBuilder.addLayerOnTop(info);
  59. paint->setMaskFilter(SkMaskFilter::MakeBlur(
  60. kNormal_SkBlurStyle,
  61. SkBlurMask::ConvertRadiusToSigma(SK_ScalarHalf)));
  62. paint->setColorFilter(SkColorFilters::Blend(SK_ColorLTGRAY, SkBlendMode::kSrcIn));
  63. paint->setColor(SK_ColorGRAY);
  64. }
  65. {
  66. SkLayerDrawLooper::LayerInfo info;
  67. looperBuilder.addLayerOnTop(info);
  68. }
  69. SkPaint paint;
  70. canvas->drawRect(fRRect.rect(), paint);
  71. paint.setLooper(looperBuilder.detach());
  72. paint.setColor(SK_ColorCYAN);
  73. paint.setAntiAlias(true);
  74. canvas->drawRRect(fRRect, paint);
  75. }
  76. SkRRect fRRect;
  77. int fWidth, fHeight;
  78. };
  79. // Rounded rect with two opposite corners with large radii, the other two
  80. // small.
  81. DEF_GM(return new BlurRoundRectGM(100, 100);)
  82. #endif
  83. /*
  84. * Spits out a dummy gradient to test blur with shader on paint
  85. */
  86. static sk_sp<SkShader> MakeRadial() {
  87. SkPoint pts[2] = {
  88. { 0, 0 },
  89. { SkIntToScalar(100), SkIntToScalar(100) }
  90. };
  91. SkTileMode tm = SkTileMode::kClamp;
  92. const SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, };
  93. const SkScalar pos[] = { SK_Scalar1/4, SK_Scalar1*3/4 };
  94. SkMatrix scale;
  95. scale.setScale(0.5f, 0.5f);
  96. scale.postTranslate(5.f, 5.f);
  97. SkPoint center0, center1;
  98. center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
  99. SkScalarAve(pts[0].fY, pts[1].fY));
  100. center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
  101. SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
  102. return SkGradientShader::MakeTwoPointConical(center1, (pts[1].fX - pts[0].fX) / 7,
  103. center0, (pts[1].fX - pts[0].fX) / 2,
  104. colors, pos, SK_ARRAY_COUNT(colors), tm,
  105. 0, &scale);
  106. }
  107. // Simpler blurred RR test cases where all the radii are the same.
  108. class SimpleBlurRoundRectGM : public skiagm::GM {
  109. SkString onShortName() override { return SkString("simpleblurroundrect"); }
  110. SkISize onISize() override { return {1000, 500}; }
  111. void onDraw(SkCanvas* canvas) override {
  112. canvas->scale(1.5f, 1.5f);
  113. canvas->translate(50,50);
  114. const float blurRadii[] = { 1,5,10,20 };
  115. const int cornerRadii[] = { 1,5,10,20 };
  116. const SkRect r = SkRect::MakeWH(SkIntToScalar(25), SkIntToScalar(25));
  117. for (size_t i = 0; i < SK_ARRAY_COUNT(blurRadii); ++i) {
  118. SkAutoCanvasRestore autoRestore(canvas, true);
  119. canvas->translate(0, (r.height() + SkIntToScalar(50)) * i);
  120. for (size_t j = 0; j < SK_ARRAY_COUNT(cornerRadii); ++j) {
  121. for (int k = 0; k <= 1; k++) {
  122. SkPaint paint;
  123. paint.setColor(SK_ColorBLACK);
  124. paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle,
  125. SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(blurRadii[i]))));
  126. bool useRadial = SkToBool(k);
  127. if (useRadial) {
  128. paint.setShader(MakeRadial());
  129. }
  130. SkRRect rrect;
  131. rrect.setRectXY(r, SkIntToScalar(cornerRadii[j]),
  132. SkIntToScalar(cornerRadii[j]));
  133. canvas->drawRRect(rrect, paint);
  134. canvas->translate(r.width() + SkIntToScalar(50), 0);
  135. }
  136. }
  137. }
  138. }
  139. };
  140. // Create one with dimensions/rounded corners based on the skp
  141. //
  142. // TODO(scroggo): Disabled in an attempt to rememdy
  143. // https://code.google.com/p/skia/issues/detail?id=1801 ('Win7 Test bots all failing GenerateGMs:
  144. // ran wrong number of tests')
  145. //DEF_GM(return new BlurRoundRectGM(600, 5514, 6);)
  146. DEF_GM(return new SimpleBlurRoundRectGM();)