11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "gm.h" 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkCanvas.h" 101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkColorPriv.h" 111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkShader.h" 121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkCanvas* create_canvas(int w, int h) { 141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap bm; 151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bm.setConfig(SkBitmap::kARGB_8888_Config, w, h); 161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bm.allocPixels(); 171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bm.eraseColor(0); 181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return new SkCanvas(bm); 191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const SkBitmap& extract_bitmap(SkCanvas* canvas) { 221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return canvas->getDevice()->accessBitmap(false); 231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const struct { 261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode::Mode fMode; 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* fLabel; 281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} gModes[] = { 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkXfermode::kClear_Mode, "Clear" }, 301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkXfermode::kSrc_Mode, "Src" }, 311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkXfermode::kDst_Mode, "Dst" }, 321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkXfermode::kSrcOver_Mode, "SrcOver" }, 331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkXfermode::kDstOver_Mode, "DstOver" }, 341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkXfermode::kSrcIn_Mode, "SrcIn" }, 351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkXfermode::kDstIn_Mode, "DstIn" }, 361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkXfermode::kSrcOut_Mode, "SrcOut" }, 371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkXfermode::kDstOut_Mode, "DstOut" }, 381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkXfermode::kSrcATop_Mode, "SrcATop" }, 391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkXfermode::kDstATop_Mode, "DstATop" }, 401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkXfermode::kXor_Mode, "Xor" }, 411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}; 421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst int gWidth = 64; 441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst int gHeight = 64; 451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst SkScalar W = SkIntToScalar(gWidth); 461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst SkScalar H = SkIntToScalar(gHeight); 471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkScalar drawCell(SkCanvas* canvas, SkXfermode* mode, SkAlpha a0, SkAlpha a1) { 491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPaint paint; 511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger paint.setAntiAlias(true); 521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRect r = SkRect::MakeWH(W, H); 541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger r.inset(W/10, H/10); 551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger paint.setColor(SK_ColorBLUE); 571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger paint.setAlpha(a0); 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->drawOval(r, paint); 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger paint.setColor(SK_ColorRED); 611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger paint.setAlpha(a1); 621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger paint.setXfermode(mode); 631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int angle = 0; angle < 24; ++angle) { 641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar x = SkScalarCos(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gWidth; 651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar y = SkScalarSin(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gHeight; 661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger paint.setStrokeWidth(SK_Scalar1 * angle * 2 / 24); 671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->drawLine(W/2, H/2, W/2 + x, H/2 + y, paint); 681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return H; 711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkShader* make_bg_shader() { 741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap bm; 751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); 761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bm.allocPixels(); 771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF; 781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCC, 0xCC, 0xCC); 791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkShader* s = SkShader::CreateBitmapShader(bm, 811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkShader::kRepeat_TileMode, 821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkShader::kRepeat_TileMode); 831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMatrix m; 851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger m.setScale(SkIntToScalar(6), SkIntToScalar(6)); 861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger s->setLocalMatrix(m); 871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return s; 881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace skiagm { 911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger class HairModesGM : public GM { 931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkPaint fBGPaint; 941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger public: 951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger HairModesGM() { 961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBGPaint.setShader(make_bg_shader())->unref(); 971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger protected: 1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual SkString onShortName() { 1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkString("hairmodes"); 1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual SkISize onISize() { return make_isize(640, 480); } 1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual void onDraw(SkCanvas* canvas) { 1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkRect bounds = SkRect::MakeWH(W, H); 1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 }; 1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->translate(SkIntToScalar(4), SkIntToScalar(4)); 1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int alpha = 0; alpha < 4; ++alpha) { 1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->save(); 1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->save(); 1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) { 1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (6 == i) { 1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->restore(); 1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->translate(W * 5, 0); 1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->save(); 1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode* mode = SkXfermode::Create(gModes[i].fMode); 1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->drawRect(bounds, fBGPaint); 1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->saveLayer(&bounds, NULL); 1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar dy = drawCell(canvas, mode, 1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gAlphaValue[alpha & 1], 1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gAlphaValue[alpha & 2]); 1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->restore(); 1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->translate(0, dy * 5 / 4); 1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSafeUnref(mode); 1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->restore(); 1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->restore(); 1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->translate(W * 5 / 4, 0); 1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // disable pdf for now, since it crashes on mac 1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual uint32_t onGetFlags() const { return kSkipPDF_Flag; } 1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger private: 1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger typedef GM INHERITED; 1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger }; 1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ////////////////////////////////////////////////////////////////////////////// 1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static GM* MyFactory(void*) { return new HairModesGM; } 1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static GMRegistry reg(MyFactory); 1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 153