blob: 195ee738bc9ba71dad1068581a6fd6808f2a7a77 [file] [log] [blame]
commit-bot@chromium.orgc5d9bb02014-04-08 15:19:34 +00001/*
2 * Copyright 2014 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
8#include "gm.h"
9
10#include "SkBitmap.h"
11#include "SkPaint.h"
12#include "SkPicture.h"
robertphillips@google.com770963f2014-04-18 18:04:41 +000013#include "SkPictureRecorder.h"
commit-bot@chromium.orgc5d9bb02014-04-08 15:19:34 +000014#include "SkShader.h"
15
16namespace skiagm {
17
18static struct {
19 SkShader::TileMode tmx;
20 SkShader::TileMode tmy;
21} kTileConfigs[] = {
22 { SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode },
23 { SkShader::kRepeat_TileMode, SkShader::kClamp_TileMode },
24 { SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode },
25};
26
27class PictureShaderGM : public GM {
28public:
29
30 PictureShaderGM(SkScalar tileSize, SkScalar sceneSize)
31 : fTileSize(tileSize)
32 , fSceneSize(sceneSize) {
33
34 // Build the picture.
robertphillips@google.com84b18c72014-04-13 19:09:42 +000035 SkPictureRecorder recorder;
36 SkCanvas* pictureCanvas = recorder.beginRecording(SkScalarRoundToInt(tileSize),
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +000037 SkScalarRoundToInt(tileSize),
38 NULL, 0);
commit-bot@chromium.orgc5d9bb02014-04-08 15:19:34 +000039 this->drawTile(pictureCanvas);
robertphillips@google.com84b18c72014-04-13 19:09:42 +000040 SkAutoTUnref<SkPicture> p(recorder.endRecording());
commit-bot@chromium.orgc5d9bb02014-04-08 15:19:34 +000041
42 // Build a reference bitmap.
43 SkBitmap bm;
44 bm.allocN32Pixels(SkScalarRoundToInt(tileSize), SkScalarRoundToInt(tileSize));
45 bm.eraseColor(SK_ColorTRANSPARENT);
46 SkCanvas bitmapCanvas(bm);
47 this->drawTile(&bitmapCanvas);
48
49 for (unsigned i = 0; i < SK_ARRAY_COUNT(kTileConfigs); ++i) {
50 fPictureShaders[i].reset(SkShader::CreatePictureShader(p,
51 kTileConfigs[i].tmx,
52 kTileConfigs[i].tmy));
53
54 fBitmapShaders[i].reset(SkShader::CreateBitmapShader(bm,
55 kTileConfigs[i].tmx,
56 kTileConfigs[i].tmy));
57 }
58 }
59
60protected:
61 virtual SkString onShortName() SK_OVERRIDE {
62 return SkString("pictureshader");
63 }
64
65 virtual SkISize onISize() SK_OVERRIDE {
66 return SkISize::Make(1400, 1250);
67 }
68
69 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
70 this->drawSceneColumn(canvas, SkPoint::Make(0, 0), 1, 1, 0);
71 this->drawSceneColumn(canvas, SkPoint::Make(0, fSceneSize * 6.4f), 1, 2, 0);
72 this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, 0), 1, 1, 1);
73 this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, fSceneSize * 6.4f), 1, 1, 2);
74 this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 4.8f, 0), 2, 1, 0);
75 this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 9.6f, 0), 2, 2, 0);
76 }
77
78private:
79 void drawSceneColumn(SkCanvas* canvas, const SkPoint& pos, SkScalar scale, SkScalar localScale,
80 unsigned tileMode) {
81 SkMatrix ctm, localMatrix;
82
83 ctm.setTranslate(pos.x(), pos.y());
84 ctm.preScale(scale, scale);
85 localMatrix.setScale(localScale, localScale);
86 this->drawScene(canvas, ctm, localMatrix, tileMode);
87
88 ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 1.2f * scale);
89 ctm.preScale(scale, scale);
90 localMatrix.setTranslate(fTileSize / 4, fTileSize / 4);
91 localMatrix.preScale(localScale, localScale);
92 this->drawScene(canvas, ctm, localMatrix, tileMode);
93
94 ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 2.4f * scale);
95 ctm.preScale(scale, scale);
96 localMatrix.setRotate(45);
97 localMatrix.preScale(localScale, localScale);
98 this->drawScene(canvas, ctm, localMatrix, tileMode);
99
100 ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 3.6f * scale);
101 ctm.preScale(scale, scale);
102 localMatrix.setSkew(1, 0);
103 localMatrix.preScale(localScale, localScale);
104 this->drawScene(canvas, ctm, localMatrix, tileMode);
105
106 ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 4.8f * scale);
107 ctm.preScale(scale, scale);
108 localMatrix.setTranslate(fTileSize / 4, fTileSize / 4);
109 localMatrix.preRotate(45);
110 localMatrix.preScale(localScale, localScale);
111 this->drawScene(canvas, ctm, localMatrix, tileMode);
112 }
113
114 void drawTile(SkCanvas* canvas) {
115 SkPaint paint;
116 paint.setColor(SK_ColorGREEN);
117 paint.setStyle(SkPaint::kFill_Style);
118 paint.setAntiAlias(true);
119
120 canvas->drawCircle(fTileSize / 4, fTileSize / 4, fTileSize / 4, paint);
121 canvas->drawRect(SkRect::MakeXYWH(fTileSize / 2, fTileSize / 2,
122 fTileSize / 2, fTileSize / 2), paint);
123
124 paint.setColor(SK_ColorRED);
125 canvas->drawLine(fTileSize / 2, fTileSize * 1 / 3,
126 fTileSize / 2, fTileSize * 2 / 3, paint);
127 canvas->drawLine(fTileSize * 1 / 3, fTileSize / 2,
128 fTileSize * 2 / 3, fTileSize / 2, paint);
129 }
130
131 void drawScene(SkCanvas* canvas, const SkMatrix& matrix, const SkMatrix& localMatrix,
132 unsigned tileMode) {
133 SkASSERT(tileMode < SK_ARRAY_COUNT(kTileConfigs));
134
135 SkPaint paint;
136 paint.setStyle(SkPaint::kFill_Style);
137 paint.setColor(SK_ColorLTGRAY);
138
139 canvas->save();
140 canvas->concat(matrix);
141 canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
142 canvas->drawRect(SkRect::MakeXYWH(fSceneSize * 1.1f, 0, fSceneSize, fSceneSize), paint);
143
144 fPictureShaders[tileMode]->setLocalMatrix(localMatrix);
145 paint.setShader(fPictureShaders[tileMode].get());
146 canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
147
148 canvas->translate(fSceneSize * 1.1f, 0);
149
150 fBitmapShaders[tileMode]->setLocalMatrix(localMatrix);
151 paint.setShader(fBitmapShaders[tileMode].get());
152 canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
153
154 canvas->restore();
155 }
156
157 SkScalar fTileSize;
158 SkScalar fSceneSize;
159
160 SkAutoTUnref<SkShader> fPictureShaders[SK_ARRAY_COUNT(kTileConfigs)];
161 SkAutoTUnref<SkShader> fBitmapShaders[SK_ARRAY_COUNT(kTileConfigs)];
162
163 typedef GM INHERITED;
164};
165
166DEF_GM( return SkNEW_ARGS(PictureShaderGM, (50, 100)); )
167}