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