Home | History | Annotate | Download | only in api
      1 SkPaint
      2 =======
      3 
      4 *color, stroke, font, effects*
      5 
      6 -   [SkXfermode](#SkXfermode) - transfer modes
      7 -   [ShShader](#ShShader) - gradients and patterns
      8 -   [SkMaskFilter](#SkMaskFilter) - modifications to the alpha mask
      9 -   [SkColorFilter](#SkColorFilter) - modify the source color before applying the
     10 -   [SkPathEffect](#SkPathEffect) - modify to the geometry before it
     11     generates an alpha mask.
     12 
     13 Anytime you draw something in Skia, and want to specify what color it
     14 is, or how it blends with the background, or what style or font to
     15 draw it in, you specify those attributes in a paint.
     16 
     17 Unlike `SkCanvas`, paints do not maintain an internal stack of state
     18 (i.e. there is no save/restore on a paint). However, paints are
     19 relatively light-weight, so the client may create and maintain any
     20 number of paint objects, each set up for a particular use. Factoring
     21 all of these color and stylistic attribute out of the canvas state,
     22 and into (multiple) paint objects, allows canvas' save/restore to be
     23 that much more efficient, as all they have to do is maintain the stack
     24 of matrix and clip settings.
     25 
     26 <!--?prettify lang=cc?-->
     27 
     28     void draw(SkCanvas* canvas) {
     29         canvas->clear(SK_ColorWHITE);
     30 
     31         SkPaint paint1, paint2, paint3;
     32 
     33         paint1.setTextSize(64.0f);
     34         paint1.setAntiAlias(true);
     35         paint1.setColor(SkColorSetRGB(255, 0, 0);
     36         paint1.setStyle(SkPaint::kFill_Style);
     37 
     38         paint2.setTextSize(64.f);
     39         paint2.setAntiAlias(true);
     40         paint2.setColor(SkColorSetRGB(0, 136, 0);
     41         paint2.setStyle(SkPaint::kStroke_Style);
     42         paint2.setStrokeWidth(SkIntToScalar(3));
     43 
     44         paint3.setTextSize(64.0f);
     45         paint3.setAntiAlias(true);
     46         paint3.setColor(SkColorSetRGB(136, 136, 136));
     47         paint3.setTextScaleX(SkFloatToScalar(1.5f));
     48 
     49         const char text[] = "Skia!";
     50         canvas->drawText(text, strlen(text), 20.0f, 64.0f,  paint1);
     51         canvas->drawText(text, strlen(text), 20.0f, 144.0f, paint2);
     52         canvas->drawText(text, strlen(text), 20.0f, 224.0f, paint3);
     53     }
     54 
     55 <a href="https://fiddle.skia.org/c/c4cfc71ed9232dac9c0d6518311b386e">
     56 <img src="https://fiddle.skia.org/i/c4cfc71ed9232dac9c0d6518311b386e_raster.png"></a>
     57 
     58 This shows three different paints, each set up to draw in a different
     59 style. Now the caller can intermix these paints freely, either using
     60 them as is, or modifying them as the drawing proceeds.
     61 
     62 <!--?prettify lang=cc?-->
     63 
     64     SkPaint paint1, paint2, paint3;
     65     paint2.setStyle(SkPaint::kStroke_Style);
     66     paint2.setStrokeWidth(3);
     67     paint3.setAntiAlias(true);
     68     paint3.setColor(SK_ColorRED);
     69     paint3.setTextSize(80);
     70 
     71     canvas->drawRect(SkRect::MakeXYWH(10,10,60,20), paint1);
     72     canvas->drawRect(SkRect::MakeXYWH(80,10,60,20), paint2);
     73 
     74     paint2.setStrokeWidth(SkIntToScalar(5));
     75     canvas->drawOval(SkRect::MakeXYWH(150,10,60,20), paint2);
     76 
     77     canvas->drawText("SKIA", 4, 20, 120, paint3);
     78     paint3.setColor(SK_ColorBLUE);
     79     canvas->drawText("SKIA", 4, 20, 220, paint3);
     80 
     81 <a href="https://fiddle.skia.org/c/5203b17103f487dd33965b4211d80956">
     82 <img src="https://fiddle.skia.org/i/5203b17103f487dd33965b4211d80956_raster.png"></a>
     83 
     84 Beyond simple attributes such as color, strokes, and text values,
     85 paints support effects. These are subclasses of different aspects of
     86 the drawing pipeline, that when referenced by a paint (each of them is
     87 reference-counted), are called to override some part of the drawing
     88 pipeline.
     89 
     90 For example, to draw using a gradient instead of a single color,
     91 assign a SkShader to the paint.
     92 
     93 <!--?prettify lang=cc?-->
     94 
     95     SkPoint points[2] = {
     96         SkPoint::Make(0.0f, 0.0f),
     97         SkPoint::Make(256.0f, 256.0f)
     98     };
     99     SkColor colors[2] = {SK_ColorBLUE, SK_ColorYELLOW};
    100     SkShader* shader =
    101             SkGradientShader::CreateLinear(
    102                      points, colors, nullptr, 2,
    103                      SkShader::kClamp_TileMode, 0, nullptr);
    104     SkPaint paint;
    105     paint.setShader(shader);
    106     shader->unref();
    107     canvas->drawPaint(paint);
    108 
    109 <a href="https://fiddle.skia.org/c/f91b5310d57744a5a1475b7e47d4a172">
    110 <img src="https://fiddle.skia.org/i/f91b5310d57744a5a1475b7e47d4a172_raster.png"></a>
    111 
    112 Now, anything drawn with that paint will be drawn with the gradient
    113 specified in the call to `CreateLinear()`. The shader object that is
    114 returned is reference-counted. Whenever any effects object, like a
    115 shader, is assigned to a paint, its reference-count is increased by
    116 the paint. To balance this, the caller in the above example calls
    117 `unref()` on the shader once it has assigned it to the paint. Now the
    118 paint is the only "owner" of that shader, and it will automatically
    119 call `unref()` on the shader when either the paint goes out of scope, or
    120 if another shader (or null) is assigned to it.
    121 
    122 There are 6 types of effects that can be assigned to a paint:
    123 
    124 *   **SkPathEffect** - modifications to the geometry (path) before it
    125     generates an alpha mask (e.g. dashing)
    126 *   **SkRasterizer** - composing custom mask layers (e.g. shadows)
    127 *   **SkMaskFilter** - modifications to the alpha mask before it is
    128     colorized and drawn (e.g. blur, emboss)
    129 *   **SkShader** - e.g. gradients (linear, radial, sweep), bitmap patterns
    130     (clamp, repeat, mirror)
    131 *   **SkColorFilter** - modify the source color(s) before applying the
    132     xfermode (e.g. color matrix)
    133 *   **SkXfermode** - e.g. porter-duff transfermodes, blend modes
    134 
    135 Paints also hold a reference to a SkTypeface. The typeface represents
    136 a specific font style, to be used for measuring and drawing
    137 text. Speaking of which, paints are used not only for drawing text,
    138 but also for measuring it.
    139 
    140 <!--?prettify lang=cc?-->
    141 
    142     paint.measureText(...);
    143     paint.getTextBounds(...);
    144     paint.textToGlyphs(...);
    145     paint.getFontMetrics(...);
    146 
    147 <span id="SkXfermode"></span>
    148 
    149 SkXfermode
    150 ----------
    151 
    152 The following example demonstrates all of the Skia's standard transfer
    153 modes.  In this example the source is a solid magenta color with a
    154 horizontal alpha gradient and the destination is a solid cyan color
    155 with a vertical alpha gradient.
    156 
    157 <!--?prettify lang=cc?-->
    158 
    159     SkXfermode::Mode modes[] = {
    160         SkXfermode::kClear_Mode,
    161         SkXfermode::kSrc_Mode,
    162         SkXfermode::kDst_Mode,
    163         SkXfermode::kSrcOver_Mode,
    164         SkXfermode::kDstOver_Mode,
    165         SkXfermode::kSrcIn_Mode,
    166         SkXfermode::kDstIn_Mode,
    167         SkXfermode::kSrcOut_Mode,
    168         SkXfermode::kDstOut_Mode,
    169         SkXfermode::kSrcATop_Mode,
    170         SkXfermode::kDstATop_Mode,
    171         SkXfermode::kXor_Mode,
    172         SkXfermode::kPlus_Mode,
    173         SkXfermode::kModulate_Mode,
    174         SkXfermode::kScreen_Mode,
    175         SkXfermode::kOverlay_Mode,
    176         SkXfermode::kDarken_Mode,
    177         SkXfermode::kLighten_Mode,
    178         SkXfermode::kColorDodge_Mode,
    179         SkXfermode::kColorBurn_Mode,
    180         SkXfermode::kHardLight_Mode,
    181         SkXfermode::kSoftLight_Mode,
    182         SkXfermode::kDifference_Mode,
    183         SkXfermode::kExclusion_Mode,
    184         SkXfermode::kMultiply_Mode,
    185         SkXfermode::kHue_Mode,
    186         SkXfermode::kSaturation_Mode,
    187         SkXfermode::kColor_Mode,
    188         SkXfermode::kLuminosity_Mode,
    189     };
    190     SkRect rect = SkRect::MakeWH(64.0f, 64.0f);
    191     SkPaint text, stroke, src, dst;
    192     stroke.setStyle(SkPaint::kStroke_Style);
    193     text.setTextSize(24.0f);
    194     text.setAntiAlias(true);
    195     SkPoint srcPoints[2] = {
    196         SkPoint::Make(0.0f, 0.0f),
    197         SkPoint::Make(64.0f, 0.0f)
    198     };
    199     SkColor srcColors[2] = {
    200         SK_ColorMAGENTA & 0x00FFFFFF,
    201         SK_ColorMAGENTA};
    202     SkAutoTUnref<SkShader> srcShader(
    203         SkGradientShader::CreateLinear(
    204                 srcPoints, srcColors, nullptr, 2,
    205                 SkShader::kClamp_TileMode, 0, nullptr));
    206     src.setShader(srcShader);
    207 
    208     SkPoint dstPoints[2] = {
    209         SkPoint::Make(0.0f, 0.0f),
    210         SkPoint::Make(0.0f, 64.0f)
    211     };
    212     SkColor dstColors[2] = {
    213         SK_ColorCYAN & 0x00FFFFFF,
    214         SK_ColorCYAN};
    215     SkAutoTUnref<SkShader> dstShader(
    216         SkGradientShader::CreateLinear(
    217                 dstPoints, dstColors, nullptr, 2,
    218                 SkShader::kClamp_TileMode, 0, nullptr));
    219     dst.setShader(dstShader);
    220     canvas->clear(SK_ColorWHITE);
    221     size_t N = sizeof(modes) / sizeof(modes[0]);
    222     size_t K = (N - 1) / 3 + 1;
    223     SkASSERT(K * 64 == 640);  // tall enough
    224     for (size_t i = 0; i < N; ++i) {
    225         SkAutoCanvasRestore autoCanvasRestore(canvas, true);
    226         canvas->translate(192.0f * (i / K), 64.0f * (i % K));
    227         const char* desc = SkXfermode::ModeName(modes[i]);
    228         canvas->drawText(desc, strlen(desc), 68.0f, 30.0f, text);
    229         canvas->clipRect(SkRect::MakeWH(64.0f, 64.0f));
    230         canvas->drawColor(SK_ColorLTGRAY);
    231         (void)canvas->saveLayer(nullptr, nullptr);
    232         canvas->clear(SK_ColorTRANSPARENT);
    233         canvas->drawPaint(dst);
    234         src.setXfermodeMode(modes[i]);
    235         canvas->drawPaint(src);
    236         canvas->drawRect(rect, stroke);
    237     }
    238 
    239 <a href="https://fiddle.skia.org/c/0a2392be5adf339ce6537799f2807f3c"><img src="https://fiddle.skia.org/i/0a2392be5adf339ce6537799f2807f3c_raster.png" alt=""></a>
    240 
    241 <span id="ShShader"></span>
    242 
    243 ShShader
    244 --------
    245 
    246 Several shaders are defined (besides the linear gradient already mentioned):
    247 
    248 *   Bitmap Shader
    249 
    250     <!--?prettify lang=cc?-->
    251 
    252         canvas->clear(SK_ColorWHITE);
    253         SkMatrix matrix;
    254         matrix.setScale(0.75f, 0.75f);
    255         matrix.preRotate(30.0f);
    256         SkShader* shader =
    257             SkShader::CreateBitmapShader(
    258                 source,
    259                 SkShader::kRepeat_TileMode ,
    260                 SkShader::kRepeat_TileMode ,
    261                 &matrix);
    262         SkPaint paint;
    263         paint.setShader(shader);
    264         shader->unref();
    265         canvas->drawPaint(paint);
    266 
    267     <a href="https://fiddle.skia.org/c/0e8d08e0a0b342e9e45c364d0e5cea8a">
    268     <img src="https://fiddle.skia.org/i/0e8d08e0a0b342e9e45c364d0e5cea8a_raster.png"></a>
    269 
    270 *   Radial Gradient Shader
    271 
    272     <!--?prettify lang=cc?-->
    273 
    274         SkColor colors[2] = {SK_ColorBLUE, SK_ColorYELLOW};
    275         SkShader* shader =
    276                 SkGradientShader::CreateRadial(
    277                         SkPoint::Make(128.0f, 128.0f), 180.0f,
    278                         colors, nullptr, 2, SkShader::kClamp_TileMode, 0, nullptr);
    279         SkPaint paint;
    280         paint.setShader(shader);
    281         shader->unref();
    282         canvas->drawPaint(paint);
    283 
    284     <a href="https://fiddle.skia.org/c/601abd2819e38365900bf62286986024">
    285     <img src="https://fiddle.skia.org/i/601abd2819e38365900bf62286986024_raster.png"></a>
    286 
    287 *  Two-Point Conical Gradient Shader
    288 
    289     <!--?prettify lang=cc?-->
    290 
    291         SkColor colors[2] = {SK_ColorBLUE, SK_ColorYELLOW};
    292         SkShader* shader =
    293                 SkGradientShader::CreateTwoPointConical(
    294                          SkPoint::Make(128.0f, 128.0f), 128.0f,
    295                          SkPoint::Make(128.0f, 16.0f), 16.0f,
    296                          colors, nullptr, 2, SkShader::kClamp_TileMode, 0, nullptr);
    297         SkPaint paint;
    298         paint.setShader(shader);
    299         shader->unref();
    300         canvas->drawPaint(paint);
    301 
    302     <a href="https://fiddle.skia.org/c/991f7d67ff1ccebd6c2c4fab18a76edc">
    303     <img src="https://fiddle.skia.org/i/991f7d67ff1ccebd6c2c4fab18a76edc_raster.png"></a>
    304 
    305 
    306 *   Sweep Gradient Shader
    307 
    308     <!--?prettify lang=cc?-->
    309 
    310         SkColor colors[4] = {
    311             SK_ColorCYAN, SK_ColorMAGENTA, SK_ColorYELLOW, SK_ColorCYAN};
    312         SkShader* shader =
    313                 SkGradientShader::CreateSweep(
    314                     128.0f, 128.0f, colors, nullptr, 4, 0, nullptr);
    315         SkPaint paint;
    316         paint.setShader(shader);
    317         shader->unref();
    318         canvas->drawPaint(paint);
    319 
    320     <a href="https://fiddle.skia.org/c/cee9d1831f6679c3d88170f857995d12">
    321     <img src="https://fiddle.skia.org/i/cee9d1831f6679c3d88170f857995d12_raster.png"></a>
    322 
    323 *   Fractal Perlin Noise Shader
    324 
    325     <!--?prettify lang=cc?-->
    326 
    327         canvas->clear(SK_ColorWHITE);
    328         SkShader* shader = SkPerlinNoiseShader::CreateFractalNoise(
    329                  0.05f, 0.05f, 4, 0.0f, nullptr);
    330         SkPaint paint;
    331         paint.setShader(shader);
    332         shader->unref();
    333         canvas->drawPaint(paint);
    334 
    335     <a href="https://fiddle.skia.org/c/cc45c5349c3b31f97da7c1af7f84162a">
    336     <img src="https://fiddle.skia.org/i/cc45c5349c3b31f97da7c1af7f84162a_raster.png"></a>
    337 
    338 *   Turbulence Perlin Noise Shader
    339 
    340     <!--?prettify lang=cc?-->
    341 
    342         canvas->clear(SK_ColorWHITE);
    343         SkShader* shader = SkPerlinNoiseShader::CreateTurbulence(
    344                  0.05f, 0.05f, 4, 0.0f, nullptr);
    345         SkPaint paint;
    346         paint.setShader(shader);
    347         shader->unref();
    348         canvas->drawPaint(paint);
    349 
    350     <a href="https://fiddle.skia.org/c/52729ed3a71b89a6dba4f60e8eb67727">
    351     <img src="https://fiddle.skia.org/i/52729ed3a71b89a6dba4f60e8eb67727_raster.png"></a>
    352 
    353 *   Compose Shader
    354 
    355     <!--?prettify lang=cc?-->
    356 
    357         SkColor colors[2] = {SK_ColorBLUE, SK_ColorYELLOW};
    358         SkShader* shader1 =
    359                 SkGradientShader::CreateRadial(
    360                     SkPoint::Make(128.0f, 128.0f), 180.0f,
    361                     colors, nullptr, 2, SkShader::kClamp_TileMode, 0, nullptr);
    362         SkShader* shader2 = SkPerlinNoiseShader::CreateTurbulence(
    363                  0.025f, 0.025f, 2, 0.0f, nullptr);
    364         SkShader* shader =
    365             new SkComposeShader(shader1, shader2);
    366         SkPaint paint;
    367         paint.setShader(shader);
    368         shader->unref();
    369         shader2->unref();
    370         shader1->unref();
    371         canvas->drawPaint(paint);
    372 
    373     <a href="https://fiddle.skia.org/c/1209b7a29d870302edcc43dc0916e8d5">
    374     <img src="https://fiddle.skia.org/i/1209b7a29d870302edcc43dc0916e8d5_raster.png"></a>
    375 
    376 
    377 <span id="SkMaskFilter"></span>
    378 
    379 SkMaskFilter
    380 ------------
    381 
    382 *   Blur Mask Filter
    383 
    384     <!--?prettify lang=cc?-->
    385 
    386         canvas->drawColor(SK_ColorWHITE);
    387         SkPaint paint;
    388         paint.setAntiAlias(true);
    389         paint.setTextSize(120);
    390         SkMaskFilter* filter =
    391             SkBlurMaskFilter::Create(
    392                 kNormal_SkBlurStyle, 5.0f, 0);
    393         paint.setMaskFilter(filter);
    394         filter->unref();
    395         const char text[] = "Skia";
    396         canvas->drawText(text, strlen(text), 0, 160, paint);
    397 
    398     <a href="https://fiddle.skia.org/c/0e004664122851691d67a291007b64d7">
    399     <img src="https://fiddle.skia.org/i/0e004664122851691d67a291007b64d7_raster.png"></a>
    400 
    401 *   Emboss Mask Filter
    402 
    403     <!--?prettify lang=cc?-->
    404 
    405         canvas->drawColor(SK_ColorWHITE);
    406         SkPaint paint;
    407         paint.setAntiAlias(true);
    408         paint.setTextSize(120);
    409         SkScalar direction[3] = {1.0f, 1.0f, 1.0f};
    410         SkMaskFilter* filter =
    411             SkBlurMaskFilter::CreateEmboss(
    412                 2.0f, direction, 0.3f, 0.1f);
    413         paint.setMaskFilter(filter);
    414         filter->unref();
    415         const char text[] = "Skia";
    416         canvas->drawText(text, strlen(text), 0, 160, paint);
    417 
    418     <a href="https://fiddle.skia.org/c/1ef71be7fb749a2d81a55721b2d2c77d">
    419     <img src="https://fiddle.skia.org/i/1ef71be7fb749a2d81a55721b2d2c77d_raster.png"></a>
    420 
    421 
    422 <span id="SkColorFilter"></span>
    423 
    424 SkColorFilter
    425 -------------
    426 
    427 *   Color Matrix Color Filter
    428 
    429     <!--?prettify lang=cc?-->
    430 
    431         void f(SkCanvas* c, SkScalar x, SkScalar y, SkScalar colorMatrix[20]) {
    432             SkColorFilter* cf = SkColorMatrixFilter::Create(colorMatrix);
    433             SkPaint paint;
    434             paint.setColorFilter(cf);
    435             cf->unref();
    436             c->drawBitmap(source, x, y, &paint);
    437         }
    438         void draw(SkCanvas* c) {
    439             c->scale(0.25, 0.25);
    440             SkScalar colorMatrix1[20] = {
    441                 0, 1, 0, 0, 0,
    442                 0, 0, 1, 0, 0,
    443                 1, 0, 0, 0, 0,
    444                 0, 0, 0, 1, 0};
    445             f(c, 0, 0, colorMatrix1);
    446 
    447             SkScalar grayscale[20] = {
    448                 0.21, 0.72, 0.07, 0.0, 0.0,
    449                 0.21, 0.72, 0.07, 0.0, 0.0,
    450                 0.21, 0.72, 0.07, 0.0, 0.0,
    451                 0.0,  0.0,  0.0,  1.0, 0.0};
    452             f(c, 512, 0, grayscale);
    453 
    454             SkScalar colorMatrix3[20] = {
    455                 -1, 1, 1, 0, 0,
    456                 1, -1, 1, 0, 0,
    457                 1, 1, -1, 0, 0,
    458                 0, 0, 0, 1, 0};
    459             f(c, 0, 512, colorMatrix3);
    460 
    461             SkScalar colorMatrix4[20] = {
    462                 0.0, 0.5, 0.5, 0, 0,
    463                 0.5, 0.0, 0.5, 0, 0,
    464                 0.5, 0.5, 0.0, 0, 0,
    465                 0.0, 0.0, 0.0, 1, 0};
    466             f(c, 512, 512, colorMatrix4);
    467 
    468             SkScalar highContrast[20] = {
    469                 4.0, 0.0, 0.0, 0.0, -4.0 * 255 / (4.0 - 1),
    470                 0.0, 4.0, 0.0, 0.0, -4.0 * 255 / (4.0 - 1),
    471                 0.0, 0.0, 4.0, 0.0, -4.0 * 255 / (4.0 - 1),
    472                 0.0, 0.0, 0.0, 1.0, 0.0};
    473             f(c, 1024, 0, highContrast);
    474 
    475             SkScalar colorMatrix6[20] = {
    476                 0, 0, 1, 0, 0,
    477                 1, 0, 0, 0, 0,
    478                 0, 1, 0, 0, 0,
    479                 0, 0, 0, 1, 0};
    480             f(c, 1024, 512, colorMatrix6);
    481 
    482             SkScalar sepia[20] = {
    483                 0.393, 0.769, 0.189, 0.0, 0.0,
    484                 0.349, 0.686, 0.168, 0.0, 0.0,
    485                 0.272, 0.534, 0.131, 0.0, 0.0,
    486                 0.0,   0.0,   0.0,   1.0, 0.0};
    487             f(c, 1536, 0, sepia);
    488 
    489             SkScalar inverter[20] = {
    490                 -1,  0,  0, 0, 255,
    491                  0, -1,  0, 0, 255,
    492                  0,  0, -1, 0, 255,
    493                  0,  0,  0, 1, 0};
    494             f(c, 1536, 512, inverter);
    495         }
    496 
    497     <a href="https://fiddle.skia.org/c/91fb5341ee7903c9682df20bb3d73dbb">
    498     <img src="https://fiddle.skia.org/i/91fb5341ee7903c9682df20bb3d73dbb_raster.png"></a>
    499 
    500 *   Color Table Color Filter
    501 
    502     <!--?prettify lang=cc?-->
    503 
    504         canvas->scale(0.5, 0.5);
    505         uint8_t ct[256];
    506         for (int i = 0; i < 256; ++i) {
    507             int x = (i - 96) * 255 / 64;
    508             ct[i] = x < 0 ? 0 : x > 255 ? 255 : x;
    509         }
    510         SkColorFilter* cf = SkTableColorFilter::CreateARGB(nullptr, ct, ct, ct);
    511         SkPaint paint;
    512         paint.setColorFilter(cf);
    513         cf->unref();
    514         canvas->drawBitmap(source, 0, 0, &paint);
    515 
    516     <a href="https://fiddle.skia.org/c/0d3d339543afa1b10c60f9826f264c3f">
    517     <img src="https://fiddle.skia.org/i/0d3d339543afa1b10c60f9826f264c3f_raster.png"></a>
    518 
    519 
    520 <span id="SkPathEffect"></span>
    521 
    522 SkPathEffect
    523 ------------
    524 
    525 *   SkPath2DPathEffect: Stamp the specified path to fill the shape,
    526     using the matrix to define the latice.
    527 
    528     <!--?prettify lang=cc?-->
    529 
    530         void draw(SkCanvas* canvas) {
    531             SkScalar scale = 10.0f;
    532             SkPath path;
    533             static const int8_t pts[] = { 2, 2, 1, 3, 0, 3, 2, 1, 3, 1,
    534                  4, 0, 4, 1, 5, 1, 4, 2, 4, 3, 2, 5, 2, 4, 3, 3, 2, 3 };
    535             path.moveTo(2 * scale, 3 * scale);
    536             for (size_t i = 0 ; i < sizeof(pts)/sizeof(pts[0]); i += 2) {
    537                 path.lineTo(pts[i] * scale, pts[i + 1] * scale);
    538             }
    539             path.close();
    540             SkMatrix matrix = SkMatrix::MakeScale(4 * scale);
    541             SkAutoTUnref<SkPathEffect> pathEffect(
    542                     SkPath2DPathEffect::Create(matrix, path));
    543             SkPaint paint;
    544             paint.setPathEffect(pathEffect);
    545             paint.setAntiAlias(true);
    546             canvas->clear(SK_ColorWHITE);
    547             SkRect bounds;
    548             (void)canvas->getClipBounds(&bounds);
    549             bounds.outset(2 * scale, 2 * scale);
    550             canvas->drawRect(bounds, paint);
    551         }
    552 
    553     <a href="https://fiddle.skia.org/c/aae271e4f0178455f0e128981d714d73"><img src="https://fiddle.skia.org/i/aae271e4f0178455f0e128981d714d73_raster.png" alt=""></a>
    554 
    555 *   SkLine2DPathEffect: a special case of SkPath2DPathEffect where the
    556     path is a straight line to be stroked, not a path to be filled.
    557 
    558     <!--?prettify lang=cc?-->
    559 
    560         void draw(SkCanvas* canvas) {
    561             SkPaint paint;
    562             SkMatrix lattice;
    563             lattice.setScale(8.0f, 8.0f);
    564             lattice.preRotate(30.0f);
    565             SkAutoTUnref<SkPathEffect> pe(
    566                 SkLine2DPathEffect::Create(0.0f, lattice));
    567             paint.setPathEffect(pe);
    568             paint.setAntiAlias(true);
    569             SkRect bounds;
    570             (void)canvas->getClipBounds(&bounds);
    571             bounds.outset(8.0f, 8.0f);
    572             canvas->clear(SK_ColorWHITE);
    573             canvas->drawRect(bounds, paint);
    574         }
    575 
    576     <a href="https://fiddle.skia.org/c/3f49502145886920f95d43912e0f550d"><img src="https://fiddle.skia.org/i/3f49502145886920f95d43912e0f550d_raster.png" alt=""></a>
    577 
    578 *   SkPath1DPathEffect: create dash-like effects by replicating the specified path along the drawn path.
    579 
    580     <!--?prettify lang=cc?-->
    581 
    582         void draw(SkCanvas* canvas) {
    583             SkPaint paint;
    584             SkPath path;
    585             path.addOval(SkRect::MakeWH(16.0f, 6.0f));
    586             SkAutoTUnref<SkPathEffect> pe(
    587                 SkPath1DPathEffect::Create(
    588                     path, 32.0f, 0.0f, SkPath1DPathEffect::kRotate_Style));
    589             paint.setPathEffect(pe);
    590             paint.setAntiAlias(true);
    591             canvas->clear(SK_ColorWHITE);
    592             canvas->drawCircle(128.0f, 128.0f, 122.0f, paint);
    593         }
    594 
    595     <a href="https://fiddle.skia.org/c/756a8cdb9458c05f6c1c7c398d979dac"><img src="https://fiddle.skia.org/i/756a8cdb9458c05f6c1c7c398d979dac_raster.png" alt=""></a>
    596 
    597 *   SkArcToPathEffect
    598 
    599 	The following few examples use this function:
    600 
    601     <!--?prettify lang=cc?-->
    602 
    603         SkPath star() {
    604             const SkScalar R = 115.2f, C = 128.0f;
    605             SkPath path;
    606             path.moveTo(C + R, C);
    607             for (int i = 1; i < 7; ++i) {
    608                 SkScalar a = 2.6927937f * i;
    609                 path.lineTo(C + R * cos(a), C + R * sin(a));
    610             }
    611             path.close();
    612             return path;
    613         }
    614 
    615     <!--?prettify lang=cc?-->
    616 
    617         void draw(SkCanvas* canvas) {
    618             SkPaint paint;
    619             SkAutoTUnref<SkPathEffect> pe(
    620                 SkArcToPathEffect::Create(8.0f));
    621             paint.setPathEffect(pe);
    622             paint.setStyle(SkPaint::kStroke_Style);
    623             paint.setAntiAlias(true);
    624             canvas->clear(SK_ColorWHITE);
    625             SkPath path(star());
    626             canvas->drawPath(path, paint);
    627         }
    628 
    629     <a href="https://fiddle.skia.org/c/1cc2a1363dd0e96954e084f7ca29aa5f"><img src="https://fiddle.skia.org/i/1cc2a1363dd0e96954e084f7ca29aa5f_raster.png" alt=""></a>
    630 
    631 *   SkCornerPathEffect: a path effect that can turn sharp corners into
    632     various treatments (e.g. rounded corners).
    633 
    634     <!--?prettify lang=cc?-->
    635 
    636         void draw(SkCanvas* canvas) {
    637             SkPaint paint;
    638             SkAutoTUnref<SkPathEffect> pe(
    639                 SkCornerPathEffect::Create(32.0f));
    640             paint.setPathEffect(pe);
    641             paint.setStyle(SkPaint::kStroke_Style);
    642             paint.setAntiAlias(true);
    643             canvas->clear(SK_ColorWHITE);
    644             const SkScalar R = 115.2f;
    645             SkPath path(star());
    646             canvas->drawPath(path, paint);
    647         }
    648 
    649     <a href="https://fiddle.skia.org/c/f5361bbb33ad43c656dd40bb03ee2114"><img src="https://fiddle.skia.org/i/f5361bbb33ad43c656dd40bb03ee2114_raster.png" alt=""></a>
    650 
    651 *   SkDashPathEffect:  a path effect that implements dashing.
    652 
    653     <!--?prettify lang=cc?-->
    654 
    655         void draw(SkCanvas* canvas) {
    656             const SkScalar intervals[] = { 10.0f, 5.0f, 2.0f, 5.0f };
    657             size_t count  = sizeof(intervals) / sizeof(intervals[0]);
    658             SkAutoTUnref<SkPathEffect> pe(
    659                 SkDashPathEffect::Create(intervals, count, 0.0f));
    660             SkPaint paint;
    661             paint.setPathEffect(pe);
    662             paint.setStyle(SkPaint::kStroke_Style);
    663             paint.setStrokeWidth(2.0f);
    664             paint.setAntiAlias(true);
    665             canvas->clear(SK_ColorWHITE);
    666             SkPath path(star());
    667             canvas->drawPath(path, paint);
    668         }
    669 
    670     <a href="https://fiddle.skia.org/c/d221ced999a80ac23870d0301ffeedad"><img src="https://fiddle.skia.org/i/d221ced999a80ac23870d0301ffeedad_raster.png" alt=""></a>
    671 
    672 *   SkDiscretePathEffect: This path effect chops a path into discrete
    673     segments, and randomly displaces them.
    674 
    675     <!--?prettify lang=cc?-->
    676 
    677         void draw(SkCanvas* canvas) {
    678             SkAutoTUnref<SkPathEffect> pe(
    679                 SkDiscretePathEffect::Create(10.0f, 4.0f));
    680             SkPaint paint;
    681             paint.setPathEffect(pe);
    682             paint.setStyle(SkPaint::kStroke_Style);
    683             paint.setStrokeWidth(2.0f);
    684             paint.setAntiAlias(true);
    685             canvas->clear(SK_ColorWHITE);
    686             SkPath path(star());
    687             canvas->drawPath(path, paint);
    688         }
    689 
    690     <a href="https://fiddle.skia.org/c/af2f177438b376ca45cfffc29cc0177a"><img src="https://fiddle.skia.org/i/af2f177438b376ca45cfffc29cc0177a_raster.png" alt=""></a>
    691 
    692 *   SkComposePathEffect: a pathEffect whose effect is to apply
    693     first the inner pathEffect and the the outer pathEffect (i.e.
    694     outer(inner(path))).
    695 
    696     <!--?prettify lang=cc?-->
    697 
    698         void draw(SkCanvas* canvas) {
    699             SkAutoTUnref<SkPathEffect> pe0(
    700                 SkDiscretePathEffect::Create(10.0f, 4.0f));
    701             const SkScalar intervals[] = { 10.0f, 5.0f, 2.0f, 5.0f };
    702             size_t count  = sizeof(intervals) / sizeof(intervals[0]);
    703             SkAutoTUnref<SkPathEffect> pe1(
    704                 SkDashPathEffect::Create(intervals, count, 0.0f));
    705             SkAutoTUnref<SkPathEffect> pe(
    706                 SkComposePathEffect::Create(pe1, pe0));
    707             SkPaint paint;
    708             paint.setPathEffect(pe);
    709             paint.setStyle(SkPaint::kStroke_Style);
    710             paint.setStrokeWidth(2.0f);
    711             paint.setAntiAlias(true);
    712             canvas->clear(SK_ColorWHITE);
    713             SkPath path(star());
    714             canvas->drawPath(path, paint);
    715         }
    716 
    717     <a href="https://fiddle.skia.org/c/39a644161da79e8b5e49c193adac7173"><img src="https://fiddle.skia.org/i/39a644161da79e8b5e49c193adac7173_raster.png" alt=""></a>
    718 
    719 *    SkSumPathEffect: a pathEffect whose effect is to apply two effects,
    720      in sequence (i.e. first(path) + second(path)).
    721 
    722     <!--?prettify lang=cc?-->
    723 
    724         void draw(SkCanvas* canvas) {
    725             SkAutoTUnref<SkPathEffect> pe0(
    726                 SkDiscretePathEffect::Create(10.0f, 4.0f));
    727             SkAutoTUnref<SkPathEffect> pe1(
    728                 SkDiscretePathEffect::Create(10.0f, 4.0f, 1245u));
    729             SkAutoTUnref<SkPathEffect> pe(
    730                 SkSumPathEffect::Create(pe1, pe0));
    731             SkPaint paint;
    732             paint.setPathEffect(pe);
    733             paint.setStyle(SkPaint::kStroke_Style);
    734             paint.setStrokeWidth(2.0f);
    735             paint.setAntiAlias(true);
    736             canvas->clear(SK_ColorWHITE);
    737             SkPath path(star());
    738             canvas->drawPath(path, paint);
    739         }
    740 
    741     <a href="https://fiddle.skia.org/c/e5f7861072893bd08c305a076bf32958"><img src="https://fiddle.skia.org/i/e5f7861072893bd08c305a076bf32958_raster.png" alt=""></a>
    742 
    743 <!--
    744     <a href="https://fiddle.skia.org/c/"><img src="https://fiddle.skia.org/i/_raster.png" alt=""></a>
    745 -->
    746 
    747