Everywhere: Unify naming of RGBA-like colors

The `Bitmap` type was referring to to its internal pixel format by a
name that represents the order of the color components as they are layed
out in memory. Contrary, the `Color` type was using a naming that where
the name represents the order of the components from most to least
significant byte when viewed as a unsigned 32bit integer. This is
confusing as you have to keep remembering which mental model to use
depending on which code you work with.

To unify the two, the naming of RGBA-like colors in the `Color` type has
been adjusted to match the one from the Bitmap type. This seems to be
generally in line with how web APIs think about these types:
* `ImageData.pixelFormat` can be `rgba-8unorm` backed by a
  `Uint8ClamedArray`, but there is no pixel format backed by a 32bit
  unsigned type.
* WebGL can use format `RGBA` with type `UNSIGNED_BYTE`, but there is no
  such format with type `UNSIGNED_INT`.

Additionally, it appears that other browsers and browser-adjacent
libraries also think similarly about these types:
* Firefox:
  https://github.com/mozilla-firefox/firefox/blob/main/gfx/2d/Types.h
* WebKit:
  https://github.com/WebKit/WebKit/blob/main/Source/WebCore/platform/graphics/PixelFormat.h
* Skia:
  https://chromium.googlesource.com/skia/+/refs/heads/main/include/core/SkColorType.h

This has the not so nice side effect that APIs that interact with these
types through 32bit unsigned integers now have the component order
inverted due to little-endian byte order. E.g. specifying a color as hex
constant needs to be done as `0xAABBGGRR` if it is to be treated as
RGBA8888.

We could alleviate this by providing endian-independent APIs to callers.
But I suspect long-term we might want to think differently about bitmap
data anyway, e.g. to better support HDR in the future. However, such
changes would be more involved than just unifying the naming as done
here. So I considered that out of scope for now.
This commit is contained in:
InvalidUsernameException 2025-11-23 13:07:38 +01:00 committed by Jelle Raaijmakers
parent 07f61f2cec
commit 7c315ef67f
Notes: github-actions[bot] 2025-11-28 17:34:55 +00:00
14 changed files with 130 additions and 128 deletions

View file

@ -241,7 +241,7 @@ Bitmap::~Bitmap()
void Bitmap::strip_alpha_channel()
{
VERIFY(m_format == BitmapFormat::BGRA8888 || m_format == BitmapFormat::BGRx8888);
for (ARGB32& pixel : *this)
for (BGRA8888& pixel : *this)
pixel = 0xff000000 | (pixel & 0xffffff);
m_format = BitmapFormat::BGRx8888;
}

View file

