diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-04-08 15:19:34 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-04-08 15:19:34 +0000 |
commit | c5d9bb0f677069f62ec76373b9730e70e7352455 (patch) | |
tree | 675c12cf12966ea1b37d06d9c5e0416b1ca7be79 /gm/pictureshader.cpp | |
parent | 03a99b8f96b56d3349fa7b6832638e3b9830d169 (diff) |
Initial picture shader implementation
This CL adds an SkPictureShader class to support SkPicture-based
patterns.
The implementation renders the picture into an SkBitmap tile and then
delegates to SkBitmapProcShader for the actual operation.
R=bsalomon@google.com, reed@google.com, robertphillips@google.com
Committed: http://code.google.com/p/skia/source/detail?r=14085
Author: fmalita@chromium.org
Review URL: https://codereview.chromium.org/221923007
git-svn-id: http://skia.googlecode.com/svn/trunk@14092 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gm/pictureshader.cpp')
-rw-r--r-- | gm/pictureshader.cpp | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/gm/pictureshader.cpp b/gm/pictureshader.cpp new file mode 100644 index 0000000000..5d37c907ac --- /dev/null +++ b/gm/pictureshader.cpp @@ -0,0 +1,165 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gm.h" + +#include "SkBitmap.h" +#include "SkPaint.h" +#include "SkPicture.h" +#include "SkShader.h" + +namespace skiagm { + +static struct { + SkShader::TileMode tmx; + SkShader::TileMode tmy; +} kTileConfigs[] = { + { SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode }, + { SkShader::kRepeat_TileMode, SkShader::kClamp_TileMode }, + { SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode }, +}; + +class PictureShaderGM : public GM { +public: + + PictureShaderGM(SkScalar tileSize, SkScalar sceneSize) + : fTileSize(tileSize) + , fSceneSize(sceneSize) { + + // Build the picture. + SkAutoTUnref<SkPicture> p(SkNEW(SkPicture)); + SkCanvas* pictureCanvas = p->beginRecording(SkScalarRoundToInt(tileSize), + SkScalarRoundToInt(tileSize)); + this->drawTile(pictureCanvas); + p->endRecording(); + + // Build a reference bitmap. + SkBitmap bm; + bm.allocN32Pixels(SkScalarRoundToInt(tileSize), SkScalarRoundToInt(tileSize)); + bm.eraseColor(SK_ColorTRANSPARENT); + SkCanvas bitmapCanvas(bm); + this->drawTile(&bitmapCanvas); + + for (unsigned i = 0; i < SK_ARRAY_COUNT(kTileConfigs); ++i) { + fPictureShaders[i].reset(SkShader::CreatePictureShader(p, + kTileConfigs[i].tmx, + kTileConfigs[i].tmy)); + + fBitmapShaders[i].reset(SkShader::CreateBitmapShader(bm, + kTileConfigs[i].tmx, + kTileConfigs[i].tmy)); + } + } + +protected: + virtual SkString onShortName() SK_OVERRIDE { + return SkString("pictureshader"); + } + + virtual SkISize onISize() SK_OVERRIDE { + return SkISize::Make(1400, 1250); + } + + virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { + this->drawSceneColumn(canvas, SkPoint::Make(0, 0), 1, 1, 0); + this->drawSceneColumn(canvas, SkPoint::Make(0, fSceneSize * 6.4f), 1, 2, 0); + this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, 0), 1, 1, 1); + this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, fSceneSize * 6.4f), 1, 1, 2); + this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 4.8f, 0), 2, 1, 0); + this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 9.6f, 0), 2, 2, 0); + } + +private: + void drawSceneColumn(SkCanvas* canvas, const SkPoint& pos, SkScalar scale, SkScalar localScale, + unsigned tileMode) { + SkMatrix ctm, localMatrix; + + ctm.setTranslate(pos.x(), pos.y()); + ctm.preScale(scale, scale); + localMatrix.setScale(localScale, localScale); + this->drawScene(canvas, ctm, localMatrix, tileMode); + + ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 1.2f * scale); + ctm.preScale(scale, scale); + localMatrix.setTranslate(fTileSize / 4, fTileSize / 4); + localMatrix.preScale(localScale, localScale); + this->drawScene(canvas, ctm, localMatrix, tileMode); + + ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 2.4f * scale); + ctm.preScale(scale, scale); + localMatrix.setRotate(45); + localMatrix.preScale(localScale, localScale); + this->drawScene(canvas, ctm, localMatrix, tileMode); + + ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 3.6f * scale); + ctm.preScale(scale, scale); + localMatrix.setSkew(1, 0); + localMatrix.preScale(localScale, localScale); + this->drawScene(canvas, ctm, localMatrix, tileMode); + + ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 4.8f * scale); + ctm.preScale(scale, scale); + localMatrix.setTranslate(fTileSize / 4, fTileSize / 4); + localMatrix.preRotate(45); + localMatrix.preScale(localScale, localScale); + this->drawScene(canvas, ctm, localMatrix, tileMode); + } + + void drawTile(SkCanvas* canvas) { + SkPaint paint; + paint.setColor(SK_ColorGREEN); + paint.setStyle(SkPaint::kFill_Style); + paint.setAntiAlias(true); + + canvas->drawCircle(fTileSize / 4, fTileSize / 4, fTileSize / 4, paint); + canvas->drawRect(SkRect::MakeXYWH(fTileSize / 2, fTileSize / 2, + fTileSize / 2, fTileSize / 2), paint); + + paint.setColor(SK_ColorRED); + canvas->drawLine(fTileSize / 2, fTileSize * 1 / 3, + fTileSize / 2, fTileSize * 2 / 3, paint); + canvas->drawLine(fTileSize * 1 / 3, fTileSize / 2, + fTileSize * 2 / 3, fTileSize / 2, paint); + } + + void drawScene(SkCanvas* canvas, const SkMatrix& matrix, const SkMatrix& localMatrix, + unsigned tileMode) { + SkASSERT(tileMode < SK_ARRAY_COUNT(kTileConfigs)); + + SkPaint paint; + paint.setStyle(SkPaint::kFill_Style); + paint.setColor(SK_ColorLTGRAY); + + canvas->save(); + canvas->concat(matrix); + canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint); + canvas->drawRect(SkRect::MakeXYWH(fSceneSize * 1.1f, 0, fSceneSize, fSceneSize), paint); + + fPictureShaders[tileMode]->setLocalMatrix(localMatrix); + paint.setShader(fPictureShaders[tileMode].get()); + canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint); + + canvas->translate(fSceneSize * 1.1f, 0); + + fBitmapShaders[tileMode]->setLocalMatrix(localMatrix); + paint.setShader(fBitmapShaders[tileMode].get()); + canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint); + + canvas->restore(); + } + + SkScalar fTileSize; + SkScalar fSceneSize; + + SkAutoTUnref<SkShader> fPictureShaders[SK_ARRAY_COUNT(kTileConfigs)]; + SkAutoTUnref<SkShader> fBitmapShaders[SK_ARRAY_COUNT(kTileConfigs)]; + + typedef GM INHERITED; +}; + +DEF_GM( return SkNEW_ARGS(PictureShaderGM, (50, 100)); ) +} |