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