OLD | NEW |
---|---|
1 SkPaint | 1 SkPaint |
2 ======= | 2 ======= |
3 | 3 |
4 *color, stroke, font, effects* | 4 *color, stroke, font, effects* |
5 | 5 |
6 <!-- Updated Jan 17, 2013 by humper@google.com --> | 6 <!-- Updated Jan 17, 2013 by humper@google.com --> |
hcm
2015/07/27 19:22:04
Should take this update stamp out..or update it!
hal.canary
2015/07/27 19:24:38
Done.
| |
7 | 7 |
8 Anytime you draw something in Skia, and want to specify what color it | 8 Anytime you draw something in Skia, and want to specify what color it |
9 is, or how it blends with the background, or what style or font to | 9 is, or how it blends with the background, or what style or font to |
10 draw it in, you specify those attributes in a paint. | 10 draw it in, you specify those attributes in a paint. |
11 | 11 |
12 Unlike `SkCanvas`, paints do not maintain an internal stack of state | 12 Unlike `SkCanvas`, paints do not maintain an internal stack of state |
13 (i.e. there is no save/restore on a paint). However, paints are | 13 (i.e. there is no save/restore on a paint). However, paints are |
14 relatively light-weight, so the client may create and maintain any | 14 relatively light-weight, so the client may create and maintain any |
15 number of paint objects, each setup for a particular use. Factoring | 15 number of paint objects, each setup for a particular use. Factoring |
16 all of these color and stylistic attribute out of the canvas state, | 16 all of these color and stylistic attribute out of the canvas state, |
(...skipping 26 matching lines...) Expand all Loading... | |
43 | 43 |
44 const char text[] = "Skia!"; | 44 const char text[] = "Skia!"; |
45 canvas->drawText(text, strlen(text), 20.0f, 64.0f, paint1); | 45 canvas->drawText(text, strlen(text), 20.0f, 64.0f, paint1); |
46 canvas->drawText(text, strlen(text), 20.0f, 144.0f, paint2); | 46 canvas->drawText(text, strlen(text), 20.0f, 144.0f, paint2); |
47 canvas->drawText(text, strlen(text), 20.0f, 224.0f, paint3); | 47 canvas->drawText(text, strlen(text), 20.0f, 224.0f, paint3); |
48 } | 48 } |
49 | 49 |
50 <a href="https://fiddle.skia.org/c/b8e7991ede1ca88e5458aa1f0039caf9"> | 50 <a href="https://fiddle.skia.org/c/b8e7991ede1ca88e5458aa1f0039caf9"> |
51 <img src="https://fiddle.skia.org/i/b8e7991ede1ca88e5458aa1f0039caf9_raster.png" ></a> | 51 <img src="https://fiddle.skia.org/i/b8e7991ede1ca88e5458aa1f0039caf9_raster.png" ></a> |
52 | 52 |
53 This shows three different paints, each setup to draw in a different | 53 This shows three different paints, each setup to draw in a different |
hcm
2015/07/27 19:22:04
I know this is not new, but setup --> set up
hal.canary
2015/07/27 19:24:38
Done.
| |
54 style. Now the caller can intermix these paints freely, either using | 54 style. Now the caller can intermix these paints freely, either using |
55 them as is, or modifying them as the drawing proceeds. | 55 them as is, or modifying them as the drawing proceeds. |
56 | 56 |
57 <!--?prettify lang=cc?--> | 57 <!--?prettify lang=cc?--> |
58 | 58 |
59 canvas->drawRect(..., paint1); | 59 SkPaint paint1, paint2, paint3; |
60 canvas->drawRect(..., paint2); | 60 paint2.setStyle(SkPaint::kStroke_Style); |
61 paint2.setStrokeWidth(3); | |
62 paint3.setAntiAlias(true); | |
63 paint3.setColor(SK_ColorRED); | |
64 paint3.setTextSize(80); | |
65 | |
66 canvas->drawRect(SkRect::MakeXYWH(10,10,60,20), paint1); | |
67 canvas->drawRect(SkRect::MakeXYWH(80,10,60,20), paint2); | |
61 | 68 |
62 paint2.setStrokeWidth(SkIntToScalar(5)); | 69 paint2.setStrokeWidth(SkIntToScalar(5)); |
63 canvas->drawOval(..., paint2); | 70 canvas->drawOval(SkRect::MakeXYWH(150,10,60,20), paint2); |
64 | 71 |
65 canvas->drawText(..., paint3); | 72 canvas->drawText("SKIA", 4, 20, 120, paint3); |
66 paint3.setColor(0xFF0000FF); | 73 paint3.setColor(SK_ColorBLUE); |
67 canvas->drawText(..., paint3); | 74 canvas->drawText("SKIA", 4, 20, 220, paint3); |
68 | 75 |
76 <a href="https://fiddle.skia.org/c/5203b17103f487dd33965b4211d80956"> | |
77 <img src="https://fiddle.skia.org/i/5203b17103f487dd33965b4211d80956_raster.png" ></a> | |
69 | 78 |
70 Beyond simple attributes such as color, strokes, and text values, | 79 Beyond simple attributes such as color, strokes, and text values, |
71 paints support effects. These are subclasses of different aspects of | 80 paints support effects. These are subclasses of different aspects of |
72 the drawing pipeline, that when referenced by a paint (each of them is | 81 the drawing pipeline, that when referenced by a paint (each of them is |
73 reference-counted), are called to override some part of the drawing | 82 reference-counted), are called to override some part of the drawing |
74 pipeline. | 83 pipeline. |
75 | 84 |
76 For example, to draw using a gradient instead of a single color, | 85 For example, to draw using a gradient instead of a single color, |
77 assign a SkShader to the paint. | 86 assign a SkShader to the paint. |
78 | 87 |
79 <!--?prettify lang=cc?--> | 88 <!--?prettify lang=cc?--> |
80 | 89 |
81 SkShader* shader = SkGradientShader::CreateLinear(...); | 90 SkPoint points[2] = { |
91 SkPoint::Make(0.0f, 0.0f), | |
92 SkPoint::Make(256.0f, 256.0f) | |
93 }; | |
94 SkColor colors[2] = {SK_ColorBLUE, SK_ColorYELLOW}; | |
95 SkShader* shader = | |
96 SkGradientShader::CreateLinear( | |
97 points, colors, NULL, 2, | |
98 SkShader::kClamp_TileMode, 0, NULL); | |
99 SkPaint paint; | |
82 paint.setShader(shader); | 100 paint.setShader(shader); |
83 shader->unref(); | 101 shader->unref(); |
102 canvas->drawPaint(paint); | |
103 | |
104 <a href="https://fiddle.skia.org/c/f91b5310d57744a5a1475b7e47d4a172"> | |
105 <img src="https://fiddle.skia.org/i/f91b5310d57744a5a1475b7e47d4a172_raster.png" ></a> | |
84 | 106 |
85 Now, anything drawn with that paint will be drawn with the gradient | 107 Now, anything drawn with that paint will be drawn with the gradient |
86 specified in the call to CreateLinear(). The shader object that is | 108 specified in the call to `CreateLinear()`. The shader object that is |
87 returned is reference-counted. Whenever any effects object, like a | 109 returned is reference-counted. Whenever any effects object, like a |
88 shader, is assigned to a paint, its reference-count is increased by | 110 shader, is assigned to a paint, its reference-count is increased by |
89 the paint. To balance this, the caller in the above example calls | 111 the paint. To balance this, the caller in the above example calls |
90 unref() on the shader once it has assigned it to the paint. Now the | 112 `unref()` on the shader once it has assigned it to the paint. Now the |
91 paint is the only "owner" of that shader, and it will automatically | 113 paint is the only "owner" of that shader, and it will automatically |
92 call unref() on the shader when either the paint goes out of scope, or | 114 call `unref()` on the shader when either the paint goes out of scope, or |
93 if another shader (or null) is assigned to it. | 115 if another shader (or null) is assigned to it. |
94 | 116 |
95 There are 6 types of effects that can be assigned to a paint: | 117 There are 6 types of effects that can be assigned to a paint: |
96 | 118 |
97 * **SkPathEffect** - modifications to the geometry (path) before it | 119 * **SkPathEffect** - modifications to the geometry (path) before it |
98 generates an alpha mask (e.g. dashing) | 120 generates an alpha mask (e.g. dashing) |
99 * **SkRasterizer** - composing custom mask layers (e.g. shadows) | 121 * **SkRasterizer** - composing custom mask layers (e.g. shadows) |
100 * **SkMaskFilter** - modifications to the alpha mask before it is | 122 * **SkMaskFilter** - modifications to the alpha mask before it is |
101 colorized and drawn (e.g. blur, emboss) | 123 colorized and drawn (e.g. blur, emboss) |
102 * **SkShader** - e.g. gradients (linear, radial, sweep), bitmap patterns | 124 * **SkShader** - e.g. gradients (linear, radial, sweep), bitmap patterns |
103 (clamp, repeat, mirror) | 125 (clamp, repeat, mirror) |
104 * **SkColorFilter** - modify the source color(s) before applying the | 126 * **SkColorFilter** - modify the source color(s) before applying the |
105 xfermode (e.g. color matrix) | 127 xfermode (e.g. color matrix) |
106 * **SkXfermode** - e.g. porter-duff transfermodes, blend modes | 128 * **SkXfermode** - e.g. porter-duff transfermodes, blend modes |
107 | 129 |
108 Paints also hold a reference to a SkTypeface. The typeface represents | 130 Paints also hold a reference to a SkTypeface. The typeface represents |
109 a specific font style, to be used for measuring and drawing | 131 a specific font style, to be used for measuring and drawing |
110 text. Speaking of which, paints are used not only for drawing text, | 132 text. Speaking of which, paints are used not only for drawing text, |
111 but also for measuring it. | 133 but also for measuring it. |
112 | 134 |
113 <!--?prettify lang=cc?--> | 135 <!--?prettify lang=cc?--> |
114 | 136 |
115 paint.measureText(...); | 137 paint.measureText(...); |
116 paint.getTextBounds(...); | 138 paint.getTextBounds(...); |
117 paint.textToGlyphs(...); | 139 paint.textToGlyphs(...); |
118 paint.getFontMetrics(...); | 140 paint.getFontMetrics(...); |
141 | |
142 ShShader | |
143 -------- | |
144 | |
145 Several shaders are defined (besides the linear gradient already mentioned): | |
146 | |
147 * Bitmap Shader | |
148 | |
149 <!--?prettify lang=cc?--> | |
150 | |
151 canvas->clear(SK_ColorWHITE); | |
152 SkMatrix matrix; | |
153 matrix.setScale(0.75f, 0.75f); | |
154 matrix.preRotate(30.0f); | |
155 SkShader* shader = | |
156 SkShader::CreateBitmapShader( | |
157 source, | |
158 SkShader::kRepeat_TileMode , | |
159 SkShader::kRepeat_TileMode , | |
160 &matrix); | |
161 SkPaint paint; | |
162 paint.setShader(shader); | |
163 shader->unref(); | |
164 canvas->drawPaint(paint); | |
165 | |
166 <a href="https://fiddle.skia.org/c/0e8d08e0a0b342e9e45c364d0e5cea8a"> | |
167 <img src="https://fiddle.skia.org/i/0e8d08e0a0b342e9e45c364d0e5cea8a_raster. png"></a> | |
168 | |
169 * Radial Gradient Shader | |
170 | |
171 <!--?prettify lang=cc?--> | |
172 | |
173 SkColor colors[2] = {SK_ColorBLUE, SK_ColorYELLOW}; | |
174 SkShader* shader = | |
175 SkGradientShader::CreateRadial( | |
176 SkPoint::Make(128.0f, 128.0f), 180.0f, | |
177 colors, NULL, 2, SkShader::kClamp_TileMode, 0, NULL); | |
178 SkPaint paint; | |
179 paint.setShader(shader); | |
180 shader->unref(); | |
181 canvas->drawPaint(paint); | |
182 | |
183 <a href="https://fiddle.skia.org/c/601abd2819e38365900bf62286986024"> | |
184 <img src="https://fiddle.skia.org/i/601abd2819e38365900bf62286986024_raster. png"></a> | |
185 | |
186 * Two-Point Conical Gradient Shader | |
187 | |
188 <!--?prettify lang=cc?--> | |
189 | |
190 SkColor colors[2] = {SK_ColorBLUE, SK_ColorYELLOW}; | |
191 SkShader* shader = | |
192 SkGradientShader::CreateTwoPointConical( | |
193 SkPoint::Make(128.0f, 128.0f), 128.0f, | |
194 SkPoint::Make(128.0f, 16.0f), 16.0f, | |
195 colors, NULL, 2, SkShader::kClamp_TileMode, 0, NULL); | |
196 SkPaint paint; | |
197 paint.setShader(shader); | |
198 shader->unref(); | |
199 canvas->drawPaint(paint); | |
200 | |
201 <a href="https://fiddle.skia.org/c/991f7d67ff1ccebd6c2c4fab18a76edc"> | |
202 <img src="https://fiddle.skia.org/i/991f7d67ff1ccebd6c2c4fab18a76edc_raster. png"></a> | |
203 | |
204 | |
205 * Sweep Gradient Shader | |
206 | |
207 <!--?prettify lang=cc?--> | |
208 | |
209 SkColor colors[4] = { | |
210 SK_ColorCYAN, SK_ColorMAGENTA, SK_ColorYELLOW, SK_ColorCYAN}; | |
211 SkShader* shader = | |
212 SkGradientShader::CreateSweep( | |
213 128.0f, 128.0f, colors, NULL, 4, 0, NULL); | |
214 SkPaint paint; | |
215 paint.setShader(shader); | |
216 shader->unref(); | |
217 canvas->drawPaint(paint); | |
218 | |
219 <a href="https://fiddle.skia.org/c/cee9d1831f6679c3d88170f857995d12"> | |
220 <img src="https://fiddle.skia.org/i/cee9d1831f6679c3d88170f857995d12_raster. png"></a> | |
221 | |
222 * Fractal Perlin Noise Shader | |
223 | |
224 <!--?prettify lang=cc?--> | |
225 | |
226 canvas->clear(SK_ColorWHITE); | |
227 SkShader* shader = SkPerlinNoiseShader::CreateFractalNoise( | |
228 0.05f, 0.05f, 4, 0.0f, NULL); | |
229 SkPaint paint; | |
230 paint.setShader(shader); | |
231 shader->unref(); | |
232 canvas->drawPaint(paint); | |
233 | |
234 <a href="https://fiddle.skia.org/c/cc45c5349c3b31f97da7c1af7f84162a"> | |
235 <img src="https://fiddle.skia.org/i/cc45c5349c3b31f97da7c1af7f84162a_raster. png"></a> | |
236 | |
237 * Turbulence Perlin Noise Shader | |
238 | |
239 <!--?prettify lang=cc?--> | |
240 | |
241 canvas->clear(SK_ColorWHITE); | |
242 SkShader* shader = SkPerlinNoiseShader::CreateTurbulence( | |
243 0.05f, 0.05f, 4, 0.0f, NULL); | |
244 SkPaint paint; | |
245 paint.setShader(shader); | |
246 shader->unref(); | |
247 canvas->drawPaint(paint); | |
248 | |
249 <a href="https://fiddle.skia.org/c/52729ed3a71b89a6dba4f60e8eb67727"> | |
250 <img src="https://fiddle.skia.org/i/52729ed3a71b89a6dba4f60e8eb67727_raster. png"></a> | |
251 | |
252 * Compose Shader | |
253 | |
254 <!--?prettify lang=cc?--> | |
255 | |
256 SkColor colors[2] = {SK_ColorBLUE, SK_ColorYELLOW}; | |
257 SkShader* shader1 = | |
258 SkGradientShader::CreateRadial( | |
259 SkPoint::Make(128.0f, 128.0f), 180.0f, | |
260 colors, NULL, 2, SkShader::kClamp_TileMode, 0, NULL); | |
261 SkShader* shader2 = SkPerlinNoiseShader::CreateTurbulence( | |
262 0.025f, 0.025f, 2, 0.0f, NULL); | |
263 SkShader* shader = | |
264 new SkComposeShader(shader1, shader2); | |
265 SkPaint paint; | |
266 paint.setShader(shader); | |
267 shader->unref(); | |
268 shader2->unref(); | |
269 shader1->unref(); | |
270 canvas->drawPaint(paint); | |
271 | |
272 <a href="https://fiddle.skia.org/c/1209b7a29d870302edcc43dc0916e8d5"> | |
273 <img src="https://fiddle.skia.org/i/1209b7a29d870302edcc43dc0916e8d5_raster. png"></a> | |
274 | |
275 | |
276 SkMaskFilter | |
277 ------------ | |
278 | |
279 * Blur Mask Filter | |
280 | |
281 <!--?prettify lang=cc?--> | |
282 | |
283 canvas->drawColor(SK_ColorWHITE); | |
284 SkPaint paint; | |
285 paint.setAntiAlias(true); | |
286 paint.setTextSize(120); | |
287 SkMaskFilter* filter = | |
288 SkBlurMaskFilter::Create( | |
289 kNormal_SkBlurStyle, 5.0f, 0); | |
290 paint.setMaskFilter(filter); | |
291 filter->unref(); | |
292 const char text[] = "Skia"; | |
293 canvas->drawText(text, strlen(text), 0, 160, paint); | |
294 | |
295 <a href="https://fiddle.skia.org/c/0e004664122851691d67a291007b64d7"> | |
296 <img src="https://fiddle.skia.org/i/0e004664122851691d67a291007b64d7_raster. png"></a> | |
297 | |
298 * Emboss Mask Filter | |
299 | |
300 <!--?prettify lang=cc?--> | |
301 | |
302 canvas->drawColor(SK_ColorWHITE); | |
303 SkPaint paint; | |
304 paint.setAntiAlias(true); | |
305 paint.setTextSize(120); | |
306 SkScalar direction[3] = {1.0f, 1.0f, 1.0f}; | |
307 SkMaskFilter* filter = | |
308 SkBlurMaskFilter::CreateEmboss( | |
309 2.0f, direction, 0.3f, 0.1f); | |
310 paint.setMaskFilter(filter); | |
311 filter->unref(); | |
312 const char text[] = "Skia"; | |
313 canvas->drawText(text, strlen(text), 0, 160, paint); | |
314 | |
315 <a href="https://fiddle.skia.org/c/1ef71be7fb749a2d81a55721b2d2c77d"> | |
316 <img src="https://fiddle.skia.org/i/1ef71be7fb749a2d81a55721b2d2c77d_raster. png"></a> | |
317 | |
318 | |
319 SkColorFilter | |
320 ------------- | |
321 | |
322 * Color Matrix Color Filter | |
323 | |
324 <!--?prettify lang=cc?--> | |
325 | |
326 void f(SkCanvas* c, SkScalar x, SkScalar y, SkScalar colorMatrix[20]) { | |
327 SkColorFilter* cf = SkColorMatrixFilter::Create(colorMatrix); | |
328 SkPaint paint; | |
329 paint.setColorFilter(cf); | |
330 cf->unref(); | |
331 c->drawBitmap(source, x, y, &paint); | |
332 } | |
333 void draw(SkCanvas* c) { | |
334 c->scale(0.25, 0.25); | |
335 SkScalar colorMatrix1[20] = { | |
336 0, 1, 0, 0, 0, | |
337 0, 0, 1, 0, 0, | |
338 1, 0, 0, 0, 0, | |
339 0, 0, 0, 1, 0}; | |
340 f(c, 0, 0, colorMatrix1); | |
341 | |
342 SkScalar grayscale[20] = { | |
343 0.21, 0.72, 0.07, 0.0, 0.0, | |
344 0.21, 0.72, 0.07, 0.0, 0.0, | |
345 0.21, 0.72, 0.07, 0.0, 0.0, | |
346 0.0, 0.0, 0.0, 1.0, 0.0}; | |
347 f(c, 512, 0, grayscale); | |
348 | |
349 SkScalar colorMatrix3[20] = { | |
350 -1, 1, 1, 0, 0, | |
351 1, -1, 1, 0, 0, | |
352 1, 1, -1, 0, 0, | |
353 0, 0, 0, 1, 0}; | |
354 f(c, 0, 512, colorMatrix3); | |
355 | |
356 SkScalar colorMatrix4[20] = { | |
357 0.0, 0.5, 0.5, 0, 0, | |
358 0.5, 0.0, 0.5, 0, 0, | |
359 0.5, 0.5, 0.0, 0, 0, | |
360 0.0, 0.0, 0.0, 1, 0}; | |
361 f(c, 512, 512, colorMatrix4); | |
362 | |
363 SkScalar highContrast[20] = { | |
364 4.0, 0.0, 0.0, 0.0, -4.0 * 255 / (4.0 - 1), | |
365 0.0, 4.0, 0.0, 0.0, -4.0 * 255 / (4.0 - 1), | |
366 0.0, 0.0, 4.0, 0.0, -4.0 * 255 / (4.0 - 1), | |
367 0.0, 0.0, 0.0, 1.0, 0.0}; | |
368 f(c, 1024, 0, highContrast); | |
369 | |
370 SkScalar colorMatrix6[20] = { | |
371 0, 0, 1, 0, 0, | |
372 1, 0, 0, 0, 0, | |
373 0, 1, 0, 0, 0, | |
374 0, 0, 0, 1, 0}; | |
375 f(c, 1024, 512, colorMatrix6); | |
376 | |
377 SkScalar sepia[20] = { | |
378 0.393, 0.769, 0.189, 0.0, 0.0, | |
379 0.349, 0.686, 0.168, 0.0, 0.0, | |
380 0.272, 0.534, 0.131, 0.0, 0.0, | |
381 0.0, 0.0, 0.0, 1.0, 0.0}; | |
382 f(c, 1536, 0, sepia); | |
383 | |
384 SkScalar inverter[20] = { | |
385 -1, 0, 0, 0, 255, | |
386 0, -1, 0, 0, 255, | |
387 0, 0, -1, 0, 255, | |
388 0, 0, 0, 1, 0}; | |
389 f(c, 1536, 512, inverter); | |
390 } | |
391 | |
392 <a href="https://fiddle.skia.org/c/91fb5341ee7903c9682df20bb3d73dbb"> | |
393 <img src="https://fiddle.skia.org/i/91fb5341ee7903c9682df20bb3d73dbb_raster. png"></a> | |
394 | |
395 * Color Table Color Filter | |
396 | |
397 <!--?prettify lang=cc?--> | |
398 | |
399 canvas->scale(0.5, 0.5); | |
400 uint8_t ct[256]; | |
401 for (int i = 0; i < 256; ++i) { | |
402 int x = (i - 96) * 255 / 64; | |
403 ct[i] = x < 0 ? 0 : x > 255 ? 255 : x; | |
404 } | |
405 SkColorFilter* cf = SkTableColorFilter::CreateARGB(NULL, ct, ct, ct); | |
406 SkPaint paint; | |
407 paint.setColorFilter(cf); | |
408 cf->unref(); | |
409 canvas->drawBitmap(source, 0, 0, &paint); | |
410 | |
411 <a href="https://fiddle.skia.org/c/0d3d339543afa1b10c60f9826f264c3f"> | |
412 <img src="https://fiddle.skia.org/i/0d3d339543afa1b10c60f9826f264c3f_raster. png"></a> | |
OLD | NEW |