1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2014 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #include "gm/gm.h" 9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h" 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPicture.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPictureRecorder.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h" 20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkShader.h" 21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h" 22*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h" 23*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTextBlob.h" 24*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTileMode.h" 25*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h" 26*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h" 27*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h" 28*c8dee2aaSAndroid Build Coastguard Worker 29*c8dee2aaSAndroid Build Coastguard Worker static struct { 30*c8dee2aaSAndroid Build Coastguard Worker SkTileMode tmx; 31*c8dee2aaSAndroid Build Coastguard Worker SkTileMode tmy; 32*c8dee2aaSAndroid Build Coastguard Worker } kTileConfigs[] = { 33*c8dee2aaSAndroid Build Coastguard Worker { SkTileMode::kRepeat, SkTileMode::kRepeat }, 34*c8dee2aaSAndroid Build Coastguard Worker { SkTileMode::kRepeat, SkTileMode::kClamp }, 35*c8dee2aaSAndroid Build Coastguard Worker { SkTileMode::kMirror, SkTileMode::kRepeat }, 36*c8dee2aaSAndroid Build Coastguard Worker }; 37*c8dee2aaSAndroid Build Coastguard Worker 38*c8dee2aaSAndroid Build Coastguard Worker class PictureShaderGM : public skiagm::GM { 39*c8dee2aaSAndroid Build Coastguard Worker public: PictureShaderGM(SkScalar tileSize,SkScalar sceneSize,bool useLocalMatrixWrapper=false,float alpha=1)40*c8dee2aaSAndroid Build Coastguard Worker PictureShaderGM(SkScalar tileSize, SkScalar sceneSize, bool useLocalMatrixWrapper = false, 41*c8dee2aaSAndroid Build Coastguard Worker float alpha = 1) 42*c8dee2aaSAndroid Build Coastguard Worker : fTileSize(tileSize) 43*c8dee2aaSAndroid Build Coastguard Worker , fSceneSize(sceneSize) 44*c8dee2aaSAndroid Build Coastguard Worker , fAlpha(alpha) 45*c8dee2aaSAndroid Build Coastguard Worker , fUseLocalMatrixWrapper(useLocalMatrixWrapper) 46*c8dee2aaSAndroid Build Coastguard Worker {} 47*c8dee2aaSAndroid Build Coastguard Worker 48*c8dee2aaSAndroid Build Coastguard Worker protected: onOnceBeforeDraw()49*c8dee2aaSAndroid Build Coastguard Worker void onOnceBeforeDraw() override { 50*c8dee2aaSAndroid Build Coastguard Worker // Build the picture. 51*c8dee2aaSAndroid Build Coastguard Worker SkPictureRecorder recorder; 52*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* pictureCanvas = recorder.beginRecording(fTileSize, fTileSize); 53*c8dee2aaSAndroid Build Coastguard Worker this->drawTile(pictureCanvas); 54*c8dee2aaSAndroid Build Coastguard Worker fPicture = recorder.finishRecordingAsPicture(); 55*c8dee2aaSAndroid Build Coastguard Worker 56*c8dee2aaSAndroid Build Coastguard Worker // Build a reference bitmap. 57*c8dee2aaSAndroid Build Coastguard Worker fBitmap.allocN32Pixels(SkScalarCeilToInt(fTileSize), SkScalarCeilToInt(fTileSize)); 58*c8dee2aaSAndroid Build Coastguard Worker fBitmap.eraseColor(SK_ColorTRANSPARENT); 59*c8dee2aaSAndroid Build Coastguard Worker SkCanvas bitmapCanvas(fBitmap); 60*c8dee2aaSAndroid Build Coastguard Worker this->drawTile(&bitmapCanvas); 61*c8dee2aaSAndroid Build Coastguard Worker } 62*c8dee2aaSAndroid Build Coastguard Worker getName() const63*c8dee2aaSAndroid Build Coastguard Worker SkString getName() const override { 64*c8dee2aaSAndroid Build Coastguard Worker return SkStringPrintf("pictureshader%s%s", 65*c8dee2aaSAndroid Build Coastguard Worker fUseLocalMatrixWrapper ? "_localwrapper" : "", 66*c8dee2aaSAndroid Build Coastguard Worker fAlpha < 1 ? "_alpha" : ""); 67*c8dee2aaSAndroid Build Coastguard Worker } 68*c8dee2aaSAndroid Build Coastguard Worker getISize()69*c8dee2aaSAndroid Build Coastguard Worker SkISize getISize() override { return SkISize::Make(1400, 1450); } 70*c8dee2aaSAndroid Build Coastguard Worker onDraw(SkCanvas * canvas)71*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas* canvas) override { 72*c8dee2aaSAndroid Build Coastguard Worker this->drawSceneColumn(canvas, SkPoint::Make(0, 0), 1, 1, 0); 73*c8dee2aaSAndroid Build Coastguard Worker this->drawSceneColumn(canvas, SkPoint::Make(0, fSceneSize * 6.4f), 1, 2, 0); 74*c8dee2aaSAndroid Build Coastguard Worker this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, 0), 1, 1, 1); 75*c8dee2aaSAndroid Build Coastguard Worker this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, fSceneSize * 6.4f), 1, 1, 2); 76*c8dee2aaSAndroid Build Coastguard Worker this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 4.8f, 0), 2, 1, 0); 77*c8dee2aaSAndroid Build Coastguard Worker this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 9.6f, 0), 2, 2, 0); 78*c8dee2aaSAndroid Build Coastguard Worker 79*c8dee2aaSAndroid Build Coastguard Worker // One last custom row to exercise negative scaling 80*c8dee2aaSAndroid Build Coastguard Worker SkMatrix ctm, localMatrix; 81*c8dee2aaSAndroid Build Coastguard Worker ctm.setTranslate(fSceneSize * 2.1f, fSceneSize * 13.8f); 82*c8dee2aaSAndroid Build Coastguard Worker ctm.preScale(-1, -1); 83*c8dee2aaSAndroid Build Coastguard Worker localMatrix.setScale(2, 2); 84*c8dee2aaSAndroid Build Coastguard Worker this->drawScene(canvas, ctm, localMatrix, 0); 85*c8dee2aaSAndroid Build Coastguard Worker 86*c8dee2aaSAndroid Build Coastguard Worker ctm.setTranslate(fSceneSize * 2.4f, fSceneSize * 12.8f); 87*c8dee2aaSAndroid Build Coastguard Worker localMatrix.setScale(-1, -1); 88*c8dee2aaSAndroid Build Coastguard Worker this->drawScene(canvas, ctm, localMatrix, 0); 89*c8dee2aaSAndroid Build Coastguard Worker 90*c8dee2aaSAndroid Build Coastguard Worker ctm.setTranslate(fSceneSize * 4.8f, fSceneSize * 12.3f); 91*c8dee2aaSAndroid Build Coastguard Worker ctm.preScale(2, 2); 92*c8dee2aaSAndroid Build Coastguard Worker this->drawScene(canvas, ctm, localMatrix, 0); 93*c8dee2aaSAndroid Build Coastguard Worker 94*c8dee2aaSAndroid Build Coastguard Worker ctm.setTranslate(fSceneSize * 13.8f, fSceneSize * 14.3f); 95*c8dee2aaSAndroid Build Coastguard Worker ctm.preScale(-2, -2); 96*c8dee2aaSAndroid Build Coastguard Worker localMatrix.setTranslate(fTileSize / 4, fTileSize / 4); 97*c8dee2aaSAndroid Build Coastguard Worker localMatrix.preRotate(45); 98*c8dee2aaSAndroid Build Coastguard Worker localMatrix.preScale(-2, -2); 99*c8dee2aaSAndroid Build Coastguard Worker this->drawScene(canvas, ctm, localMatrix, 0); 100*c8dee2aaSAndroid Build Coastguard Worker } 101*c8dee2aaSAndroid Build Coastguard Worker 102*c8dee2aaSAndroid Build Coastguard Worker private: drawSceneColumn(SkCanvas * canvas,const SkPoint & pos,SkScalar scale,SkScalar localScale,unsigned tileMode)103*c8dee2aaSAndroid Build Coastguard Worker void drawSceneColumn(SkCanvas* canvas, const SkPoint& pos, SkScalar scale, SkScalar localScale, 104*c8dee2aaSAndroid Build Coastguard Worker unsigned tileMode) { 105*c8dee2aaSAndroid Build Coastguard Worker SkMatrix ctm, localMatrix; 106*c8dee2aaSAndroid Build Coastguard Worker 107*c8dee2aaSAndroid Build Coastguard Worker ctm.setTranslate(pos.x(), pos.y()); 108*c8dee2aaSAndroid Build Coastguard Worker ctm.preScale(scale, scale); 109*c8dee2aaSAndroid Build Coastguard Worker localMatrix.setScale(localScale, localScale); 110*c8dee2aaSAndroid Build Coastguard Worker this->drawScene(canvas, ctm, localMatrix, tileMode); 111*c8dee2aaSAndroid Build Coastguard Worker 112*c8dee2aaSAndroid Build Coastguard Worker ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 1.2f * scale); 113*c8dee2aaSAndroid Build Coastguard Worker ctm.preScale(scale, scale); 114*c8dee2aaSAndroid Build Coastguard Worker localMatrix.setTranslate(fTileSize / 4, fTileSize / 4); 115*c8dee2aaSAndroid Build Coastguard Worker localMatrix.preScale(localScale, localScale); 116*c8dee2aaSAndroid Build Coastguard Worker this->drawScene(canvas, ctm, localMatrix, tileMode); 117*c8dee2aaSAndroid Build Coastguard Worker 118*c8dee2aaSAndroid Build Coastguard Worker ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 2.4f * scale); 119*c8dee2aaSAndroid Build Coastguard Worker ctm.preScale(scale, scale); 120*c8dee2aaSAndroid Build Coastguard Worker localMatrix.setRotate(45); 121*c8dee2aaSAndroid Build Coastguard Worker localMatrix.preScale(localScale, localScale); 122*c8dee2aaSAndroid Build Coastguard Worker this->drawScene(canvas, ctm, localMatrix, tileMode); 123*c8dee2aaSAndroid Build Coastguard Worker 124*c8dee2aaSAndroid Build Coastguard Worker ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 3.6f * scale); 125*c8dee2aaSAndroid Build Coastguard Worker ctm.preScale(scale, scale); 126*c8dee2aaSAndroid Build Coastguard Worker localMatrix.setSkew(1, 0); 127*c8dee2aaSAndroid Build Coastguard Worker localMatrix.preScale(localScale, localScale); 128*c8dee2aaSAndroid Build Coastguard Worker this->drawScene(canvas, ctm, localMatrix, tileMode); 129*c8dee2aaSAndroid Build Coastguard Worker 130*c8dee2aaSAndroid Build Coastguard Worker ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 4.8f * scale); 131*c8dee2aaSAndroid Build Coastguard Worker ctm.preScale(scale, scale); 132*c8dee2aaSAndroid Build Coastguard Worker localMatrix.setTranslate(fTileSize / 4, fTileSize / 4); 133*c8dee2aaSAndroid Build Coastguard Worker localMatrix.preRotate(45); 134*c8dee2aaSAndroid Build Coastguard Worker localMatrix.preScale(localScale, localScale); 135*c8dee2aaSAndroid Build Coastguard Worker this->drawScene(canvas, ctm, localMatrix, tileMode); 136*c8dee2aaSAndroid Build Coastguard Worker } 137*c8dee2aaSAndroid Build Coastguard Worker drawTile(SkCanvas * canvas)138*c8dee2aaSAndroid Build Coastguard Worker void drawTile(SkCanvas* canvas) { 139*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 140*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorGREEN); 141*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kFill_Style); 142*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 143*c8dee2aaSAndroid Build Coastguard Worker 144*c8dee2aaSAndroid Build Coastguard Worker canvas->drawCircle(fTileSize / 4, fTileSize / 4, fTileSize / 4, paint); 145*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(SkRect::MakeXYWH(fTileSize / 2, fTileSize / 2, 146*c8dee2aaSAndroid Build Coastguard Worker fTileSize / 2, fTileSize / 2), paint); 147*c8dee2aaSAndroid Build Coastguard Worker 148*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorRED); 149*c8dee2aaSAndroid Build Coastguard Worker canvas->drawLine(fTileSize / 2, fTileSize * 1 / 3, 150*c8dee2aaSAndroid Build Coastguard Worker fTileSize / 2, fTileSize * 2 / 3, paint); 151*c8dee2aaSAndroid Build Coastguard Worker canvas->drawLine(fTileSize * 1 / 3, fTileSize / 2, 152*c8dee2aaSAndroid Build Coastguard Worker fTileSize * 2 / 3, fTileSize / 2, paint); 153*c8dee2aaSAndroid Build Coastguard Worker } 154*c8dee2aaSAndroid Build Coastguard Worker drawScene(SkCanvas * canvas,const SkMatrix & matrix,const SkMatrix & localMatrix,unsigned tileMode)155*c8dee2aaSAndroid Build Coastguard Worker void drawScene(SkCanvas* canvas, const SkMatrix& matrix, const SkMatrix& localMatrix, 156*c8dee2aaSAndroid Build Coastguard Worker unsigned tileMode) { 157*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(tileMode < std::size(kTileConfigs)); 158*c8dee2aaSAndroid Build Coastguard Worker 159*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 160*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kFill_Style); 161*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorLTGRAY); 162*c8dee2aaSAndroid Build Coastguard Worker 163*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 164*c8dee2aaSAndroid Build Coastguard Worker canvas->concat(matrix); 165*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint); 166*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(SkRect::MakeXYWH(fSceneSize * 1.1f, 0, fSceneSize, fSceneSize), paint); 167*c8dee2aaSAndroid Build Coastguard Worker 168*c8dee2aaSAndroid Build Coastguard Worker paint.setAlphaf(fAlpha); 169*c8dee2aaSAndroid Build Coastguard Worker 170*c8dee2aaSAndroid Build Coastguard Worker auto pictureShader = fPicture->makeShader(kTileConfigs[tileMode].tmx, 171*c8dee2aaSAndroid Build Coastguard Worker kTileConfigs[tileMode].tmy, 172*c8dee2aaSAndroid Build Coastguard Worker SkFilterMode::kNearest, 173*c8dee2aaSAndroid Build Coastguard Worker fUseLocalMatrixWrapper ? nullptr : &localMatrix, 174*c8dee2aaSAndroid Build Coastguard Worker nullptr); 175*c8dee2aaSAndroid Build Coastguard Worker paint.setShader(fUseLocalMatrixWrapper 176*c8dee2aaSAndroid Build Coastguard Worker ? pictureShader->makeWithLocalMatrix(localMatrix) 177*c8dee2aaSAndroid Build Coastguard Worker : pictureShader); 178*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint); 179*c8dee2aaSAndroid Build Coastguard Worker 180*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(fSceneSize * 1.1f, 0); 181*c8dee2aaSAndroid Build Coastguard Worker 182*c8dee2aaSAndroid Build Coastguard Worker auto bitmapShader = fBitmap.makeShader(kTileConfigs[tileMode].tmx, 183*c8dee2aaSAndroid Build Coastguard Worker kTileConfigs[tileMode].tmy, 184*c8dee2aaSAndroid Build Coastguard Worker SkSamplingOptions(), 185*c8dee2aaSAndroid Build Coastguard Worker fUseLocalMatrixWrapper ? nullptr : &localMatrix); 186*c8dee2aaSAndroid Build Coastguard Worker paint.setShader(fUseLocalMatrixWrapper 187*c8dee2aaSAndroid Build Coastguard Worker ? bitmapShader->makeWithLocalMatrix(localMatrix) 188*c8dee2aaSAndroid Build Coastguard Worker : bitmapShader); 189*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint); 190*c8dee2aaSAndroid Build Coastguard Worker 191*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 192*c8dee2aaSAndroid Build Coastguard Worker } 193*c8dee2aaSAndroid Build Coastguard Worker 194*c8dee2aaSAndroid Build Coastguard Worker const SkScalar fTileSize; 195*c8dee2aaSAndroid Build Coastguard Worker const SkScalar fSceneSize; 196*c8dee2aaSAndroid Build Coastguard Worker const float fAlpha; 197*c8dee2aaSAndroid Build Coastguard Worker const bool fUseLocalMatrixWrapper; 198*c8dee2aaSAndroid Build Coastguard Worker 199*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPicture> fPicture; 200*c8dee2aaSAndroid Build Coastguard Worker SkBitmap fBitmap; 201*c8dee2aaSAndroid Build Coastguard Worker 202*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = GM; 203*c8dee2aaSAndroid Build Coastguard Worker }; 204*c8dee2aaSAndroid Build Coastguard Worker 205*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new PictureShaderGM(50, 100);) 206*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new PictureShaderGM(50, 100, true);) 207*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new PictureShaderGM(50, 100, false, 0.25f);) 208*c8dee2aaSAndroid Build Coastguard Worker 209*c8dee2aaSAndroid Build Coastguard Worker DEF_SIMPLE_GM(tiled_picture_shader, canvas, 400, 400) { 210*c8dee2aaSAndroid Build Coastguard Worker // https://code.google.com/p/skia/issues/detail?id=3398 211*c8dee2aaSAndroid Build Coastguard Worker SkRect tile = SkRect::MakeWH(100, 100); 212*c8dee2aaSAndroid Build Coastguard Worker 213*c8dee2aaSAndroid Build Coastguard Worker SkPictureRecorder recorder; 214*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* c = recorder.beginRecording(tile); 215*c8dee2aaSAndroid Build Coastguard Worker 216*c8dee2aaSAndroid Build Coastguard Worker SkRect r = tile; 217*c8dee2aaSAndroid Build Coastguard Worker r.inset(4, 4); 218*c8dee2aaSAndroid Build Coastguard Worker SkPaint p; 219*c8dee2aaSAndroid Build Coastguard Worker p.setColor(ToolUtils::color_to_565(0xFF303F9F)); // dark blue 220*c8dee2aaSAndroid Build Coastguard Worker c->drawRect(r, p); 221*c8dee2aaSAndroid Build Coastguard Worker p.setColor(ToolUtils::color_to_565(0xFFC5CAE9)); // light blue 222*c8dee2aaSAndroid Build Coastguard Worker p.setStrokeWidth(10); 223*c8dee2aaSAndroid Build Coastguard Worker c->drawLine(20, 20, 80, 80, p); 224*c8dee2aaSAndroid Build Coastguard Worker 225*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 226*c8dee2aaSAndroid Build Coastguard Worker 227*c8dee2aaSAndroid Build Coastguard Worker p.setColor(ToolUtils::color_to_565(0xFF8BC34A)); // green 228*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPaint(p); 229*c8dee2aaSAndroid Build Coastguard Worker 230*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRect(SkRect::MakeXYWH(0, 0, 400, 350)); 231*c8dee2aaSAndroid Build Coastguard Worker p.setColor(0xFFB6B6B6); // gray 232*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPaint(p); 233*c8dee2aaSAndroid Build Coastguard Worker 234*c8dee2aaSAndroid Build Coastguard Worker p.setShader(picture->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, 235*c8dee2aaSAndroid Build Coastguard Worker SkFilterMode::kNearest)); 236*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPaint(p); 237*c8dee2aaSAndroid Build Coastguard Worker } 238*c8dee2aaSAndroid Build Coastguard Worker 239*c8dee2aaSAndroid Build Coastguard Worker DEF_SIMPLE_GM(pictureshader_persp, canvas, 215, 110) { 240*c8dee2aaSAndroid Build Coastguard Worker enum class DrawStrategy { 241*c8dee2aaSAndroid Build Coastguard Worker kDirect, 242*c8dee2aaSAndroid Build Coastguard Worker kPictureShader, 243*c8dee2aaSAndroid Build Coastguard Worker }; 244*c8dee2aaSAndroid Build Coastguard Worker __anon510b76250202(SkCanvas* canvas, sk_sp<SkPicture> picture, DrawStrategy strategy) 245*c8dee2aaSAndroid Build Coastguard Worker auto drawPicture = [](SkCanvas* canvas, sk_sp<SkPicture> picture, DrawStrategy strategy) { 246*c8dee2aaSAndroid Build Coastguard Worker // Only want local upper 50x50 of 'picture' before we apply decal (or clip) 247*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds = {0.f, 0.f, 50.f, 50.f}; 248*c8dee2aaSAndroid Build Coastguard Worker switch(strategy) { 249*c8dee2aaSAndroid Build Coastguard Worker case DrawStrategy::kDirect: { 250*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRect(bounds, true); 251*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPicture(picture); 252*c8dee2aaSAndroid Build Coastguard Worker break; } 253*c8dee2aaSAndroid Build Coastguard Worker case DrawStrategy::kPictureShader: { 254*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 255*c8dee2aaSAndroid Build Coastguard Worker paint.setShader(picture->makeShader(SkTileMode::kDecal, SkTileMode::kDecal, 256*c8dee2aaSAndroid Build Coastguard Worker SkFilterMode::kLinear, nullptr, &bounds)); 257*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect({0.f, 0.f, 50.f, 50.f}, paint); 258*c8dee2aaSAndroid Build Coastguard Worker break; } 259*c8dee2aaSAndroid Build Coastguard Worker } 260*c8dee2aaSAndroid Build Coastguard Worker }; 261*c8dee2aaSAndroid Build Coastguard Worker __anon510b76250302() 262*c8dee2aaSAndroid Build Coastguard Worker auto picture = []() { 263*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> typeface = ToolUtils::DefaultPortableTypeface(); 264*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(typeface); 265*c8dee2aaSAndroid Build Coastguard Worker SkFont font; 266*c8dee2aaSAndroid Build Coastguard Worker font.setTypeface(typeface); 267*c8dee2aaSAndroid Build Coastguard Worker font.setHinting(SkFontHinting::kNormal); 268*c8dee2aaSAndroid Build Coastguard Worker font.setSize(8.f); 269*c8dee2aaSAndroid Build Coastguard Worker 270*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 271*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorGREEN); 272*c8dee2aaSAndroid Build Coastguard Worker SkPictureRecorder recorder; 273*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* record_canvas = recorder.beginRecording({0, 0, 100, 100}); 274*c8dee2aaSAndroid Build Coastguard Worker record_canvas->drawTextBlob(SkTextBlob::MakeFromString("Hamburgefons", font), 275*c8dee2aaSAndroid Build Coastguard Worker 0, 16.f, paint); 276*c8dee2aaSAndroid Build Coastguard Worker return recorder.finishRecordingAsPicture(); 277*c8dee2aaSAndroid Build Coastguard Worker }(); 278*c8dee2aaSAndroid Build Coastguard Worker 279*c8dee2aaSAndroid Build Coastguard Worker SkM44 m; 280*c8dee2aaSAndroid Build Coastguard Worker m.preScale(2.f, 2.f); 281*c8dee2aaSAndroid Build Coastguard Worker SkM44 persp = SkM44::Perspective(0.01f, 10.f, SK_ScalarPI / 3.f); 282*c8dee2aaSAndroid Build Coastguard Worker persp.preTranslate(0.f, 5.f, -0.1f); 283*c8dee2aaSAndroid Build Coastguard Worker persp.preConcat(SkM44::Rotate({0.f, 1.f, 0.f}, 0.008f)); 284*c8dee2aaSAndroid Build Coastguard Worker m.postConcat(persp); 285*c8dee2aaSAndroid Build Coastguard Worker 286*c8dee2aaSAndroid Build Coastguard Worker canvas->clear(SK_ColorBLACK); 287*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(5.f, 5.f); 288*c8dee2aaSAndroid Build Coastguard Worker for (auto strategy : { DrawStrategy::kDirect, 289*c8dee2aaSAndroid Build Coastguard Worker DrawStrategy::kPictureShader }) { 290*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 291*c8dee2aaSAndroid Build Coastguard Worker 292*c8dee2aaSAndroid Build Coastguard Worker SkPaint outline; 293*c8dee2aaSAndroid Build Coastguard Worker outline.setColor(SK_ColorWHITE); 294*c8dee2aaSAndroid Build Coastguard Worker outline.setStyle(SkPaint::kStroke_Style); 295*c8dee2aaSAndroid Build Coastguard Worker outline.setStrokeWidth(1.f); 296*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect({-1, -1, 101, 101}, outline); 297*c8dee2aaSAndroid Build Coastguard Worker 298*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRect({0, 0, 100, 100}); 299*c8dee2aaSAndroid Build Coastguard Worker canvas->concat(m); 300*c8dee2aaSAndroid Build Coastguard Worker 301*c8dee2aaSAndroid Build Coastguard Worker drawPicture(canvas, picture, strategy); 302*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 303*c8dee2aaSAndroid Build Coastguard Worker 304*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(105.f, 0.f); 305*c8dee2aaSAndroid Build Coastguard Worker } 306*c8dee2aaSAndroid Build Coastguard Worker } 307