#Topic Blend_Mode

#PhraseDef list_of_blend_modes
SkBlendMode::kClear, SkBlendMode::kSrc, SkBlendMode::kDst, SkBlendMode::kSrcOver,
SkBlendMode::kDstOver, SkBlendMode::kSrcIn, SkBlendMode::kDstIn,
SkBlendMode::kSrcOut, SkBlendMode::kDstOut, SkBlendMode::kSrcATop,
SkBlendMode::kDstATop, SkBlendMode::kXor, SkBlendMode::kPlus,
SkBlendMode::kModulate, SkBlendMode::kScreen, SkBlendMode::kOverlay,
SkBlendMode::kDarken, SkBlendMode::kLighten, SkBlendMode::kColorDodge,
SkBlendMode::kColorBurn, SkBlendMode::kHardLight, SkBlendMode::kSoftLight,
SkBlendMode::kDifference, SkBlendMode::kExclusion, SkBlendMode::kMultiply,
SkBlendMode::kHue, SkBlendMode::kSaturation, SkBlendMode::kColor,
SkBlendMode::kLuminosity
##

#Code
#Populate
##

#EnumClass SkBlendMode
#Line # algorithm combining source and destination pixels ##

# ------------------------------------------------------------------------------

#Const kClear 0
#Line # replaces destination with zero: fully transparent ##
#Details Clear
Replaces destination with Alpha and Color components set to zero;
a fully transparent pixel.
##

#Const kSrc 1
#Line # replaces destination ##
#Details Src
Replaces destination with source. Destination alpha and color component values
are ignored.
##

#Const kDst 2
#Line # preserves destination ##
#Details Dst
Preserves destination, ignoring source. Drawing with Paint set to kDst has
no effect.
##

#Const kSrcOver 3
#Line # source over destination ##
#Details Src_Over
Replaces destination with source blended with destination. If source is opaque,
replaces destination with source. Used as the default Blend_Mode for SkPaint.
##

#Const kDstOver 4
#Line # destination over source ##
#Details Dst_Over
Replaces destination with destination blended with source. If destination is opaque,
has no effect.
##

#Const kSrcIn 5
#Line # source trimmed inside destination ##
#Details Src_In
Replaces destination with source using destination opacity.
##

#Const kDstIn 6
#Line # destination trimmed by source ##
#Details Dst_In
Scales destination opacity by source opacity. 
##

#Const kSrcOut 7
#Line # source trimmed outside destination ##
#Details Src_Out
Replaces destination with source using the inverse of destination opacity,
drawing source fully where destination opacity is zero.
##

#Const kDstOut 8
#Line # destination trimmed outside source ##
#Details Dst_Out
Replaces destination opacity with inverse of source opacity. If source is
transparent, has no effect.
##

#Const kSrcATop 9
#Line # source inside destination blended with destination ##
#Details Src_Atop
Blends destination with source using read destination opacity.
##

#Const kDstATop 10
#Line # destination inside source blended with source ##
#Details Dst_Atop
Blends destination with source using source opacity.
##

#Const kXor 11
#Line # each of source and destination trimmed outside the other ##
#Details Xor
Blends destination by exchanging transparency of the source and destination.
##

#Const kPlus 12
#Line # sum of colors ##
#Details Plus
Replaces destination with source and destination added together.
##

#Const kModulate 13
#Line # product of Premultiplied colors; darkens destination ##
#Details Modulate
Replaces destination with source and destination multiplied together.
##

#Const kScreen 14
#Line # multiply inverse of pixels, inverting result; brightens destination ##
#Details Screen
Replaces destination with inverted source and destination multiplied together.
##

#Const kLastCoeffMode 14
#Line # last Porter_Duff blend mode ##
##

#Const kOverlay 15
#Line # multiply or screen, depending on destination ##
#Details Overlay
Replaces destination with multiply or screen, depending on destination.
##

#Const kDarken 16
#Line # darker of source and destination ##
#Details Darken
Replaces destination with darker of source and destination.
##

