OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2013 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 "SkGradientShader.h" | |
10 #include "SkBitmapAlphaThresholdShader.h" | |
11 #include "SkTArray.h" | |
12 #include "SkParsePath.h" | |
13 | |
14 class BitmapAlphaThresholdGM : public skiagm::GM { | |
15 public: | |
16 BitmapAlphaThresholdGM() { | |
17 this->setBGColor(0xFF000000); | |
18 } | |
19 | |
20 private: | |
21 virtual uint32_t onGetFlags() const SK_OVERRIDE { | |
22 // narrow this flags when the shader has a CPU implementation and | |
23 // when it serializes. | |
24 return | |
25 kSkipPDF_Flag | | |
26 kSkipPicture_Flag | | |
27 kSkipPipe_Flag | | |
28 kSkipPipeCrossProcess_Flag | | |
29 kSkipTiled_Flag | | |
30 kSkip565_Flag | | |
31 kSkipScaledReplay_Flag | | |
32 kSkipPDFRasterization_Flag | | |
33 | |
34 kGPUOnly_Flag; | |
35 } | |
36 | |
37 virtual void onOnceBeforeDraw() SK_OVERRIDE { | |
38 fBM.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); | |
39 if (!fBM.allocPixels()) { | |
40 return; | |
41 } | |
42 SkCanvas canvas(fBM); | |
43 SkPoint pts[] = { {0, 0}, {SkIntToScalar(fBM.width()), SkIntToScalar(fBM
.height())} }; | |
44 SkColor colors[] = {0x00000000, 0xffffffff}; | |
45 SkShader* grad = SkGradientShader::CreateLinear(pts, colors, NULL, 2, | |
46 SkShader::kClamp_TileMod
e); | |
47 SkPaint gradPaint; | |
48 gradPaint.setShader(grad)->unref(); | |
49 gradPaint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
50 canvas.drawPaint(gradPaint); | |
51 | |
52 // Construct the region used as a mask. | |
53 SkRegion bmpBoundsClip; | |
54 bmpBoundsClip.setRect(0, 0, fBM.width(), fBM.height()); | |
55 SkPath circlePath; | |
56 SkScalar radius = SkScalarSqrt(SkIntToScalar(fBM.width() * fBM.height())
) / 2; | |
57 circlePath.addCircle(SkIntToScalar(fBM.width() / 2), | |
58 SkIntToScalar(fBM.height() / 2), | |
59 radius); | |
60 fMask.setPath(circlePath, bmpBoundsClip); | |
61 | |
62 SkPath batPath; | |
63 SkParsePath::FromSVGString( | |
64 "M305.214,374.779c2.463,0,3.45,0.493,3.45,0.493l1.478-6.241c0,0,1.15,4.7
63,1.643,9.034" | |
65 "c0.493,4.271,8.048,1.479,14.454,0.164c6.405-1.314,7.72-11.662,7.72-11.6
62h59.294c0,0-35.807,10.841-26.772,34.656" | |
66 "c0,0-52.889-8.048-61.101,24.967h-0.001c-8.212-33.015-61.101-24.967-61.1
01-24.967c9.034-23.815-26.772-34.656-26.772-34.656" | |
67 "h59.294c0,0,1.314,10.348,7.719,11.662c6.406,1.314,13.962,4.106,14.454-0
.164c0.493-4.271,1.643-9.034,1.643-9.034l1.479,6.241" | |
68 "c0,0,0.985-0.493,3.449-0.493H305.214L305.214,374.779z", | |
69 &batPath); | |
70 | |
71 SkMatrix matrix; | |
72 matrix.setTranslate(-208, -280); | |
73 matrix.postScale(radius / 100, radius / 100); | |
74 batPath.transform(matrix, &batPath); | |
75 SkRegion batRegion; | |
76 batRegion.setPath(batPath, bmpBoundsClip); | |
77 | |
78 fMask.op(batRegion, SkRegion::kDifference_Op); | |
79 } | |
80 | |
81 virtual SkString onShortName() SK_OVERRIDE { | |
82 return SkString("bat"); | |
83 } | |
84 | |
85 virtual SkISize onISize() SK_OVERRIDE { | |
86 return SkISize::Make(518, 735); | |
87 } | |
88 | |
89 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { | |
90 | |
91 SkTArray<SkMatrix> lms; | |
92 lms.push_back().reset(); | |
93 lms.push_back().setScale(SK_Scalar1 / 2, SK_Scalar1); | |
94 lms.push_back().setScale(SK_Scalar1, 2 * SK_Scalar1); | |
95 lms.push_back().setRotate(-SK_Scalar1 * 30); | |
96 lms.push_back().setSkew(0, SK_Scalar1 / 5); | |
97 | |
98 static const SkScalar kMargin = 5 * SK_Scalar1; | |
99 canvas->translate(kMargin, kMargin); | |
100 canvas->save(); | |
101 | |
102 static const U8CPU kThresholds[] = { 0x0, 0x08, 0x40, 0x80, 0xC0, 0xF0,
0xFF }; | |
103 | |
104 for (size_t i = 0; i < SK_ARRAY_COUNT(kThresholds); ++i) { | |
105 for (int j = 0; j < lms.count(); ++j) { | |
106 SkRect rect; | |
107 rect.fLeft = 0; | |
108 rect.fTop = 0; | |
109 rect.fRight = SkIntToScalar(fBM.width()); | |
110 rect.fBottom = SkIntToScalar(fBM.height()); | |
111 | |
112 SkShader* thresh; | |
113 // This SkShader currently only has a GPU implementation. | |
114 if (canvas->getDevice()->accessRenderTarget()) { | |
115 thresh = SkBitmapAlphaThresholdShader::Create(fBM, fMask, kT
hresholds[i]); | |
116 } else { | |
117 thresh = SkShader::CreateBitmapShader(fBM, SkShader::kClamp_
TileMode, | |
118 SkShader::kClamp_
TileMode); | |
119 } | |
120 | |
121 thresh->setLocalMatrix(lms[j]); | |
122 | |
123 SkPaint paint; | |
124 paint.setShader(thresh)->unref(); | |
125 | |
126 canvas->drawRect(rect, paint); | |
127 canvas->translate(SkIntToScalar(fBM.width() + kMargin), 0); | |
128 } | |
129 canvas->restore(); | |
130 canvas->translate(0, SkIntToScalar(fBM.height() + kMargin)); | |
131 canvas->save(); | |
132 } | |
133 | |
134 } | |
135 | |
136 SkBitmap fBM; | |
137 SkRegion fMask; | |
138 | |
139 typedef skiagm::GM INHERITED; | |
140 }; | |
141 | |
142 ////////////////////////////////////////////////////////////////////////////// | |
143 | |
144 DEF_GM( return new BitmapAlphaThresholdGM(); ) | |
OLD | NEW |