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