50 * Note that it only makes sense to construct a color index from an integer |
37 * Note that it only makes sense to construct a color index from an integer |
51 * value if the integer comes from an external source (e.g. user or |
38 * value if the integer comes from an external source (e.g. user or |
52 * LDConfig.ldr). Since this structure only contains an integer, it should be |
39 * LDConfig.ldr). Since this structure only contains an integer, it should be |
53 * passed by value to functions instead of l-value reference. |
40 * passed by value to functions instead of l-value reference. |
54 */ |
41 */ |
55 struct ldraw::Color |
42 struct ColorIndex |
56 { |
43 { |
57 qint32 index = 0; |
44 qint32 index = 0; |
58 constexpr auto operator<=>(const Color&) const = default; |
45 constexpr auto operator<=>(const ColorIndex&) const = default; |
59 }; |
46 }; |
60 |
47 |
61 Q_DECLARE_METATYPE(ldraw::Color) |
48 Q_DECLARE_METATYPE(ColorIndex) |
62 QDataStream& operator<<(QDataStream&, ldraw::Color); |
49 static constexpr ColorIndex MAIN_COLOR {16}; |
63 QDataStream& operator>>(QDataStream&, ldraw::Color&); |
50 static constexpr ColorIndex EDGE_COLOR {24}; |
64 |
|
65 namespace ldraw |
|
66 { |
|
67 static constexpr Color MAIN_COLOR {16}; |
|
68 static constexpr Color EDGE_COLOR {24}; |
|
69 } |
|
70 |
51 |
71 /** |
52 /** |
72 * @brief Contains the information about a specific color |
53 * @brief Contains the information about a specific color |
73 */ |
54 */ |
74 struct ldraw::ColorDefinition |
55 struct ColorDefinition |
75 { |
56 { |
76 /** |
57 //! @brief The face color. This is the color used for most objects. |
77 * @brief The face color. This is the color used for most objects. |
|
78 * This is also used for the polygons of a subfile reference. |
|
79 */ |
|
80 QColor faceColor; |
58 QColor faceColor; |
81 /** |
59 //! @brief The edge color, used for the edge lines of a subfile reference. |
82 * @brief The edge color, used for the edge lines of a subfile reference. |
60 //! Note that edges using a color actually use the face color. LDraw standards |
83 * Note that edges using a color actually use the face color. LDraw standards |
61 //! require edges to use color 24, however. |
84 * require edges to use color 24, however. |
|
85 */ |
|
86 QColor edgeColor; |
62 QColor edgeColor; |
87 /** |
63 //! @brief Name of the color |
88 * @brief Name of the color |
|
89 */ |
|
90 QString name; |
64 QString name; |
91 /** |
65 //! @brief A version of the name that can be shown to the user. |
92 * @brief A version of the name that can be shown to the user. |
|
93 */ |
|
94 QString displayName; |
66 QString displayName; |
95 }; |
67 }; |
96 |
68 |
97 /** |
69 //extern const ColorDefinition unknownColor; |
98 * @brief Reads LDConfig.ldr and contains color table information for lookup purposes. |
70 using ColorTable = std::map<ColorIndex, ColorDefinition>; |
99 */ |
71 std::optional<ColorTable> loadColorTable(QIODevice& device, QTextStream& errors); |
100 class ldraw::ColorTable |
72 qreal luma(const QColor& color); |
|
73 ColorIndex directColor(const QColor& color); |
|
74 std::optional<QColor> colorFace(ColorIndex color, const ColorTable& colorTable); |
|
75 std::optional<QColor> colorEdge(ColorIndex color, const ColorTable& colorTable); |
|
76 std::optional<QString> colorDisplayName(ColorIndex color, const ColorTable& colorTable); |
|
77 QDataStream& operator<<(QDataStream&, ColorIndex); |
|
78 QDataStream& operator>>(QDataStream&, ColorIndex&); |
|
79 |
|
80 //! @brief Calculates the luma-value for the given color. |
|
81 //! @details c.f. https://en.wikipedia.org/wiki/Luma_(video) |
|
82 template<typename T> |
|
83 constexpr T luma(T r, T g, T b) |
101 { |
84 { |
102 public: |
85 return 0.2126 * r + 0.7152 * g + 0.0722 * b; |
103 void clear(); |
86 } |
104 Result load(QIODevice& device, QTextStream& errors); |
|
105 const ColorDefinition& operator[](Color index) const; |
|
106 static const ColorDefinition unknownColor; |
|
107 auto begin() const { return this->definitions.begin(); } |
|
108 auto end() const { return this->definitions.end(); } |
|
109 int size() const; |
|
110 private: |
|
111 void loadColorFromString(const QString& string); |
|
112 std::map<qint32, ColorDefinition> definitions; |
|
113 }; |
|
114 |
87 |
115 double luma(const QColor& color); |
88 //! @brief Checks whether or not the specified color index is a direct color |
|
89 constexpr bool isDirectColor(ColorIndex color) |
|
90 { |
|
91 return color.index >= 0x2000000; |
|
92 } |
|
93 |
|
94 //! @brief Returns a direct color index that codes the specified color value |
|
95 constexpr ColorIndex directColor(int r, int g, int b) |
|
96 { |
|
97 return ColorIndex{0x2000000 | (r << 16) | (g << 8) | b}; |
|
98 } |
|
99 |
|
100 //! @brief Extracts the r, g and b color channel values from a direct color |
|
101 //! index. Returns a default-constructed QColor in case a non-direct color is |
|
102 //! given. |
|
103 constexpr std::array<int, 3> directColorRgb(ColorIndex color) |
|
104 { |
|
105 return { |
|
106 (color.index >> 16) & 0xff, |
|
107 (color.index >> 8) & 0xff, |
|
108 color.index & 0xff |
|
109 }; |
|
110 } |
|
111 |
|
112 namespace ldraw |
|
113 { |
|
114 using Color = ColorIndex; |
|
115 } |