|  | /* | 
|  | * Copyright 2011 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 "SkCanvas.h" | 
|  | #include "SkColorPriv.h" | 
|  | #include "SkShader.h" | 
|  |  | 
|  | /* | 
|  | *  Want to ensure that our bitmap sampler (in bitmap shader) keeps plenty of | 
|  | *  precision when scaling very large images (where the dx might get very small. | 
|  | */ | 
|  |  | 
|  | #define W   257 | 
|  | #define H   161 | 
|  |  | 
|  | class GiantBitmapGM : public skiagm::GM { | 
|  | SkBitmap* fBM; | 
|  | SkShader::TileMode fMode; | 
|  | bool fDoFilter; | 
|  | bool fDoRotate; | 
|  |  | 
|  | const SkBitmap& getBitmap() { | 
|  | if (NULL == fBM) { | 
|  | fBM = new SkBitmap; | 
|  | fBM->allocN32Pixels(W, H); | 
|  | fBM->eraseColor(SK_ColorWHITE); | 
|  |  | 
|  | const SkColor colors[] = { | 
|  | SK_ColorBLUE, SK_ColorRED, SK_ColorBLACK, SK_ColorGREEN | 
|  | }; | 
|  |  | 
|  | SkCanvas canvas(*fBM); | 
|  | SkPaint paint; | 
|  | paint.setAntiAlias(true); | 
|  | paint.setStrokeWidth(SkIntToScalar(20)); | 
|  |  | 
|  | #if 0 | 
|  | for (int y = -H*2; y < H; y += 50) { | 
|  | SkScalar yy = SkIntToScalar(y); | 
|  | paint.setColor(colors[y/50 & 0x3]); | 
|  | canvas.drawLine(0, yy, SkIntToScalar(W), yy + SkIntToScalar(W), | 
|  | paint); | 
|  | } | 
|  | #else | 
|  | for (int x = -W; x < W; x += 60) { | 
|  | paint.setColor(colors[x/60 & 0x3]); | 
|  |  | 
|  | SkScalar xx = SkIntToScalar(x); | 
|  | canvas.drawLine(xx, 0, xx, SkIntToScalar(H), | 
|  | paint); | 
|  | } | 
|  | #endif | 
|  | } | 
|  | return *fBM; | 
|  | } | 
|  |  | 
|  | public: | 
|  | GiantBitmapGM(SkShader::TileMode mode, bool doFilter, bool doRotate) : fBM(NULL) { | 
|  | fMode = mode; | 
|  | fDoFilter = doFilter; | 
|  | fDoRotate = doRotate; | 
|  | } | 
|  |  | 
|  | virtual ~GiantBitmapGM() { | 
|  | SkDELETE(fBM); | 
|  | } | 
|  |  | 
|  | protected: | 
|  | virtual uint32_t onGetFlags() const SK_OVERRIDE { | 
|  | if (fDoFilter && fDoRotate && fMode != SkShader::kClamp_TileMode) { | 
|  | return kSkipTiled_Flag; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | virtual SkString onShortName() { | 
|  | SkString str("giantbitmap_"); | 
|  | switch (fMode) { | 
|  | case SkShader::kClamp_TileMode: | 
|  | str.append("clamp"); | 
|  | break; | 
|  | case SkShader::kRepeat_TileMode: | 
|  | str.append("repeat"); | 
|  | break; | 
|  | case SkShader::kMirror_TileMode: | 
|  | str.append("mirror"); | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  | str.append(fDoFilter ? "_bilerp" : "_point"); | 
|  | str.append(fDoRotate ? "_rotate" : "_scale"); | 
|  | return str; | 
|  | } | 
|  |  | 
|  | virtual SkISize onISize() { return SkISize::Make(640, 480); } | 
|  |  | 
|  | virtual void onDraw(SkCanvas* canvas) { | 
|  | SkPaint paint; | 
|  |  | 
|  | SkMatrix m; | 
|  | if (fDoRotate) { | 
|  | //            m.setRotate(SkIntToScalar(30), 0, 0); | 
|  | m.setSkew(SK_Scalar1, 0, 0, 0); | 
|  | //            m.postScale(2*SK_Scalar1/3, 2*SK_Scalar1/3); | 
|  | } else { | 
|  | SkScalar scale = 11*SK_Scalar1/12; | 
|  | m.setScale(scale, scale); | 
|  | } | 
|  | SkShader* s = SkShader::CreateBitmapShader(getBitmap(), fMode, fMode, &m); | 
|  |  | 
|  | paint.setShader(s)->unref(); | 
|  | paint.setFilterLevel(fDoFilter ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel); | 
|  |  | 
|  | canvas->translate(SkIntToScalar(50), SkIntToScalar(50)); | 
|  |  | 
|  | //        SkRect r = SkRect::MakeXYWH(-50, -50, 32, 16); | 
|  | //        canvas->drawRect(r, paint); return; | 
|  | canvas->drawPaint(paint); | 
|  | } | 
|  |  | 
|  | private: | 
|  | typedef GM INHERITED; | 
|  | }; | 
|  |  | 
|  | /////////////////////////////////////////////////////////////////////////////// | 
|  |  | 
|  | static skiagm::GM* G000(void*) { return new GiantBitmapGM(SkShader::kClamp_TileMode, false, false); } | 
|  | static skiagm::GM* G100(void*) { return new GiantBitmapGM(SkShader::kRepeat_TileMode, false, false); } | 
|  | static skiagm::GM* G200(void*) { return new GiantBitmapGM(SkShader::kMirror_TileMode, false, false); } | 
|  | static skiagm::GM* G010(void*) { return new GiantBitmapGM(SkShader::kClamp_TileMode, true, false); } | 
|  | static skiagm::GM* G110(void*) { return new GiantBitmapGM(SkShader::kRepeat_TileMode, true, false); } | 
|  | static skiagm::GM* G210(void*) { return new GiantBitmapGM(SkShader::kMirror_TileMode, true, false); } | 
|  |  | 
|  | static skiagm::GM* G001(void*) { return new GiantBitmapGM(SkShader::kClamp_TileMode, false, true); } | 
|  | static skiagm::GM* G101(void*) { return new GiantBitmapGM(SkShader::kRepeat_TileMode, false, true); } | 
|  | static skiagm::GM* G201(void*) { return new GiantBitmapGM(SkShader::kMirror_TileMode, false, true); } | 
|  | static skiagm::GM* G011(void*) { return new GiantBitmapGM(SkShader::kClamp_TileMode, true, true); } | 
|  | static skiagm::GM* G111(void*) { return new GiantBitmapGM(SkShader::kRepeat_TileMode, true, true); } | 
|  | static skiagm::GM* G211(void*) { return new GiantBitmapGM(SkShader::kMirror_TileMode, true, true); } | 
|  |  | 
|  | static skiagm::GMRegistry reg000(G000); | 
|  | static skiagm::GMRegistry reg100(G100); | 
|  | static skiagm::GMRegistry reg200(G200); | 
|  | static skiagm::GMRegistry reg010(G010); | 
|  | static skiagm::GMRegistry reg110(G110); | 
|  | static skiagm::GMRegistry reg210(G210); | 
|  |  | 
|  | static skiagm::GMRegistry reg001(G001); | 
|  | static skiagm::GMRegistry reg101(G101); | 
|  | static skiagm::GMRegistry reg201(G201); | 
|  | static skiagm::GMRegistry reg011(G011); | 
|  | static skiagm::GMRegistry reg111(G111); | 
|  | static skiagm::GMRegistry reg211(G211); |