Home | History | Annotate | Download | only in docs
      1 #Topic Blend_Mode
      2 
      3 #PhraseDef list_of_blend_modes
      4 SkBlendMode::kClear, SkBlendMode::kSrc, SkBlendMode::kDst, SkBlendMode::kSrcOver,
      5 SkBlendMode::kDstOver, SkBlendMode::kSrcIn, SkBlendMode::kDstIn,
      6 SkBlendMode::kSrcOut, SkBlendMode::kDstOut, SkBlendMode::kSrcATop,
      7 SkBlendMode::kDstATop, SkBlendMode::kXor, SkBlendMode::kPlus,
      8 SkBlendMode::kModulate, SkBlendMode::kScreen, SkBlendMode::kOverlay,
      9 SkBlendMode::kDarken, SkBlendMode::kLighten, SkBlendMode::kColorDodge,
     10 SkBlendMode::kColorBurn, SkBlendMode::kHardLight, SkBlendMode::kSoftLight,
     11 SkBlendMode::kDifference, SkBlendMode::kExclusion, SkBlendMode::kMultiply,
     12 SkBlendMode::kHue, SkBlendMode::kSaturation, SkBlendMode::kColor,
     13 SkBlendMode::kLuminosity
     14 ##
     15 
     16 #Code
     17 #Populate
     18 ##
     19 
     20 #EnumClass SkBlendMode
     21 #Line # algorithm combining source and destination pixels ##
     22 
     23 # ------------------------------------------------------------------------------
     24 
     25 #Const kClear 0
     26 #Line # replaces destination with zero: fully transparent ##
     27 #Details Clear
     28 Replaces destination with Alpha and Color components set to zero;
     29 a fully transparent pixel.
     30 ##
     31 
     32 #Const kSrc 1
     33 #Line # replaces destination ##
     34 #Details Src
     35 Replaces destination with source. Destination alpha and color component values
     36 are ignored.
     37 ##
     38 
     39 #Const kDst 2
     40 #Line # preserves destination ##
     41 #Details Dst
     42 Preserves destination, ignoring source. Drawing with Paint set to kDst has
     43 no effect.
     44 ##
     45 
     46 #Const kSrcOver 3
     47 #Line # source over destination ##
     48 #Details Src_Over
     49 Replaces destination with source blended with destination. If source is opaque,
     50 replaces destination with source. Used as the default Blend_Mode for SkPaint.
     51 ##
     52 
     53 #Const kDstOver 4
     54 #Line # destination over source ##
     55 #Details Dst_Over
     56 Replaces destination with destination blended with source. If destination is opaque,
     57 has no effect.
     58 ##
     59 
     60 #Const kSrcIn 5
     61 #Line # source trimmed inside destination ##
     62 #Details Src_In
     63 Replaces destination with source using destination opacity.
     64 ##
     65 
     66 #Const kDstIn 6
     67 #Line # destination trimmed by source ##
     68 #Details Dst_In
     69 Scales destination opacity by source opacity. 
     70 ##
     71 
     72 #Const kSrcOut 7
     73 #Line # source trimmed outside destination ##
     74 #Details Src_Out
     75 Replaces destination with source using the inverse of destination opacity,
     76 drawing source fully where destination opacity is zero.
     77 ##
     78 
     79 #Const kDstOut 8
     80 #Line # destination trimmed outside source ##
     81 #Details Dst_Out
     82 Replaces destination opacity with inverse of source opacity. If source is
     83 transparent, has no effect.
     84 ##
     85 
     86 #Const kSrcATop 9
     87 #Line # source inside destination blended with destination ##
     88 #Details Src_Atop
     89 Blends destination with source using read destination opacity.
     90 ##
     91 
     92 #Const kDstATop 10
     93 #Line # destination inside source blended with source ##
     94 #Details Dst_Atop
     95 Blends destination with source using source opacity.
     96 ##
     97 
     98 #Const kXor 11
     99 #Line # each of source and destination trimmed outside the other ##
    100 #Details Xor
    101 Blends destination by exchanging transparency of the source and destination.
    102 ##
    103 
    104 #Const kPlus 12
    105 #Line # sum of colors ##
    106 #Details Plus
    107 Replaces destination with source and destination added together.
    108 ##
    109 
    110 #Const kModulate 13
    111 #Line # product of Premultiplied colors; darkens destination ##
    112 #Details Modulate
    113 Replaces destination with source and destination multiplied together.
    114 ##
    115 
    116 #Const kScreen 14
    117 #Line # multiply inverse of pixels, inverting result; brightens destination ##
    118 #Details Screen
    119 Replaces destination with inverted source and destination multiplied together.
    120 ##
    121 
    122 #Const kLastCoeffMode 14
    123 #Line # last Porter_Duff blend mode ##
    124 ##
    125 
    126 #Const kOverlay 15
    127 #Line # multiply or screen, depending on destination ##
    128 #Details Overlay
    129 Replaces destination with multiply or screen, depending on destination.
    130 ##
    131 
    132 #Const kDarken 16
    133 #Line # darker of source and destination ##
    134 #Details Darken
    135 Replaces destination with darker of source and destination.
    136 ##
    137 
    138 #Const kLighten 17
    139 #Line # lighter of source and destination ##
    140 #Details Lighten
    141 Replaces destination with lighter of source and destination.
    142 ##
    143 
    144 #Const kColorDodge 18
    145 #Line # brighten destination to reflect source ##
    146 #Details Color_Dodge
    147 Makes destination brighter to reflect source.
    148 ##
    149 
    150 #Const kColorBurn 19
    151 #Line # darken destination to reflect source ##
    152 #Details Color_Burn
    153 Makes destination darker to reflect source.
    154 ##
    155 
    156 #Const kHardLight 20
    157 #Line # multiply or screen, depending on source ##
    158 #Details Hard_Light
    159 Makes destination lighter or darker, depending on source.
    160 ##
    161 
    162 #Const kSoftLight 21
    163 #Line # lighten or darken, depending on source ##
    164 #Details Soft_Light
    165 Makes destination lighter or darker, depending on source.
    166 ##
    167 
    168 #Const kDifference 22
    169 #Line # subtract darker from lighter with higher contrast ##
    170 #Details Difference
    171 Subtracts darker from lighter with higher contrast.
    172 ##
    173 
    174 #Const kExclusion 23
    175 #Line # subtract darker from lighter with lower contrast ##
    176 #Details Exclusion
    177 Subtracts darker from lighter with lower contrast.
    178 ##
    179 
    180 #Const kMultiply 24
    181 #Line # multiply source with destination, darkening image ##
    182 #Details Multiply
    183 Multiplies source with destination, darkening image.
    184 ##
    185 
    186 #Const kLastSeparableMode 24
    187 #Line # last blend mode operating separately on components ##
    188 Last blend mode operating separately on components.
    189 ##
    190 
    191 #Const kHue 25
    192 #Line # hue of source with saturation and luminosity of destination ##
    193 #Details Hue
    194 Replaces hue of destination with hue of source, leaving saturation and luminosity
    195 unchanged.
    196 ##
    197 
    198 #Const kSaturation 26
    199 #Line # saturation of source with hue and luminosity of destination ##
    200 #Details Saturation
    201 Replaces saturation of destination saturation hue of source, leaving hue and
    202 luminosity unchanged.
    203 ##
    204 
    205 #Const kColor 27
    206 #Line # hue and saturation of source with luminosity of destination ##
    207 #Details Color
    208 Replaces hue and saturation of destination with hue and saturation of source,
    209 leaving luminosity unchanged.
    210 ##
    211 
    212 #Const kLuminosity 28
    213 #Line # luminosity of source with hue and saturation of destination ##
    214 #Details Luminosity
    215 Replaces luminosity of destination with luminosity of source, leaving hue and
    216 saturation unchanged.
    217 ##
    218 
    219 #Const kLastMode 28
    220 #Line # last valid value ##
    221 Used by tests to iterate through all valid values.
    222 ##
    223 
    224 #NoExample
    225 ##
    226 
    227 #SeeAlso SkCanvas::drawColor SkCanvas::drawVertices SkPaint SkShader::MakeCompose SkXfermodeImageFilter
    228 
    229 #Subtopic Clear
    230 #Line # makes destination pixels transparent ##
    231 SkBlendMode::kClear sets destination to: #Formula # [0, 0] ##. 
    232 Use SkBlendMode::kClear to initialize a buffer to fully transparent pixels when
    233 creating a mask with irregular edges.
    234 
    235 #Example
    236 #Description
    237 SK_ColorYELLOW is ignored because SkBlendMode::kClear ignores the source pixel
    238 value and the destination pixel value, always setting the destination to zero.
    239 ##
    240     canvas->saveLayer(nullptr, nullptr);
    241     canvas->drawColor(SK_ColorYELLOW, SkBlendMode::kClear);
    242     SkPaint paint;
    243     for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
    244         SkColor colors[] = { color, SkColorSetA(color, 0) }; 
    245         paint.setShader(SkGradientShader::MakeRadial({ 64, 64}, 100,
    246                 colors, nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
    247         canvas->drawCircle(64, 64, 100, paint);
    248         canvas->translate(64, 64);
    249     }
    250     canvas->restore();
    251 ##
    252 #SeeAlso SkCanvas::clear
    253 ##
    254 
    255 #Subtopic Src
    256 #Line # replaces destination, ignoring Alpha ##
    257 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component;
    258 SkBlendMode::kSrc sets destination to: #Formula # [Sa, Sc] ##. 
    259 Use SkBlendMode::kSrc to copy one buffer to another. All pixels are copied,
    260 regardless of source and destination Alpha values. As a parameter to
    261 SkCanvas::drawAtlas, selects sprites and ignores colors.
    262 #Example
    263 #Image 3
    264 #Description
    265 SkBlendMode::kSrc does not blend transparent pixels with existing background;
    266 it punches a transparent hole in the existing image.
    267 ##
    268     canvas->drawImage(image, 0, 0);
    269     canvas->clipRect({50, 50, 200, 200});
    270     SkPaint srcBlend;
    271     srcBlend.setBlendMode(SkBlendMode::kSrc);
    272     canvas->saveLayer(nullptr, &srcBlend);
    273     canvas->drawColor(0);
    274     SkPaint transRed;
    275     transRed.setColor(SkColorSetA(SK_ColorRED, 127));
    276     canvas->drawCircle(125, 125, 75, transRed);
    277     canvas->restore();
    278 ##
    279 #SeeAlso SkSurface::draw SkSurface::readPixels
    280 ##
    281 
    282 #Subtopic Dst
    283 #Line # preserves destination, ignoring source ##
    284 Given: #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    285  SkBlendMode::kDst preserves destination set to: #Formula # [Da, Dc] ##.
    286 Setting Paint Blend_Mode to SkBlendMode::kDst causes drawing with
    287 Paint to have no effect. As a parameter to SkCanvas::drawAtlas,
    288 selects colors and ignores sprites.
    289 #Example
    290 #Image 3
    291   SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 125, 128 } };
    292   SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
    293   SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
    294   canvas->drawAtlas(image.get(), xforms, tex, colors, 2, SkBlendMode::kSrc, nullptr, nullptr);
    295   canvas->translate(128, 0);
    296   canvas->drawAtlas(image.get(), xforms, tex, colors, 2, SkBlendMode::kDst, nullptr, nullptr);
    297 ##
    298 ##
    299 
    300 #Subtopic Src_Over
    301 #Line # blends source with destination ##
    302 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    303 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    304 SkBlendMode::kSrcOver replaces destination with: #Formula # [Sa + Da * (1 - Sa), Sc + Dc * (1 - Sa)] ##,
    305 drawing source over destination. SkBlendMode::kSrcOver is the default for Paint.
    306 
    307 SkBlendMode::kSrcOver cannot make destination more transparent; the result will
    308 be at least as opaque as the less transparent of source and original destination.
    309 #Example
    310     SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    311     SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    312     SkPaint paint;
    313     paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
    314             SkShader::kClamp_TileMode));
    315     canvas->drawPaint(paint);
    316     paint.setBlendMode(SkBlendMode::kDstIn);
    317     SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    318     SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    319     paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
    320             SkShader::kClamp_TileMode));
    321     canvas->drawPaint(paint);
    322     canvas->clipRect( { 30, 30, 226, 226 } );
    323     canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kSrcOver);
    324 ##
    325 ##
    326 
    327 #Subtopic Dst_Over
    328 #Line # blends destination with source ##
    329 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    330 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    331 SkBlendMode::kDstOver replaces destination with: #Formula # [Da + Sa * (1 - Da), Dc + Sc * (1 - Da)] ##,
    332 drawing destination over source. Has no effect destination if is opaque.
    333 #Example
    334     SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    335     SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    336     SkPaint paint;
    337     paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
    338             SkShader::kClamp_TileMode));
    339     canvas->drawPaint(paint);
    340     paint.setBlendMode(SkBlendMode::kDstIn);
    341     SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    342     SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    343     paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
    344             SkShader::kClamp_TileMode));
    345     canvas->drawPaint(paint);
    346     canvas->clipRect( { 30, 30, 226, 226 } );
    347     canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kDstOver);
    348 ##
    349 ##
    350 
    351 #Subtopic Src_In
    352 #Line # source trimmed inside destination ##
    353 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    354 #Formula # Da ## as destination Alpha;
    355 SkBlendMode::kSrcIn replaces destination with: #Formula # [Sa * Da, Sc * Da] ##,
    356 drawing source with destination opacity.
    357 #Example
    358     SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    359     SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    360     SkPaint paint;
    361     paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
    362             SkShader::kClamp_TileMode));
    363     canvas->drawPaint(paint);
    364     paint.setBlendMode(SkBlendMode::kDstIn);
    365     SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    366     SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    367     paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
    368             SkShader::kClamp_TileMode));
    369     canvas->drawPaint(paint);
    370     canvas->clipRect( { 30, 30, 226, 226 } );
    371     canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kSrcIn);
    372 ##
    373 ##
    374 
    375 #Subtopic Dst_In
    376 #Line # destination trimmed by source ##
    377 Given: #Formula # Sa ## as source Alpha,
    378 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    379 SkBlendMode::kDstIn replaces destination with: #Formula # [Da * Sa, Dc * Sa] ##,
    380 scaling destination Alpha by source Alpha. Resulting
    381 destination is visible where source is visible.
    382 #Example
    383     SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    384     SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    385     SkPaint paint;
    386     paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
    387             SkShader::kClamp_TileMode));
    388     canvas->drawPaint(paint);
    389     paint.setBlendMode(SkBlendMode::kDstIn);
    390     SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    391     SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    392     paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
    393             SkShader::kClamp_TileMode));
    394     canvas->drawPaint(paint);
    395     canvas->clipRect( { 30, 30, 226, 226 } );
    396     canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kDstIn);
    397 ##
    398 ##
    399 
    400 #Subtopic Src_Out
    401 #Line # source trimmed outside destination ##
    402 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    403 #Formula # Da ## as destination Alpha;
    404 SkBlendMode::kSrcOut replaces destination with: #Formula # [Sa * (1 - Da), Sc * (1 - Da)] ##,
    405 drawing source fully where destination Alpha is zero. Is destination
    406 is opaque, has no effect.
    407 #Example
    408     SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    409     SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    410     SkPaint paint;
    411     paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
    412             SkShader::kClamp_TileMode));
    413     canvas->drawPaint(paint);
    414     paint.setBlendMode(SkBlendMode::kDstIn);
    415     SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    416     SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    417     paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
    418             SkShader::kClamp_TileMode));
    419     canvas->drawPaint(paint);
    420     canvas->clipRect( { 30, 30, 226, 226 } );
    421     canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kSrcOut);
    422 ##
    423 ##
    424 
    425 #Subtopic Dst_Out
    426 #Line # destination trimmed outside source ##
    427 Given: #Formula # Sa ## as source Alpha,
    428 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    429 SkBlendMode::kDstOut replaces destination with: #Formula # [Da * (1 - Sa), Dc * (1 - Sa)] ##,
    430 scaling destination Alpha by source transparency. Resulting
    431 destination is visible where source is transparent. If source is transparent,
    432 has no effect.
    433 #Example
    434     SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    435     SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    436     SkPaint paint;
    437     paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
    438             SkShader::kClamp_TileMode));
    439     canvas->drawPaint(paint);
    440     paint.setBlendMode(SkBlendMode::kDstIn);
    441     SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    442     SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    443     paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
    444             SkShader::kClamp_TileMode));
    445     canvas->drawPaint(paint);
    446     canvas->clipRect( { 30, 30, 226, 226 } );
    447     canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kDstOut);
    448 ##
    449 ##
    450 
    451 #Subtopic Src_Atop
    452 #Line # source inside destination over destination ##
    453 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    454 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    455 SkBlendMode::kSrcATop replaces destination with: #Formula # [Da, Sc * Da + Dc * (1 - Sa)] ##,
    456 replacing opaque destination with opaque source. If source or destination
    457 is transparent, has no effect.
    458 #Example
    459     SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    460     SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    461     SkPaint paint;
    462     paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
    463             SkShader::kClamp_TileMode));
    464     canvas->drawPaint(paint);
    465     paint.setBlendMode(SkBlendMode::kDstIn);
    466     SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    467     SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    468     paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
    469             SkShader::kClamp_TileMode));
    470     canvas->drawPaint(paint);
    471     canvas->clipRect( { 30, 30, 226, 226 } );
    472     canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kSrcATop);
    473 ##
    474 ##
    475 
    476 #Subtopic Dst_Atop
    477 #Line # destination inside source over source ##
    478 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    479 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    480 SkBlendMode::kDstATop replaces destination with: #Formula # [Sa, Dc * Sa + Sc * (1 - Da)] ##,
    481 making destination transparent where source is transparent.
    482 #Example
    483     SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    484     SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    485     SkPaint paint;
    486     paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
    487             SkShader::kClamp_TileMode));
    488     canvas->drawPaint(paint);
    489     paint.setBlendMode(SkBlendMode::kDstATop);
    490     SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    491     SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    492     paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
    493             SkShader::kClamp_TileMode));
    494     canvas->drawPaint(paint);
    495     canvas->clipRect( { 30, 30, 226, 226 } );
    496     canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kSrcATop);
    497 ##
    498 ##
    499 
    500 #Subtopic Xor
    501 #Line # each of source and destination trimmed outside the other ##
    502 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    503 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    504 SkBlendMode::kXor replaces destination with:
    505 #Formula # [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa)] ##,
    506 exchanging the transparency of the source and destination.
    507 #Example
    508    SkPaint paint;
    509    paint.setBlendMode(SkBlendMode::kXor);
    510    for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
    511        SkColor colors[] = { color, SkColorSetA(color, 192), SkColorSetA(color, 128),
    512                             SkColorSetA(color, 0) }; 
    513        paint.setShader(SkGradientShader::MakeRadial({ 64, 64}, 100,
    514                colors, nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
    515        canvas->drawCircle(64, 64, 100, paint);
    516        canvas->translate(64, 64);
    517    }
    518 ##
    519 ##
    520 
    521 #Subtopic Plus
    522 #Line # sum of colors ##
    523 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    524 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    525 SkBlendMode::kPlus replaces destination with: #Formula # [Sa + Da, Sc + Dc] ##,
    526 summing the Alpha and Color components.
    527 #Example
    528    canvas->drawColor(SK_ColorBLACK);
    529    SkPaint paint;
    530    paint.setBlendMode(SkBlendMode::kPlus);
    531    for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
    532        SkColor colors[] = { color, SkColorSetA(color, 192), SkColorSetA(color, 128),
    533                             SkColorSetA(color, 0) }; 
    534        paint.setShader(SkGradientShader::MakeRadial({ 64, 64}, 100,
    535                colors, nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
    536        canvas->drawCircle(64, 64, 100, paint);
    537        canvas->translate(64, 64);
    538    }
    539 ##
    540 ##
    541 
    542 #Subtopic Modulate
    543 #Line # product of Premultiplied colors; darkens destination ##
    544 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    545 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    546 SkBlendMode::kModulate replaces destination with: #Formula # [Sa * Da, Sc * Dc] ##,
    547 scaling Alpha and Color components by the lesser of the values.
    548 SkBlendMode::kModulate differs from SkBlendMode::kMultiply in two ways.
    549 SkBlendMode::kModulate like SkBlendMode::kSrcATop alters the destination inside
    550 the destination area, as if the destination Alpha defined the boundaries of a
    551 soft clip. SkBlendMode::kMultiply like SkBlendMode::kSrcOver can alter the
    552 destination where the destination is transparent.
    553 SkBlendMode::kModulate computes the product of the source and destination using
    554 Premultiplied component values. SkBlendMode::kMultiply the product of the source
    555 and destination using Unpremultiplied component values.
    556 #Example
    557 #Description
    558     If source and destination are opaque, SkBlendMode::kModulate and
    559     SkBlendMode::kMultiply produce the same results.
    560 ##
    561     auto drawSquare = [=](int dx, int dy, SkBlendMode mode, const char* label) -> void {
    562         const SkColor colors[] = { SK_ColorBLACK, SK_ColorWHITE };
    563         const SkPoint horz[] = { { 0, 0 }, { 128, 0 } };
    564         SkPaint paint;
    565         paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
    566                 SkShader::kClamp_TileMode));
    567         paint.setBlendMode(mode);
    568         canvas->translate(dx, dy);
    569         canvas->drawRect({0, 0, 128, 128}, paint);
    570         paint.setBlendMode(SkBlendMode::kXor);
    571         canvas->drawString(label, 40, 100, paint);
    572     };
    573     drawSquare(0, 0, SkBlendMode::kSrc, "destination");
    574     drawSquare(128, 0, SkBlendMode::kSrc, "");
    575     drawSquare(0, 128, SkBlendMode::kSrc, "");
    576     canvas->translate(-128, -128);
    577     canvas->rotate(90, 0, 128);
    578     drawSquare(0, 0, SkBlendMode::kSrc, "source");
    579     drawSquare(0, -128, SkBlendMode::kModulate, "modulate");
    580     drawSquare(-128, 0, SkBlendMode::kMultiply, "multiply");
    581 ##
    582 ##
    583 
    584 #Subtopic Screen
    585 #Line # multiply inverse of pixels, inverting result; brightens destination ##
    586 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    587 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    588 SkBlendMode::kScreen replaces destination with: #Formula # [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] ##.
    589 
    590 #Example
    591     SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    592     SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    593     SkPaint paint;
    594     paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
    595             SkShader::kClamp_TileMode));
    596     canvas->drawPaint(paint);
    597     paint.setBlendMode(SkBlendMode::kDstATop);
    598     SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    599     SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    600     paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
    601             SkShader::kClamp_TileMode));
    602     canvas->drawPaint(paint);
    603     canvas->clipRect( { 30, 30, 226, 226 } );
    604     canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kScreen);
    605 ##
    606 ##
    607 
    608 #Subtopic Overlay
    609 #Line # multiply or screen, depending on destination ##
    610 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    611 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    612 SkBlendMode::kOverlay replaces destination with:
    613 #Formula # [Sa + Da - Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa) +
    614     (2 * Dc <= Da ? 2 * Sc * Dc : Sa * Da - 2 * (Da - Dc) * (Sa - Sc))] ##.
    615 #Example
    616     SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    617     SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    618     SkPaint paint;
    619     paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
    620             SkShader::kClamp_TileMode));
    621     canvas->drawPaint(paint);
    622     paint.setBlendMode(SkBlendMode::kDstATop);
    623     SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    624     SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    625     paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
    626             SkShader::kClamp_TileMode));
    627     canvas->drawPaint(paint);
    628     canvas->clipRect( { 30, 30, 226, 226 } );
    629     canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kOverlay);
    630 ##
    631 ##
    632 
    633 #Subtopic Darken
    634 #Line # darker of source and destination ##
    635 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    636 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    637 SkBlendMode::kDarken replaces destination with:
    638 #Formula # [Sa + Da - Sa * Da,  Sc + Dc - max(Sc * Da, Dc * Sa)] ##.
    639 SkBlendMode::kDarken does not make an image darker; it replaces the destination
    640 component with source if source is darker. 
    641 #Example
    642 #Image 3
    643     canvas->drawImage(image, 0, 0);
    644     SkColor colors[] = { SK_ColorWHITE, SK_ColorBLACK };
    645     SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    646     SkPaint paint;
    647     paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
    648             SkShader::kClamp_TileMode));
    649     paint.setBlendMode(SkBlendMode::kDarken);
    650     canvas->drawPaint(paint);
    651 ##
    652 ##
    653 
    654 #Subtopic Lighten
    655 #Line # lighter of source and destination ##
    656 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    657 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    658 SkBlendMode::kLighten replaces destination with:
    659 #Formula # [Sa + Da - Sa * Da,  Sc + Dc - min(Sc * Da, Dc * Sa)] ##. 
    660 SkBlendMode::kDarken does not make an image lighter; it replaces the destination
    661 component with source if source is lighter. 
    662 #Example
    663 #Image 3
    664     canvas->drawImage(image, 0, 0);
    665     SkColor colors[] = { SK_ColorBLACK, SK_ColorWHITE };
    666     SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    667     SkPaint paint;
    668     paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
    669             SkShader::kClamp_TileMode));
    670     paint.setBlendMode(SkBlendMode::kLighten);
    671     canvas->drawPaint(paint);
    672 ##
    673 ##
    674 
    675 #Subtopic Color_Dodge
    676 #Line # brighten destination to reflect source ##
    677 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    678 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    679 SkBlendMode::kColorDodge replaces destination with:
    680 #Formula # [Sa + Da - Sa * Da, Dc == 0 ? Sc * (1 - Da) : Sc == Sa ? Sc + Da * (1 - Sa) :
    681             Sa * min(Da, Dc * Sa / (Sa - Sc)) + Sc * (1 - Da) + Da * (1 - Sa)] ##,
    682 making destination brighter to reflect source.
    683 #Example
    684 #Image 3
    685     canvas->drawImage(image, 0, 0);
    686     canvas->clipRect({128, 0, 256, 256});
    687     canvas->drawColor(SkColorSetARGB(0x80, 0x90, 0x90, 0x90), SkBlendMode::kColorDodge);
    688 ##
    689 ##
    690 
    691 #Subtopic Color_Burn
    692 #Line # darken destination to reflect source ##
    693 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    694 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    695 SkBlendMode::kColorBurn replaces destination with:
    696 #Formula # [Sa + Da - Sa * Da, Dc == Da ? Dc + Sc * (1 - Da) : Sc == 0 ? Da * (1 - Sa) :
    697             Sa * (Da - min(Da, (Da - Dc) * Sa / Sc)) + Sc * (1 - Da) + Da * (1 - Sa)] ##,
    698 making destination darker to reflect source.
    699 #Example
    700 #Image 3
    701     canvas->drawImage(image, 0, 0);
    702     canvas->clipRect({128, 0, 256, 256});
    703     canvas->drawColor(SkColorSetARGB(0x80, 0x90, 0x90, 0x90), SkBlendMode::kColorBurn);
    704 ##
    705 ##
    706 
    707 #Subtopic Hard_Light
    708 #Line # multiply or screen, depending on source ##
    709 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    710 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    711 SkBlendMode::kHardLight replaces destination with:
    712 #Formula # [Sa + Da - Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa) +
    713         2 * Sc <= Sa ? 2 * Sc * Dc : Sa * Da - 2 * (Da - Dc) * (Sa - Sc)] ##,
    714 making destination lighter or darker, depending on source.
    715 #Example
    716 #Image 3
    717    canvas->drawImage(image, 0, 0);
    718    const SkColor colors[] = { 0xFFFFFFFF, 0x00000000 };
    719    SkPaint paint;
    720    paint.setBlendMode(SkBlendMode::kHardLight);
    721    paint.setShader(SkGradientShader::MakeRadial({ 128, 128}, 100, colors,
    722         nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
    723    canvas->clipRect({0, 128, 256, 256});
    724    canvas->drawPaint(paint);
    725 ##
    726 ##
    727 
    728 #Subtopic Soft_Light
    729 #Line # lighten or darken, depending on source ##
    730 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    731 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    732 where #Formula # m = Da > 0 ? Dc / Da : 0 ##;
    733 SkBlendMode::kSoftLight replaces destination with: #Formula # [Sa + Da - Sa * Da, Sc / Da + Dc / Sa +
    734     (2 * Sc <= Sa ? Dc * (Sa + (2 * Sc - Sa) * (1 - m)) : Dc * Sa + Da * (2 * Sc - Sa) *
    735     (4 * Dc <= Da ? (16 * m * m  + 4 * m) * (m - 1) + 7 * m : sqrt(m) - m))] ##,
    736 making destination lighter or darker, depending on source.
    737 #Example
    738 #Image 3
    739    const SkColor colors[] = { 0xFFFFFFFF, 0x3FFFFFFF };
    740    SkPaint paint;
    741    paint.setBlendMode(SkBlendMode::kSoftLight);
    742    paint.setShader(SkGradientShader::MakeRadial({ 128, 128}, 100, colors,
    743         nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
    744    canvas->drawImage(image, 0, 0);
    745    canvas->drawCircle(128, 128, 100, paint);
    746 ##
    747 ##
    748 
    749 #Subtopic Difference
    750 #Line # subtract darker from lighter with higher contrast ##
    751 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    752 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    753 SkBlendMode::kDifference replaces destination with:
    754 #Formula # [Sa + Da - Sa * Da, Sc + Dc - 2 * min(Sc * Da, Dc * Sa)] ##,
    755 replacing destination with lighter less darker.
    756 #Example
    757 #Image 5
    758     canvas->drawImage(image, 0, 0);
    759     canvas->drawImage(image, 128, 0);
    760     canvas->drawImage(image, 0, 128);
    761     canvas->drawImage(image, 128, 128);
    762     SkPaint paint;
    763     paint.setBlendMode(SkBlendMode::kDstATop);
    764     SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    765     SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    766     paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
    767             SkShader::kClamp_TileMode));
    768     canvas->drawPaint(paint);
    769     canvas->clipRect( { 30, 30, 226, 226 } );
    770     canvas->drawColor(0x80bb9977, SkBlendMode::kDifference);
    771 ##
    772 ##
    773 
    774 #Subtopic Exclusion
    775 #Line # subtract darker from lighter with lower contrast ##
    776 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    777 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    778 SkBlendMode::kExclusion replaces destination with:
    779 #Formula # [Sa + Da - Sa * Da, Sc + Dc - 2 * Sc * Dc] ##,
    780 replacing destination with lighter less darker, ignoring Alpha.
    781 #Example
    782 #Image 5
    783     canvas->drawImage(image, 0, 0);
    784     canvas->drawImage(image, 128, 0);
    785     canvas->drawImage(image, 0, 128);
    786     canvas->drawImage(image, 128, 128);
    787     SkPaint paint;
    788     paint.setBlendMode(SkBlendMode::kDstATop);
    789     SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    790     SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    791     paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
    792             SkShader::kClamp_TileMode));
    793     canvas->drawPaint(paint);
    794     canvas->clipRect( { 30, 30, 226, 226 } );
    795     canvas->drawColor(0x80bb9977, SkBlendMode::kExclusion);
    796 ##
    797 ##
    798 
    799 #Subtopic Multiply
    800 #Line # multiply source with destination, darkening image ##
    801 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
    802 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
    803 SkBlendMode::kMultiply replaces destination with:
    804 #Formula # [Sa + Da - Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa) + Sc * Dc] ##,
    805 the product of Unpremultiplied source and destination.
    806 SkBlendMode::kMultiply makes the image darker.
    807 #Example
    808 #Image 5
    809     canvas->drawImage(image, 0, 0);
    810     canvas->drawImage(image, 128, 0);
    811     canvas->drawImage(image, 0, 128);
    812     canvas->drawImage(image, 128, 128);
    813     SkPaint paint;
    814     paint.setBlendMode(SkBlendMode::kDstATop);
    815     SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    816     SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    817     paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
    818             SkShader::kClamp_TileMode));
    819     canvas->drawPaint(paint);
    820     canvas->clipRect( { 30, 30, 226, 226 } );
    821     canvas->drawColor(0x80bb9977, SkBlendMode::kMultiply);
    822 ##
    823 ##
    824 
    825 #Subtopic Hue
    826 #Line # hue of source with saturation and luminosity of destination ##
    827 Given: #Formula # Sa ## as source Alpha, #Formula # S ## as source Color,
    828 #Formula # Da ## as destination Alpha, #Formula # D ## as destination Color;
    829 SkBlendMode::kHue replaces destination with:
    830 #Formula # [Sa + Da - Sa * Da, SetLuminosity(SetSaturation(S, Saturation(D)), Luminosity(D))] ##,
    831 source hue, leaving destination luminosity and saturation unchanged.
    832 #Example
    833 #Image 3
    834 canvas->drawImage(image, 0, 0);
    835 canvas->drawColor(0xFF00FF00, SkBlendMode::kHue);
    836 ##
    837 ##
    838 
    839 #Subtopic Saturation
    840 #Line # saturation of source with hue and luminosity of destination ##
    841 Given: #Formula # Sa ## as source Alpha, #Formula # S ## as source Color,
    842 #Formula # Da ## as destination Alpha, #Formula # D ## as destination Color;
    843 SkBlendMode::kHue replaces destination with:
    844 #Formula # [Sa + Da - Sa * Da, SetLuminosity(SetSaturation(D, Saturation(S)), Luminosity(D))] ##,
    845 source hue, leaving destination luminosity and saturation unchanged.
    846 #Example
    847 #Image 3
    848 canvas->drawImage(image, 0, 0);
    849 canvas->drawColor(0xFF00FF00, SkBlendMode::kSaturation);
    850 ##
    851 ##
    852 
    853 #Subtopic Color
    854 #Line # hue and saturation of source with luminosity of destination ##
    855 Given: #Formula # Sa ## as source Alpha, #Formula # S ## as source Color,
    856 #Formula # Da ## as destination Alpha, #Formula # D ## as destination Color;
    857 SkBlendMode::kColor replaces destination with:
    858 #Formula # [Sa + Da - Sa * Da, SetLuminosity(S, Luminosity(D))] ##,
    859 source hue and saturation, leaving destination luminosity unchanged.
    860 #Example
    861 #Image 3
    862 canvas->drawImage(image, 0, 0);
    863 canvas->drawColor(0xFF00FF00, SkBlendMode::kColor);
    864 ##
    865 ##
    866 
    867 #Subtopic Luminosity
    868 #Line # luminosity of source with hue and saturation of destination ##
    869 Given: #Formula # Sa ## as source Alpha, #Formula # S ## as source Color,
    870 #Formula # Da ## as destination Alpha, #Formula # D ## as destination Color;
    871 SkBlendMode::kLuminosity replaces destination with:
    872 #Formula # [Sa + Da - Sa * Da, SetLuminosity(D, Luminosity(S))] ##,
    873 source luminosity, leaving destination hue and saturation unchanged.
    874 #Example
    875 #Image 3
    876 canvas->drawImage(image, 0, 0);
    877 canvas->drawColor(0xFF00FF00, SkBlendMode::kLuminosity);
    878 ##
    879 ##
    880 
    881 #EnumClass SkBlendMode ##
    882 
    883 # ------------------------------------------------------------------------------
    884 
    885 #Method const char* SkBlendMode_Name(SkBlendMode blendMode)
    886 #In Utility
    887 #Line # returns mode as C string ##
    888 #Populate
    889 
    890 #Example
    891 SkDebugf("default blend: SkBlendMode::k%s\n", SkBlendMode_Name(SkPaint().getBlendMode()));
    892 #StdOut
    893 default blend: SkBlendMode::kSrcOver
    894 ##
    895 ##
    896 
    897 #SeeAlso SkBlendMode
    898 
    899 #Method ##
    900 
    901 #Topic Blend_Mode ##
    902