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