@ -70,18 +70,18 @@ public:
[[nodiscard]] u8* scanline_u8(int physical_y);
[[nodiscard]] u8 const* scanline_u8(int physical_y) const;
[[nodiscard]] ARGB32* scanline(int physical_y);
[[nodiscard]] ARGB32 const* scanline(int physical_y) const;
[[nodiscard]] BGRA8888* scanline(int physical_y);
[[nodiscard]] BGRA8888 const* scanline(int physical_y) const;
[[nodiscard]] u8* unchecked_scanline_u8(int physical_y);
[[nodiscard]] u8 const* unchecked_scanline_u8(int physical_y) const;
[[nodiscard]] ARGB32* unchecked_scanline(int physical_y);
[[nodiscard]] ARGB32 const* unchecked_scanline(int physical_y) const;
[[nodiscard]] BGRA8888* unchecked_scanline(int physical_y);
[[nodiscard]] BGRA8888 const* unchecked_scanline(int physical_y) const;
[[nodiscard]] ARGB32* begin();
[[nodiscard]] ARGB32 const* begin() const;
[[nodiscard]] ARGB32* end();
[[nodiscard]] ARGB32 const* end() const;
[[nodiscard]] BGRA8888* begin();
[[nodiscard]] BGRA8888 const* begin() const;
[[nodiscard]] BGRA8888* end();
[[nodiscard]] BGRA8888 const* end() const;
[[nodiscard]] size_t data_size() const;
[[nodiscard]] IntRect rect() const { return { {}, m_size }; }
@ -164,14 +164,14 @@ ALWAYS_INLINE u8 const* Bitmap::unchecked_scanline_u8(int y) const
return reinterpret_cast<u8 const*>(m_data) + (y * m_pitch);
}
ALWAYS_INLINE ARGB32* Bitmap::unchecked_scanline(int y)
ALWAYS_INLINE BGRA8888* Bitmap::unchecked_scanline(int y)
{
return reinterpret_cast<ARGB32*>(unchecked_scanline_u8(y));
return reinterpret_cast<BGRA8888*>(unchecked_scanline_u8(y));
}
ALWAYS_INLINE ARGB32 const* Bitmap::unchecked_scanline(int y) const
ALWAYS_INLINE BGRA8888 const* Bitmap::unchecked_scanline(int y) const
{
return reinterpret_cast<ARGB32 const*>(unchecked_scanline_u8(y));
return reinterpret_cast<BGRA8888 const*>(unchecked_scanline_u8(y));
}
ALWAYS_INLINE u8* Bitmap::scanline_u8(int y)
@ -188,34 +188,34 @@ ALWAYS_INLINE u8 const* Bitmap::scanline_u8(int y) const
return unchecked_scanline_u8(y);
}
ALWAYS_INLINE ARGB32* Bitmap::scanline(int y)
ALWAYS_INLINE BGRA8888* Bitmap::scanline(int y)
{
return reinterpret_cast<ARGB32*>(scanline_u8(y));
return reinterpret_cast<BGRA8888*>(scanline_u8(y));
}
ALWAYS_INLINE ARGB32 const* Bitmap::scanline(int y) const
ALWAYS_INLINE BGRA8888 const* Bitmap::scanline(int y) const
{
return reinterpret_cast<ARGB32 const*>(scanline_u8(y));
return reinterpret_cast<BGRA8888 const*>(scanline_u8(y));
}
ALWAYS_INLINE ARGB32* Bitmap::begin()
ALWAYS_INLINE BGRA8888* Bitmap::begin()
{
return scanline(0);
}
ALWAYS_INLINE ARGB32 const* Bitmap::begin() const
ALWAYS_INLINE BGRA8888 const* Bitmap::begin() const
{
return scanline(0);
}
ALWAYS_INLINE ARGB32* Bitmap::end()
ALWAYS_INLINE BGRA8888* Bitmap::end()
{
return reinterpret_cast<ARGB32*>(reinterpret_cast<u8*>(m_data) + data_size());
return reinterpret_cast<BGRA8888*>(reinterpret_cast<u8*>(m_data) + data_size());
}
ALWAYS_INLINE ARGB32 const* Bitmap::end() const
ALWAYS_INLINE BGRA8888 const* Bitmap::end() const
{
return reinterpret_cast<ARGB32 const*>(reinterpret_cast<u8 const*>(m_data) + data_size());
return reinterpret_cast<BGRA8888 const*>(reinterpret_cast<u8 const*>(m_data) + data_size());
}
ALWAYS_INLINE size_t Bitmap::data_size() const
@ -230,13 +230,13 @@ ALWAYS_INLINE Color Bitmap::get_pixel(int x, int y) const
auto pixel = scanline(y)[x];
switch (m_format) {
case BitmapFormat::BGRx8888:
return Color::from_rgb(pixel);
return Color::from_bgrx(pixel);
case BitmapFormat::BGRA8888:
return Color::from_argb(pixel);
return Color::from_bgra(pixel);
case BitmapFormat::RGBA8888:
return Color::from_abgr(pixel);
return Color::from_rgba(pixel);
case BitmapFormat::RGBx8888:
return Color::from_bgr(pixel);
return Color::from_rgbx(pixel);
case BitmapFormat::Invalid:
VERIFY_NOT_REACHED();
}

View file

