aboutsummaryrefslogtreecommitdiffhomepage
path: root/docs
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
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')
-rw-r--r--docs/SkBitmap_Reference.bmh10
-rw-r--r--docs/SkBlendMode_Reference.bmh1180
-rw-r--r--docs/SkCanvas_Reference.bmh8
-rw-r--r--docs/SkImageInfo_Reference.bmh95
-rw-r--r--docs/SkPath_Reference.bmh2
-rw-r--r--docs/SkPicture_Reference.bmh312
-rw-r--r--docs/SkRRect_Reference.bmh1121
-rw-r--r--docs/SkRect_Reference.bmh2
-rw-r--r--docs/illustrations.bmh269
-rw-r--r--docs/status.json6
-rw-r--r--docs/undocumented.bmh59
11 files changed, 3007 insertions, 57 deletions
diff --git a/docs/SkBitmap_Reference.bmh b/docs/SkBitmap_Reference.bmh
index 40c2d58369..ab9d7c8730 100644
--- a/docs/SkBitmap_Reference.bmh
+++ b/docs/SkBitmap_Reference.bmh
@@ -3201,9 +3201,8 @@ pixels are treated as if they are linear, regardless of how they are encoded.
#Method bool hasHardwareMipMap() const
#In Property
#Line # returns Mip_Map support present; Android only ##
-#Private
-Android framework only.
-##
+
+For use by Android framework only.
#Return true if setHasHardwareMipMap has been called with true ##
@@ -3219,9 +3218,8 @@ Android framework only.
#Method void setHasHardwareMipMap(bool hasHardwareMipMap)
#In Set
#Line # sets Mip_Map support present; Android only ##
-#Private
-Android framework only.
-##
+
+For use by Android framework only.
#Param hasHardwareMipMap sets state ##
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 ##
diff --git a/docs/SkCanvas_Reference.bmh b/docs/SkCanvas_Reference.bmh
index 57125d7fb0..fc6093cf7a 100644
--- a/docs/SkCanvas_Reference.bmh
+++ b/docs/SkCanvas_Reference.bmh
@@ -1877,8 +1877,7 @@ Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
##
-#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint,
- SaveLayerFlags saveLayerFlags = 0)
+#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
@@ -5918,10 +5917,13 @@ to draw, if present. For each entry in the array, Rect tex locates sprite in
atlas, and RSXform xform transforms it into destination space.
xform, text, and colors if present, must contain count entries.
-Optional colors are applied for each sprite using Blend_Mode.
+Optional colors are applied for each sprite using Blend_Mode mode, treating
+sprite as source and colors as destination.
Optional cullRect is a conservative bounds of all transformed sprites.
If cullRect is outside of Clip, canvas can skip drawing.
+
+
#Param atlas Image containing sprites ##
#Param xform RSXform mappings for sprites in atlas ##
#Param tex Rect locations of sprites in atlas ##
diff --git a/docs/SkImageInfo_Reference.bmh b/docs/SkImageInfo_Reference.bmh
index 096695cecf..c78f63b452 100644
--- a/docs/SkImageInfo_Reference.bmh
+++ b/docs/SkImageInfo_Reference.bmh
@@ -250,8 +250,8 @@ kGray_8_SkColorType, kRGBA_F16_SkColorType
kRGB_101010x_SkColorType,
kGray_8_SkColorType,
kRGBA_F16_SkColorType,
-
- kLastEnum_SkColorType = kRGBA_F16_SkColorType,
+ kRGBA_F32_SkColorType,
+ kLastEnum_SkColorType = kRGBA_F32_SkColorType,
###$
#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
kN32_SkColorType = kBGRA_8888_SkColorType,
@@ -345,10 +345,19 @@ kRGBA_8888_SkColorType.
#Line # pixel with half floats for red, green, blue, alpha; in 64-bit word ##
#Details RGBA_F16
Stores 64-bit word pixel encoding that contains 16 bits of blue,
- 16 bits of green, 16 bits of red, and 16 bits of alpha.
+ 16 bits of green, 16 bits of red, and 16 bits of alpha. Each component
+ is encoded as a half float.
+##
+
+#Const kRGBA_F32_SkColorType 11
+#Line # pixel using C float for red, green, blue, alpha; in 128-bit word ##
+#Details RGBA_F32
+ Stores 128-bit word pixel encoding that contains 32 bits of blue,
+ 32 bits of green, 32 bits of red, and 32 bits of alpha. Each component
+ is encoded as a single precision float.
##
-#Const kLastEnum_SkColorType 10
+#Const kLastEnum_SkColorType 11
#NoJustify
#Line # last valid value ##
Used by tests to iterate through all valid values.
@@ -761,7 +770,7 @@ kRGBA_8888_SkColorType.
#Subtopic RGBA_F16
#Line # encodes ARGB as half floats ##
kRGBA_F16_SkColorType encodes ARGB into a 64-bit word. Each component:
- blue, green, red, and alpha; use 16 bits, describing a floating point value.
+ blue, green, red, and alpha; use 16 bits, describing a floating point value,
from -65500 to 65000 with 3.31 decimal digits of precision.
At present, Color in Paint does not provide enough precision or range to
@@ -784,7 +793,7 @@ kRGBA_8888_SkColorType.
If paired with kOpaque_SkAlphaType: all alpha component values are at the maximum;
blue, green, and red components are fully opaque. If any alpha component is
- less than 255, the drawn result is undefined.
+ less than one, the drawn result is undefined.
#ToDo
FloatToHalf should be replaced with SkFloatToHalf if/when that's made public
@@ -824,14 +833,14 @@ kRGBA_8888_SkColorType.
return FloatToHalf(c);
};
// R G B A
- uint16_t red_f16[][4] = { { H(1.0f), H(0.0f), H(0.0f), H(1.0f) },
- { H(.75f), H(0.0f), H(0.0f), H(1.0f) },
- { H(.50f), H(0.0f), H(0.0f), H(1.0f) },
- { H(.25f), H(0.0f), H(0.0f), H(1.0f) } };
- uint16_t blue_f16[][4] = { { H(0.0f), H(0.0f), H(1.0f), H(1.0f) },
- { H(0.0f), H(0.0f), H(.75f), H(1.0f) },
- { H(0.0f), H(0.0f), H(.50f), H(1.0f) },
- { H(0.0f), H(0.0f), H(.25f), H(1.0f) } };
+ uint16_t red_f16[][4] = { { H(1.0), H(0.0), H(0.0), H(1.0) },
+ { H(.75), H(0.0), H(0.0), H(1.0) },
+ { H(.50), H(0.0), H(0.0), H(1.0) },
+ { H(.25), H(0.0), H(0.0), H(1.0) } };
+ uint16_t blue_f16[][4] = { { H(0.0), H(0.0), H(1.0), H(1.0) },
+ { H(0.0), H(0.0), H(.75), H(1.0) },
+ { H(0.0), H(0.0), H(.50), H(1.0) },
+ { H(0.0), H(0.0), H(.25), H(1.0) } };
SkPixmap redPixmap(imageInfo, red_f16, imageInfo.minRowBytes());
if (bitmap.writePixels(redPixmap, 0, 0)) {
canvas->drawBitmap(bitmap, 2, 2);
@@ -845,6 +854,64 @@ kRGBA_8888_SkColorType.
#SeeAlso SkColor4f
##
+#Subtopic RGBA_F32
+#Line # encodes ARGB as single precision floats ##
+ kRGBA_F32_SkColorType encodes ARGB into a 128-bit word. Each component:
+ blue, green, red, and alpha; use 32 bits, describing a floating point value,
+ from -3.402823e+38 to 3.402823e+38 with 7.225 decimal digits of precision.
+
+ At present, Color in Paint does not provide enough precision or range to
+ draw all colors possible to a kRGBA_F32_SkColorType Surface.
+
+ Each component encodes a floating point value using
+ #A single-precision floats # https://en.wikipedia.org/wiki/Single-precision_floating-point_format ##
+ . Meaningful colors are represented by the range 0.0 to 1.0, although smaller
+ and larger values may be useful when used in combination with Transfer_Mode.
+
+ #Illustration
+
+ If paired with kPremul_SkAlphaType: blue, green, and red components are
+ Premultiplied by the alpha value. If blue, green, or red is greater than alpha,
+ the drawn result is undefined.
+
+ If paired with kUnpremul_SkAlphaType: blue, green, red, and alpha components
+ may have any value. There may be a performance penalty with Unpremultiplied
+ pixels.
+
+ If paired with kOpaque_SkAlphaType: all alpha component values are at the maximum;
+ blue, green, and red components are fully opaque. If any alpha component is
+ less than one, the drawn result is undefined.
+
+ #NoExample
+ canvas->scale(16, 16);
+ SkBitmap bitmap;
+ SkImageInfo imageInfo = SkImageInfo::Make(2, 2, kRGBA_F32_SkColorType, kPremul_SkAlphaType);
+ bitmap.allocPixels(imageInfo);
+ SkCanvas offscreen(bitmap);
+ offscreen.clear(SK_ColorGREEN);
+ canvas->drawBitmap(bitmap, 0, 0);
+ // R G B A
+ float red_f32[][4] = { { 1.0, 0.0, 0.0, 1.0 },
+ { .75, 0.0, 0.0, 1.0 },
+ { .50, 0.0, 0.0, 1.0 },
+ { .25, 0.0, 0.0, 1.0 } };
+ float blue_f32[][4] = { { 0.0, 0.0, 1.0, 1.0 },
+ { 0.0, 0.0, .75, 1.0 },
+ { 0.0, 0.0, .50, 1.0 },
+ { 0.0, 0.0, .25, 1.0 } };
+ SkPixmap redPixmap(imageInfo, red_f32, imageInfo.minRowBytes());
+ if (bitmap.writePixels(redPixmap, 0, 0)) {
+ canvas->drawBitmap(bitmap, 2, 2);
+ }
+ SkPixmap bluePixmap(imageInfo, blue_f32, imageInfo.minRowBytes());
+ if (bitmap.writePixels(bluePixmap, 0, 0)) {
+ canvas->drawBitmap(bitmap, 4, 4);
+ }
+ ##
+ #SeeAlso SkColor4f
+##
+
+
#Subtopic Color_Type ##
# ------------------------------------------------------------------------------
diff --git a/docs/SkPath_Reference.bmh b/docs/SkPath_Reference.bmh
index 75840b3144..e0e8da2540 100644
--- a/docs/SkPath_Reference.bmh
+++ b/docs/SkPath_Reference.bmh
@@ -5050,7 +5050,7 @@ standard output. Set forceClose to true to get edges used to fill Path.
Set dumpAsHex true to generate exact binary representations
of floating point numbers used in Point_Array and Conic_Weights.
-#Param stream writable Stream receiving Path text representation; may be nullptr ##
+#Param stream writable WStream receiving Path text representation; may be nullptr ##
#Param forceClose true if missing kClose_Verb is output ##
#Param dumpAsHex true if SkScalar values are written as hexadecimal ##
diff --git a/docs/SkPicture_Reference.bmh b/docs/SkPicture_Reference.bmh
new file mode 100644
index 0000000000..a722a1deb6
--- /dev/null
+++ b/docs/SkPicture_Reference.bmh
@@ -0,0 +1,312 @@
+#Topic Picture
+#Alias Pictures ##
+#Alias Picture_Reference ##
+
+#Class SkPicture
+
+An SkPicture records drawing commands made to a canvas to be played back at a later time.
+This base class handles serialization and a few other miscellany.
+
+#Subtopic Overview
+#Populate
+##
+
+#Subtopic Class
+#Populate
+##
+
+#Subtopic Member_Function
+#Populate
+##
+
+# ------------------------------------------------------------------------------
+
+#Class AbortCallback
+#Line # incomplete ##
+
+#Code
+#ToDo fill this in manually ##
+##
+
+Subclasses of this can be passed to playback(). During the playback
+of the picture, this callback will periodically be invoked. If its
+abort() returns true, then picture playback will be interrupted.
+The resulting drawing is undefined, as there is no guarantee how often the
+callback will be invoked. If the abort happens inside some level of nested
+calls to save(), restore will automatically be called to return the state
+to the same level it was before the playback call was made.
+
+# ------------------------------------------------------------------------------
+
+#Method AbortCallback()
+#In incomplete
+#Line # incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method virtual ~AbortCallback()
+#In Constructor
+#Line # incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method virtual bool abort() = 0
+#In incomplete
+#Line # incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+#Class AbortCallback ##
+
+# ------------------------------------------------------------------------------
+
+#Method static sk_sp<SkPicture> MakeFromStream(SkStream* stream,
+ const SkDeserialProcs* procs = nullptr)
+#In incomplete
+#Line # incomplete ##
+
+Recreate a picture that was serialized into a stream or data.
+
+#Param stream incomplete ##
+#Param procs incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method static sk_sp<SkPicture> MakeFromData(const SkData* data,
+ const SkDeserialProcs* procs = nullptr)
+#In incomplete
+#Line # incomplete ##
+
+#Param data incomplete ##
+#Param procs incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method static sk_sp<SkPicture> MakeFromData(const void* data, size_t size,
+ const SkDeserialProcs* procs = nullptr)
+#In incomplete
+#Line # incomplete ##
+
+#Param data incomplete ##
+#Param size incomplete ##
+#Param procs incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method virtual void playback(SkCanvas* canvas, AbortCallback* callback = nullptr) const = 0
+#In incomplete
+#Line # incomplete ##
+
+Replays the drawing commands on the specified canvas. Note that
+this has the effect of unfurling this picture into the destination
+canvas. Using the SkCanvas::drawPicture entry point gives the destination
+canvas the option of just taking a ref.
+
+#Param canvas the canvas receiving the drawing commands.
+##
+#Param callback a callback that allows interruption of playback
+##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method virtual SkRect cullRect() const = 0
+#In incomplete
+#Line # incomplete ##
+
+Return a cull rect for this picture.
+Ops recorded into this picture that attempt to draw outside the cull might not be drawn.
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method uint32_t uniqueID() const
+#In incomplete
+#Line # incomplete ##
+
+Returns a non-zero value unique among all pictures.
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method sk_sp<SkData> serialize(const SkSerialProcs* procs = nullptr) const
+#In incomplete
+#Line # incomplete ##
+
+#Param procs incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void serialize(SkWStream* stream, const SkSerialProcs* procs = nullptr) const
+#In incomplete
+#Line # incomplete ##
+
+#Param stream incomplete ##
+#Param procs incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method static sk_sp<SkPicture> MakePlaceholder(SkRect cull)
+#In incomplete
+#Line # incomplete ##
+
+Return a placeholder SkPicture.
+This placeholder does not draw anything itself. It has a distinct uniqueID()
+(just like all Pictures) and will always be visible to SkSerialProcs.
+
+#Param cull the placeholder's dimensions
+##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method virtual int approximateOpCount() const = 0
+#In incomplete
+#Line # incomplete ##
+
+Return the approximate number of operations in this picture. This
+number may be greater or less than the number of SkCanvas calls
+recorded: some calls may be recorded as more than one operation, or some
+calls may be optimized away.
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method virtual size_t approximateBytesUsed() const = 0
+#In incomplete
+#Line # incomplete ##
+
+Returns the approximate byte size of this picture, not including large ref'd objects.
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+#Class SkPicture ##
+
+#Topic Picture ##
diff --git a/docs/SkRRect_Reference.bmh b/docs/SkRRect_Reference.bmh
new file mode 100644
index 0000000000..d6caebe166
--- /dev/null
+++ b/docs/SkRRect_Reference.bmh
@@ -0,0 +1,1121 @@
+#Topic RRect
+#Alias Round_Rect ##
+#Alias RRect_Reference ##
+
+#Class SkRRect
+
+#Private
+Path forward:
+ core work
+ add contains(SkRect&) - for clip stack
+ add contains(SkRRect&) - for clip stack
+ add heart rect computation (max rect inside RR)
+ add 9patch rect computation
+ add growToInclude(SkPath&)
+ analysis
+ use growToInclude to fit skp round rects & generate stats (RRs vs. real paths)
+ check on # of rectorus's the RRs could handle
+ rendering work
+ update SkPath.addRRect() to only use quads
+ add GM and bench
+ further out
+ detect and triangulate RRectorii rather than falling back to SW in Ganesh
+##
+
+The SkRRect class represents a rounded rect with a potentially different
+radii for each corner. It does not have a constructor so must be
+initialized with one of the initialization functions (e.g., setEmpty,
+setRectRadii, etc.)
+
+This class allows implementing CSS properties that describe rounded corners.
+A rectangle may have up to eight radii, one for each axis on each of its four
+corners.
+
+If either corner's radii are zero, the corner is square.
+Negative radii are treated as zero.
+If corner curves overlap, they are proportionally reduced to fit.
+
+#Subtopic Overview
+#Populate
+##
+
+#Subtopic Constructor
+#Populate
+##
+
+#Subtopic Operator
+#Populate
+##
+
+#Subtopic Member_Function
+#Populate
+##
+
+# ------------------------------------------------------------------------------
+
+#Method SkRRect() = default
+#In Constructor
+#Line # incomplete ##
+
+Default initialized to a rrect at the origin with zero width and height.
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method SkRRect(const SkRRect& rrect) = default
+#In Constructor
+#Line # incomplete ##
+
+#Param rrect incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method SkRRect& operator=(const SkRRect& rrect) = default
+#In Operator
+#Line # incomplete ##
+
+#Param rrect incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Enum Type
+#Line # incomplete ##
+
+#Code
+ enum Type {
+ kEmpty_Type,
+ kRect_Type,
+ kOval_Type,
+ kSimple_Type,
+ kNinePatch_Type,
+ kComplex_Type,
+ kLastType = kComplex_Type,
+ };
+##
+
+Enum to capture the various possible subtypes of Round_Rect. Accessed
+by type(). The subtypes become progressively less restrictive.
+
+#Const kEmpty_Type
+#Line # incomplete ##
+Round_Rect has zero width or height. All radii are zero.
+##
+#Const kRect_Type
+#Line # incomplete ##
+Round_Rect has width and height. All radii are zero.
+##
+#Const kOval_Type
+#Line # incomplete ##
+Round_Rect has width and height. All four x-radii are equal,
+and at least half the width. All four y-radii are equal,
+and at least half the height.
+##
+#Const kSimple_Type
+#Line # incomplete ##
+Round_Rect has width and height. All four x-radii are equal and
+greater than zero, and all four y-radii are equal and greater than
+zero. Either x-radii are less than half the width, or y-radii is
+less than half the height, or both.
+##
+#Const kNinePatch_Type
+#Line # incomplete ##
+Round_Rect has width and height. Left x-radii are equal, top
+y-radii are equal, right x-radii are equal, and bottom y-radii
+are equal. The radii do not descript a rect, oval, or simple type.
+
+The centers of the corner ellipses form an axis-aligned rectangle
+that divides the Round_Rect into nine rectangular patches; an
+interior rectangle, four edges, and four corners.
+##
+#Const kComplex_Type
+#Line # incomplete ##
+both radii are non-zero.
+##
+#Const kLastType = kComplex_Type
+#Line # incomplete ##
+##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Enum ##
+
+# ------------------------------------------------------------------------------
+
+#Method Type getType() const
+#In incomplete
+#Line # incomplete ##
+
+Returns the RR's sub type.
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method Type type() const
+#In incomplete
+#Line # incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method inline bool isEmpty() const
+#In Property
+#Line # returns true if width or height are zero ##
+Returns true if rect().fLeft is equal to rect().fRight, or if rect().fTop is equal
+to rect().fBottom.
+
+#Return true if width() or height() are zero ##
+
+#Example
+#Height 100
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTextAlign(SkPaint::kCenter_Align);
+ paint.setTextSize(16);
+ SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 10, 5);
+ canvas->drawRRect(rrect, paint);
+ canvas->drawString(rrect.isEmpty() ? "empty" : "not empty", 64, 90, paint);
+ rrect.inset(40, 0);
+ canvas->translate(128, 0);
+ canvas->drawRRect(rrect, paint);
+ canvas->drawString(rrect.isEmpty() ? "empty" : "not empty", 64, 90, paint);
+##
+
+#SeeAlso SkRect::isEmpty height width
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method inline bool isRect() const
+#In Property
+#Line # returns true if not empty, and one radius at each corner is zero ##
+Returns true if not empty, and if either x or y radius at each corner is zero.
+
+#Return true if not empty, and one radius at each corner is zero ##
+
+#Example
+#Height 100
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTextAlign(SkPaint::kCenter_Align);
+ paint.setTextSize(16);
+ SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});
+ canvas->drawRRect(rrect, paint);
+ canvas->drawString(rrect.isRect() ? "rect" : "not rect", 64, 90, paint);
+ SkVector radii[] = {{10, 10}, {0, 0}, {0, 0}, {0, 0}};
+ rrect.setRectRadii(rrect.getBounds(), radii);
+ canvas->translate(128, 0);
+ canvas->drawRRect(rrect, paint);
+ canvas->drawString(rrect.isRect() ? "rect" : "not rect", 64, 90, paint);
+##
+
+#SeeAlso isEmpty radii
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method inline bool isOval() const
+#In Property
+#Line # returns true if not empty, axes radii are equal, radii fill bounds ##
+Returns true if not empty, if all x-axis radii are equal, if all y-axis radii
+are equal, x-axis radii are at least half the width, and y-axis radii are at
+least half the height.
+
+#Return true if has identical geometry to Oval ##
+
+#Example
+#Height 100
+#Description
+The first radii are scaled down proportionately until both x-axis and y-axis fit
+within the bounds. After scaling, x-axis radius is smaller than half the width;
+left round rect is not an oval. The second radii are equal to half the
+dimensions; right round rect is an oval.
+##
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTextAlign(SkPaint::kCenter_Align);
+ paint.setTextSize(16);
+ SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 40, 30);
+ canvas->drawRRect(rrect, paint);
+ canvas->drawString(rrect.isOval() ? "oval" : "not oval", 64, 90, paint);
+ rrect.setRectXY(rrect.getBounds(), 35, 25);
+ canvas->translate(128, 0);
+ canvas->drawRRect(rrect, paint);
+ canvas->drawString(rrect.isOval() ? "oval" : "not oval", 64, 90, paint);
+##
+
+#SeeAlso isEmpty isSimple SkCanvas::drawOval
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method inline bool isSimple() const
+#In Property
+#Line # returns true if not empty, rect or oval; and axes radii are equal ##
+Returns true if not empty, if all x-axis radii are equal but not zero,
+if all y-axis radii are equal but not zero; and x-axis radius is less than half
+width(), or y-axis radius is less than half height().
+
+#Return true if not empty, rect or oval; and axes radii are equal ##
+
+#Bug 8107
+#Example
+#Height 100
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTextAlign(SkPaint::kCenter_Align);
+ paint.setTextSize(16);
+ SkVector radii[] = {{40, 30}, {40, 30}, {40, 30}, {40, 30}};
+ SkRRect rrect;
+ rrect.setRectRadii({30, 10, 100, 60}, radii);
+ canvas->drawRRect(rrect, paint);
+ canvas->drawString(rrect.isSimple() ? "simple" : "not simple", 64, 90, paint);
+ radii[0].fX = 35;
+ rrect.setRectRadii(rrect.getBounds(), radii);
+ canvas->translate(128, 0);
+ canvas->drawRRect(rrect, paint);
+ canvas->drawString(rrect.isSimple() ? "simple" : "not simple", 64, 90, paint);
+##
+
+#SeeAlso isEmpty isRect isOval isNinePatch
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method inline bool isNinePatch() const
+#In Property
+#Line # returns true if not empty, rect, oval or simple; and radii are axis-aligned ##
+Returns true if isEmpty, isRect, isOval, and isSimple return false; and if
+left x-axis radii are equal, right x-axis radii are equal, top y-axis radii are
+equal, and bottom y-axis radii are equal.
+
+#Return true if not empty, rect, oval or simple; and radii are axis-aligned ##
+
+#Bug 8107
+#Example
+#Height 100
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTextAlign(SkPaint::kCenter_Align);
+ paint.setTextSize(16);
+ SkVector radii[] = {{20, 30}, {40, 30}, {40, 30}, {20, 30}};
+ SkRRect rrect;
+ rrect.setRectRadii({30, 10, 100, 60}, radii);
+ canvas->drawRRect(rrect, paint);
+ canvas->drawString(rrect.isNinePatch() ? "9 patch" : "not 9 patch", 64, 90, paint);
+ radii[0].fX = 35;
+ rrect.setRectRadii(rrect.getBounds(), radii);
+ canvas->translate(128, 0);
+ canvas->drawRRect(rrect, paint);
+ canvas->drawString(rrect.isNinePatch() ? "9 patch" : "not 9 patch", 64, 90, paint);
+##
+
+#SeeAlso isEmpty isRect isOval isSimple isComplex
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method inline bool isComplex() const
+#In Property
+#Line # returns true if not empty, rect, oval, simple, or nine-patch ##
+
+Returns true if isEmpty, isRect, isOval, isSimple, and isNinePatch return false.
+If true: width and height are greater than zero, at least one corner radii are
+both greater than zero; left x-axis radii are not equal, or right x-axis radii
+are not equal, or top y-axis radii are not equal, or bottom y-axis radii are not
+equal.
+
+#Return true if not empty, rect, oval, simple, or nine-patch ##
+
+#Example
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTextAlign(SkPaint::kCenter_Align);
+ paint.setTextSize(16);
+ SkVector radii[] = {{25, 30}, {40, 30}, {40, 30}, {20, 30}};
+ SkRRect rrect;
+ rrect.setRectRadii({30, 10, 100, 60}, radii);
+ canvas->drawRRect(rrect, paint);
+ canvas->drawString(rrect.isComplex() ? "complex" : "not complex", 64, 90, paint);
+ radii[0].fX = 20;
+ rrect.setRectRadii(rrect.getBounds(), radii);
+ canvas->translate(128, 0);
+ canvas->drawRRect(rrect, paint);
+ canvas->drawString(rrect.isComplex() ? "complex" : "not complex", 64, 90, paint);
+##
+
+#SeeAlso isEmpty isRect isOval isSimple isNinePatch
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method SkScalar width() const
+#In Property
+#Line # returns span in x ##
+Returns span on the x-axis. This does not check if result fits in 32-bit float;
+result may be infinity.
+
+#Return bounds().fRight minus bounds().fLeft ##
+
+#Example
+#Description
+SkRRect::MakeRect sorts its input, so width() is always zero or larger.
+##
+ SkRRect unsorted = SkRRect::MakeRect({ 15, 25, 10, 5 });
+ SkDebugf("unsorted width: %g\n", unsorted.width());
+ SkRRect large = SkRRect::MakeRect({ -FLT_MAX, 1, FLT_MAX, 2 });
+ SkDebugf("large width: %.0f\n", large.width());
+#StdOut
+unsorted width: 5
+large width: inf
+##
+##
+
+#SeeAlso SkRect::width height getBounds
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method SkScalar height() const
+#In Property
+#Line # returns span in y ##
+Returns span on the y-axis. This does not check if result fits in 32-bit float;
+result may be infinity.
+
+#Return bounds().fBottom minus bounds().fTop ##
+
+#Example
+#Description
+SkRRect::MakeRect sorts its input, so height() is always zero or larger.
+##
+ SkRRect unsorted = SkRRect::MakeRect({ 15, 25, 10, 20 });
+ SkDebugf("unsorted height: %g\n", unsorted.height());
+ SkRRect large = SkRRect::MakeRect({ 1, -FLT_MAX, 2, FLT_MAX });
+ SkDebugf("large height: %.0f\n", large.height());
+#StdOut
+unsorted height: 5
+large height: inf
+##
+##
+
+#SeeAlso SkRect.height width getBounds
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method SkVector getSimpleRadii() const
+#In Property
+#Line # returns corner radii for simple types ##
+
+Returns top-left corner x-radii. If type() returns kEmpty_Type, kRect_Type,
+kOval_Type, or kSimple_Type, returns a value representative of all corner radii.
+If type() returns kNinePatch_Type or kComplex_Type, at least one of the
+remaining three corners has a different value.
+
+#Return corner radii for simple types ##
+
+#Example
+ auto drawDetails = [=](const SkRRect& rrect) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTextAlign(SkPaint::kCenter_Align);
+ paint.setTextSize(12);
+ canvas->drawRRect(rrect, paint);
+ SkVector corner = rrect.getSimpleRadii();
+ std::string label = "corner: " + std::to_string(corner.fX).substr(0, 3) + ", " +
+ std::to_string(corner.fY).substr(0, 3);
+ canvas->drawString(label.c_str(), 64, 90, paint);
+ canvas->translate(128, 0);
+ };
+ SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});
+ drawDetails(rrect);
+ rrect.setRectXY(rrect.getBounds(), 5, 8);
+ drawDetails(rrect);
+##
+
+#SeeAlso radii getBounds getType isSimple
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void setEmpty()
+#In Set
+#Line # zeroes width, height, and corner radii ##
+
+Sets bounds to zero width and height at (0, 0), the origin. Sets
+corner radii to zero and sets type to kEmpty_Type.
+
+#Example
+#Description
+Nothing blue is drawn because rrect is set to empty.
+##
+ SkPaint paint;
+ SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});
+ canvas->drawRRect(rrect, paint);
+ rrect.setEmpty();
+ paint.setColor(SK_ColorBLUE);
+ canvas->drawRRect(rrect, paint);
+##
+
+#SeeAlso MakeEmpty setRect
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void setRect(const SkRect& rect)
+#In Set
+#Line # sets rect bounds with zeroed corners ##
+
+Sets bounds to sorted rect, and sets corner radii to zero.
+If set bounds has width and height, and sets type to kRect_Type;
+otherwise, sets type to kEmpty_Type.
+
+#Param rect bounds to set ##
+
+#Example
+ SkPaint paint;
+ SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});
+ canvas->drawRRect(rrect, paint);
+ rrect.setRect({60, 30, 120, 80});
+ paint.setColor(SK_ColorBLUE);
+ canvas->drawRRect(rrect, paint);
+##
+
+#SeeAlso MakeRect setRectXY
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method static SkRRect MakeEmpty()
+#In Constructor
+#Line # incomplete ##
+
+Makes an empty rrect at the origin with zero width and height.
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method static SkRRect MakeRect(const SkRect& r)
+#In Constructor
+#Line # incomplete ##
+
+#Param r incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method static SkRRect MakeOval(const SkRect& oval)
+#In incomplete
+#Line # incomplete ##
+
+#Param oval incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method static SkRRect MakeRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad)
+#In incomplete
+#Line # incomplete ##
+
+#Param rect incomplete ##
+#Param xRad incomplete ##
+#Param yRad incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void setOval(const SkRect& oval)
+#In incomplete
+#Line # incomplete ##
+
+Sets Round_Rect to match the supplied oval. All x-radii will equal half the
+width and all y-radii will equal half the height.
+
+#Param oval incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad)
+#In incomplete
+#Line # incomplete ##
+
+Initializes Round_Rect with the same radii for all four corners.
+
+#Param rect incomplete ##
+#Param xRad incomplete ##
+#Param yRad incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void setNinePatch(const SkRect& rect, SkScalar leftRad, SkScalar topRad,
+ SkScalar rightRad, SkScalar bottomRad)
+#In incomplete
+#Line # incomplete ##
+
+Initializes Round_Rect with one radius per-side.
+
+#Param rect incomplete ##
+#Param leftRad incomplete ##
+#Param topRad incomplete ##
+#Param rightRad incomplete ##
+#Param bottomRad incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void setRectRadii(const SkRect& rect, const SkVector radii[4])
+#In incomplete
+#Line # incomplete ##
+
+Initializes Round_Rect with potentially different radii for all four corners.
+
+#Param rect incomplete ##
+#Param radii incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Enum Corner
+#Line # incomplete ##
+
+#Code
+ enum Corner {
+ kUpperLeft_Corner,
+ kUpperRight_Corner,
+ kLowerRight_Corner,
+ kLowerLeft_Corner,
+ };
+##
+
+The radii are stored: top-left, top-right, bottom-right, bottom-left.
+
+#Const kUpperLeft_Corner
+#Line # incomplete ##
+##
+#Const kUpperRight_Corner
+#Line # incomplete ##
+##
+#Const kLowerRight_Corner
+#Line # incomplete ##
+##
+#Const kLowerLeft_Corner
+#Line # incomplete ##
+##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Enum ##
+
+# ------------------------------------------------------------------------------
+
+#Method const SkRect& rect() const
+#In incomplete
+#Line # incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method SkVector radii(Corner corner) const
+#In incomplete
+#Line # incomplete ##
+
+#Param corner incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method const SkRect& getBounds() const
+#In incomplete
+#Line # incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method bool operator==(const SkRRect& a, const SkRRect& b)
+#In Operator
+#Line # incomplete ##
+
+#Param a incomplete ##
+#Param b incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method bool operator!=(const SkRRect& a, const SkRRect& b)
+#In Operator
+#Line # incomplete ##
+
+#Param a incomplete ##
+#Param b incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void inset(SkScalar dx, SkScalar dy, SkRRect* dst) const
+#In incomplete
+#Line # incomplete ##
+
+Calls inset on the bounds, and adjust the radii to reflect what happens.
+If the corner is sharp (no curvature), leave it alone,
+otherwise we grow/shrink the radii by the amount of the inset. If a
+given radius becomes negative, it is pinned to 0.
+If the inset amount is larger than the width/height then the rrect collapses to
+a degenerate line or point.
+If the inset is sufficiently negative to cause the bounds to become infinite then
+the result is a default initialized rrect.
+It is valid for dst == this.
+
+#Param dx incomplete ##
+#Param dy incomplete ##
+#Param dst incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void inset(SkScalar dx, SkScalar dy)
+#In incomplete
+#Line # incomplete ##
+
+#Param dx incomplete ##
+#Param dy incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void outset(SkScalar dx, SkScalar dy, SkRRect* dst) const
+#In incomplete
+#Line # incomplete ##
+
+Call outset on the bounds, and adjust the radii to reflect what happens
+in stroking. If the corner is sharp (no curvature), leave it alone,
+otherwise we grow/shrink the radii by the amount of the inset. If a
+given radius becomes negative, it is pinned to 0.
+It is valid for dst == this.
+
+#Param dx incomplete ##
+#Param dy incomplete ##
+#Param dst incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void outset(SkScalar dx, SkScalar dy)
+#In incomplete
+#Line # incomplete ##
+
+#Param dx incomplete ##
+#Param dy incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void offset(SkScalar dx, SkScalar dy)
+#In incomplete
+#Line # incomplete ##
+
+Translate the rrect by (dx, dy).
+
+#Param dx incomplete ##
+#Param dy incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method SkRRect SK_WARN_UNUSED_RESULT makeOffset(SkScalar dx, SkScalar dy) const
+#In incomplete
+#Line # incomplete ##
+
+#Param dx incomplete ##
+#Param dy incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method bool contains(const SkRect& rect) const
+#In incomplete
+#Line # incomplete ##
+
+Returns true if 'rect' is wholy inside the RR, and both
+are not empty.
+
+#Param rect incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method bool isValid() const
+#In incomplete
+#Line # incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Const kSizeInMemory 48
+#Line # incomplete ##
+
+#Example
+// incomplete
+##
+
+#Const ##
+
+# ------------------------------------------------------------------------------
+
+#Method size_t writeToMemory(void* buffer) const
+#In incomplete
+#Line # incomplete ##
+
+Write the rrect into the specified buffer. This is guaranteed to always
+write kSizeInMemory bytes, and that value is guaranteed to always be
+a multiple of 4. Return kSizeInMemory.
+
+#Param buffer incomplete ##
+
+#Return incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method size_t readFromMemory(const void* buffer, size_t length)
+#In incomplete
+#Line # incomplete ##
+
+Reads the rrect from the specified buffer.
+If the specified buffer is large enough, this will read kSizeInMemory bytes,
+and that value is guaranteed to always be a multiple of 4.
+
+#Param buffer memory to read from
+##
+#Param length amount of memory available in the buffer
+##
+
+#Return number of bytes read (must be a multiple of 4) or
+ 0 if there was not enough memory available
+##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method bool transform(const SkMatrix& matrix, SkRRect* dst) const
+#In incomplete
+#Line # incomplete ##
+
+Transform by the specified matrix, and put the result in dst.
+
+#Param matrix SkMatrix specifying the transform. Must only contain
+ scale and/or translate, or this call will fail.
+##
+#Param dst SkRRect to store the result. It is an error to use this,
+ which would make this function no longer const.
+##
+
+#Return true on success, false on failure.
+##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void dump(bool asHex) const
+#In incomplete
+#Line # incomplete ##
+
+#Param asHex incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void dump() const
+#In incomplete
+#Line # incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method void dumpHex() const
+#In incomplete
+#Line # incomplete ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso incomplete
+
+#Method ##
+
+#Class SkRRect ##
+
+#Topic RRect ##
diff --git a/docs/SkRect_Reference.bmh b/docs/SkRect_Reference.bmh
index 71e26f2e33..cb0c1ed190 100644
--- a/docs/SkRect_Reference.bmh
+++ b/docs/SkRect_Reference.bmh
@@ -609,7 +609,7 @@ large width: 4294967296
#In Property
#Line # returns span in y ##
-Returns span on the y-axis. This does not check if IRect is sorted, or if
+Returns span on the y-axis. This does not check if Rect is sorted, or if
result fits in 32-bit float; result may be negative or infinity.
#Return fBottom minus fTop ##
diff --git a/docs/illustrations.bmh b/docs/illustrations.bmh
index ef528adf60..0558722029 100644
--- a/docs/illustrations.bmh
+++ b/docs/illustrations.bmh
@@ -449,4 +449,273 @@ void draw(SkCanvas* canvas) {
##
##
+#Subtopic Image_Info_Color_Type_RGBA_F32
+#Example
+#Width 812
+#Height 685
+void draw(SkCanvas* canvas) {
+ canvas->scale(1.25f, 1.25f);
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTextSize(10);
+ paint.setTextAlign(SkPaint::kCenter_Align);
+ canvas->drawString("128-bit word", 5 + 20 * 16, 20, paint);
+ canvas->drawString("little endian byte order", 5 + 20 * 4, 135, paint);
+ for (int i = 0; i < 4; ++i) {
+ canvas->drawString("(low bits)", 5 + 10 * 4, 187 + i * 100, paint);
+ canvas->drawString("(high bits)", 105 + 10 * 4, 237 + i * 100, paint);
+ }
+ auto drawBoxText = [=](SkScalar e[], const char* s[], const char* nums[] ,
+ int count, int n, SkScalar yPos) -> void {
+ SkPaint p(paint);
+ p.setColor(SK_ColorRED);
+ SkScalar xPos = 15;
+ int stringIndex = 0;
+ for (int i = n; i >= 0; --i) {
+ if (0 == i || n == i || 32 == i || 31 == i) {
+ int x = xPos;
+ if (2 == count) {
+ x += stringIndex * 12 + (stringIndex ? 8 : 0);
+ }
+ canvas->drawString(nums[stringIndex], x, yPos - 5, p);
+ if (1 == count) {
+ canvas->drawString(nums[stringIndex], xPos + 100, yPos - 5, p);
+ }
+ ++stringIndex;
+ }
+ xPos += 9;
+ }
+ p.setColor(SK_ColorBLACK);
+ for (int i = 0; i < count; ++i) {
+ canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 5, yPos + 10, p);
+ if (1 == count) {
+ canvas->drawString(s[i], 105 + (e[i] + e[i + 1]) * 5, yPos + 10, p);
+ }
+ }
+ p.setStyle(SkPaint::kStroke_Style);
+ for (int i = 0; i <= count; ++i) {
+ canvas->drawLine(5 + e[i] * 10, yPos, 5 + e[i] * 10, yPos + 15, p);
+ if (1 == count) {
+ canvas->drawLine(105 + e[i] * 10, yPos, 105 + e[i] * 10, yPos + 15, p);
+ }
+ }
+ for (int i = 0; i < 2; ++i) {
+ canvas->drawLine(5 + e[0] * 10, yPos + i * 15,
+ 5 + e[count] * 10, yPos + i * 15, p);
+ if (1 == count) {
+ canvas->drawLine(105 + e[0] * 10, yPos + i * 15,
+ 105 + e[count] * 10, yPos + i * 15, p);
+ }
+ }
+ };
+ SkScalar edges[] = { 0, 32, 64,
+ 0, 8
+ };
+ const char* labels[] = { "alpha", "blue", "green", "red" };
+ const char* nums128[] = { "127", "96", "95", "64"};
+ const char* nums64[] = { "63", "32", "31", "0"};
+ const char* nums8[] = { "7", "0"};
+ drawBoxText(&edges[0], &labels[0], nums128, 2, 63, 45);
+ drawBoxText(&edges[0], &labels[2], nums64, 2, 63, 95);
+ drawBoxText(&edges[3], &labels[3], nums8, 1, 7, 160);
+ drawBoxText(&edges[3], &labels[3], nums8, 1, 7, 210);
+ drawBoxText(&edges[3], &labels[2], nums8, 1, 7, 260);
+ drawBoxText(&edges[3], &labels[2], nums8, 1, 7, 310);
+ drawBoxText(&edges[3], &labels[1], nums8, 1, 7, 360);
+ drawBoxText(&edges[3], &labels[1], nums8, 1, 7, 410);
+ drawBoxText(&edges[3], &labels[0], nums8, 1, 7, 460);
+ drawBoxText(&edges[3], &labels[0], nums8, 1, 7, 510);
+}
+##
+##
+
+#Subtopic Blend_Mode_Porter_Duff
+#Example
+#Width 480
+#Height 330
+ SkPaint srcPaint;
+ srcPaint.setAntiAlias(true);
+ SkPaint labelPaint = srcPaint;
+ labelPaint.setTextAlign(SkPaint::kCenter_Align);
+ labelPaint.setTextSize(16);
+ SkPaint dstPaint = labelPaint;
+ dstPaint.setTextSize(80);
+ dstPaint.setColor(0xFF606080);
+ dstPaint.setTypeface(SkTypeface::MakeFromName("Roboto", SkFontStyle::Bold()));
+
+ SkBitmap srcBits;
+ srcBits.allocN32Pixels(80, 84);
+ SkCanvas srcCanvas(srcBits);
+ srcPaint.setColor(0xFFcc6633);
+ SkPath srcPath;
+ const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};
+ srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);
+ srcBits.eraseColor(0);
+ srcCanvas.drawPath(srcPath, srcPaint);
+
+ canvas->drawColor(0, SkBlendMode::kClear);
+ for (auto blend : { SkBlendMode::kSrc, SkBlendMode::kSrcATop, SkBlendMode::kSrcOver,
+ SkBlendMode::kSrcIn, SkBlendMode::kSrcOut,
+ SkBlendMode::kDst, SkBlendMode::kDstATop, SkBlendMode::kDstOver,
+ SkBlendMode::kDstIn, SkBlendMode::kDstOut,
+ SkBlendMode::kClear, SkBlendMode::kXor } ) {
+ canvas->drawString("&", 50, 80, dstPaint);
+ srcPaint.setBlendMode(blend);
+ canvas->drawBitmap(srcBits, 0, 0, &srcPaint);
+ canvas->drawString(SkBlendMode_Name(blend), 50, 100, labelPaint);
+ canvas->translate(80, 0);
+ if (SkBlendMode::kSrcOut == blend || SkBlendMode::kDstOut == blend) {
+ canvas->translate(-80 * 5, 100);
+ }
+ }
+##
+##
+
+#Subtopic Blend_Mode_Porter_Duff_2
+#Example
+#Width 480
+#Height 330
+ SkPaint srcPaint;
+ srcPaint.setAntiAlias(true);
+ SkPaint labelPaint = srcPaint;
+ labelPaint.setTextAlign(SkPaint::kCenter_Align);
+ labelPaint.setTextSize(16);
+ SkPaint dstPaint = labelPaint;
+ dstPaint.setTextSize(80);
+ dstPaint.setColor(0xFF606080);
+ dstPaint.setTypeface(SkTypeface::MakeFromName("Roboto", SkFontStyle::Bold()));
+
+ srcPaint.setColor(0xFFcc6633);
+ SkPath srcPath;
+ const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};
+ srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);
+ canvas->drawColor(0, SkBlendMode::kClear);
+
+ SkBitmap dstBits;
+ dstBits.allocN32Pixels(80, 80);
+ SkCanvas dstCanvas(dstBits);
+ for (auto blend : { SkBlendMode::kSrc, SkBlendMode::kSrcATop, SkBlendMode::kSrcOver,
+ SkBlendMode::kSrcIn, SkBlendMode::kSrcOut,
+ SkBlendMode::kDst, SkBlendMode::kDstATop, SkBlendMode::kDstOver,
+ SkBlendMode::kDstIn, SkBlendMode::kDstOut,
+ SkBlendMode::kClear, SkBlendMode::kXor } ) {
+ canvas->drawString("&", 50, 80, dstPaint);
+ srcPaint.setBlendMode(blend);
+ canvas->drawPath(srcPath, srcPaint);
+ canvas->drawString(SkBlendMode_Name(blend), 50, 100, labelPaint);
+ canvas->translate(80, 0);
+ if (SkBlendMode::kSrcOut == blend || SkBlendMode::kDstOut == blend) {
+ canvas->translate(-80 * 5, 100);
+ }
+ }
+##
+##
+
+#Subtopic Blend_Mode_Lighten_Darken
+#Example
+#Width 480
+#Height 330
+ SkPaint srcPaint;
+ srcPaint.setAntiAlias(true);
+ SkPaint labelPaint = srcPaint;
+ labelPaint.setTextAlign(SkPaint::kCenter_Align);
+ labelPaint.setTextSize(16);
+ SkPaint dstPaint = labelPaint;
+ dstPaint.setTextSize(80);
+ dstPaint.setColor(0xFF606080);
+ dstPaint.setTypeface(SkTypeface::MakeFromName("Roboto", SkFontStyle::Bold()));
+
+ srcPaint.setColor(0xFFcc6633);
+ SkPath srcPath;
+ const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};
+ srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);
+ canvas->drawColor(0, SkBlendMode::kClear);
+ for (auto blend : { SkBlendMode::kPlus, SkBlendMode::kScreen, SkBlendMode::kOverlay,
+ SkBlendMode::kDarken, SkBlendMode::kLighten, SkBlendMode::kColorDodge,
+ SkBlendMode::kColorBurn, SkBlendMode::kHardLight, SkBlendMode::kSoftLight,
+ SkBlendMode::kDifference, SkBlendMode::kExclusion, SkBlendMode::kMultiply } ) {
+ canvas->drawString("&", 50, 80, dstPaint);
+ srcPaint.setBlendMode(blend);
+ canvas->drawPath(srcPath, srcPaint);
+ canvas->drawString(SkBlendMode_Name(blend), 50, 100, labelPaint);
+ canvas->translate(90, 0);
+ if (SkBlendMode::kLighten == blend || SkBlendMode::kDifference == blend) {
+ canvas->translate(-90 * 5, 100);
+ }
+ }
+##
+##
+
+#Subtopic Blend_Mode_Color_Blends
+#Example
+#Width 480
+#Height 110
+ SkPaint srcPaint;
+ srcPaint.setAntiAlias(true);
+ SkPaint labelPaint = srcPaint;
+ labelPaint.setTextAlign(SkPaint::kCenter_Align);
+ labelPaint.setTextSize(16);
+ SkPaint dstPaint = labelPaint;
+ dstPaint.setTextSize(80);
+ dstPaint.setColor(0xFF606080);
+ dstPaint.setTypeface(SkTypeface::MakeFromName("Roboto", SkFontStyle::Bold()));
+
+ srcPaint.setColor(0xFFcc6633);
+ SkPath srcPath;
+ const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};
+ srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);
+ canvas->drawColor(0, SkBlendMode::kClear);
+ for (auto blend : { SkBlendMode::kHue, SkBlendMode::kSaturation, SkBlendMode::kColor,
+ SkBlendMode::kLuminosity } ) {
+ canvas->drawString("&", 50, 80, dstPaint);
+ srcPaint.setBlendMode(blend);
+ canvas->drawPath(srcPath, srcPaint);
+ canvas->drawString(SkBlendMode_Name(blend), 50, 100, labelPaint);
+ canvas->translate(90, 0);
+ }
+##
+##
+
+#Subtopic Blend_Mode_Modulate_Blend
+#Example
+#Width 480
+#Height 110
+ SkPaint srcPaint;
+ srcPaint.setAntiAlias(true);
+ SkPaint labelPaint = srcPaint;
+ labelPaint.setTextAlign(SkPaint::kCenter_Align);
+ labelPaint.setTextSize(16);
+ SkPaint dstPaint = labelPaint;
+ dstPaint.setTextSize(80);
+ dstPaint.setColor(0xFF606080);
+ dstPaint.setTypeface(SkTypeface::MakeFromName("Roboto", SkFontStyle::Bold()));
+
+ SkBitmap srcBits;
+ srcBits.allocN32Pixels(80, 84);
+ SkCanvas srcCanvas(srcBits);
+ srcPaint.setColor(0xFFcc6633);
+ SkPath srcPath;
+ const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};
+ srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);
+ srcBits.eraseColor(0);
+ srcCanvas.drawPath(srcPath, srcPaint);
+
+ canvas->drawColor(0, SkBlendMode::kClear);
+ srcPaint.setBlendMode(SkBlendMode::kModulate);
+ for (auto step: { 1, 2 } ) {
+ canvas->drawString("&", 50, 80, dstPaint);
+ if (1 == step) {
+ canvas->drawBitmap(srcBits, 0, 0, &srcPaint);
+ canvas->drawString("Bitmap", 50, 18, labelPaint);
+ } else {
+ canvas->drawPath(srcPath, srcPaint);
+ canvas->drawString("Geometry", 50, 18, labelPaint);
+ }
+ canvas->drawString(SkBlendMode_Name(SkBlendMode::kModulate), 50, 100, labelPaint);
+ canvas->translate(120, 0);
+ }
+
+##
+##
+
#Topic Illustrations ##
diff --git a/docs/status.json b/docs/status.json
index 07563837bb..2cdd6a5b05 100644
--- a/docs/status.json
+++ b/docs/status.json
@@ -40,9 +40,15 @@
"InProgress": {
"include": {
"core": [
+ "SkBlendMode.h",
+ "SkPicture.h",
+ "SkRRect.h"
]
},
"docs": [
+ "SkBlendMode_Reference.bmh",
+ "SkPicture_Reference.bmh",
+ "SkRRect_Reference.bmh",
"overview.bmh",
"usingBookmaker.bmh"
]
diff --git a/docs/undocumented.bmh b/docs/undocumented.bmh
index 2335aa3dd3..91e3a4030e 100644
--- a/docs/undocumented.bmh
+++ b/docs/undocumented.bmh
@@ -14,6 +14,9 @@
C C++ SIZE_MAX
CSS HTML
+
+ Sa Da Sc Dc max min # temporary until figure out what to do
+
SkUserConfig # not external, but still thinking about how markup refers to this
SkXXX.h # ditto
SkXXX_Reference # ditto
@@ -192,16 +195,6 @@ FT_Load_Glyph
##
##
-#Topic Blend_Mode
-#EnumClass SkBlendMode
- #Const kSrc 1
- ##
- #Const kSrcOver 3
- ##
- #Const kPlus 12
- ##
-#EnumClass ##
-#Topic ##
#Topic Circle
#Alias Circles ##
@@ -280,6 +273,11 @@ FT_Load_Glyph
##
##
+#Topic Deserial_Procs
+#Struct SkDeserialProcs
+##
+##
+
#Topic Device
#Class SkBaseDevice
##
@@ -572,12 +570,7 @@ FT_Load_Glyph
##
#Topic ##
-#Topic Picture
-#Class SkPicture
-#Method virtual void playback(SkCanvas*, AbortCallback* = nullptr) const = 0
-##
-##
-#Subtopic Recorder
+#Topic Picture_Recorder
#Class SkPictureRecorder
#Method SkCanvas* beginRecording(const SkRect& bounds,
SkBBHFactory* bbhFactory = NULL,
@@ -585,7 +578,6 @@ FT_Load_Glyph
##
##
##
-##
#Topic Pixel
#Subtopic Storage
@@ -670,20 +662,16 @@ FT_Load_Glyph
#Topic Right_Side_Bearing
##
-#Topic Round_Rect
- #Class SkRRect
- #Method void dump() const
- ##
- #Method void dumpHex() const
- ##
- ##
-#Topic ##
-
#Topic RSXform
#Struct SkRSXform
##
##
+#Topic Serial_Procs
+#Struct SkSerialProcs
+##
+##
+
#Topic Shader
#Class SkShader
#Enum TileMode
@@ -697,6 +685,9 @@ FT_Load_Glyph
#Method static sk_sp<SkShader> MakeBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
const SkMatrix* localMatrix = nullptr)
##
+ #Method static sk_sp<SkShader> MakeCompose(sk_sp<SkShader> dst, sk_sp<SkShader> src,
+ SkBlendMode mode, float lerp = 1)
+ ##
#Class ##
#Topic ##
@@ -710,9 +701,9 @@ FT_Load_Glyph
#Topic ##
#Topic Stream
-#Class SkWStream
+#Class SkStream
+##
##
-#Topic ##
#Topic String
#Class SkString
@@ -821,8 +812,12 @@ FT_Load_Glyph
##
#Topic ##
-# to be in Topic Read_Buffer
- #Struct SkReadBuffer
- #Struct ##
-# end of Topic Read_Buffer
+#Topic WStream
+#Class SkWStream
+##
+#Topic ##
+#Topic Xfermode_Image_Filter
+#Class SkXfermodeImageFilter
+##
+##