1 /* 2 * Copyright 2011 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 #include "SkCanvas.h" 10 #include "SkColorPriv.h" 11 #include "SkShader.h" 12 13 #include "SkArithmeticMode.h" 14 #include "SkGradientShader.h" 15 #define WW 100 16 #define HH 32 17 18 static SkBitmap make_bm() { 19 SkBitmap bm; 20 bm.allocN32Pixels(WW, HH); 21 bm.eraseColor(SK_ColorTRANSPARENT); 22 return bm; 23 } 24 25 static SkBitmap make_src() { 26 SkBitmap bm = make_bm(); 27 SkCanvas canvas(bm); 28 SkPaint paint; 29 SkPoint pts[] = { {0, 0}, {SkIntToScalar(WW), SkIntToScalar(HH)} }; 30 SkColor colors[] = { 31 SK_ColorTRANSPARENT, SK_ColorGREEN, SK_ColorCYAN, 32 SK_ColorRED, SK_ColorMAGENTA, SK_ColorWHITE, 33 }; 34 SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, SK_ARRAY_COUNT(colors), 35 SkShader::kClamp_TileMode); 36 paint.setShader(s)->unref(); 37 canvas.drawPaint(paint); 38 return bm; 39 } 40 41 static SkBitmap make_dst() { 42 SkBitmap bm = make_bm(); 43 SkCanvas canvas(bm); 44 SkPaint paint; 45 SkPoint pts[] = { {0, SkIntToScalar(HH)}, {SkIntToScalar(WW), 0} }; 46 SkColor colors[] = { 47 SK_ColorBLUE, SK_ColorYELLOW, SK_ColorBLACK, SK_ColorGREEN, SK_ColorGRAY 48 }; 49 SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, SK_ARRAY_COUNT(colors), 50 SkShader::kClamp_TileMode); 51 paint.setShader(s)->unref(); 52 canvas.drawPaint(paint); 53 return bm; 54 } 55 56 static void show_k_text(SkCanvas* canvas, SkScalar x, SkScalar y, const SkScalar k[]) { 57 SkPaint paint; 58 paint.setTextSize(SkIntToScalar(24)); 59 paint.setAntiAlias(true); 60 for (int i = 0; i < 4; ++i) { 61 SkString str; 62 str.appendScalar(k[i]); 63 SkScalar width = paint.measureText(str.c_str(), str.size()); 64 canvas->drawText(str.c_str(), str.size(), x, y + paint.getTextSize(), paint); 65 x += width + SkIntToScalar(10); 66 } 67 } 68 69 class ArithmodeGM : public skiagm::GM { 70 public: 71 ArithmodeGM () {} 72 73 protected: 74 75 virtual SkString onShortName() { 76 return SkString("arithmode"); 77 } 78 79 virtual SkISize onISize() { return SkISize::Make(640, 480); } 80 81 virtual void onDraw(SkCanvas* canvas) { 82 SkBitmap src = make_src(); 83 SkBitmap dst = make_dst(); 84 85 const SkScalar one = SK_Scalar1; 86 static const SkScalar K[] = { 87 0, 0, 0, 0, 88 0, 0, 0, one, 89 0, one, 0, 0, 90 0, 0, one, 0, 91 0, one, one, 0, 92 0, one, -one, 0, 93 0, one/2, one/2, 0, 94 0, one/2, one/2, one/4, 95 0, one/2, one/2, -one/4, 96 one/4, one/2, one/2, 0, 97 -one/4, one/2, one/2, 0, 98 }; 99 100 const SkScalar* k = K; 101 const SkScalar* stop = k + SK_ARRAY_COUNT(K); 102 SkScalar y = 0; 103 SkScalar gap = SkIntToScalar(src.width() + 20); 104 while (k < stop) { 105 SkScalar x = 0; 106 canvas->drawBitmap(src, x, y, NULL); 107 x += gap; 108 canvas->drawBitmap(dst, x, y, NULL); 109 x += gap; 110 SkRect rect = SkRect::MakeXYWH(x, y, SkIntToScalar(WW), SkIntToScalar(HH)); 111 canvas->saveLayer(&rect, NULL); 112 canvas->drawBitmap(dst, x, y, NULL); 113 SkXfermode* xfer = SkArithmeticMode::Create(k[0], k[1], k[2], k[3]); 114 SkPaint paint; 115 paint.setXfermode(xfer)->unref(); 116 canvas->drawBitmap(src, x, y, &paint); 117 canvas->restore(); 118 x += gap; 119 show_k_text(canvas, x, y, k); 120 k += 4; 121 y += SkIntToScalar(src.height() + 12); 122 } 123 } 124 125 private: 126 typedef GM INHERITED; 127 }; 128 129 /////////////////////////////////////////////////////////////////////////////// 130 131 static skiagm::GM* MyFactory(void*) { return new ArithmodeGM; } 132 static skiagm::GMRegistry reg(MyFactory); 133