#Const kLighten 17
#Line # lighter of source and destination ##
#Details Lighten
Replaces destination with lighter of source and destination.
##

#Const kColorDodge 18
#Line # brighten destination to reflect source ##
#Details Color_Dodge
Makes destination brighter to reflect source.
##

#Const kColorBurn 19
#Line # darken destination to reflect source ##
#Details Color_Burn
Makes destination darker to reflect source.
##

#Const kHardLight 20
#Line # multiply or screen, depending on source ##
#Details Hard_Light
Makes destination lighter or darker, depending on source.
##

#Const kSoftLight 21
#Line # lighten or darken, depending on source ##
#Details Soft_Light
Makes destination lighter or darker, depending on source.
##

#Const kDifference 22
#Line # subtract darker from lighter with higher contrast ##
#Details Difference
Subtracts darker from lighter with higher contrast.
##

#Const kExclusion 23
#Line # subtract darker from lighter with lower contrast ##
#Details Exclusion
Subtracts darker from lighter with lower contrast.
##

#Const kMultiply 24
#Line # multiply source with destination, darkening image ##
#Details Multiply
Multiplies source with destination, darkening image.
##

#Const kLastSeparableMode 24
#Line # last blend mode operating separately on components ##
Last blend mode operating separately on components.
##

#Const kHue 25
#Line # hue of source with saturation and luminosity of destination ##
#Details Hue
Replaces hue of destination with hue of source, leaving saturation and luminosity
unchanged.
##

#Const kSaturation 26
#Line # saturation of source with hue and luminosity of destination ##
#Details Saturation
Replaces saturation of destination saturation hue of source, leaving hue and
luminosity unchanged.
##

#Const kColor 27
#Line # hue and saturation of source with luminosity of destination ##
#Details Color
Replaces hue and saturation of destination with hue and saturation of source,
leaving luminosity unchanged.
##

#Const kLuminosity 28
#Line # luminosity of source with hue and saturation of destination ##
#Details Luminosity
Replaces luminosity of destination with luminosity of source, leaving hue and
saturation unchanged.
##

#Const kLastMode 28
#Line # last valid value ##
Used by tests to iterate through all valid values.
##

#NoExample
##

#SeeAlso SkCanvas::drawColor SkCanvas::drawVertices SkPaint SkShader::MakeCompose SkXfermodeImageFilter

#Subtopic Clear
#Line # makes destination pixels transparent ##
SkBlendMode::kClear sets destination to: #Formula # [0, 0] ##. 
Use SkBlendMode::kClear to initialize a buffer to fully transparent pixels when
creating a mask with irregular edges.

#Example
#Description
SK_ColorYELLOW is ignored because SkBlendMode::kClear ignores the source pixel
value and the destination pixel value, always setting the destination to zero.
##
    canvas->saveLayer(nullptr, nullptr);
    canvas->drawColor(SK_ColorYELLOW, SkBlendMode::kClear);
    SkPaint paint;
    for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
        SkColor colors[] = { color, SkColorSetA(color, 0) }; 
        paint.setShader(SkGradientShader::MakeRadial({ 64, 64}, 100,
                colors, nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
        canvas->drawCircle(64, 64, 100, paint);
        canvas->translate(64, 64);
    }
    canvas->restore();
##
#SeeAlso SkCanvas::clear
##

#Subtopic Src
#Line # replaces destination, ignoring Alpha ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component;
SkBlendMode::kSrc sets destination to: #Formula # [Sa, Sc] ##. 
Use SkBlendMode::kSrc to copy one buffer to another. All pixels are copied,
regardless of source and destination Alpha values. As a parameter to
SkCanvas::drawAtlas, selects sprites and ignores colors.
#Example
#Image 3
#Description
SkBlendMode::kSrc does not blend transparent pixels with existing background;
it punches a transparent hole in the existing image.
##
    canvas->drawImage(image, 0, 0);
    canvas->clipRect({50, 50, 200, 200});
    SkPaint srcBlend;
    srcBlend.setBlendMode(SkBlendMode::kSrc);
    canvas->saveLayer(nullptr, &srcBlend);
    canvas->drawColor(0);
    SkPaint transRed;
    transRed.setColor(SkColorSetA(SK_ColorRED, 127));
    canvas->drawCircle(125, 125, 75, transRed);
    canvas->restore();
##
#SeeAlso SkSurface::draw SkSurface::readPixels
##

#Subtopic Dst
#Line # preserves destination, ignoring source ##
Given: #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
 SkBlendMode::kDst preserves destination set to: #Formula # [Da, Dc] ##.
Setting Paint Blend_Mode to SkBlendMode::kDst causes drawing with
Paint to have no effect. As a parameter to SkCanvas::drawAtlas,
selects colors and ignores sprites.
#Example
#Image 3
  SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 125, 128 } };
  SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
  SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
  canvas->drawAtlas(image.get(), xforms, tex, colors, 2, SkBlendMode::kSrc, nullptr, nullptr);
  canvas->translate(128, 0);
  canvas->drawAtlas(image.get(), xforms, tex, colors, 2, SkBlendMode::kDst, nullptr, nullptr);
