Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.compose.ui.graphics
import androidx.compose.runtime.Immutable
/**
* Algorithms to use when painting on the canvas.
*
* When drawing a shape or image onto a canvas, different algorithms can be
* used to blend the pixels. The different values of [BlendMode] specify
* different such algorithms.
*
* Each algorithm has two inputs, the _source_, which is the image being drawn,
* and the _destination_, which is the image into which the source image is
* being composited. The destination is often thought of as the _background_.
* The source and destination both have four color channels, the red, green,
* blue, and alpha channels. These are typically represented as numbers in the
* range 0.0 to 1.0. The output of the algorithm also has these same four
* channels, with values computed from the source and destination.
*
* ## Application to the [Canvas] API
*
* When using [Canvas.saveLayer] and [Canvas.restore], the blend mode of the
* [Paint] given to the [Canvas.saveLayer] will be applied when
* [Canvas.restore] is called. Each call to [Canvas.saveLayer] introduces a new
* layer onto which shapes and images are painted; when [Canvas.restore] is
* called, that layer is then composited onto the parent layer, with the source
* being the most-recently-drawn shapes and images, and the destination being
* the parent layer. (For the first [Canvas.saveLayer] call, the parent layer
* is the canvas itself.)
*
* See also:
*
* * [Paint.blendMode], which uses [BlendMode] to define the compositing
* strategy.
*/
@Immutable
@kotlin.jvm.JvmInline
value class BlendMode internal constructor(@Suppress("unused") private val value: Int) {
companion object {
/**
* Drop both the source and destination images, leaving nothing.
*/
val Clear = BlendMode(0)
/**
* Drop the destination image, only paint the source image.
*
* Conceptually, the destination is first cleared, then the source image is
* painted.
*/
val Src = BlendMode(1)
/**
* Drop the source image, only paint the destination image.
*
* Conceptually, the source image is discarded, leaving the destination
* untouched.
*/
val Dst = BlendMode(2)
/**
* Composite the source image over the destination image.
*
* This is the default value. It represents the most intuitive case, where
* shapes are painted on top of what is below, with transparent areas showing
* the destination layer.
*/
val SrcOver = BlendMode(3)
/**
* Composite the source image under the destination image.
*
* This is the opposite of [SrcOver].
*
* This is useful when the source image should have been painted before the
* destination image, but could not be.
*/
val DstOver = BlendMode(4)
/**
* Show the source image, but only where the two images overlap. The
* destination image is not rendered, it is treated merely as a mask. The
* color channels of the destination are ignored, only the opacity has an
* effect.
*
* To show the destination image instead, consider [DstIn].
*
* To reverse the semantic of the mask (only showing the source where the
* destination is absent, rather than where it is present), consider
* [SrcOut].
*/
val SrcIn = BlendMode(5)
/**
* Show the destination image, but only where the two images overlap. The
* source image is not rendered, it is treated merely as a mask. The color
* channels of the source are ignored, only the opacity has an effect.
*
* To show the source image instead, consider [SrcIn].
*
* To reverse the semantic of the mask (only showing the source where the
* destination is present, rather than where it is absent), consider [DstOut].
*/
val DstIn = BlendMode(6)
/**
* Show the source image, but only where the two images do not overlap. The
* destination image is not rendered, it is treated merely as a mask. The color
* channels of the destination are ignored, only the opacity has an effect.
*
* To show the destination image instead, consider [DstOut].
*
* To reverse the semantic of the mask (only showing the source where the
* destination is present, rather than where it is absent), consider [SrcIn].
*
* This corresponds to the "Source out Destination" Porter-Duff operator.
*/
val SrcOut = BlendMode(7)
/**
* Show the destination image, but only where the two images do not overlap. The
* source image is not rendered, it is treated merely as a mask. The color
* channels of the source are ignored, only the opacity has an effect.
*
* To show the source image instead, consider [SrcOut].
*
* To reverse the semantic of the mask (only showing the destination where the
* source is present, rather than where it is absent), consider [DstIn].
*
* This corresponds to the "Destination out Source" Porter-Duff operator.
*/
val DstOut = BlendMode(8)
/**
* Composite the source image over the destination image, but only where it
* overlaps the destination.
*
* This is essentially the [SrcOver] operator, but with the output's opacity
* channel being set to that of the destination image instead of being a
* combination of both image's opacity channels.
*
* For a variant with the destination on top instead of the source, see
* [DstAtop].
*/
val SrcAtop = BlendMode(9)
/**
* Composite the destination image over the source image, but only where it
* overlaps the source.
*
* This is essentially the [DstOver] operator, but with the output's opacity
* channel being set to that of the source image instead of being a
* combination of both image's opacity channels.
*
* For a variant with the source on top instead of the destination, see
* [SrcAtop].
*/
val DstAtop = BlendMode(10)
/**
* Apply a bitwise `xor` operator to the source and destination images. This
* leaves transparency where they would overlap.
*/
val Xor = BlendMode(11)
/**
* Sum the components of the source and destination images.
*
* Transparency in a pixel of one of the images reduces the contribution of
* that image to the corresponding output pixel, as if the color of that
* pixel in that image was darker.
*
*/
val Plus = BlendMode(12)
/**
* Multiply the color components of the source and destination images.
*
* This can only result in the same or darker colors (multiplying by white,
* 1.0, results in no change; multiplying by black, 0.0, results in black).
*
* When compositing two opaque images, this has similar effect to overlapping
* two transparencies on a projector.
*
* For a variant that also multiplies the alpha channel, consider [Multiply].
*
* See also:
*
* * [Screen], which does a similar computation but inverted.
* * [Overlay], which combines [Modulate] and [Screen] to favor the
* destination image.
* * [Hardlight], which combines [Modulate] and [Screen] to favor the
* source image.
*/
val Modulate = BlendMode(13)
/**
* Multiply the inverse of the components of the source and destination
* images, and inverse the result.
*
* Inverting the components means that a fully saturated channel (opaque
* white) is treated as the value 0.0, and values normally treated as 0.0
* (black, transparent) are treated as 1.0.
*
* This is essentially the same as [Modulate] blend mode, but with the values
* of the colors inverted before the multiplication and the result being
* inverted back before rendering.
*
* This can only result in the same or lighter colors (multiplying by black,
* 1.0, results in no change; multiplying by white, 0.0, results in white).
* Similarly, in the alpha channel, it can only result in more opaque colors.
*
* This has similar effect to two projectors displaying their images on the
* same screen simultaneously.
*
* See also:
*
* * [Modulate], which does a similar computation but without inverting the
* values.
* * [Overlay], which combines [Modulate] and [Screen] to favor the
* destination image.
* * [Hardlight], which combines [Modulate] and [Screen] to favor the
* source image.
*/
val Screen = BlendMode(14) // The last coeff mode.
/**
* Multiply the components of the source and destination images after
* adjusting them to favor the destination.
*
* Specifically, if the destination value is smaller, this multiplies it with
* the source value, whereas is the source value is smaller, it multiplies
* the inverse of the source value with the inverse of the destination value,
* then inverts the result.
*
* Inverting the components means that a fully saturated channel (opaque
* white) is treated as the value 0.0, and values normally treated as 0.0
* (black, transparent) are treated as 1.0.
*
* See also:
*
* * [Modulate], which always multiplies the values.
* * [Screen], which always multiplies the inverses of the values.
* * [Hardlight], which is similar to [Overlay] but favors the source image
* instead of the destination image.
*/
val Overlay = BlendMode(15)
/**
* Composite the source and destination image by choosing the lowest value
* from each color channel.
*
* The opacity of the output image is computed in the same way as for
* [SrcOver].
*/
val Darken = BlendMode(16)
/**
* Composite the source and destination image by choosing the highest value
* from each color channel.
*
* The opacity of the output image is computed in the same way as for
* [SrcOver].
*/
val Lighten = BlendMode(17)
/**
* Divide the destination by the inverse of the source.
*
* Inverting the components means that a fully saturated channel (opaque
* white) is treated as the value 0.0, and values normally treated as 0.0
* (black, transparent) are treated as 1.0.
*
* **NOTE** This [BlendMode] can only be used on Android API level 29 and above
*/
val ColorDodge = BlendMode(18)
/**
* Divide the inverse of the destination by the source, and inverse the result.
*
* Inverting the components means that a fully saturated channel (opaque
* white) is treated as the value 0.0, and values normally treated as 0.0
* (black, transparent) are treated as 1.0.
*
* **NOTE** This [BlendMode] can only be used on Android API level 29 and above
*/
val ColorBurn = BlendMode(19)
/**
* Multiply the components of the source and destination images after
* adjusting them to favor the source.
*
* Specifically, if the source value is smaller, this multiplies it with the
* destination value, whereas is the destination value is smaller, it
* multiplies the inverse of the destination value with the inverse of the
* source value, then inverts the result.
*
* Inverting the components means that a fully saturated channel (opaque
* white) is treated as the value 0.0, and values normally treated as 0.0
* (black, transparent) are treated as 1.0.
*
* **NOTE** This [BlendMode] can only be used on Android API level 29 and above
*
* See also:
*
* * [Modulate], which always multiplies the values.
* * [Screen], which always multiplies the inverses of the values.
* * [Overlay], which is similar to [Hardlight] but favors the destination
* image instead of the source image.
*/
val Hardlight = BlendMode(20)
/**
* Use [ColorDodge] for source values below 0.5 and [ColorBurn] for source
* values above 0.5.
*
* This results in a similar but softer effect than [Overlay].
*
* **NOTE** This [BlendMode] can only be used on Android API level 29 and above
*
* See also:
*
* * [Color], which is a more subtle tinting effect.
*/
val Softlight = BlendMode(21)
/**
* Subtract the smaller value from the bigger value for each channel.
*
* Compositing black has no effect; compositing white inverts the colors of
* the other image.
*
* The opacity of the output image is computed in the same way as for
* [SrcOver].
*
* **NOTE** This [BlendMode] can only be used on Android API level 29 and above
*
* The effect is similar to [Exclusion] but harsher.
*/
val Difference = BlendMode(22)
/**
* Subtract double the product of the two images from the sum of the two
* images.
*
* Compositing black has no effect; compositing white inverts the colors of
* the other image.
*
* The opacity of the output image is computed in the same way as for
* [SrcOver].
*
* **NOTE** This [BlendMode] can only be used on Android API level 29 and above
*
* The effect is similar to [Difference] but softer.
*/
val Exclusion = BlendMode(23)
/**
* Multiply the components of the source and destination images, including
* the alpha channel.
*
* This can only result in the same or darker colors (multiplying by white,
* 1.0, results in no change; multiplying by black, 0.0, results in black).
*
* Since the alpha channel is also multiplied, a fully-transparent pixel
* (opacity 0.0) in one image results in a fully transparent pixel in the
* output. This is similar to [DstIn], but with the colors combined.
*
* For a variant that multiplies the colors but does not multiply the alpha
* channel, consider [Modulate].
*
* **NOTE** This [BlendMode] can only be used on Android API level 29 and above
*/
val Multiply = BlendMode(24) // The last separable mode.
/**
* Take the hue of the source image, and the saturation and luminosity of the
* destination image.
*
* The effect is to tint the destination image with the source image.
*
* The opacity of the output image is computed in the same way as for
* [SrcOver]. Regions that are entirely transparent in the source image take
* their hue from the destination.
*
* **NOTE** This [BlendMode] can only be used on Android API level 29 and above
*/
val Hue = BlendMode(25)
/**
* Take the saturation of the source image, and the hue and luminosity of the
* destination image.
*
* The opacity of the output image is computed in the same way as for
* [SrcOver]. Regions that are entirely transparent in the source image take
* their saturation from the destination.
*
* **NOTE** This [BlendMode] can only be used on Android API level 29 and above
*
* See also:
*
* * [Color], which also applies the hue of the source image.
* * [Luminosity], which applies the luminosity of the source image to the
* destination.
*/
val Saturation = BlendMode(26)
/**
* Take the hue and saturation of the source image, and the luminosity of the
* destination image.
*
* The effect is to tint the destination image with the source image.
*
* The opacity of the output image is computed in the same way as for
* [SrcOver]. Regions that are entirely transparent in the source image take
* their hue and saturation from the destination.
*
* **NOTE** This [BlendMode] can only be used on Android API level 29 and above
*
* See also:
*
* * [Hue], which is a similar but weaker effect.
* * [Softlight], which is a similar tinting effect but also tints white.
* * [Saturation], which only applies the saturation of the source image.
*/
val Color = BlendMode(27)
/**
* Take the luminosity of the source image, and the hue and saturation of the
* destination image.
*
* The opacity of the output image is computed in the same way as for
* [SrcOver]. Regions that are entirely transparent in the source image take
* their luminosity from the destination.
*
* **NOTE** This [BlendMode] can only be used on Android API level 29 and above
*
* See also:
*
* * [Saturation], which applies the saturation of the source image to the
* destination.
*/
val Luminosity = BlendMode(28)
}
override fun toString() = when (this) {
Clear -> "Clear"
Src -> "Src"
Dst -> "Dst"
SrcOver -> "SrcOver"
DstOver -> "DstOver"
SrcIn -> "SrcIn"
DstIn -> "DstIn"
SrcOut -> "SrcOut"
DstOut -> "DstOut"
SrcAtop -> "SrcAtop"
DstAtop -> "DstAtop"
Xor -> "Xor"
Plus -> "Plus"
Modulate -> "Modulate"
Screen -> "Screen"
Overlay -> "Overlay"
Darken -> "Darken"
Lighten -> "Lighten"
ColorDodge -> "ColorDodge"
ColorBurn -> "ColorBurn"
Hardlight -> "HardLight"
Softlight -> "Softlight"
Difference -> "Difference"
Exclusion -> "Exclusion"
Multiply -> "Multiply"
Hue -> "Hue"
Saturation -> "Saturation"
Color -> "Color"
Luminosity -> "Luminosity"
else -> "Unknown" // Should not get here since we have an internal constructor
}
}
/**
* Capability query to determine if the particular platform supports the [BlendMode]. Not
* all platforms support all blend mode algorithms, however, [BlendMode.SrcOver] is guaranteed
* to be supported as it is the default drawing algorithm. If a [BlendMode] that is not supported
* is used, the default of SrcOver is consumed instead.
*/
expect fun BlendMode.isSupported(): Boolean