1 #Topic Blend_Mode 2 3 #PhraseDef list_of_blend_modes 4 SkBlendMode::kClear, SkBlendMode::kSrc, SkBlendMode::kDst, SkBlendMode::kSrcOver, 5 SkBlendMode::kDstOver, SkBlendMode::kSrcIn, SkBlendMode::kDstIn, 6 SkBlendMode::kSrcOut, SkBlendMode::kDstOut, SkBlendMode::kSrcATop, 7 SkBlendMode::kDstATop, SkBlendMode::kXor, SkBlendMode::kPlus, 8 SkBlendMode::kModulate, SkBlendMode::kScreen, SkBlendMode::kOverlay, 9 SkBlendMode::kDarken, SkBlendMode::kLighten, SkBlendMode::kColorDodge, 10 SkBlendMode::kColorBurn, SkBlendMode::kHardLight, SkBlendMode::kSoftLight, 11 SkBlendMode::kDifference, SkBlendMode::kExclusion, SkBlendMode::kMultiply, 12 SkBlendMode::kHue, SkBlendMode::kSaturation, SkBlendMode::kColor, 13 SkBlendMode::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 28 Replaces destination with Alpha and Color components set to zero; 29 a fully transparent pixel. 30 ## 31 32 #Const kSrc 1 33 #Line # replaces destination ## 34 #Details Src 35 Replaces destination with source. Destination alpha and color component values 36 are ignored. 37 ## 38 39 #Const kDst 2 40 #Line # preserves destination ## 41 #Details Dst 42 Preserves destination, ignoring source. Drawing with Paint set to kDst has 43 no effect. 44 ## 45 46 #Const kSrcOver 3 47 #Line # source over destination ## 48 #Details Src_Over 49 Replaces destination with source blended with destination. If source is opaque, 50 replaces 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 56 Replaces destination with destination blended with source. If destination is opaque, 57 has no effect. 58 ## 59 60 #Const kSrcIn 5 61 #Line # source trimmed inside destination ## 62 #Details Src_In 63 Replaces destination with source using destination opacity. 64 ## 65 66 #Const kDstIn 6 67 #Line # destination trimmed by source ## 68 #Details Dst_In 69 Scales destination opacity by source opacity. 70 ## 71 72 #Const kSrcOut 7 73 #Line # source trimmed outside destination ## 74 #Details Src_Out 75 Replaces destination with source using the inverse of destination opacity, 76 drawing source fully where destination opacity is zero. 77 ## 78 79 #Const kDstOut 8 80 #Line # destination trimmed outside source ## 81 #Details Dst_Out 82 Replaces destination opacity with inverse of source opacity. If source is 83 transparent, has no effect. 84 ## 85 86 #Const kSrcATop 9 87 #Line # source inside destination blended with destination ## 88 #Details Src_Atop 89 Blends 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 95 Blends 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 101 Blends destination by exchanging transparency of the source and destination. 102 ## 103 104 #Const kPlus 12 105 #Line # sum of colors ## 106 #Details Plus 107 Replaces destination with source and destination added together. 108 ## 109 110 #Const kModulate 13 111 #Line # product of Premultiplied colors; darkens destination ## 112 #Details Modulate 113 Replaces 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 119 Replaces 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 129 Replaces destination with multiply or screen, depending on destination. 130 ## 131 132 #Const kDarken 16 133 #Line # darker of source and destination ## 134 #Details Darken 135 Replaces destination with darker of source and destination. 136 ## 137 138 #Const kLighten 17 139 #Line # lighter of source and destination ## 140 #Details Lighten 141 Replaces destination with lighter of source and destination. 142 ## 143 144 #Const kColorDodge 18 145 #Line # brighten destination to reflect source ## 146 #Details Color_Dodge 147 Makes destination brighter to reflect source. 148 ## 149 150 #Const kColorBurn 19 151 #Line # darken destination to reflect source ## 152 #Details Color_Burn 153 Makes destination darker to reflect source. 154 ## 155 156 #Const kHardLight 20 157 #Line # multiply or screen, depending on source ## 158 #Details Hard_Light 159 Makes 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 165 Makes 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 171 Subtracts darker from lighter with higher contrast. 172 ## 173 174 #Const kExclusion 23 175 #Line # subtract darker from lighter with lower contrast ## 176 #Details Exclusion 177 Subtracts darker from lighter with lower contrast. 178 ## 179 180 #Const kMultiply 24 181 #Line # multiply source with destination, darkening image ## 182 #Details Multiply 183 Multiplies source with destination, darkening image. 184 ## 185 186 #Const kLastSeparableMode 24 187 #Line # last blend mode operating separately on components ## 188 Last 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 194 Replaces hue of destination with hue of source, leaving saturation and luminosity 195 unchanged. 196 ## 197 198 #Const kSaturation 26 199 #Line # saturation of source with hue and luminosity of destination ## 200 #Details Saturation 201 Replaces saturation of destination saturation hue of source, leaving hue and 202 luminosity unchanged. 203 ## 204 205 #Const kColor 27 206 #Line # hue and saturation of source with luminosity of destination ## 207 #Details Color 208 Replaces hue and saturation of destination with hue and saturation of source, 209 leaving luminosity unchanged. 210 ## 211 212 #Const kLuminosity 28 213 #Line # luminosity of source with hue and saturation of destination ## 214 #Details Luminosity 215 Replaces luminosity of destination with luminosity of source, leaving hue and 216 saturation unchanged. 217 ## 218 219 #Const kLastMode 28 220 #Line # last valid value ## 221 Used 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 ## 231 SkBlendMode::kClear sets destination to: #Formula # [0, 0] ##. 232 Use SkBlendMode::kClear to initialize a buffer to fully transparent pixels when 233 creating a mask with irregular edges. 234 235 #Example 236 #Description 237 SK_ColorYELLOW is ignored because SkBlendMode::kClear ignores the source pixel 238 value 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 ## 257 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component; 258 SkBlendMode::kSrc sets destination to: #Formula # [Sa, Sc] ##. 259 Use SkBlendMode::kSrc to copy one buffer to another. All pixels are copied, 260 regardless of source and destination Alpha values. As a parameter to 261 SkCanvas::drawAtlas, selects sprites and ignores colors. 262 #Example 263 #Image 3 264 #Description 265 SkBlendMode::kSrc does not blend transparent pixels with existing background; 266 it 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 ## 284 Given: #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 285 SkBlendMode::kDst preserves destination set to: #Formula # [Da, Dc] ##. 286 Setting Paint Blend_Mode to SkBlendMode::kDst causes drawing with 287 Paint to have no effect. As a parameter to SkCanvas::drawAtlas, 288 selects 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 ## 302 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 303 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 304 SkBlendMode::kSrcOver replaces destination with: #Formula # [Sa + Da * (1 - Sa), Sc + Dc * (1 - Sa)] ##, 305 drawing source over destination. SkBlendMode::kSrcOver is the default for Paint. 306 307 SkBlendMode::kSrcOver cannot make destination more transparent; the result will 308 be 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 ## 329 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 330 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 331 SkBlendMode::kDstOver replaces destination with: #Formula # [Da + Sa * (1 - Da), Dc + Sc * (1 - Da)] ##, 332 drawing 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 ## 353 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 354 #Formula # Da ## as destination Alpha; 355 SkBlendMode::kSrcIn replaces destination with: #Formula # [Sa * Da, Sc * Da] ##, 356 drawing 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 ## 377 Given: #Formula # Sa ## as source Alpha, 378 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 379 SkBlendMode::kDstIn replaces destination with: #Formula # [Da * Sa, Dc * Sa] ##, 380 scaling destination Alpha by source Alpha. Resulting 381 destination 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 ## 402 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 403 #Formula # Da ## as destination Alpha; 404 SkBlendMode::kSrcOut replaces destination with: #Formula # [Sa * (1 - Da), Sc * (1 - Da)] ##, 405 drawing source fully where destination Alpha is zero. Is destination 406 is 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 ## 427 Given: #Formula # Sa ## as source Alpha, 428 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 429 SkBlendMode::kDstOut replaces destination with: #Formula # [Da * (1 - Sa), Dc * (1 - Sa)] ##, 430 scaling destination Alpha by source transparency. Resulting 431 destination is visible where source is transparent. If source is transparent, 432 has 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 ## 453 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 454 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 455 SkBlendMode::kSrcATop replaces destination with: #Formula # [Da, Sc * Da + Dc * (1 - Sa)] ##, 456 replacing opaque destination with opaque source. If source or destination 457 is 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 ## 478 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 479 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 480 SkBlendMode::kDstATop replaces destination with: #Formula # [Sa, Dc * Sa + Sc * (1 - Da)] ##, 481 making 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 ## 502 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 503 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 504 SkBlendMode::kXor replaces destination with: 505 #Formula # [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa)] ##, 506 exchanging 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 ## 523 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 524 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 525 SkBlendMode::kPlus replaces destination with: #Formula # [Sa + Da, Sc + Dc] ##, 526 summing 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 ## 544 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 545 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 546 SkBlendMode::kModulate replaces destination with: #Formula # [Sa * Da, Sc * Dc] ##, 547 scaling Alpha and Color components by the lesser of the values. 548 SkBlendMode::kModulate differs from SkBlendMode::kMultiply in two ways. 549 SkBlendMode::kModulate like SkBlendMode::kSrcATop alters the destination inside 550 the destination area, as if the destination Alpha defined the boundaries of a 551 soft clip. SkBlendMode::kMultiply like SkBlendMode::kSrcOver can alter the 552 destination where the destination is transparent. 553 SkBlendMode::kModulate computes the product of the source and destination using 554 Premultiplied component values. SkBlendMode::kMultiply the product of the source 555 and 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 ## 586 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 587 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 588 SkBlendMode::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 ## 610 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 611 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 612 SkBlendMode::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 ## 635 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 636 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 637 SkBlendMode::kDarken replaces destination with: 638 #Formula # [Sa + Da - Sa * Da, Sc + Dc - max(Sc * Da, Dc * Sa)] ##. 639 SkBlendMode::kDarken does not make an image darker; it replaces the destination 640 component 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 ## 656 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 657 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 658 SkBlendMode::kLighten replaces destination with: 659 #Formula # [Sa + Da - Sa * Da, Sc + Dc - min(Sc * Da, Dc * Sa)] ##. 660 SkBlendMode::kDarken does not make an image lighter; it replaces the destination 661 component 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 ## 677 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 678 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 679 SkBlendMode::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)] ##, 682 making 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 ## 693 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 694 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 695 SkBlendMode::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)] ##, 698 making 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 ## 709 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 710 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 711 SkBlendMode::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)] ##, 714 making 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 ## 730 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 731 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 732 where #Formula # m = Da > 0 ? Dc / Da : 0 ##; 733 SkBlendMode::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))] ##, 736 making 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 ## 751 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 752 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 753 SkBlendMode::kDifference replaces destination with: 754 #Formula # [Sa + Da - Sa * Da, Sc + Dc - 2 * min(Sc * Da, Dc * Sa)] ##, 755 replacing 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 ## 776 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 777 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 778 SkBlendMode::kExclusion replaces destination with: 779 #Formula # [Sa + Da - Sa * Da, Sc + Dc - 2 * Sc * Dc] ##, 780 replacing 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 ## 801 Given: #Formula # Sa ## as source Alpha, #Formula # Sc ## as source Color component, 802 #Formula # Da ## as destination Alpha, #Formula # Dc ## as destination Color component; 803 SkBlendMode::kMultiply replaces destination with: 804 #Formula # [Sa + Da - Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa) + Sc * Dc] ##, 805 the product of Unpremultiplied source and destination. 806 SkBlendMode::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 ## 827 Given: #Formula # Sa ## as source Alpha, #Formula # S ## as source Color, 828 #Formula # Da ## as destination Alpha, #Formula # D ## as destination Color; 829 SkBlendMode::kHue replaces destination with: 830 #Formula # [Sa + Da - Sa * Da, SetLuminosity(SetSaturation(S, Saturation(D)), Luminosity(D))] ##, 831 source hue, leaving destination luminosity and saturation unchanged. 832 #Example 833 #Image 3 834 canvas->drawImage(image, 0, 0); 835 canvas->drawColor(0xFF00FF00, SkBlendMode::kHue); 836 ## 837 ## 838 839 #Subtopic Saturation 840 #Line # saturation of source with hue and luminosity of destination ## 841 Given: #Formula # Sa ## as source Alpha, #Formula # S ## as source Color, 842 #Formula # Da ## as destination Alpha, #Formula # D ## as destination Color; 843 SkBlendMode::kHue replaces destination with: 844 #Formula # [Sa + Da - Sa * Da, SetLuminosity(SetSaturation(D, Saturation(S)), Luminosity(D))] ##, 845 source hue, leaving destination luminosity and saturation unchanged. 846 #Example 847 #Image 3 848 canvas->drawImage(image, 0, 0); 849 canvas->drawColor(0xFF00FF00, SkBlendMode::kSaturation); 850 ## 851 ## 852 853 #Subtopic Color 854 #Line # hue and saturation of source with luminosity of destination ## 855 Given: #Formula # Sa ## as source Alpha, #Formula # S ## as source Color, 856 #Formula # Da ## as destination Alpha, #Formula # D ## as destination Color; 857 SkBlendMode::kColor replaces destination with: 858 #Formula # [Sa + Da - Sa * Da, SetLuminosity(S, Luminosity(D))] ##, 859 source hue and saturation, leaving destination luminosity unchanged. 860 #Example 861 #Image 3 862 canvas->drawImage(image, 0, 0); 863 canvas->drawColor(0xFF00FF00, SkBlendMode::kColor); 864 ## 865 ## 866 867 #Subtopic Luminosity 868 #Line # luminosity of source with hue and saturation of destination ## 869 Given: #Formula # Sa ## as source Alpha, #Formula # S ## as source Color, 870 #Formula # Da ## as destination Alpha, #Formula # D ## as destination Color; 871 SkBlendMode::kLuminosity replaces destination with: 872 #Formula # [Sa + Da - Sa * Da, SetLuminosity(D, Luminosity(S))] ##, 873 source luminosity, leaving destination hue and saturation unchanged. 874 #Example 875 #Image 3 876 canvas->drawImage(image, 0, 0); 877 canvas->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 891 SkDebugf("default blend: SkBlendMode::k%s\n", SkBlendMode_Name(SkPaint().getBlendMode())); 892 #StdOut 893 default blend: SkBlendMode::kSrcOver 894 ## 895 ## 896 897 #SeeAlso SkBlendMode 898 899 #Method ## 900 901 #Topic Blend_Mode ## 902