##
##

#Subtopic Src_Over
#Line # blends source with destination ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kSrcOver replaces destination with: #Formula # [Sa + Da * (1 - Sa), Sc + Dc * (1 - Sa)] ##,
drawing source over destination. SkBlendMode::kSrcOver is the default for Paint.

SkBlendMode::kSrcOver cannot make destination more transparent; the result will
be at least as opaque as the less transparent of source and original destination.
#Example
    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    SkPaint paint;
    paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    paint.setBlendMode(SkBlendMode::kDstIn);
    SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    canvas->clipRect( { 30, 30, 226, 226 } );
    canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kSrcOver);
##
##

#Subtopic Dst_Over
#Line # blends destination with source ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kDstOver replaces destination with: #Formula # [Da + Sa * (1 - Da), Dc + Sc * (1 - Da)] ##,
drawing destination over source. Has no effect destination if is opaque.
#Example
    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    SkPaint paint;
    paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    paint.setBlendMode(SkBlendMode::kDstIn);
    SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    canvas->clipRect( { 30, 30, 226, 226 } );
    canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kDstOver);
##
##

#Subtopic Src_In
#Line # source trimmed inside destination ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha;
SkBlendMode::kSrcIn replaces destination with: #Formula # [Sa * Da, Sc * Da] ##,
drawing source with destination opacity.
#Example
    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    SkPaint paint;
    paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    paint.setBlendMode(SkBlendMode::kDstIn);
    SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    canvas->clipRect( { 30, 30, 226, 226 } );
    canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kSrcIn);
##
##

#Subtopic Dst_In
#Line # destination trimmed by source ##
Given: #Formula # Sa ## as source Alpha,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kDstIn replaces destination with: #Formula # [Da * Sa, Dc * Sa] ##,
scaling destination Alpha by source Alpha. Resulting
destination is visible where source is visible.
#Example
    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    SkPaint paint;
    paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    paint.setBlendMode(SkBlendMode::kDstIn);
    SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    canvas->clipRect( { 30, 30, 226, 226 } );
    canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kDstIn);
##
##

#Subtopic Src_Out
#Line # source trimmed outside destination ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha;
SkBlendMode::kSrcOut replaces destination with: #Formula # [Sa * (1 - Da), Sc * (1 - Da)] ##,
drawing source fully where destination Alpha is zero. Is destination
is opaque, has no effect.
#Example
    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    SkPaint paint;
    paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    paint.setBlendMode(SkBlendMode::kDstIn);
    SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    canvas->clipRect( { 30, 30, 226, 226 } );
    canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kSrcOut);
##
##

