12#include "roo_io/data/byte_order.h"
13#include "roo_logging/stream.h"
71[[deprecated(
"Use `BlendingMode::kSource` instead.")]]
73[[deprecated(
"Use `BlendingMode::kSourceOver` instead.")]]
75[[deprecated(
"Use `BlendingMode::kSourceIn` instead.")]]
77[[deprecated(
"Use `BlendingMode::kSourceAtop` instead.")]]
79[[deprecated(
"Use `BlendingMode::kDestination` instead.")]]
81[[deprecated(
"Use `BlendingMode::kDestinationOver` instead.")]]
84[[deprecated(
"Use `BlendingMode::kDestinationIn` instead.")]]
87[[deprecated(
"Use `BlendingMode::kDestinationAtop` instead.")]]
90[[deprecated(
"Use `BlendingMode::kClear` instead.")]]
92[[deprecated(
"Use `BlendingMode::kSourceOut` instead.")]]
94[[deprecated(
"Use `BlendingMode::kDestinationOut` instead.")]]
97[[deprecated(
"Use `BlendingMode::kXor` instead.")]]
112[[deprecated(
"Use `TransparencyMode::kNone` instead.")]]
114[[deprecated(
"Use `TransparencyMode::kCrude` instead.")]]
116[[deprecated(
"Use `TransparencyMode::kFull` instead.")]]
125inline constexpr uint8_t
__div_255(uint16_t arg) {
return (arg * 257) >> 16; }
132 return ((arg >> 8) + (arg >> 16)) >> 8;
140template <
typename Functor,
typename... Args>
142 ->
decltype(std::declval<Functor>()
147 std::forward<Args>(args)...);
150 std::forward<Args>(args)...);
153 std::forward<Args>(args)...);
158 std::forward<Args>(args)...);
161 std::forward<Args>(args)...);
164 std::forward<Args>(args)...);
167 std::forward<Args>(args)...);
171 std::forward<Args>(args)...);
174 std::forward<Args>(args)...);
177 std::forward<Args>(args)...);
180 std::forward<Args>(args)...);
183 std::forward<Args>(args)...);
186 std::forward<Args>(args)...);
189 std::forward<Args>(args)...);
192 std::forward<Args>(args)...);
199template <BlendingMode blending_mode>
210 uint16_t alpha = src.
a();
211 uint16_t inv_alpha = alpha ^ 0xFF;
213 inv_alpha * dst.
r()));
215 inv_alpha * dst.
g()));
217 inv_alpha * dst.
b()));
232 return Color(0xFF000000 |
r << 16 | g << 8 | b);
236#ifndef ROO_DISPLAY_BLENDING_PRECITION
237#define ROO_DISPLAY_BLENDING_PRECISION 1
247 uint16_t src_alpha = src.
a();
248 if (src_alpha == 0xFF) {
251 uint16_t dst_alpha = dst.
a();
252 if (dst_alpha == 0xFF) {
255 if (src_alpha == 0) {
258 if (dst_alpha == 0) {
265#if ROO_DISPLAY_BLENDING_PRECISION == 2
268 (uint16_t)dst_alpha * 255 + (uint16_t)src_alpha * (255 - dst_alpha);
270 uint16_t cs = (256 * 255 * 255 * src_alpha + a16 / 2 + 1) / a16;
271 uint16_t cd = 256 * 255 - cs;
279#elif ROO_DISPLAY_BLENDING_PRECISION == 1
281 uint16_t tmp = dst_alpha * src_alpha;
283 uint16_t cs = (src_alpha * 255) / alpha;
284 uint16_t cd = 255 - cs;
293#elif ROO_DISPLAY_BLENDING_PRECISION == 0
295 uint16_t tmp = dst_alpha * src_alpha;
297 uint16_t cs = ((src_alpha + 1) << 8) / (alpha + 1);
298 uint16_t cd = 256 - cs;
300 uint8_t
r = (uint8_t)((cs * src.
r() + cd * dst.
r() + 128) >> 8);
301 uint8_t g = (uint8_t)((cs * src.
g() + cd * dst.
g() + 128) >> 8);
302 uint8_t b = (uint8_t)((cs * src.
b() + cd * dst.
b() + 128) >> 8);
306 return Color(alpha << 24 |
r << 16 | g << 8 | b);
317 uint16_t src_alpha = src.
a();
318 uint16_t dst_alpha = dst.
a();
319 if (src_alpha == 0xFF) {
320 return src.
withA(dst_alpha);
322 if (src_alpha == 0) {
325 if (dst_alpha == 0) {
326 return color::Background;
328 uint16_t src_multi = src_alpha;
329 uint16_t dst_multi = 255 - src_alpha;
331 uint8_t
r = (uint8_t)((src_multi * src.
r() + dst_multi * dst.
r()) >> 8);
332 uint8_t g = (uint8_t)((src_multi * src.
g() + dst_multi * dst.
g()) >> 8);
333 uint8_t b = (uint8_t)((src_multi * src.
b() + dst_multi * dst.
b()) >> 8);
334 return Color(dst_alpha << 24 |
r << 16 | g << 8 | b);
360 return dst == color::Transparent && src == color::Transparent
372 uint16_t dst_alpha = dst.
a();
373 if (dst_alpha == 0xFF) {
376 uint16_t src_alpha = src.
a();
377 if (src_alpha == 0xFF) {
378 return src.
withA(dst_alpha);
380 if (src_alpha == 0) {
381 return color::Background;
407 uint8_t dst_alpha = dst.
a();
408 if (dst_alpha == 0) {
411 uint8_t src_alpha = src.
a();
412 if (src_alpha == 0xFF) {
413 return src.
withA(dst_alpha ^ 0xFF);
415 if (src_alpha == 0) {
416 return color::Background;
436 uint16_t src_alpha = src.
a();
437 uint16_t dst_alpha = dst.
a();
438 if (src_alpha == 0xFF) {
439 return src.
withA(255 - dst_alpha);
440 }
else if (src_alpha == 0) {
442 }
else if (dst_alpha == 0xFF) {
443 return dst.
withA(255 - src_alpha);
444 }
else if (dst_alpha == 0) {
448 dst_alpha * (255 - src_alpha));
449 uint16_t cs = (src_alpha * (255 - dst_alpha) + alpha / 2) / alpha;
450 uint16_t cd = 255 - cs;
458 return Color(alpha << 24 |
r << 16 | g << 8 | b);
469template <BlendingMode mode>
475 while (count-- > 0) {
476 *dst = op(*dst, *src);
484 while (count-- > 0) {
485 *dst = op(*dst, src);
493 while (count-- > 0) {
494 dst[*index] = op(dst[*index], *src);
502 while (count-- > 0) {
512 template <BlendingMode blending_mode>
519 template <BlendingMode blending_mode>
527 template <BlendingMode blending_mode>
535 template <BlendingMode blending_mode>
544 template <BlendingMode blending_mode>
555 return internal::BlenderSpecialization<internal::ApplyBlendingResolver>(
603 roo_io::ByteOrder byte_order>
616template <
typename ColorMode, roo_io::ByteOrder
byte_order>
620 io.store(src, dst, mode);
625 io.store(src, dst, mode);
629template <
typename ColorMode, roo_io::ByteOrder
byte_order>
636template <
typename ColorMode, BlendingMode blending_mode>
639 const ColorMode& color_mode)
const {
640 return color_mode.fromArgbColor(
645 return color_mode.fromArgbColor(
650template <
typename ColorMode>
653 const ColorMode& color_mode)
const {
654 return color_mode.fromArgbColor(src);
658 return color_mode.fromArgbColor(src);
662template <
typename ColorMode>
665 const ColorMode& color_mode)
const {
671template <
typename ColorMode, roo_io::ByteOrder
byte_order>
673 template <BlendingMode blending_mode>
675 const ColorMode& color_mode)
const {
680 template <BlendingMode blending_mode>
687template <
typename ColorMode>
689 template <BlendingMode blending_mode>
692 const ColorMode& color_mode)
const {
696 template <BlendingMode blending_mode>
699 ColorMode& color_mode)
const {
707template <
typename ColorMode, roo_io::ByteOrder
byte_order>
709 Color src,
const ColorMode& color_mode) {
716template <
typename ColorMode, roo_io::ByteOrder
byte_order>
718 Color src, ColorMode& color_mode) {
727template <
typename ColorMode>
730 const ColorMode& color_mode) {
737template <
typename ColorMode>
ARGB8888 color stored as a 32-bit unsigned integer.
constexpr uint8_t a() const
Alpha channel.
constexpr uint8_t b() const
Blue channel.
constexpr uint8_t g() const
Green channel.
constexpr uint8_t r() const
Red channel.
constexpr Color withA(uint8_t a) const
Return a copy with the specified alpha channel.
constexpr uint8_t __div_255_rounded(uint16_t arg)
constexpr uint8_t __div_65280(uint32_t arg)
constexpr uint8_t __div_65280_rounded(uint32_t arg)
auto BlenderSpecialization(const BlendingMode blending_mode, Args &&... args) -> decltype(std::declval< Functor >() .template operator()<BlendingMode::kSourceOver >(args...))
constexpr uint8_t __div_255(uint16_t arg)
Defines 140 opaque HTML named colors.
constexpr BlendingMode BLENDING_MODE_SOURCE_IN
ColorStorageType< ColorMode > ApplyRawSubByteBlending(BlendingMode blending_mode, uint8_t dst, Color src, const ColorMode &color_mode)
void ApplyBlendingOverBackground(BlendingMode mode, Color bg, Color *src, int16_t count)
constexpr BlendingMode BLENDING_MODE_DESTINATION
constexpr BlendingMode BLENDING_MODE_SOURCE_ATOP
BlendingMode
Porter-Duff style blending modes.
@ kDestinationOver
Destination is placed over the source.
@ kDestinationIn
Destination which overlaps the source, replaces the source.
@ kDestinationOut
Destination is placed, where it falls outside of the source.
@ kSourceOverOpaque
Similar to kSourceOver, but assumes that the destination is opaque.
@ kXor
The non-overlapping regions of source and destination are combined.
@ kDestination
Only the destination will be present.
@ kSource
The new ARGB8888 value completely replaces the old one.
@ kDestinationAtop
Destination which overlaps the source replaces the source. Source is placed elsewhere.
@ kSourceIn
The source that overlaps the destination, replaces the destination.
@ kSourceAtop
Source which overlaps the destination, replaces the destination. Destination is placed elsewhere.
@ kDestinationOverOpaque
Similar to kDestinationOver, but assumes that the source is opaque.
@ kClear
No regions are enabled.
@ kSourceOver
Source is placed (alpha-blended) over the destination. This is the default blending mode.
@ kSourceOut
Source is placed, where it falls outside of the destination.
void ApplyBlendingInPlace(BlendingMode mode, Color *dst, const Color *src, int16_t count)
constexpr BlendingMode BLENDING_MODE_DESTINATION_IN
constexpr BlendingMode BLENDING_MODE_SOURCE_OVER
Color AlphaBlend(Color bgc, Color fgc)
void ApplyRawFullByteBlending(BlendingMode blending_mode, roo::byte *dst, Color src, const ColorMode &color_mode)
constexpr BlendingMode BLENDING_MODE_DESTINATION_ATOP
TransparencyMode
Transparency information for a stream or color mode.
@ kNone
All colors are fully opaque.
@ kCrude
Colors are either fully opaque or fully transparent.
@ kFull
Colors may include partial transparency (alpha channel).
Color AlphaBlendOverOpaque(Color bgc, Color fgc)
roo_logging::Stream & operator<<(roo_logging::Stream &os, BlendingMode mode)
constexpr BlendingMode BLENDING_MODE_SOURCE
void ApplyBlendingSingleSourceInPlace(BlendingMode mode, Color *dst, Color src, int16_t count)
void ApplyBlendingInPlaceIndexed(BlendingMode mode, Color *dst, const Color *src, int16_t count, const uint32_t *index)
constexpr BlendingMode BLENDING_MODE_CLEAR
Color ApplyBlending(BlendingMode mode, Color dst, Color src)
constexpr BlendingMode BLENDING_MODE_DESTINATION_OUT
constexpr TransparencyMode TRANSPARENCY_NONE
constexpr TransparencyMode TRANSPARENCY_GRADUAL
constexpr BlendingMode BLENDING_MODE_DESTINATION_OVER
constexpr BlendingMode BLENDING_MODE_SOURCE_OUT
constexpr TransparencyMode TRANSPARENCY_BINARY
constexpr BlendingMode BLENDING_MODE_EXCLUSIVE_OR
BlendingMode blending_mode
Color operator()(Color dst, Color src) const
Color operator()(Color dst, Color src) const
Color operator()(Color dst, Color src) const
Color operator()(Color dst, Color src) const
Color operator()(Color dst, Color src) const
Color operator()(Color dst, Color src) const
Color operator()(Color dst, Color src) const
Color operator()(Color dst, Color src) const
Color operator()(Color dst, Color src) const
Color operator()(Color dst, Color src) const
Color operator()(Color dst, Color src) const
Color operator()(Color dst, Color src) const
Color operator()(Color dst, Color src) const
Color operator()(Color dst, Color src) const
void applyInPlace(Color *dst, const Color *src, int16_t count)
void applyOverBackground(Color bg, Color *src, int16_t count)
void applyInPlaceIndexed(Color *dst, const Color *src, int16_t count, const uint32_t *index)
void applySingleSourceInPlace(Color *dst, Color src, int16_t count)
Color apply(Color dst, Color src)
void operator()(roo::byte *dst, Color src, const ColorMode &mode) const
void operator()(roo::byte *dst, Color src, ColorMode &mode) const
void operator()(roo::byte *dst, Color src, const ColorMode &mode) const
void operator()(roo::byte *dst, Color src, ColorMode &mode) const
void operator()(roo::byte *dst, Color src, const ColorMode &mode) const
uint8_t operator()(uint8_t dst, Color src, const ColorMode &color_mode) const
uint8_t operator()(uint8_t dst, Color src, ColorMode &color_mode) const
uint8_t operator()(uint8_t dst, Color src, const ColorMode &color_mode) const
uint8_t operator()(uint8_t dst, Color src, const ColorMode &color_mode) const
uint8_t operator()(uint8_t dst, Color src, ColorMode &color_mode) const
__attribute__((always_inline)) void operator()(Color *dst
const Color int16_t count
__attribute__((always_inline)) void operator()(Color *dst
__attribute__((always_inline)) void operator()(Color bg
__attribute__((always_inline)) Color operator()(Color dst
__attribute__((always_inline)) void operator()(Color *dst
void operator()(roo::byte *dst, Color src, const ColorMode &color_mode) const
void operator()(roo::byte *dst, Color src, ColorMode &color_mode) const
ColorStorageType< ColorMode > operator()(ColorStorageType< ColorMode > dst, Color src, const ColorMode &color_mode) const
ColorStorageType< ColorMode > operator()(ColorStorageType< ColorMode > dst, Color src, ColorMode &color_mode) const