aboutsummaryrefslogtreecommitdiffhomepage
path: root/docs/SkBlendMode_Reference.bmh
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2018-06-27 11:00:21 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-27 15:47:45 +0000
commit224c700a1fb0b7f6abd85a9729d29cbbdf5872dd (patch)
tree7d480bf6340a28bf71c89a8b837c9f022f75ca3f /docs/SkBlendMode_Reference.bmh
parenta1ac841b1a367c6b319b90ec04911e7e4cd9ad93 (diff)
sync docs up with tip of tree
Also check in work in progress for blend modes, round rects, and a placeholder for pictures. One minor include change to add a parameter name for SkBlendMode function. TBR=reed@google.com R=caryclark@google.com Docs-Preview: https://skia.org/?cl=134200 Bug: skia:6898 Change-Id: I5d2a9221d61edb32d9c7edbb3193401605b2b513 Reviewed-on: https://skia-review.googlesource.com/134200 Reviewed-by: Cary Clark <caryclark@google.com> Reviewed-by: Cary Clark <caryclark@skia.org> Commit-Queue: Cary Clark <caryclark@skia.org> Auto-Submit: Cary Clark <caryclark@skia.org>
Diffstat (limited to 'docs/SkBlendMode_Reference.bmh')
-rw-r--r--docs/SkBlendMode_Reference.bmh1180
1 files changed, 1180 insertions, 0 deletions
diff --git a/docs/SkBlendMode_Reference.bmh b/docs/SkBlendMode_Reference.bmh
new file mode 100644
index 0000000000..1dbba49db3
--- /dev/null
+++ b/docs/SkBlendMode_Reference.bmh
@@ -0,0 +1,1180 @@
+#Topic Blend_Mode
+#Alias BlendMode_Reference ##
+
+#Subtopic Overview
+#Populate
+##
+
+#Subtopic Member_Function
+#Populate
+##
+
+#Subtopic Constant
+#Populate
+##
+
+Describes how destination pixel is replaced with a combination of itself and
+source pixel. Blend_Mode may use source, destination, or both. Blend_Mode may
+operate on each Color component independently, or may allow all source pixel
+components to contribute to one destination pixel component.
+
+Blend_Mode does not use adjacent pixels to determine the outcome.
+
+Blend_Mode uses source and read destination Alpha to determine written
+destination Alpha; both source and destination Alpha may also affect written
+destination Color components.
+
+Regardless of how Alpha is encoded in source and destination pixel, nearly all
+Color_Types treat it as ranging from zero to one. And, nearly all Blend_Mode
+algorithms limit the output so that all results are also zero to one.
+
+Two exceptions are SkBlendMode::kPlus and kRGBA_F16_SkColorType.
+
+SkBlendMode::kPlus permits computing Alpha and Color component values larger
+than one. For Color_Types other than kRGBA_F16_SkColorType, resulting Alpha
+and component values are clamped to one.
+
+kRGBA_F16_SkColorType permits values outside the zero to one range. It is up
+to the client to ensure that the result is within the range of zero to one,
+and therefore well-defined.
+
+#Subtopic Porter_Duff
+
+#A Compositing Digital Images # https://graphics.pixar.com/library/Compositing/paper.pdf ##
+describes Porter_Duff modes SkBlendMode::kClear through SkBlendMode::kXor.
+
+Drawing a bitmap with transparency using Porter_Duff compositing is free to clear
+the destination.
+
+#Illustration 1
+
+Draw geometry with transparency using Porter_Duff compositing does not combine
+transparent source pixels, leaving the destination outside the geometry untouched.
+
+#Illustration 2
+
+##
+
+#Subtopic Lighten_Darken
+
+Modes SkBlendMode::kPlus and SkBlendMode::kScreen use
+simple arithmetic to lighten or darken the destination. Modes
+SkBlendMode::kOverlay through SkBlendMode::kMultiply use more complicated
+algorithms to lighten or darken; sometimes one mode does both, as described by
+#A Blend Modes # https://en.wikipedia.org/wiki/Blend_modes ##
+.
+
+#Illustration
+
+##
+
+#Subtopic Modulate_Blend
+SkBlendMode::kModulate is a mashup of SkBlendMode::kSrcATop and SkBlendMode::kMultiply.
+It multiplies all components, including Alpha; unlike SkBlendMode::kMultiply, if either
+source or destination is transparent, result is transparent. SkBlendMode::kModulate
+uses Premultiplied values to compute the product; SkBlendMode::kMultiply uses Unpremultiplied
+values to compute the product.
+
+#Illustration
+
+##
+
+#Subtopic Color_Blends
+
+Modes SkBlendMode::kHue, SkBlendMode::kSaturation, SkBlendMode::kColor, and
+SkBlendMode::kLuminosity convert source and destination pixels using all
+components color information, using
+###$
+$A non-separable blend modes $ https://www.w3.org/TR/compositing-1/#blendingnonseparable $$
+$$$#
+.
+
+#Illustration
+
+##
+
+# ------------------------------------------------------------------------------
+
+#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
+##
+
+#EnumClass SkBlendMode
+#Line # algorithm combining source and destination pixels ##
+
+#Code
+ enum class SkBlendMode {
+ kClear,
+ kSrc,
+ kDst,
+ kSrcOver,
+ kDstOver,
+ kSrcIn,
+ kDstIn,
+ kSrcOut,
+ kDstOut,
+ kSrcATop,
+ kDstATop,
+ kXor,
+ kPlus,
+ kModulate,
+ kScreen,
+ kLastCoeffMode = kScreen,
+ kOverlay,
+ kDarken,
+ kLighten,
+ kColorDodge,
+ kColorBurn,
+ kHardLight,
+ kSoftLight,
+ kDifference,
+ kExclusion,
+ kMultiply,
+ kLastSeparableMode = kMultiply,
+ kHue,
+ kSaturation,
+ kColor,
+ kLuminosity,
+ kLastMode = kLuminosity,
+ };
+##
+
+#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
+
+#EnumClass SkBlendMode ##
+
+#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, 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, 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, Sc as source Color component,
+Da as destination Alpha, 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, Sc as source Color component,
+Da as destination Alpha, 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, Sc as source Color component, 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, Da as destination Alpha, 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, Sc as source Color component, 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, Da as destination Alpha, 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, Sc as source Color component,
+Da as destination Alpha, 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, Sc as source Color component,
+Da as destination Alpha, 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, Sc as source Color component,
+Da as destination Alpha, 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, Sc as source Color component,
+Da as destination Alpha, 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, Sc as source Color component,
+Da as destination Alpha, 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 boudaries 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, Sc as source Color component,
+Da as destination Alpha, 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, Sc as source Color component,
+Da as destination Alpha, 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, Sc as source Color component,
+Da as destination Alpha, 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
+ 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, Sc as source Color component,
+Da as destination Alpha, 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
+ 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, Sc as source Color component,
+Da as destination Alpha, 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, Sc as source Color component,
+Da as destination Alpha, 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, Sc as source Color component,
+Da as destination Alpha, 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, Sc as source Color component,
+Da as destination Alpha, Dc as destination Color component
+where 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, Sc as source Color component,
+Da as destination Alpha, 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, Sc as source Color,
+Da as destination Alpha, 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, Sc as source Color component,
+Da as destination Alpha, 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
+ 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, S as source Color,
+Da as destination Alpha, 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
+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, S as source Color,
+Da as destination Alpha, 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
+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, S as source Color,
+Da as destination Alpha, 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
+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, S as source Color,
+Da as destination Alpha, 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
+canvas->drawImage(image, 0, 0);
+canvas->drawColor(0xFF00FF00, SkBlendMode::kLuminosity);
+##
+##
+
+# ------------------------------------------------------------------------------
+
+#Method SK_API const char* SkBlendMode_Name(SkBlendMode blendMode)
+#In Utility
+#Line # returns mode as C string ##
+
+Returns name of blendMode as null-terminated C string.
+
+#Param blendMode one of: #list_of_blend_modes#
+##
+
+#Return C string ##
+
+#Example
+SkDebugf("default blend: SkBlendMode::k%s\n", SkBlendMode_Name(SkPaint().getBlendMode()));
+#StdOut
+default blend: SkBlendMode::kSrcOver
+##
+##
+
+#SeeAlso SkBlendMode
+
+#Method ##
+
+#Topic Blend_Mode ##