• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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