SampleShadowReference.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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 "include/core/SkCanvas.h"
  8. #include "include/core/SkImage.h"
  9. #include "include/core/SkPath.h"
  10. #include "include/core/SkPoint3.h"
  11. #include "include/utils/SkShadowUtils.h"
  12. #include "samplecode/Sample.h"
  13. #include "tools/Resources.h"
  14. ////////////////////////////////////////////////////////////////////////////
  15. // Sample to compare the Material Design shadow reference to our results
  16. class ShadowRefView : public Sample {
  17. SkPath fRRectPath;
  18. sk_sp<SkImage> fReferenceImage;
  19. bool fShowAmbient;
  20. bool fShowSpot;
  21. bool fUseAlt;
  22. bool fShowObject;
  23. public:
  24. ShadowRefView()
  25. : fShowAmbient(true)
  26. , fShowSpot(true)
  27. , fUseAlt(false)
  28. , fShowObject(true) {}
  29. protected:
  30. void onOnceBeforeDraw() override {
  31. fRRectPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-130, -128.5, 130, 128.5), 4, 4));
  32. fReferenceImage = GetResourceAsImage("images/shadowreference.png");
  33. }
  34. SkString name() override { return SkString("ShadowReference"); }
  35. bool onChar(SkUnichar uni) override {
  36. bool handled = false;
  37. switch (uni) {
  38. case 'W':
  39. fShowAmbient = !fShowAmbient;
  40. handled = true;
  41. break;
  42. case 'S':
  43. fShowSpot = !fShowSpot;
  44. handled = true;
  45. break;
  46. case 'T':
  47. fUseAlt = !fUseAlt;
  48. handled = true;
  49. break;
  50. case 'O':
  51. fShowObject = !fShowObject;
  52. handled = true;
  53. break;
  54. default:
  55. break;
  56. }
  57. if (handled) {
  58. return true;
  59. }
  60. return false;
  61. }
  62. void drawBG(SkCanvas* canvas) {
  63. canvas->drawColor(0xFFFFFFFF);
  64. canvas->drawImage(fReferenceImage, 10, 30);
  65. }
  66. void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
  67. const SkPoint3& zPlaneParams,
  68. const SkPaint& paint, SkScalar ambientAlpha,
  69. const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
  70. if (!fShowAmbient) {
  71. ambientAlpha = 0;
  72. }
  73. if (!fShowSpot) {
  74. spotAlpha = 0;
  75. }
  76. uint32_t flags = 0;
  77. if (fUseAlt) {
  78. flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
  79. }
  80. SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0);
  81. SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
  82. SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
  83. lightPos, lightWidth,
  84. ambientColor, spotColor, flags);
  85. if (fShowObject) {
  86. canvas->drawPath(path, paint);
  87. } else {
  88. SkPaint strokePaint;
  89. strokePaint.setColor(paint.getColor());
  90. strokePaint.setStyle(SkPaint::kStroke_Style);
  91. canvas->drawPath(path, strokePaint);
  92. }
  93. }
  94. void onDrawContent(SkCanvas* canvas) override {
  95. this->drawBG(canvas);
  96. const SkScalar kDP = 4; // the reference image is 4x bigger than it is displayed on
  97. // on the web page, so we need to reflect that here and
  98. // multiply the heights and light params accordingly
  99. const SkScalar kLightWidth = kDP*400;
  100. const SkScalar kAmbientAlpha = 0.03f;
  101. const SkScalar kSpotAlpha = 0.35f;
  102. SkPaint paint;
  103. paint.setAntiAlias(true);
  104. paint.setColor(SK_ColorWHITE);
  105. SkPoint3 lightPos = { 175, -800, kDP * 600 };
  106. SkScalar xPos = 230;
  107. SkScalar yPos = 254.25f;
  108. SkRect clipRect = SkRect::MakeXYWH(45, 75, 122, 250);
  109. SkPoint clipDelta = SkPoint::Make(320, 0);
  110. SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, kDP * 2);
  111. canvas->save();
  112. canvas->clipRect(clipRect);
  113. canvas->translate(xPos, yPos);
  114. this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
  115. lightPos, kLightWidth, kSpotAlpha);
  116. canvas->restore();
  117. lightPos.fX += 320;
  118. xPos += 320;
  119. clipRect.offset(clipDelta);
  120. zPlaneParams.fZ = kDP * 3;
  121. canvas->save();
  122. canvas->clipRect(clipRect);
  123. canvas->translate(xPos, yPos);
  124. this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
  125. lightPos, kLightWidth, kSpotAlpha);
  126. canvas->restore();
  127. lightPos.fX += 320;
  128. xPos += 320;
  129. clipRect.offset(clipDelta);
  130. zPlaneParams.fZ = kDP * 4;
  131. canvas->save();
  132. canvas->clipRect(clipRect);
  133. canvas->translate(xPos, yPos);
  134. this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
  135. lightPos, kLightWidth, kSpotAlpha);
  136. canvas->restore();
  137. lightPos.fX += 320;
  138. xPos += 320;
  139. clipRect.offset(clipDelta);
  140. zPlaneParams.fZ = kDP * 6;
  141. canvas->save();
  142. canvas->clipRect(clipRect);
  143. canvas->translate(xPos, yPos);
  144. this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
  145. lightPos, kLightWidth, kSpotAlpha);
  146. canvas->restore();
  147. lightPos.fX += 320;
  148. xPos += 320;
  149. clipRect.offset(clipDelta);
  150. zPlaneParams.fZ = kDP * 8;
  151. canvas->save();
  152. canvas->clipRect(clipRect);
  153. canvas->translate(xPos, yPos);
  154. this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
  155. lightPos, kLightWidth, kSpotAlpha);
  156. canvas->restore();
  157. lightPos.fX += 320;
  158. xPos += 320;
  159. clipRect.offset(clipDelta);
  160. zPlaneParams.fZ = kDP * 16;
  161. canvas->save();
  162. canvas->clipRect(clipRect);
  163. canvas->translate(xPos, yPos);
  164. this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
  165. lightPos, kLightWidth, kSpotAlpha);
  166. canvas->restore();
  167. }
  168. private:
  169. typedef Sample INHERITED;
  170. };
  171. //////////////////////////////////////////////////////////////////////////////
  172. DEF_SAMPLE( return new ShadowRefView(); )