#Subtopic Dst_Out
#Line # destination trimmed outside source ##
Given: #Formula # Sa ## as source Alpha,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kDstOut replaces destination with: #Formula # [Da * (1 - Sa), Dc * (1 - Sa)] ##,
scaling destination Alpha by source transparency. Resulting
destination is visible where source is transparent. If source is transparent,
has no effect.
#Example
    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    SkPaint paint;
    paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    paint.setBlendMode(SkBlendMode::kDstIn);
    SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    canvas->clipRect( { 30, 30, 226, 226 } );
    canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kDstOut);
##
##

#Subtopic Src_Atop
#Line # source inside destination over destination ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kSrcATop replaces destination with: #Formula # [Da, Sc * Da + Dc * (1 - Sa)] ##,
replacing opaque destination with opaque source. If source or destination
is transparent, has no effect.
#Example
    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    SkPaint paint;
    paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    paint.setBlendMode(SkBlendMode::kDstIn);
    SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    canvas->clipRect( { 30, 30, 226, 226 } );
    canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kSrcATop);
##
##

#Subtopic Dst_Atop
#Line # destination inside source over source ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kDstATop replaces destination with: #Formula # [Sa, Dc * Sa + Sc * (1 - Da)] ##,
making destination transparent where source is transparent.
#Example
    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    SkPaint paint;
    paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    paint.setBlendMode(SkBlendMode::kDstATop);
    SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    canvas->clipRect( { 30, 30, 226, 226 } );
    canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kSrcATop);
##
##

#Subtopic Xor
#Line # each of source and destination trimmed outside the other ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kXor replaces destination with:
#Formula # [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa)] ##,
exchanging the transparency of the source and destination.
#Example
   SkPaint paint;
   paint.setBlendMode(SkBlendMode::kXor);
   for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
       SkColor colors[] = { color, SkColorSetA(color, 192), SkColorSetA(color, 128),
                            SkColorSetA(color, 0) }; 
       paint.setShader(SkGradientShader::MakeRadial({ 64, 64}, 100,
               colors, nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
       canvas->drawCircle(64, 64, 100, paint);
       canvas->translate(64, 64);
   }
##
##

#Subtopic Plus
#Line # sum of colors ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kPlus replaces destination with: #Formula # [Sa + Da, Sc + Dc] ##,
summing the Alpha and Color components.
#Example
   canvas->drawColor(SK_ColorBLACK);
   SkPaint paint;
   paint.setBlendMode(SkBlendMode::kPlus);
   for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
       SkColor colors[] = { color, SkColorSetA(color, 192), SkColorSetA(color, 128),
                            SkColorSetA(color, 0) }; 
       paint.setShader(SkGradientShader::MakeRadial({ 64, 64}, 100,
               colors, nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
       canvas->drawCircle(64, 64, 100, paint);
       canvas->translate(64, 64);
   }
##
##

#Subtopic Modulate
#Line # product of Premultiplied colors; darkens destination ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kModulate replaces destination with: #Formula # [Sa * Da, Sc * Dc] ##,
scaling Alpha and Color components by the lesser of the values.
SkBlendMode::kModulate differs from SkBlendMode::kMultiply in two ways.
SkBlendMode::kModulate like SkBlendMode::kSrcATop alters the destination inside
the destination area, as if the destination Alpha defined the boundaries of a
soft clip. SkBlendMode::kMultiply like SkBlendMode::kSrcOver can alter the
destination where the destination is transparent.
SkBlendMode::kModulate computes the product of the source and destination using
Premultiplied component values. SkBlendMode::kMultiply the product of the source
and destination using Unpremultiplied component values.
#Example
#Description
    If source and destination are opaque, SkBlendMode::kModulate and
    SkBlendMode::kMultiply produce the same results.
##
    auto drawSquare = [=](int dx, int dy, SkBlendMode mode, const char* label) -> void {
        const SkColor colors[] = { SK_ColorBLACK, SK_ColorWHITE };
        const SkPoint horz[] = { { 0, 0 }, { 128, 0 } };
        SkPaint paint;
        paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
                SkShader::kClamp_TileMode));
        paint.setBlendMode(mode);
        canvas->translate(dx, dy);
        canvas->drawRect({0, 0, 128, 128}, paint);
        paint.setBlendMode(SkBlendMode::kXor);
        canvas->drawString(label, 40, 100, paint);
    };
    drawSquare(0, 0, SkBlendMode::kSrc, "destination");
    drawSquare(128, 0, SkBlendMode::kSrc, "");
    drawSquare(0, 128, SkBlendMode::kSrc, "");
    canvas->translate(-128, -128);
    canvas->rotate(90, 0, 128);
    drawSquare(0, 0, SkBlendMode::kSrc, "source");
    drawSquare(0, -128, SkBlendMode::kModulate, "modulate");
    drawSquare(-128, 0, SkBlendMode::kMultiply, "multiply");
