1
0
Fork 0

Codechange: Remove TTD_ENDIAN from Colour union. (#13396)

`TTD_ENDIAN` is used to change the order of the r,g,b,a members of `Colour` to suit the architecture.

This kind of conditional is not supported by C++/`std::endian`, so instead three separate Colour unions are defined, `ColourRGBA`, `ColourARGB` and `ColourBGRA`. The correct union is then aliased to `Colour` using `std::conditional`.
pull/13397/head
Peter Nelson 2025-01-28 17:51:04 +00:00 committed by GitHub
parent d1e001f1c8
commit 4b2b113292
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 57 additions and 23 deletions

View File

@ -10,7 +10,6 @@
#ifndef GFX_TYPE_H #ifndef GFX_TYPE_H
#define GFX_TYPE_H #define GFX_TYPE_H
#include "core/endian_type.hpp"
#include "core/enum_type.hpp" #include "core/enum_type.hpp"
#include "core/geometry_type.hpp" #include "core/geometry_type.hpp"
#include "zoom_type.h" #include "zoom_type.h"
@ -161,17 +160,11 @@ struct DrawPixelInfo {
ZoomLevel zoom; ZoomLevel zoom;
}; };
/** Structure to access the alpha, red, green, and blue channels from a 32 bit number. */ /** Packed colour union to access the alpha, red, green, and blue channels from a 32 bit number for Emscripten build. */
union Colour { union ColourRGBA {
uint32_t data; ///< Conversion of the channel information to a 32 bit number. uint32_t data; ///< Conversion of the channel information to a 32 bit number.
struct { struct {
#if defined(__EMSCRIPTEN__) uint8_t r, g, b, a; ///< colour channels as used in browsers
uint8_t r, g, b, a; ///< colour channels as used in browsers
#elif TTD_ENDIAN == TTD_BIG_ENDIAN
uint8_t a, r, g, b; ///< colour channels in BE order
#else
uint8_t b, g, r, a; ///< colour channels in LE order
#endif /* TTD_ENDIAN == TTD_BIG_ENDIAN */
}; };
/** /**
@ -181,26 +174,67 @@ union Colour {
* @param b The channel for the blue colour. * @param b The channel for the blue colour.
* @param a The channel for the alpha/transparency. * @param a The channel for the alpha/transparency.
*/ */
Colour(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 0xFF) : constexpr ColourRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 0xFF) : r(r), g(g), b(b), a(a) { }
#if defined(__EMSCRIPTEN__)
r(r), g(g), b(b), a(a)
#elif TTD_ENDIAN == TTD_BIG_ENDIAN
a(a), r(r), g(g), b(b)
#else
b(b), g(g), r(r), a(a)
#endif /* TTD_ENDIAN == TTD_BIG_ENDIAN */
{
}
/** /**
* Create a new colour. * Create a new colour.
* @param data The colour in the correct packed format. * @param data The colour in the correct packed format.
*/ */
Colour(uint data = 0) : data(data) constexpr ColourRGBA(uint data = 0) : data(data) { }
{
}
}; };
/** Packed colour union to access the alpha, red, green, and blue channels from a 32 bit number for big-endian systems. */
union ColourARGB {
uint32_t data; ///< Conversion of the channel information to a 32 bit number.
struct {
uint8_t a, r, g, b; ///< colour channels in BE order
};
/**
* Create a new colour.
* @param r The channel for the red colour.
* @param g The channel for the green colour.
* @param b The channel for the blue colour.
* @param a The channel for the alpha/transparency.
*/
constexpr ColourARGB(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 0xFF) : a(a), r(r), g(g), b(b) { }
/**
* Create a new colour.
* @param data The colour in the correct packed format.
*/
constexpr ColourARGB(uint data = 0) : data(data) { }
};
/** Packed colour union to access the alpha, red, green, and blue channels from a 32 bit number for little-endian systems. */
union ColourBGRA {
uint32_t data; ///< Conversion of the channel information to a 32 bit number.
struct {
uint8_t b, g, r, a; ///< colour channels in LE order
};
/**
* Create a new colour.
* @param r The channel for the red colour.
* @param g The channel for the green colour.
* @param b The channel for the blue colour.
* @param a The channel for the alpha/transparency.
*/
constexpr ColourBGRA(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 0xFF) : b(b), g(g), r(r), a(a) { }
/**
* Create a new colour.
* @param data The colour in the correct packed format.
*/
constexpr ColourBGRA(uint data = 0) : data(data) { }
};
#if defined(__EMSCRIPTEN__)
using Colour = ColourRGBA;
#else
using Colour = std::conditional_t<std::endian::native == std::endian::little, ColourBGRA, ColourARGB>;
#endif /* defined(__EMSCRIPTEN__) */
static_assert(sizeof(Colour) == sizeof(uint32_t)); static_assert(sizeof(Colour) == sizeof(uint32_t));