From 224c700a1fb0b7f6abd85a9729d29cbbdf5872dd Mon Sep 17 00:00:00 2001 From: Cary Clark Date: Wed, 27 Jun 2018 11:00:21 -0400 Subject: 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 Reviewed-by: Cary Clark Commit-Queue: Cary Clark Auto-Submit: Cary Clark --- docs/SkBitmap_Reference.bmh | 10 +- docs/SkBlendMode_Reference.bmh | 1180 ++++++++++++++++++++++++++++++++++++++++ docs/SkCanvas_Reference.bmh | 8 +- docs/SkImageInfo_Reference.bmh | 95 +++- docs/SkPath_Reference.bmh | 2 +- docs/SkPicture_Reference.bmh | 312 +++++++++++ docs/SkRRect_Reference.bmh | 1121 ++++++++++++++++++++++++++++++++++++++ docs/SkRect_Reference.bmh | 2 +- docs/illustrations.bmh | 269 +++++++++ docs/status.json | 6 + docs/undocumented.bmh | 59 +- 11 files changed, 3007 insertions(+), 57 deletions(-) create mode 100644 docs/SkBlendMode_Reference.bmh create mode 100644 docs/SkPicture_Reference.bmh create mode 100644 docs/SkRRect_Reference.bmh (limited to 'docs') 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 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 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 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 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 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 MakeBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy, const SkMatrix* localMatrix = nullptr) ## + #Method static sk_sp MakeCompose(sk_sp dst, sk_sp 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 +## +## -- cgit v1.2.3