Wed, 22 Sep 2021 14:03:43 +0300
Document and refactor colors.cpp and colors.h
--- a/src/colors.cpp Wed Sep 22 13:28:53 2021 +0300 +++ b/src/colors.cpp Wed Sep 22 14:03:43 2021 +0300 @@ -18,13 +18,22 @@ #include "colors.h" -const ldraw::ColorTable::ColorDefinition ldraw::ColorTable::unknownColor{{}, {}, "Unknown", "???"}; +const ldraw::ColorDefinition ldraw::ColorTable::unknownColor{{}, {}, "Unknown", "???"}; +/** + * @brief Clears the color table + */ void ldraw::ColorTable::clear() { - definitions = {}; + this->definitions = {}; } +/** + * @brief Loads colors from LDConfig.ldr + * @param device Opened LDConfig.ldr I/O device + * @param errors Where to write any errors into + * @returns whether or not it succeeded. + */ Result ldraw::ColorTable::load(QIODevice& device, QTextStream& errors) { this->clear(); @@ -45,7 +54,12 @@ } } -const ldraw::ColorTable::ColorDefinition& ldraw::ColorTable::operator[](Color color) const +/** + * @brief Gets color information by color index. + * @param color + * @returns color table information + */ +const ldraw::ColorDefinition& ldraw::ColorTable::operator[](Color color) const { auto it = this->definitions.find(color.index); if (it != this->definitions.end()) @@ -58,6 +72,19 @@ } } +/** + * @brief Gets the amount of elements in the color table + * @returns int + */ +int ldraw::ColorTable::size() const +{ + return this->definitions.size(); +} + +/** + * @brief Parses an LDConfig.ldr line from a string + * @param string LDConfig.ldr line to parse + */ void ldraw::ColorTable::loadColorFromString(const QString& string) { const QRegExp pattern{ @@ -70,7 +97,7 @@ if (pattern.indexIn(string) != -1) { const int code = pattern.cap(2).toInt(); - ColorDefinition& definition = definitions[code]; + ColorDefinition& definition = this->definitions[code]; definition = {}; // in case there's an existing definition definition.name = pattern.cap(1); definition.displayName = definition.name; @@ -85,25 +112,42 @@ } } -/* - * Calculates the luma-value for the given color. - * c.f. https://en.wikipedia.org/wiki/Luma_(video) +/** + * @brief Calculates the luma-value for the given color. + * @details c.f. https://en.wikipedia.org/wiki/Luma_(video) + * @param color + * @returns luma value [0, 1] */ double luma(const QColor& color) { return 0.2126 * color.redF() + 0.7152 * color.greenF() + 0.0722 * color.blueF(); } +/** + * @brief Returns a direct color index that codes the specified color value + * @param color + * @returns direct color index + */ ldraw::Color ldraw::directColor(const QColor& color) { return ldraw::Color{0x2000000 | (color.red() << 16) | (color.green() << 8) | color.blue()}; } +/** + * @brief Checks whether or not the specified color index is a direct color + * @param color Color to check + * @returns bool + */ bool ldraw::isDirectColor(ldraw::Color color) { return color.index >= 0x2000000; } +/** + * @brief Extracts the color value from a direct color index + * @param color Direct color index + * @returns color value. Returns a default-constructed QColor in case a non-direct color is given. + */ QColor ldraw::directColorFace(ldraw::Color color) { if (isDirectColor(color)) @@ -116,6 +160,12 @@ } } +/** + * @brief Gets the face color for the specified color index + * @param color Color index to get face color for + * @param colorTable Color table to use for lookup + * @returns QColor + */ QColor ldraw::colorFace(ldraw::Color color, const ldraw::ColorTable& colorTable) { if (isDirectColor(color)) @@ -128,11 +178,23 @@ } } +/** + * @brief Writes a color index into a @c QDataStream + * @param stream + * @param color + * @returns stream + */ QDataStream& operator<<(QDataStream& stream, ldraw::Color color) { return stream << color.index; } +/** + * @brief Reads a color index from a @c QDataStream + * @param stream + * @param color + * @returns stream + */ QDataStream& operator>>(QDataStream& stream, ldraw::Color& color) { return stream >> color.index;
--- a/src/colors.h Wed Sep 22 13:28:53 2021 +0300 +++ b/src/colors.h Wed Sep 22 14:03:43 2021 +0300 @@ -23,6 +23,7 @@ namespace ldraw { struct Color; + struct ColorDefinition; class ColorTable; Color directColor(const QColor& color); bool isDirectColor(Color color); @@ -30,80 +31,118 @@ QColor colorFace(Color color, const ColorTable& colorTable); } +/** + * @brief Represents an LDraw color index (e.g 16, 24, ...) + * + * @details + * This is essentially just an integer. It is its own structure for the sake + * of type correctness. Commonly used color values are 16 for the main color + * and 24 for the edge color. + * + * Use @c ldraw::ColorTable to obtain rgb values for color indices. + * + * Direct colors are colors whose index is at least 0x2000000. These colors + * encode the rgb values directly in the index. The color table code also + * handles these cases. + * + * Note that it only makes sense to construct a color index from an integer + * value if the integer comes from an external source (e.g. user or + * 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 { qint32 index = 0; }; Q_DECLARE_METATYPE(ldraw::Color) +QDataStream& operator<<(QDataStream&, ldraw::Color); +QDataStream& operator>>(QDataStream&, ldraw::Color&); +namespace ldraw +{ + constexpr bool operator==(Color one, Color other) + { + return one.index == other.index; + } + + constexpr bool operator!=(Color one, Color other) + { + return one.index != other.index; + } + + constexpr bool operator<(Color one, Color other) + { + return one.index < other.index; + } + + constexpr bool operator<=(Color one, Color other) + { + return one.index <= other.index; + } + + constexpr bool operator>(Color one, Color other) + { + return one.index > other.index; + } + + constexpr bool operator>=(Color one, Color other) + { + return one.index >= other.index; + } + + static constexpr Color BLACK {0}; + static constexpr Color BLUE {1}; + static constexpr Color GREEN {2}; + static constexpr Color RED {4}; + static constexpr Color YELLOW {14}; + static constexpr Color WHITE {15}; + static constexpr Color MAIN_COLOR {16}; + static constexpr Color EDGE_COLOR {24}; +} + +/** + * @brief Contains the information about a specific color + */ +struct ldraw::ColorDefinition +{ + /** + * @brief The face color. This is the color used for most objects. + * This is also used for the polygons of a subfile reference. + */ + 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. + */ + QColor edgeColor; + /** + * @brief Name of the color + */ + QString name; + /** + * @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 { public: - struct ColorDefinition - { - QColor faceColor; - QColor edgeColor; - QString name; - QString displayName; - }; 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 { return this->definitions.size(); } + int size() const; private: void loadColorFromString(const QString& string); std::map<qint32, ColorDefinition> definitions; }; -namespace ldraw -{ - inline bool operator==(const ldraw::Color& one, const ldraw::Color& other) - { - return one.index == other.index; - } - - inline bool operator!=(const ldraw::Color& one, const ldraw::Color& other) - { - return one.index != other.index; - } - - inline bool operator<(const ldraw::Color& one, const ldraw::Color& other) - { - return one.index < other.index; - } - - inline bool operator<=(const ldraw::Color& one, const ldraw::Color& other) - { - return one.index <= other.index; - } - - inline bool operator>(const ldraw::Color& one, const ldraw::Color& other) - { - return one.index > other.index; - } - - inline bool operator>=(const ldraw::Color& one, const ldraw::Color& other) - { - return one.index >= other.index; - } -} - -namespace ldraw -{ - static constexpr Color black {0}; - static constexpr Color blue {1}; - static constexpr Color green {2}; - static constexpr Color red {4}; - static constexpr Color yellow {14}; - static constexpr Color white {15}; - static constexpr Color mainColor {16}; - static constexpr Color edgeColor {24}; -} - double luma(const QColor& color); -QDataStream& operator<<(QDataStream&, ldraw::Color); -QDataStream& operator>>(QDataStream&, ldraw::Color&);
--- a/src/gl/compiler.cpp Wed Sep 22 13:28:53 2021 +0300 +++ b/src/gl/compiler.cpp Wed Sep 22 14:03:43 2021 +0300 @@ -276,11 +276,11 @@ { QColor color; // For normal colors, use the polygon's color. - if (polygon.color == ldraw::mainColor) + if (polygon.color == ldraw::MAIN_COLOR) { color = preferences.mainColor; } - else if (polygon.color == ldraw::edgeColor) + else if (polygon.color == ldraw::EDGE_COLOR) { // Edge color is black, unless we have a dark background, in which case lines need to be bright. color = luma(preferences.backgroundColor) > (40.0 / 256.0) ? Qt::black : Qt::white;
--- a/src/linetypes/object.h Wed Sep 22 13:28:53 2021 +0300 +++ b/src/linetypes/object.h Wed Sep 22 14:03:43 2021 +0300 @@ -103,12 +103,12 @@ class ldraw::ColoredObject : public Object { public: - ColoredObject(const Color colorIndex = ldraw::mainColor); + ColoredObject(const Color colorIndex = ldraw::MAIN_COLOR); bool hasColor() const override final; QVariant getProperty(Property id) const override; QDataStream &serialize(QDataStream& stream) const override; QDataStream& deserialize(QDataStream& stream) override; - Color colorIndex = ldraw::mainColor; + Color colorIndex = ldraw::MAIN_COLOR; protected: void setProperty(SetPropertyResult* result, const PropertyKeyValue& pair) override; };
--- a/src/linetypes/subfilereference.cpp Wed Sep 22 13:28:53 2021 +0300 +++ b/src/linetypes/subfilereference.cpp Wed Sep 22 14:03:43 2021 +0300 @@ -63,7 +63,7 @@ { gl::invert(polygon); } - if (polygon.color == ldraw::mainColor) + if (polygon.color == ldraw::MAIN_COLOR) { polygon.color = this->colorIndex; }
--- a/src/linetypes/subfilereference.h Wed Sep 22 13:28:53 2021 +0300 +++ b/src/linetypes/subfilereference.h Wed Sep 22 14:03:43 2021 +0300 @@ -15,7 +15,7 @@ SubfileReference( const glm::mat4& transformation, const QString &referenceName, - const Color color = ldraw::mainColor); + const Color color = ldraw::MAIN_COLOR); QVariant getProperty(Property property) const override; QString textRepresentation() const override; void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const override;
--- a/src/tools/drawtool.cpp Wed Sep 22 13:28:53 2021 +0300 +++ b/src/tools/drawtool.cpp Wed Sep 22 14:03:43 2021 +0300 @@ -146,13 +146,13 @@ switch (this->polygon.size()) { case 2: - edit.append<ldraw::Edge>(vectorToArray<2>(this->polygon), ldraw::edgeColor); + edit.append<ldraw::Edge>(vectorToArray<2>(this->polygon), ldraw::EDGE_COLOR); break; case 3: - edit.append<ldraw::Triangle>(vectorToArray<3>(this->polygon), ldraw::mainColor); + edit.append<ldraw::Triangle>(vectorToArray<3>(this->polygon), ldraw::MAIN_COLOR); break; case 4: - edit.append<ldraw::Quadrilateral>(vectorToArray<4>(this->polygon), ldraw::mainColor); + edit.append<ldraw::Quadrilateral>(vectorToArray<4>(this->polygon), ldraw::MAIN_COLOR); break; } }
--- a/src/widgets/colorselectdialog.cpp Wed Sep 22 13:28:53 2021 +0300 +++ b/src/widgets/colorselectdialog.cpp Wed Sep 22 14:03:43 2021 +0300 @@ -46,7 +46,7 @@ ++iterator ) { const qint32 index = iterator->first; - const ldraw::ColorTable::ColorDefinition& colordef = iterator->second; + const ldraw::ColorDefinition& colordef = iterator->second; QPushButton* const button = new QPushButton{QString::number(index), this}; button->setToolTip(colordef.displayName); button->setStyleSheet(styleSheetForColor(colordef.faceColor)); @@ -101,7 +101,7 @@ } else { - const ldraw::ColorTable::ColorDefinition& colordef = this->colorTable[this->selectedColor]; + const ldraw::ColorDefinition& colordef = this->colorTable[this->selectedColor]; this->ui.selectedColorName->setText(colordef.displayName); } const QColor colorFace = ldraw::colorFace(this->selectedColor, this->colorTable); @@ -147,7 +147,7 @@ } else { - const ldraw::ColorTable::ColorDefinition& colordef = this->colorTable[color]; + const ldraw::ColorDefinition& colordef = this->colorTable[color]; return colordef.displayName.contains(filterText, Qt::CaseInsensitive); } }
--- a/src/widgets/colorselectdialog.h Wed Sep 22 13:28:53 2021 +0300 +++ b/src/widgets/colorselectdialog.h Wed Sep 22 14:03:43 2021 +0300 @@ -26,5 +26,5 @@ class Ui_ColorSelectDialog& ui; const ldraw::ColorTable& colorTable; std::vector<QPushButton*> buttons; - ldraw::Color selectedColor = ldraw::mainColor; + ldraw::Color selectedColor = ldraw::MAIN_COLOR; };