--- a/src/colors.h Wed Jun 08 19:33:00 2022 +0300 +++ b/src/colors.h Wed Jun 08 20:41:21 2022 +0300 @@ -20,19 +20,6 @@ #include <QColor> #include "main.h" -namespace ldraw -{ - struct Color; - struct ColorDefinition; - class ColorTable; - Color directColor(const QColor& color); - bool isDirectColor(Color color); - QColor directColorFace(Color color); - QColor colorFace(Color color, const ColorTable& colorTable); - QColor colorEdge(Color color, const ColorTable& colorTable); - QString colorDisplayName(Color color, const ColorTable& colorTable); -} - /** * @brief Represents an LDraw color index (e.g 16, 24, ...) * @@ -52,64 +39,77 @@ * LDConfig.ldr). Since this structure only contains an integer, it should be * passed by value to functions instead of l-value reference. */ -struct ldraw::Color +struct ColorIndex { qint32 index = 0; - constexpr auto operator<=>(const Color&) const = default; + constexpr auto operator<=>(const ColorIndex&) const = default; }; -Q_DECLARE_METATYPE(ldraw::Color) -QDataStream& operator<<(QDataStream&, ldraw::Color); -QDataStream& operator>>(QDataStream&, ldraw::Color&); - -namespace ldraw -{ - static constexpr Color MAIN_COLOR {16}; - static constexpr Color EDGE_COLOR {24}; -} +Q_DECLARE_METATYPE(ColorIndex) +static constexpr ColorIndex MAIN_COLOR {16}; +static constexpr ColorIndex EDGE_COLOR {24}; /** * @brief Contains the information about a specific color */ -struct ldraw::ColorDefinition +struct ColorDefinition { - /** - * @brief The face color. This is the color used for most objects. - * This is also used for the polygons of a subfile reference. - */ + //! @brief The face color. This is the color used for most objects. QColor faceColor; - /** - * @brief The edge color, used for the edge lines of a subfile reference. - * Note that edges using a color actually use the face color. LDraw standards - * require edges to use color 24, however. - */ + //! @brief The edge color, used for the edge lines of a subfile reference. + //! Note that edges using a color actually use the face color. LDraw standards + //! require edges to use color 24, however. QColor edgeColor; - /** - * @brief Name of the color - */ + //! @brief Name of the color QString name; - /** - * @brief A version of the name that can be shown to the user. - */ + //! @brief A version of the name that can be shown to the user. QString displayName; }; -/** - * @brief Reads LDConfig.ldr and contains color table information for lookup purposes. - */ -class ldraw::ColorTable +//extern const ColorDefinition unknownColor; +using ColorTable = std::map<ColorIndex, ColorDefinition>; +std::optional<ColorTable> loadColorTable(QIODevice& device, QTextStream& errors); +qreal luma(const QColor& color); +ColorIndex directColor(const QColor& color); +std::optional<QColor> colorFace(ColorIndex color, const ColorTable& colorTable); +std::optional<QColor> colorEdge(ColorIndex color, const ColorTable& colorTable); +std::optional<QString> colorDisplayName(ColorIndex color, const ColorTable& colorTable); +QDataStream& operator<<(QDataStream&, ColorIndex); +QDataStream& operator>>(QDataStream&, ColorIndex&); + +//! @brief Calculates the luma-value for the given color. +//! @details c.f. https://en.wikipedia.org/wiki/Luma_(video) +template<typename T> +constexpr T luma(T r, T g, T b) +{ + return 0.2126 * r + 0.7152 * g + 0.0722 * b; +} + +//! @brief Checks whether or not the specified color index is a direct color +constexpr bool isDirectColor(ColorIndex color) { -public: - void clear(); - Result load(QIODevice& device, QTextStream& errors); - const ColorDefinition& operator[](Color index) const; - static const ColorDefinition unknownColor; - auto begin() const { return this->definitions.begin(); } - auto end() const { return this->definitions.end(); } - int size() const; -private: - void loadColorFromString(const QString& string); - std::map<qint32, ColorDefinition> definitions; -}; + return color.index >= 0x2000000; +} + +//! @brief Returns a direct color index that codes the specified color value +constexpr ColorIndex directColor(int r, int g, int b) +{ + return ColorIndex{0x2000000 | (r << 16) | (g << 8) | b}; +} -double luma(const QColor& color); +//! @brief Extracts the r, g and b color channel values from a direct color +//! index. Returns a default-constructed QColor in case a non-direct color is +//! given. +constexpr std::array<int, 3> directColorRgb(ColorIndex color) +{ + return { + (color.index >> 16) & 0xff, + (color.index >> 8) & 0xff, + color.index & 0xff + }; +} + +namespace ldraw +{ + using Color = ColorIndex; +}