##
##

#Subtopic Screen
#Line # multiply inverse of pixels, inverting result; brightens destination ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kScreen replaces destination with: #Formula # [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] ##.

#Example
    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    SkPaint paint;
    paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    paint.setBlendMode(SkBlendMode::kDstATop);
    SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    canvas->clipRect( { 30, 30, 226, 226 } );
    canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kScreen);
##
##

#Subtopic Overlay
#Line # multiply or screen, depending on destination ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kOverlay replaces destination with:
#Formula # [Sa + Da - Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa) +
    (2 * Dc <= Da ? 2 * Sc * Dc : Sa * Da - 2 * (Da - Dc) * (Sa - Sc))] ##.
#Example
    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    SkPaint paint;
    paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    paint.setBlendMode(SkBlendMode::kDstATop);
    SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    canvas->clipRect( { 30, 30, 226, 226 } );
    canvas->drawColor(SkColorSetA(SK_ColorGREEN, 128), SkBlendMode::kOverlay);
##
##

#Subtopic Darken
#Line # darker of source and destination ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kDarken replaces destination with:
#Formula # [Sa + Da - Sa * Da,  Sc + Dc - max(Sc * Da, Dc * Sa)] ##.
SkBlendMode::kDarken does not make an image darker; it replaces the destination
component with source if source is darker. 
#Example
#Image 3
    canvas->drawImage(image, 0, 0);
    SkColor colors[] = { SK_ColorWHITE, SK_ColorBLACK };
    SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    SkPaint paint;
    paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
            SkShader::kClamp_TileMode));
    paint.setBlendMode(SkBlendMode::kDarken);
    canvas->drawPaint(paint);
##
##

#Subtopic Lighten
#Line # lighter of source and destination ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kLighten replaces destination with:
#Formula # [Sa + Da - Sa * Da,  Sc + Dc - min(Sc * Da, Dc * Sa)] ##. 
SkBlendMode::kDarken does not make an image lighter; it replaces the destination
component with source if source is lighter. 
#Example
#Image 3
    canvas->drawImage(image, 0, 0);
    SkColor colors[] = { SK_ColorBLACK, SK_ColorWHITE };
    SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
    SkPaint paint;
    paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, SK_ARRAY_COUNT(colors),
            SkShader::kClamp_TileMode));
    paint.setBlendMode(SkBlendMode::kLighten);
    canvas->drawPaint(paint);
##
##

#Subtopic Color_Dodge
#Line # brighten destination to reflect source ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kColorDodge replaces destination with:
#Formula # [Sa + Da - Sa * Da, Dc == 0 ? Sc * (1 - Da) : Sc == Sa ? Sc + Da * (1 - Sa) :
            Sa * min(Da, Dc * Sa / (Sa - Sc)) + Sc * (1 - Da) + Da * (1 - Sa)] ##,
making destination brighter to reflect source.
#Example
#Image 3
    canvas->drawImage(image, 0, 0);
    canvas->clipRect({128, 0, 256, 256});
    canvas->drawColor(SkColorSetARGB(0x80, 0x90, 0x90, 0x90), SkBlendMode::kColorDodge);
##
##

