SampleAtlas.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * Copyright 2015 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/SkDrawable.h"
  9. #include "include/core/SkPath.h"
  10. #include "include/core/SkRSXform.h"
  11. #include "include/core/SkSurface.h"
  12. #include "include/utils/SkRandom.h"
  13. #include "include/utils/SkTextUtils.h"
  14. #include "samplecode/Sample.h"
  15. typedef void (*DrawAtlasProc)(SkCanvas*, SkImage*, const SkRSXform[], const SkRect[],
  16. const SkColor[], int, const SkRect*, const SkPaint*);
  17. static void draw_atlas(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
  18. const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
  19. const SkPaint* paint) {
  20. canvas->drawAtlas(atlas, xform, tex, colors, count, SkBlendMode::kModulate, cull, paint);
  21. }
  22. static void draw_atlas_sim(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
  23. const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
  24. const SkPaint* paint) {
  25. for (int i = 0; i < count; ++i) {
  26. SkMatrix matrix;
  27. matrix.setRSXform(xform[i]);
  28. canvas->save();
  29. canvas->concat(matrix);
  30. canvas->drawImageRect(atlas, tex[i], tex[i].makeOffset(-tex[i].x(), -tex[i].y()), paint,
  31. SkCanvas::kFast_SrcRectConstraint);
  32. canvas->restore();
  33. }
  34. }
  35. static sk_sp<SkImage> make_atlas(int atlasSize, int cellSize) {
  36. SkImageInfo info = SkImageInfo::MakeN32Premul(atlasSize, atlasSize);
  37. auto surface(SkSurface::MakeRaster(info));
  38. SkCanvas* canvas = surface->getCanvas();
  39. SkPaint paint;
  40. SkRandom rand;
  41. const SkScalar half = cellSize * SK_ScalarHalf;
  42. const char* s = "01234567890!@#$%^&*=+<>?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  43. SkFont font(nullptr, 28);
  44. int i = 0;
  45. for (int y = 0; y < atlasSize; y += cellSize) {
  46. for (int x = 0; x < atlasSize; x += cellSize) {
  47. paint.setColor(rand.nextU());
  48. paint.setAlpha(0xFF);
  49. int index = i % strlen(s);
  50. SkTextUtils::Draw(canvas, &s[index], 1, SkTextEncoding::kUTF8,
  51. x + half, y + half + half/2, font, paint,
  52. SkTextUtils::kCenter_Align);
  53. i += 1;
  54. }
  55. }
  56. return surface->makeImageSnapshot();
  57. }
  58. class DrawAtlasDrawable : public SkDrawable {
  59. enum {
  60. kMaxScale = 2,
  61. kCellSize = 32,
  62. kAtlasSize = 512,
  63. };
  64. struct Rec {
  65. SkPoint fCenter;
  66. SkVector fVelocity;
  67. SkScalar fScale;
  68. SkScalar fDScale;
  69. SkScalar fRadian;
  70. SkScalar fDRadian;
  71. SkScalar fAlpha;
  72. SkScalar fDAlpha;
  73. void advance(const SkRect& bounds) {
  74. fCenter += fVelocity;
  75. if (fCenter.fX > bounds.right()) {
  76. SkASSERT(fVelocity.fX > 0);
  77. fVelocity.fX = -fVelocity.fX;
  78. } else if (fCenter.fX < bounds.left()) {
  79. SkASSERT(fVelocity.fX < 0);
  80. fVelocity.fX = -fVelocity.fX;
  81. }
  82. if (fCenter.fY > bounds.bottom()) {
  83. if (fVelocity.fY > 0) {
  84. fVelocity.fY = -fVelocity.fY;
  85. }
  86. } else if (fCenter.fY < bounds.top()) {
  87. if (fVelocity.fY < 0) {
  88. fVelocity.fY = -fVelocity.fY;
  89. }
  90. }
  91. fScale += fDScale;
  92. if (fScale > 2 || fScale < SK_Scalar1/2) {
  93. fDScale = -fDScale;
  94. }
  95. fRadian += fDRadian;
  96. fRadian = SkScalarMod(fRadian, 2 * SK_ScalarPI);
  97. fAlpha += fDAlpha;
  98. if (fAlpha > 1) {
  99. fAlpha = 1;
  100. fDAlpha = -fDAlpha;
  101. } else if (fAlpha < 0) {
  102. fAlpha = 0;
  103. fDAlpha = -fDAlpha;
  104. }
  105. }
  106. SkRSXform asRSXform() const {
  107. return SkRSXform::MakeFromRadians(fScale, fRadian, fCenter.x(), fCenter.y(),
  108. SkScalarHalf(kCellSize), SkScalarHalf(kCellSize));
  109. }
  110. };
  111. DrawAtlasProc fProc;
  112. enum {
  113. N = 256,
  114. };
  115. sk_sp<SkImage> fAtlas;
  116. Rec fRec[N];
  117. SkRect fTex[N];
  118. SkRect fBounds;
  119. bool fUseColors;
  120. public:
  121. DrawAtlasDrawable(DrawAtlasProc proc, const SkRect& r)
  122. : fProc(proc), fBounds(r), fUseColors(false)
  123. {
  124. SkRandom rand;
  125. fAtlas = make_atlas(kAtlasSize, kCellSize);
  126. const SkScalar kMaxSpeed = 5;
  127. const SkScalar cell = SkIntToScalar(kCellSize);
  128. int i = 0;
  129. for (int y = 0; y < kAtlasSize; y += kCellSize) {
  130. for (int x = 0; x < kAtlasSize; x += kCellSize) {
  131. const SkScalar sx = SkIntToScalar(x);
  132. const SkScalar sy = SkIntToScalar(y);
  133. fTex[i].setXYWH(sx, sy, cell, cell);
  134. fRec[i].fCenter.set(sx + cell/2, sy + 3*cell/4);
  135. fRec[i].fVelocity.fX = rand.nextSScalar1() * kMaxSpeed;
  136. fRec[i].fVelocity.fY = rand.nextSScalar1() * kMaxSpeed;
  137. fRec[i].fScale = 1;
  138. fRec[i].fDScale = rand.nextSScalar1() / 16;
  139. fRec[i].fRadian = 0;
  140. fRec[i].fDRadian = rand.nextSScalar1() / 8;
  141. fRec[i].fAlpha = rand.nextUScalar1();
  142. fRec[i].fDAlpha = rand.nextSScalar1() / 10;
  143. i += 1;
  144. }
  145. }
  146. }
  147. void toggleUseColors() {
  148. fUseColors = !fUseColors;
  149. }
  150. protected:
  151. void onDraw(SkCanvas* canvas) override {
  152. SkRSXform xform[N];
  153. SkColor colors[N];
  154. for (int i = 0; i < N; ++i) {
  155. fRec[i].advance(fBounds);
  156. xform[i] = fRec[i].asRSXform();
  157. if (fUseColors) {
  158. colors[i] = SkColorSetARGB((int)(fRec[i].fAlpha * 0xFF), 0xFF, 0xFF, 0xFF);
  159. }
  160. }
  161. SkPaint paint;
  162. paint.setFilterQuality(kLow_SkFilterQuality);
  163. const SkRect cull = this->getBounds();
  164. const SkColor* colorsPtr = fUseColors ? colors : nullptr;
  165. fProc(canvas, fAtlas.get(), xform, fTex, colorsPtr, N, &cull, &paint);
  166. }
  167. SkRect onGetBounds() override {
  168. const SkScalar border = kMaxScale * kCellSize;
  169. SkRect r = fBounds;
  170. r.outset(border, border);
  171. return r;
  172. }
  173. private:
  174. typedef SkDrawable INHERITED;
  175. };
  176. class DrawAtlasView : public Sample {
  177. const char* fName;
  178. DrawAtlasProc fProc;
  179. sk_sp<DrawAtlasDrawable> fDrawable;
  180. public:
  181. DrawAtlasView(const char name[], DrawAtlasProc proc) : fName(name), fProc(proc) { }
  182. protected:
  183. SkString name() override { return SkString(fName); }
  184. bool onChar(SkUnichar uni) override {
  185. switch (uni) {
  186. case 'C': fDrawable->toggleUseColors(); return true;
  187. default: break;
  188. }
  189. return false;
  190. }
  191. void onOnceBeforeDraw() override {
  192. fDrawable = sk_make_sp<DrawAtlasDrawable>(fProc, SkRect::MakeWH(640, 480));
  193. }
  194. void onDrawContent(SkCanvas* canvas) override {
  195. canvas->drawDrawable(fDrawable.get());
  196. }
  197. bool onAnimate(double /*nanos*/) override { return true; }
  198. #if 0
  199. // TODO: switch over to use this for our animation
  200. bool onAnimate(double nanos) override {
  201. SkScalar angle = SkDoubleToScalar(fmod(1e-9 * nanos * 360 / 24, 360));
  202. fAnimatingDrawable->setSweep(angle);
  203. return true;
  204. }
  205. #endif
  206. private:
  207. typedef Sample INHERITED;
  208. };
  209. //////////////////////////////////////////////////////////////////////////////
  210. DEF_SAMPLE( return new DrawAtlasView("DrawAtlas", draw_atlas); )
  211. DEF_SAMPLE( return new DrawAtlasView("DrawAtlasSim", draw_atlas_sim); )