@ -188,7 +188,7 @@ Optional<Color> Color::from_named_css_color_string(StringView string)
return {};
struct WebColor {
ARGB32 color;
BGRA8888 color;
StringView name;
};
@ -349,7 +349,7 @@ Optional<Color> Color::from_named_css_color_string(StringView string)
for (auto const& web_color : web_colors) {
if (string.equals_ignoring_ascii_case(web_color.name))
return Color::from_rgb(web_color.color);
return Color::from_bgrx(web_color.color);
}
return {};
@ -431,7 +431,7 @@ Optional<Color> Color::from_string(StringView string)
return parse_rgba_color(string);
if (string.equals_ignoring_ascii_case("transparent"sv))
return Color::from_argb(0x00000000);
return Color::from_bgra(0x00000000);
if (auto const color = from_named_css_color_string(string); color.has_value())
return color;
@ -639,7 +639,7 @@ template<>
ErrorOr<Gfx::Color> IPC::decode(Decoder& decoder)
{
auto rgba = TRY(decoder.decode<u32>());
return Gfx::Color::from_argb(rgba);
return Gfx::Color::from_bgra(rgba);
}
ErrorOr<void> AK::Formatter<Gfx::Color>::format(FormatBuilder& builder, Gfx::Color value)

View file

@ -17,7 +17,9 @@
namespace Gfx {
typedef u32 ARGB32;
// Named after in memory-order (little-endian)
// e.g. 0xAARRGGBB
using BGRA8888 = u32;
enum class AlphaType {
Premultiplied,
@ -139,14 +141,14 @@ public:
static constexpr Color branded_color(BrandedColor);
static constexpr Color from_rgb(unsigned rgb) { return Color(rgb | 0xff000000); }
static constexpr Color from_argb(unsigned argb) { return Color(argb); }
static constexpr Color from_abgr(unsigned abgr)
static constexpr Color from_bgrx(unsigned bgrx) { return Color(bgrx | 0xff000000); }
static constexpr Color from_bgra(unsigned bgra) { return Color(bgra); }
static constexpr Color from_rgba(unsigned rgba)
{
unsigned argb = (abgr & 0xff00ff00) | ((abgr & 0xff0000) >> 16) | ((abgr & 0xff) << 16);
return Color::from_argb(argb);
unsigned bgra = (rgba & 0xff00ff00) | ((rgba & 0xff0000) >> 16) | ((rgba & 0xff) << 16);
return Color::from_bgra(bgra);
}
static constexpr Color from_bgr(unsigned bgr) { return Color::from_abgr(bgr | 0xff000000); }
static constexpr Color from_rgbx(unsigned rgbx) { return Color::from_rgba(rgbx | 0xff000000); }
static constexpr Color from_yuv(YUV const& yuv) { return from_yuv(yuv.y, yuv.u, yuv.v); }
static constexpr Color from_yuv(float y, float u, float v)
@ -464,7 +466,7 @@ public:
return Color(((other.m_value ^ m_value) & 0x00ffffff) | (m_value & 0xff000000));
}
constexpr ARGB32 value() const { return m_value; }
constexpr BGRA8888 value() const { return m_value; }
constexpr bool operator==(Color other) const
{
@ -595,12 +597,12 @@ public:
}
private:
constexpr explicit Color(ARGB32 argb)
constexpr explicit Color(BGRA8888 argb)
: m_value(argb)
{
}
ARGB32 m_value { 0 };
BGRA8888 m_value { 0 };
};
constexpr Color::Color(NamedColor named)
@ -695,41 +697,41 @@ constexpr Color Color::branded_color(BrandedColor color)
{
// clang-format off
switch (color) {
case BrandedColor::Indigo10: return from_rgb(0xa5'a6'f2);
case BrandedColor::Indigo20: return from_rgb(0x8a'88'eb);
case BrandedColor::Indigo30: return from_rgb(0x68'51'd6);
case BrandedColor::Indigo40: return from_rgb(0x55'3f'c4);
case BrandedColor::Indigo50: return from_rgb(0x4d'37'b8);
case BrandedColor::Indigo60: return from_rgb(0x3c'28'a1);
case BrandedColor::Indigo80: return from_rgb(0x30'1f'82);
case BrandedColor::Indigo100: return from_rgb(0x2a'13'73);
case BrandedColor::Indigo300: return from_rgb(0x26'0f'73);
case BrandedColor::Indigo500: return from_rgb(0x1d'0c'59);
case BrandedColor::Indigo900: return from_rgb(0x19'0c'4a);
case BrandedColor::Indigo10: return from_bgrx(0xa5'a6'f2);
case BrandedColor::Indigo20: return from_bgrx(0x8a'88'eb);
case BrandedColor::Indigo30: return from_bgrx(0x68'51'd6);
case BrandedColor::Indigo40: return from_bgrx(0x55'3f'c4);
case BrandedColor::Indigo50: return from_bgrx(0x4d'37'b8);
case BrandedColor::Indigo60: return from_bgrx(0x3c'28'a1);
case BrandedColor::Indigo80: return from_bgrx(0x30'1f'82);
case BrandedColor::Indigo100: return from_bgrx(0x2a'13'73);
case BrandedColor::Indigo300: return from_bgrx(0x26'0f'73);
case BrandedColor::Indigo500: return from_bgrx(0x1d'0c'59);
case BrandedColor::Indigo900: return from_bgrx(0x19'0c'4a);
case BrandedColor::Violet10: return from_rgb(0xe0'd4'ff);
case BrandedColor::Violet20: return from_rgb(0xca'b5'ff);
case BrandedColor::Violet30: return from_rgb(0xc3'ab'ff);
case BrandedColor::Violet40: return from_rgb(0xb4'96'ff);
case BrandedColor::Violet50: return from_rgb(0xab'8e'f5);
case BrandedColor::Violet60: return from_rgb(0x9d'7c'f2);
case BrandedColor::Violet80: return from_rgb(0x93'6f'ed);
case BrandedColor::Violet100: return from_rgb(0x8a'64'e5);
case BrandedColor::Violet300: return from_rgb(0x82'57'e6);
case BrandedColor::Violet500: return from_rgb(0x7a'4c'e6);
case BrandedColor::Violet900: return from_rgb(0x6a'39'db);
case BrandedColor::Violet10: return from_bgrx(0xe0'd4'ff);
case BrandedColor::Violet20: return from_bgrx(0xca'b5'ff);
case BrandedColor::Violet30: return from_bgrx(0xc3'ab'ff);
case BrandedColor::Violet40: return from_bgrx(0xb4'96'ff);
case BrandedColor::Violet50: return from_bgrx(0xab'8e'f5);
case BrandedColor::Violet60: return from_bgrx(0x9d'7c'f2);
case BrandedColor::Violet80: return from_bgrx(0x93'6f'ed);
case BrandedColor::Violet100: return from_bgrx(0x8a'64'e5);
case BrandedColor::Violet300: return from_bgrx(0x82'57'e6);
case BrandedColor::Violet500: return from_bgrx(0x7a'4c'e6);
case BrandedColor::Violet900: return from_bgrx(0x6a'39'db);
case BrandedColor::SlateBlue10: return from_rgb(0xcb'e0'f7);
case BrandedColor::SlateBlue20: return from_rgb(0xc1'd9'f5);
case BrandedColor::SlateBlue30: return from_rgb(0xb6'd2'f2);
case BrandedColor::SlateBlue40: return from_rgb(0xa8'c8'ed);
case BrandedColor::SlateBlue50: return from_rgb(0x97'bc'e6);
case BrandedColor::SlateBlue60: return from_rgb(0x86'ad'd9);
case BrandedColor::SlateBlue80: return from_rgb(0x77'a1'd1);
case BrandedColor::SlateBlue100: return from_rgb(0x6d'98'cc);
case BrandedColor::SlateBlue300: return from_rgb(0x5c'8e'cc);
case BrandedColor::SlateBlue500: return from_rgb(0x54'84'bf);
case BrandedColor::SlateBlue900: return from_rgb(0x48'72'a3);
case BrandedColor::SlateBlue10: return from_bgrx(0xcb'e0'f7);
case BrandedColor::SlateBlue20: return from_bgrx(0xc1'd9'f5);
case BrandedColor::SlateBlue30: return from_bgrx(0xb6'd2'f2);
case BrandedColor::SlateBlue40: return from_bgrx(0xa8'c8'ed);
case BrandedColor::SlateBlue50: return from_bgrx(0x97'bc'e6);
case BrandedColor::SlateBlue60: return from_bgrx(0x86'ad'd9);
case BrandedColor::SlateBlue80: return from_bgrx(0x77'a1'd1);
case BrandedColor::SlateBlue100: return from_bgrx(0x6d'98'cc);
case BrandedColor::SlateBlue300: return from_bgrx(0x5c'8e'cc);
case BrandedColor::SlateBlue500: return from_bgrx(0x54'84'bf);
case BrandedColor::SlateBlue900: return from_bgrx(0x48'72'a3);
}
// clang-format on

View file

@ -32,7 +32,7 @@ public:
return ExifOrientedBitmap(move(bitmap), size, orientation);
}
template<OneOf<ARGB32, CMYK> Value>
template<OneOf<BGRA8888, CMYK> Value>
void set_pixel(u32 x, u32 y, Value color)
{
auto const new_position = oriented_position(IntPoint(x, y));

View file

@ -124,13 +124,13 @@ static void clear_rect(Bitmap& bitmap, IntRect const& rect, Color color)
if (intersection_rect.is_empty())
return;
ARGB32* dst = bitmap.scanline(intersection_rect.top()) + intersection_rect.left();
size_t const dst_skip = bitmap.pitch() / sizeof(ARGB32);
BGRA8888* dst = bitmap.scanline(intersection_rect.top()) + intersection_rect.left();
size_t const dst_skip = bitmap.pitch() / sizeof(BGRA8888);
auto const value = color.value();
auto const width = intersection_rect.width();
for (int i = intersection_rect.height() - 1; i >= 0; --i) {
for (ARGB32* p = dst; p < (dst + width); ++p) {
for (BGRA8888* p = dst; p < (dst + width); ++p) {
*p = value;
}
dst += dst_skip;

View file

@ -39,7 +39,7 @@ struct IsOpaque {
NEVER_INLINE static ErrorOr<void> write_image_data(LittleEndianOutputBitStream& bit_stream, Bitmap const& bitmap, PrefixCodeGroup const& prefix_code_group)
{
// This is currently the hot loop. Keep performance in mind when you change it.
for (ARGB32 pixel : bitmap) {
for (BGRA8888 pixel : bitmap) {
u8 a = pixel >> 24;
u8 r = pixel >> 16;
u8 g = pixel >> 8;
@ -275,7 +275,7 @@ static ErrorOr<void> write_VP8L_coded_image(ImageKind image_kind, LittleEndianOu
// FIXME: Consider using a meta-prefix image and using one prefix-code-group per tile.
Array<Array<u16, 256>, 4> symbol_frequencies {};
for (ARGB32 pixel : bitmap) {
for (BGRA8888 pixel : bitmap) {
static constexpr auto saturating_increment = [](u16& value) {
if (value < UINT16_MAX)
value++;
@ -322,10 +322,10 @@ static ErrorOr<void> write_VP8L_coded_image(ImageKind image_kind, LittleEndianOu
return {};
}
static ARGB32 sub_argb32(ARGB32 a, ARGB32 b)
static BGRA8888 sub_argb32(BGRA8888 a, BGRA8888 b)
{
auto a_color = Color::from_argb(a);
auto b_color = Color::from_argb(b);
auto a_color = Color::from_bgra(a);
auto b_color = Color::from_bgra(b);
return Color(a_color.red() - b_color.red(),
a_color.green() - b_color.green(),
a_color.blue() - b_color.blue(),
@ -337,10 +337,10 @@ static ErrorOr<NonnullRefPtr<Bitmap const>> maybe_write_color_indexing_transform
{
// https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification#44_color_indexing_transform
unsigned color_table_size = 0;
HashTable<ARGB32> seen_colors;
ARGB32 channels = 0;
ARGB32 first_pixel = bitmap->get_pixel(0, 0).value();
for (ARGB32 pixel : *bitmap) {
HashTable<BGRA8888> seen_colors;
BGRA8888 channels = 0;
BGRA8888 first_pixel = bitmap->get_pixel(0, 0).value();
for (BGRA8888 pixel : *bitmap) {
auto result = seen_colors.set(pixel);
if (result == HashSetResult::InsertedNewEntry) {
++color_table_size;
@ -377,21 +377,21 @@ static ErrorOr<NonnullRefPtr<Bitmap const>> maybe_write_color_indexing_transform
TRY(bit_stream.write_bits(color_table_size - 1, 8u));
// Store color index to bit stream.
Vector<ARGB32, 256> colors;
for (ARGB32 color : seen_colors)
Vector<BGRA8888, 256> colors;
for (BGRA8888 color : seen_colors)
colors.append(color);
quick_sort(colors.begin(), colors.end());
// "The color table is stored using the image storage format itself." [...]
// "The color table is always subtraction-coded to reduce image entropy."
auto color_index_bitmap = TRY(Bitmap::create(BitmapFormat::BGRA8888, { static_cast<int>(color_table_size), 1 }));
color_index_bitmap->set_pixel(0, 0, Color::from_argb(colors[0]));
color_index_bitmap->set_pixel(0, 0, Color::from_bgra(colors[0]));
for (unsigned i = 1; i < color_table_size; ++i)
color_index_bitmap->set_pixel(i, 0, Color::from_argb(sub_argb32(colors[i], colors[i - 1])));
color_index_bitmap->set_pixel(i, 0, Color::from_bgra(sub_argb32(colors[i], colors[i - 1])));
TRY(write_VP8L_coded_image(ImageKind::EntropyCoded, bit_stream, *color_index_bitmap, is_fully_opaque));
// Return a new bitmap with the color indexing transform applied.
HashMap<ARGB32, u8> color_index_map;
HashMap<BGRA8888, u8> color_index_map;
for (unsigned i = 0; i < color_table_size; ++i)
color_index_map.set(colors[i], i);

View file

@ -28,7 +28,7 @@ public:
Color color(ColorRole role) const
{
VERIFY((int)role < (int)ColorRole::__Count);
return Color::from_argb(theme().color[(int)role]);
return Color::from_bgra(theme().color[(int)role]);
}
Gfx::TextAlignment alignment(AlignmentRole role) const

View file

@ -281,7 +281,7 @@ inline StringView to_string(PathRole role)
}
struct SystemTheme {
ARGB32 color[(int)ColorRole::__Count];
BGRA8888 color[(int)ColorRole::__Count];
Gfx::TextAlignment alignment[(int)AlignmentRole::__Count];
bool flag[(int)FlagRole::__Count];
int metric[(int)MetricRole::__Count];

View file

@ -21,7 +21,7 @@
namespace Web::Painting {
static constexpr auto CONTROL_BOX_COLOR = Gfx::Color::from_rgb(0x26'26'26);
static constexpr auto CONTROL_BOX_COLOR = Gfx::Color::from_bgrx(0x26'26'26);
static constexpr auto CONTROL_BUTTON_COLOR = Gfx::Color::branded_color(Gfx::Color::BrandedColor::Violet);
static constexpr auto CONTROL_HIGHLIGHT_COLOR = Gfx::Color::branded_color(Gfx::Color::BrandedColor::Violet60);

View file

@ -18,8 +18,8 @@
namespace Web::Painting {
static constexpr auto control_box_color = Gfx::Color::from_rgb(0x26'26'26);
static constexpr auto control_highlight_color = Gfx::Color::from_rgb(0x1d'99'f3);
static constexpr auto control_box_color = Gfx::Color::from_bgrx(0x26'26'26);
static constexpr auto control_highlight_color = Gfx::Color::from_bgrx(0x1d'99'f3);
GC_DEFINE_ALLOCATOR(VideoPaintable);
@ -134,7 +134,7 @@ void VideoPaintable::paint(DisplayListRecordingContext& context, PaintPhase phas
};
auto paint_transparent_black = [&]() {
static constexpr auto transparent_black = Gfx::Color::from_argb(0x00'00'00'00);
static constexpr auto transparent_black = Gfx::Color::from_bgra(0x00'00'00'00);
context.display_list_recorder().fill_rect(video_rect.to_type<int>(), transparent_black);
};

View file

@ -15,50 +15,50 @@ TEST_CASE(color)
}
}
TEST_CASE(from_rgb)
TEST_CASE(from_bgrx)
{
EXPECT_EQ(Color(0x00, 0x00, 0xff), Color::from_rgb(0x000000ff));
EXPECT_EQ(Color(0x00, 0xff, 0x00), Color::from_rgb(0x0000ff00));
EXPECT_EQ(Color(0xff, 0x00, 0x00), Color::from_rgb(0x00ff0000));
EXPECT_EQ(Color(0x00, 0x00, 0xff), Color::from_bgrx(0x000000ff));
EXPECT_EQ(Color(0x00, 0xff, 0x00), Color::from_bgrx(0x0000ff00));
EXPECT_EQ(Color(0xff, 0x00, 0x00), Color::from_bgrx(0x00ff0000));
EXPECT_EQ(Color(0x00, 0x00, 0xff), Color::from_rgb(0xff0000ff));
EXPECT_EQ(Color(0x00, 0xff, 0x00), Color::from_rgb(0xff00ff00));
EXPECT_EQ(Color(0xff, 0x00, 0x00), Color::from_rgb(0xffff0000));
EXPECT_EQ(Color(0x00, 0x00, 0xff), Color::from_bgrx(0xff0000ff));
EXPECT_EQ(Color(0x00, 0xff, 0x00), Color::from_bgrx(0xff00ff00));
EXPECT_EQ(Color(0xff, 0x00, 0x00), Color::from_bgrx(0xffff0000));
EXPECT_EQ(Color(0xaa, 0xbb, 0xcc), Color::from_rgb(0x00aabbcc));
EXPECT_EQ(Color(0xaa, 0xbb, 0xcc), Color::from_bgrx(0x00aabbcc));
}
TEST_CASE(from_argb)
TEST_CASE(from_bgra)
{
EXPECT_EQ(Color(0x00, 0x00, 0x00, 0xff), Color::from_argb(0xff000000));
EXPECT_EQ(Color(0x00, 0x00, 0xff, 0x00), Color::from_argb(0x000000ff));
EXPECT_EQ(Color(0x00, 0xff, 0x00, 0x00), Color::from_argb(0x0000ff00));
EXPECT_EQ(Color(0xff, 0x00, 0x00, 0x00), Color::from_argb(0x00ff0000));
EXPECT_EQ(Color(0x00, 0x00, 0x00, 0xff), Color::from_bgra(0xff000000));
EXPECT_EQ(Color(0x00, 0x00, 0xff, 0x00), Color::from_bgra(0x000000ff));
EXPECT_EQ(Color(0x00, 0xff, 0x00, 0x00), Color::from_bgra(0x0000ff00));
EXPECT_EQ(Color(0xff, 0x00, 0x00, 0x00), Color::from_bgra(0x00ff0000));
EXPECT_EQ(Color(0xaa, 0xbb, 0xcc, 0xdd), Color::from_argb(0xddaabbcc));
EXPECT_EQ(Color(0xaa, 0xbb, 0xcc, 0xdd), Color::from_bgra(0xddaabbcc));
}
TEST_CASE(from_bgr)
TEST_CASE(from_rgbx)
{
EXPECT_EQ(Color(0x00, 0x00, 0xff), Color::from_bgr(0x00ff0000));
EXPECT_EQ(Color(0x00, 0xff, 0x00), Color::from_bgr(0x0000ff00));
EXPECT_EQ(Color(0xff, 0x00, 0x00), Color::from_bgr(0x000000ff));
EXPECT_EQ(Color(0x00, 0x00, 0xff), Color::from_rgbx(0x00ff0000));
EXPECT_EQ(Color(0x00, 0xff, 0x00), Color::from_rgbx(0x0000ff00));
EXPECT_EQ(Color(0xff, 0x00, 0x00), Color::from_rgbx(0x000000ff));
EXPECT_EQ(Color(0x00, 0x00, 0xff), Color::from_bgr(0xffff0000));
EXPECT_EQ(Color(0x00, 0xff, 0x00), Color::from_bgr(0xff00ff00));
EXPECT_EQ(Color(0xff, 0x00, 0x00), Color::from_bgr(0xff0000ff));
EXPECT_EQ(Color(0x00, 0x00, 0xff), Color::from_rgbx(0xffff0000));
EXPECT_EQ(Color(0x00, 0xff, 0x00), Color::from_rgbx(0xff00ff00));
EXPECT_EQ(Color(0xff, 0x00, 0x00), Color::from_rgbx(0xff0000ff));
EXPECT_EQ(Color(0xaa, 0xbb, 0xcc), Color::from_bgr(0x00ccbbaa));
EXPECT_EQ(Color(0xaa, 0xbb, 0xcc), Color::from_rgbx(0x00ccbbaa));
}
TEST_CASE(from_abgr)
TEST_CASE(from_rgba)
{
EXPECT_EQ(Color(0x00, 0x00, 0x00, 0xff), Color::from_abgr(0xff000000));
EXPECT_EQ(Color(0x00, 0x00, 0xff, 0x00), Color::from_abgr(0x00ff0000));
EXPECT_EQ(Color(0x00, 0xff, 0x00, 0x00), Color::from_abgr(0x0000ff00));
EXPECT_EQ(Color(0xff, 0x00, 0x00, 0x00), Color::from_abgr(0x000000ff));
EXPECT_EQ(Color(0x00, 0x00, 0x00, 0xff), Color::from_rgba(0xff000000));
EXPECT_EQ(Color(0x00, 0x00, 0xff, 0x00), Color::from_rgba(0x00ff0000));
EXPECT_EQ(Color(0x00, 0xff, 0x00, 0x00), Color::from_rgba(0x0000ff00));
EXPECT_EQ(Color(0xff, 0x00, 0x00, 0x00), Color::from_rgba(0x000000ff));
EXPECT_EQ(Color(0xaa, 0xbb, 0xcc, 0xdd), Color::from_abgr(0xddccbbaa));
EXPECT_EQ(Color(0xaa, 0xbb, 0xcc, 0xdd), Color::from_rgba(0xddccbbaa));
}
TEST_CASE(all_green)

View file

@ -29,7 +29,7 @@ QIcon create_tvg_icon_with_theme_colors(QString const& name, QPalette const& pal
VERIFY(icon_engine);
auto icon_filter = [](QColor color) {
return [color = Color::from_argb(color.rgba64().toArgb32())](Gfx::Color icon_color) {
return [color = Color::from_bgra(color.rgba64().toArgb32())](Gfx::Color icon_color) {
return color.with_alpha((icon_color.alpha() * color.alpha()) / 255);
};
};

View file

@ -586,7 +586,7 @@ static Core::AnonymousBuffer make_system_theme_from_qt_palette(QWidget& widget,
auto palette = Gfx::Palette(move(palette_impl));
auto translate = [&](Gfx::ColorRole gfx_color_role, QPalette::ColorRole qt_color_role) {
auto new_color = Gfx::Color::from_argb(qt_palette.color(qt_color_role).rgba());
auto new_color = Gfx::Color::from_bgra(qt_palette.color(qt_color_role).rgba());
palette.set_color(gfx_color_role, new_color);
};