#Subtopic Color_Burn
#Line # darken destination to reflect source ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kColorBurn replaces destination with:
#Formula # [Sa + Da - Sa * Da, Dc == Da ? Dc + Sc * (1 - Da) : Sc == 0 ? Da * (1 - Sa) :
            Sa * (Da - min(Da, (Da - Dc) * Sa / Sc)) + Sc * (1 - Da) + Da * (1 - Sa)] ##,
making destination darker to reflect source.
#Example
#Image 3
    canvas->drawImage(image, 0, 0);
    canvas->clipRect({128, 0, 256, 256});
    canvas->drawColor(SkColorSetARGB(0x80, 0x90, 0x90, 0x90), SkBlendMode::kColorBurn);
##
##

#Subtopic Hard_Light
#Line # multiply or screen, depending on source ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kHardLight replaces destination with:
#Formula # [Sa + Da - Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa) +
        2 * Sc <= Sa ? 2 * Sc * Dc : Sa * Da - 2 * (Da - Dc) * (Sa - Sc)] ##,
making destination lighter or darker, depending on source.
#Example
#Image 3
   canvas->drawImage(image, 0, 0);
   const SkColor colors[] = { 0xFFFFFFFF, 0x00000000 };
   SkPaint paint;
   paint.setBlendMode(SkBlendMode::kHardLight);
   paint.setShader(SkGradientShader::MakeRadial({ 128, 128}, 100, colors,
        nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
   canvas->clipRect({0, 128, 256, 256});
   canvas->drawPaint(paint);
##
##

#Subtopic Soft_Light
#Line # lighten or darken, depending on source ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
where #Formula # m = Da > 0 ? Dc / Da : 0 ##;
SkBlendMode::kSoftLight replaces destination with: #Formula # [Sa + Da - Sa * Da, Sc / Da + Dc / Sa +
    (2 * Sc <= Sa ? Dc * (Sa + (2 * Sc - Sa) * (1 - m)) : Dc * Sa + Da * (2 * Sc - Sa) *
    (4 * Dc <= Da ? (16 * m * m  + 4 * m) * (m - 1) + 7 * m : sqrt(m) - m))] ##,
making destination lighter or darker, depending on source.
#Example
#Image 3
   const SkColor colors[] = { 0xFFFFFFFF, 0x3FFFFFFF };
   SkPaint paint;
   paint.setBlendMode(SkBlendMode::kSoftLight);
   paint.setShader(SkGradientShader::MakeRadial({ 128, 128}, 100, colors,
        nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
   canvas->drawImage(image, 0, 0);
   canvas->drawCircle(128, 128, 100, paint);
##
##

#Subtopic Difference
#Line # subtract darker from lighter with higher contrast ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kDifference replaces destination with:
#Formula # [Sa + Da - Sa * Da, Sc + Dc - 2 * min(Sc * Da, Dc * Sa)] ##,
replacing destination with lighter less darker.
#Example
#Image 5
    canvas->drawImage(image, 0, 0);
    canvas->drawImage(image, 128, 0);
    canvas->drawImage(image, 0, 128);
    canvas->drawImage(image, 128, 128);
    SkPaint paint;
    paint.setBlendMode(SkBlendMode::kDstATop);
    SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    canvas->clipRect( { 30, 30, 226, 226 } );
    canvas->drawColor(0x80bb9977, SkBlendMode::kDifference);
##
##

#Subtopic Exclusion
#Line # subtract darker from lighter with lower contrast ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kExclusion replaces destination with:
#Formula # [Sa + Da - Sa * Da, Sc + Dc - 2 * Sc * Dc] ##,
replacing destination with lighter less darker, ignoring Alpha.
#Example
#Image 5
    canvas->drawImage(image, 0, 0);
    canvas->drawImage(image, 128, 0);
    canvas->drawImage(image, 0, 128);
    canvas->drawImage(image, 128, 128);
    SkPaint paint;
    paint.setBlendMode(SkBlendMode::kDstATop);
    SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    canvas->clipRect( { 30, 30, 226, 226 } );
    canvas->drawColor(0x80bb9977, SkBlendMode::kExclusion);
##
##

#Subtopic Multiply
#Line # multiply source with destination, darkening image ##
Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component,
#Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component;
SkBlendMode::kMultiply replaces destination with:
#Formula # [Sa + Da - Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa) + Sc * Dc] ##,
the product of Unpremultiplied source and destination.
SkBlendMode::kMultiply makes the image darker.
#Example
#Image 5
    canvas->drawImage(image, 0, 0);
    canvas->drawImage(image, 128, 0);
    canvas->drawImage(image, 0, 128);
    canvas->drawImage(image, 128, 128);
    SkPaint paint;
    paint.setBlendMode(SkBlendMode::kDstATop);
    SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
    SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
    paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, SK_ARRAY_COUNT(alphas),
            SkShader::kClamp_TileMode));
    canvas->drawPaint(paint);
    canvas->clipRect( { 30, 30, 226, 226 } );
    canvas->drawColor(0x80bb9977, SkBlendMode::kMultiply);
##
##

#Subtopic Hue
#Line # hue of source with saturation and luminosity of destination ##
Given: #Formula # Sa ## as source Alpha, #Formula # S ## as source Color,
#Formula # Da ## as destination Alpha, #Formula # D ## as destination Color;
SkBlendMode::kHue replaces destination with:
#Formula # [Sa + Da - Sa * Da, SetLuminosity(SetSaturation(S, Saturation(D)), Luminosity(D))] ##,
source hue, leaving destination luminosity and saturation unchanged.
#Example
#Image 3
canvas->drawImage(image, 0, 0);
canvas->drawColor(0xFF00FF00, SkBlendMode::kHue);
##
##

#Subtopic Saturation
#Line # saturation of source with hue and luminosity of destination ##
Given: #Formula # Sa ## as source Alpha, #Formula # S ## as source Color,
#Formula # Da ## as destination Alpha, #Formula # D ## as destination Color;
SkBlendMode::kHue replaces destination with:
#Formula # [Sa + Da - Sa * Da, SetLuminosity(SetSaturation(D, Saturation(S)), Luminosity(D))] ##,
source hue, leaving destination luminosity and saturation unchanged.
#Example
#Image 3
canvas->drawImage(image, 0, 0);
canvas->drawColor(0xFF00FF00, SkBlendMode::kSaturation);
##
##

#Subtopic Color
#Line # hue and saturation of source with luminosity of destination ##
Given: #Formula # Sa ## as source Alpha, #Formula # S ## as source Color,
#Formula # Da ## as destination Alpha, #Formula # D ## as destination Color;
SkBlendMode::kColor replaces destination with:
#Formula # [Sa + Da - Sa * Da, SetLuminosity(S, Luminosity(D))] ##,
source hue and saturation, leaving destination luminosity unchanged.
#Example
#Image 3
canvas->drawImage(image, 0, 0);
canvas->drawColor(0xFF00FF00, SkBlendMode::kColor);
##
##

#Subtopic Luminosity
#Line # luminosity of source with hue and saturation of destination ##
Given: #Formula # Sa ## as source Alpha, #Formula # S ## as source Color,
#Formula # Da ## as destination Alpha, #Formula # D ## as destination Color;
SkBlendMode::kLuminosity replaces destination with:
#Formula # [Sa + Da - Sa * Da, SetLuminosity(D, Luminosity(S))] ##,
source luminosity, leaving destination hue and saturation unchanged.
#Example
#Image 3
canvas->drawImage(image, 0, 0);
canvas->drawColor(0xFF00FF00, SkBlendMode::kLuminosity);
##
##

#EnumClass SkBlendMode ##

# ------------------------------------------------------------------------------

#Method const char* SkBlendMode_Name(SkBlendMode blendMode)
#In Utility
#Line # returns mode as C string ##
#Populate

#Example
SkDebugf("default blend: SkBlendMode::k%s\n", SkBlendMode_Name(SkPaint().getBlendMode()));
#StdOut
default blend: SkBlendMode::kSrcOver
##
##

#SeeAlso SkBlendMode

#Method ##

#Topic Blend_Mode ##