diff --git a/include/xlnt/styles/alignment.hpp b/include/xlnt/styles/alignment.hpp index dc6417f9..d2972bca 100644 --- a/include/xlnt/styles/alignment.hpp +++ b/include/xlnt/styles/alignment.hpp @@ -30,7 +30,7 @@ namespace xlnt { /// -/// Text can be aligned horizontally in these enumerated ways. +/// Text can be aligned horizontally within a cell in these enumerated ways. /// enum class XLNT_API horizontal_alignment { @@ -45,7 +45,7 @@ enum class XLNT_API horizontal_alignment }; /// -/// Text can be aligned vertically in these enumerated ways. +/// Text can be aligned vertically within a cell in these enumerated ways. /// enum class XLNT_API vertical_alignment { @@ -57,68 +57,69 @@ enum class XLNT_API vertical_alignment }; /// -/// Alignment options for use in cell formats. +/// Alignment options that determine how text should be displayed within a cell. /// class XLNT_API alignment { public: /// - /// + /// Returns true if shrink-to-fit has been enabled. /// bool shrink() const; /// - /// + /// Sets whether the font size should be reduced until all of the text fits in a cell without wrapping. /// alignment &shrink(bool shrink_to_fit); /// - /// + /// Returns true if text-wrapping has been enabled. /// bool wrap() const; /// - /// + /// Sets whether text in a cell should continue to multiple lines if it doesn't fit in one line. /// alignment &wrap(bool wrap_text); /// - /// + /// Returns the optional value of indentation width in number of spaces. /// optional indent() const; /// - /// + /// Sets the indent size in number of spaces from the side of the cell. This will only + /// take effect when left or right horizontal alignment has also been set. /// alignment &indent(int indent_size); /// - /// + /// Returns the optional value of rotation for text in the cell in degrees. /// optional rotation() const; /// - /// + /// Sets the rotation for text in the cell in degrees. /// alignment &rotation(int text_rotation); /// - /// + /// Returns the optional horizontal alignment. /// optional horizontal() const; /// - /// + /// Sets the horizontal alignment. /// alignment &horizontal(horizontal_alignment horizontal); /// - /// + /// Returns the optional vertical alignment. /// optional vertical() const; /// - /// + /// Sets the vertical alignment. /// alignment &vertical(vertical_alignment vertical); @@ -133,11 +134,34 @@ public: bool operator!=(const alignment &other) const; private: - bool shrink_to_fit_ = false; - bool wrap_text_ = false; - optional indent_; + /// + /// Whether or not to shrink font size until it fits on one line + /// + bool shrink_to_fit_ = false; + + /// + /// Whether or not to wrap text to the next line + /// + bool wrap_text_ = false; + + /// + /// The indent in number of spaces from the side + /// + optional indent_; + + /// + /// The text roation in degrees + /// optional text_rotation_; + + /// + /// The horizontal alignment + /// optional horizontal_; + + /// + /// The vertical alignment + /// optional vertical_; }; diff --git a/include/xlnt/styles/border.hpp b/include/xlnt/styles/border.hpp index 5685d987..718b0ff3 100644 --- a/include/xlnt/styles/border.hpp +++ b/include/xlnt/styles/border.hpp @@ -50,7 +50,7 @@ enum class XLNT_API border_side }; /// -/// +/// Enumerates the pattern of the border lines on a particular side. /// enum class XLNT_API border_style { diff --git a/include/xlnt/styles/color.hpp b/include/xlnt/styles/color.hpp index ec9a25c8..c5790550 100644 --- a/include/xlnt/styles/color.hpp +++ b/include/xlnt/styles/color.hpp @@ -32,7 +32,7 @@ namespace xlnt { /// -/// +/// An indexed color encapsulates a simple index to a color in the indexedColors of the stylesheet. /// class XLNT_API indexed_color { @@ -60,7 +60,7 @@ private: }; /// -/// +/// A theme color encapsulates a color derived from the theme. /// class XLNT_API theme_color { @@ -88,64 +88,60 @@ private: }; /// -/// +/// An RGB color describes a color in terms of its red, green, blue, and alpha components. /// class XLNT_API rgb_color { public: /// - /// + /// Constructs an RGB color from a string in the form #[aa]rrggbb /// rgb_color(const std::string &hex_string); /// - /// + /// Constructs an RGB color from red, green, and blue values in the range 0 to 255 + /// plus an optional alpha which defaults to fully opaque. /// rgb_color(std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a = 255); /// - /// + /// Returns a string representation of this color in the form #aarrggbb /// std::string hex_string() const; /// - /// + /// Returns a byte representing the red component of this color /// std::uint8_t red() const; /// - /// + /// Returns a byte representing the red component of this color /// std::uint8_t green() const; /// - /// + /// Returns a byte representing the blue component of this color /// std::uint8_t blue() const; /// - /// + /// Returns a byte representing the alpha component of this color /// std::uint8_t alpha() const; /// - /// + /// Returns the red, green, and blue components of this color separately in an array in that order. /// std::array rgb() const; /// - /// + /// Returns the red, green, blue, and alpha components of this color separately in an array in that order. /// std::array rgba() const; private: /// - /// - /// - static std::array decode_hex_string(const std::string &hex_string); - - /// - /// + /// The four bytes of this color /// std::array rgba_; }; @@ -167,163 +163,163 @@ class XLNT_API color { public: /// - /// + /// Returns the color #000000 /// static const color black(); /// - /// + /// Returns the color #ffffff /// static const color white(); /// - /// + /// Returns the color #ff0000 /// static const color red(); /// - /// + /// Returns the color #8b0000 /// static const color darkred(); /// - /// + /// Returns the color #00ff00 /// static const color blue(); /// - /// + /// Returns the color #008b00 /// static const color darkblue(); /// - /// + /// Returns the color #0000ff /// static const color green(); /// - /// + /// Returns the color #00008b /// static const color darkgreen(); /// - /// + /// Returns the color #ffff00 /// static const color yellow(); /// - /// + /// Returns the color #cccc00 /// static const color darkyellow(); /// - /// + /// Constructs a default color /// color(); /// - /// + /// Constructs a color from a given RGB color /// color(const rgb_color &rgb); /// - /// + /// Constructs a color from a given indexed color /// color(const indexed_color &indexed); /// - /// + /// Constructs a color from a given theme color /// color(const theme_color &theme); /// - /// + /// Returns the type of this color /// color_type type() const; /// - /// + /// Returns true if this color has been set to auto /// - bool is_auto() const; + bool auto_() const; /// - /// + /// Sets the auto property of this color to value /// void auto_(bool value); /// - /// + /// Returns the internal indexed color representing this color. If this is not an RGB color, + /// an invalid_attribute exception will be thrown. /// - const rgb_color &rgb() const; + rgb_color rgb() const; /// - /// + /// Returns the internal indexed color representing this color. If this is not an indexed color, + /// an invalid_attribute exception will be thrown. /// - const indexed_color &indexed() const; + indexed_color indexed() const; /// - /// + /// Returns the internal indexed color representing this color. If this is not a theme color, + /// an invalid_attribute exception will be thrown. /// - const theme_color &theme() const; + theme_color theme() const; /// - /// + /// Returns the tint of this color. /// double tint() const; /// - /// + /// Sets the tint of this color to tint. Tints lighten or darken an existing color by multiplying the color with the tint. /// void tint(double tint); /// - /// + /// Returns true if this color is equivalent to other /// bool operator==(const color &other) const; /// - /// + /// Returns true if this color is not equivalent to other /// - bool operator!=(const color &other) const - { - return !(*this == other); - } + bool operator!=(const color &other) const; private: /// - /// + /// Throws an invalid_attribute exception if the given type is different from this color's type /// void assert_type(color_type t) const; /// - /// + /// The type of this color /// color_type type_; /// - /// + /// The internal RGB color. Only valid when this color has a type of rgb /// rgb_color rgb_; /// - /// + /// The internal RGB color. Only valid when this color has a type of indexed /// indexed_color indexed_; /// - /// + /// The internal RGB color. Only valid when this color has a type of theme /// theme_color theme_; /// - /// + /// The tint of this color /// - double tint_; + double tint_ = 0.0; /// - /// + /// Whether or not this is an auto color /// - bool auto__; + bool auto__ = false; }; } // namespace xlnt diff --git a/include/xlnt/styles/fill.hpp b/include/xlnt/styles/fill.hpp index f572fd3a..293cbad8 100644 --- a/include/xlnt/styles/fill.hpp +++ b/include/xlnt/styles/fill.hpp @@ -33,7 +33,7 @@ namespace xlnt { /// -/// +/// The pattern of pixels upon which the corresponding pattern fill will be displayed /// enum class XLNT_API pattern_fill_type { @@ -59,58 +59,56 @@ enum class XLNT_API pattern_fill_type }; /// -/// +/// Represents a fill which colors the cell based on a foreground and +/// background color and a pattern. /// class XLNT_API pattern_fill { public: /// - /// + /// Constructs a default pattern fill with a none pattern and no colors. /// pattern_fill(); /// - /// + /// Returns the pattern used by this fill /// pattern_fill_type type() const; /// - /// + /// Sets the pattern of this fill and returns a reference to it. /// pattern_fill &type(pattern_fill_type new_type); /// - /// + /// Returns the optional foreground color of this fill /// optional foreground() const; /// - /// + /// Sets the foreground color and returns a reference to this pattern. /// pattern_fill &foreground(const color &foreground); /// - /// + /// Returns the optional background color of this fill /// optional background() const; /// - /// + /// Sets the foreground color and returns a reference to this pattern. /// pattern_fill &background(const color &background); /// - /// Returns true if left is exactly equal to right. + /// Returns true if this pattern fill is equivalent to other. /// - XLNT_API friend bool operator==(const pattern_fill &left, const pattern_fill &right); + bool operator==(const pattern_fill &other) const; /// - /// Returns true if left is not exactly equal to right. + /// Returns true if this pattern fill is not equivalent to other. /// - XLNT_API friend bool operator!=(const pattern_fill &left, const pattern_fill &right) - { - return !(left == right); - } + bool operator!=(const pattern_fill &other) const; private: /// @@ -139,37 +137,37 @@ enum class XLNT_API gradient_fill_type }; /// -/// +/// Encapsulates a fill which transitions between colors at particular "stops". /// class XLNT_API gradient_fill { public: /// - /// + /// Constructs a default linear fill /// gradient_fill(); /// - /// + /// Returns the type of this gradient fill /// gradient_fill_type type() const; // Type /// - /// + /// Sets the type of this gradient fill /// gradient_fill &type(gradient_fill_type new_type); // Degree /// - /// + /// Sets the angle of the gradient in degrees /// gradient_fill °ree(double degree); /// - /// + /// Returns the angle of the gradient /// double degree() const; @@ -241,15 +239,12 @@ public: /// /// Returns true if left is exactly equal to right. /// - XLNT_API friend bool operator==(const gradient_fill &left, const gradient_fill &right); + bool operator==(const gradient_fill &other) const; /// /// Returns true if left is not exactly equal to right. /// - XLNT_API friend bool operator!=(const gradient_fill &left, const gradient_fill &right) - { - return !(left == right); - } + bool operator!=(const gradient_fill &right) const; private: /// @@ -347,29 +342,26 @@ public: /// /// Returns true if left is exactly equal to right. /// - XLNT_API friend bool operator==(const fill &left, const fill &right); + bool operator==(const fill &other) const; /// /// Returns true if left is not exactly equal to right. /// - XLNT_API friend bool operator!=(const fill &left, const fill &right) - { - return !(left == right); - } + bool operator!=(const fill &other) const; private: /// - /// + /// The type of this fill /// fill_type type_ = fill_type::pattern; /// - /// + /// The internal gradient fill if this is a gradient fill type /// xlnt::gradient_fill gradient_; /// - /// + /// The internal pattern fill if this is a pattern fill type /// xlnt::pattern_fill pattern_; }; diff --git a/source/detail/xlsx_producer.cpp b/source/detail/xlsx_producer.cpp index b845dcc8..f4c243ac 100755 --- a/source/detail/xlsx_producer.cpp +++ b/source/detail/xlsx_producer.cpp @@ -2950,7 +2950,7 @@ void xlsx_producer::write_relationships(const std::vector &r void xlsx_producer::write_color(const xlnt::color &color) { - if (color.is_auto()) + if (color.auto_()) { write_attribute("auto", write_bool(true)); return; diff --git a/source/styles/color.cpp b/source/styles/color.cpp index 3c847098..8f24977b 100644 --- a/source/styles/color.cpp +++ b/source/styles/color.cpp @@ -28,114 +28,47 @@ #include #include +namespace { + +std::array decode_hex_string(const std::string &hex_string) +{ + auto x = std::strtoul(hex_string.c_str(), NULL, 16); + + auto a = static_cast(x >> 24); + auto r = static_cast((x >> 16) & 0xff); + auto g = static_cast((x >> 8) & 0xff); + auto b = static_cast(x & 0xff); + + return { { r, g, b, a } }; +} + +} // namespace + namespace xlnt { -indexed_color::indexed_color(std::size_t index) - : index_(index) +// indexed_color implementation + +indexed_color::indexed_color(std::size_t index) : index_(index) { } -theme_color::theme_color(std::size_t index) - : index_(index) +std::size_t indexed_color::index() const +{ + return index_; +} + +// theme_color implementation + +theme_color::theme_color(std::size_t index) : index_(index) { } -const color color::black() +std::size_t theme_color::index() const { - return color(rgb_color("ff000000")); + return index_; } -const color color::white() -{ - return color(rgb_color("ffffffff")); -} - -const color color::red() -{ - return color(rgb_color("ffff0000")); -} - -const color color::darkred() -{ - return color(rgb_color("ff8b0000")); -} - -const color color::blue() -{ - return color(rgb_color("ff0000ff")); -} - -const color color::darkblue() -{ - return color(rgb_color("ff00008b")); -} - -const color color::green() -{ - return color(rgb_color("ff00ff00")); -} - -const color color::darkgreen() -{ - return color(rgb_color("ff008b00")); -} - -const color color::yellow() -{ - return color(rgb_color("ffffff00")); -} - -const color color::darkyellow() -{ - return color(rgb_color("ffcccc00")); -} - -color::color() - : type_(color_type::indexed), rgb_(rgb_color(0, 0, 0, 0)), indexed_(0), theme_(0), tint_(0), auto__(false) -{ -} - -color::color(const rgb_color &rgb) - : type_(color_type::rgb), rgb_(rgb), indexed_(0), theme_(0), tint_(0), auto__(false) -{ -} - -color::color(const indexed_color &indexed) - : type_(color_type::indexed), rgb_(rgb_color(0, 0, 0, 0)), indexed_(indexed), theme_(0), tint_(0), auto__(false) -{ -} - -color::color(const theme_color &theme) - : type_(color_type::theme), rgb_(rgb_color(0, 0, 0, 0)), indexed_(0), theme_(theme), tint_(0), auto__(false) -{ -} - -color_type color::type() const -{ - return type_; -} - -bool color::is_auto() const -{ - return auto__; -} - -void color::auto_(bool value) -{ - auto__ = value; -} - -const indexed_color &color::indexed() const -{ - assert_type(color_type::indexed); - return indexed_; -} - -const theme_color &color::theme() const -{ - assert_type(color_type::theme); - return theme_; -} +// rgb_color implementation std::string rgb_color::hex_string() const { @@ -155,18 +88,6 @@ std::string rgb_color::hex_string() const return hex_string; } -std::array rgb_color::decode_hex_string(const std::string &hex_string) -{ - auto x = std::strtoul(hex_string.c_str(), NULL, 16); - - auto a = static_cast(x >> 24); - auto r = static_cast((x >> 16) & 0xff); - auto g = static_cast((x >> 8) & 0xff); - auto b = static_cast(x & 0xff); - - return {{r, g, b, a}}; -} - rgb_color::rgb_color(const std::string &hex_string) : rgba_(decode_hex_string(hex_string)) { @@ -177,17 +98,144 @@ rgb_color::rgb_color(std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_ { } -std::size_t indexed_color::index() const +std::uint8_t rgb_color::red() const { - return index_; + return rgba_[0]; } -std::size_t theme_color::index() const +std::uint8_t rgb_color::green() const { - return index_; + return rgba_[1]; } -const rgb_color &color::rgb() const +std::uint8_t rgb_color::blue() const +{ + return rgba_[2]; +} + +std::uint8_t rgb_color::alpha() const +{ + return rgba_[3]; +} + +std::array rgb_color::rgb() const +{ + return { red(), green(), blue() }; +} + +std::array rgb_color::rgba() const +{ + return rgba_; +} + +// color implementation + +const color color::black() +{ + return color(rgb_color("ff000000")); +} + +const color color::white() +{ + return color(rgb_color("ffffffff")); +} + +const color color::red() +{ + return color(rgb_color("ffff0000")); +} + +const color color::darkred() +{ + return color(rgb_color("ff8b0000")); +} + +const color color::blue() +{ + return color(rgb_color("ff0000ff")); +} + +const color color::darkblue() +{ + return color(rgb_color("ff00008b")); +} + +const color color::green() +{ + return color(rgb_color("ff00ff00")); +} + +const color color::darkgreen() +{ + return color(rgb_color("ff008b00")); +} + +const color color::yellow() +{ + return color(rgb_color("ffffff00")); +} + +const color color::darkyellow() +{ + return color(rgb_color("ffcccc00")); +} + +color::color() : color(indexed_color(0)) +{ +} + +color::color(const rgb_color &rgb) + : type_(color_type::rgb), + rgb_(rgb), + indexed_(0), + theme_(0) +{ +} + +color::color(const indexed_color &indexed) + : type_(color_type::indexed), + rgb_(rgb_color(0, 0, 0, 0)), + indexed_(indexed), + theme_(0) +{ +} + +color::color(const theme_color &theme) + : type_(color_type::theme), + rgb_(rgb_color(0, 0, 0, 0)), + indexed_(0), + theme_(theme) +{ +} + +color_type color::type() const +{ + return type_; +} + +bool color::auto_() const +{ + return auto__; +} + +void color::auto_(bool value) +{ + auto__ = value; +} + +indexed_color color::indexed() const +{ + assert_type(color_type::indexed); + return indexed_; +} + +theme_color color::theme() const +{ + assert_type(color_type::theme); + return theme_; +} + +rgb_color color::rgb() const { assert_type(color_type::rgb); return rgb_; @@ -198,6 +246,11 @@ void color::tint(double tint) tint_ = tint; } +double color::tint() const +{ + return tint_; +} + void color::assert_type(color_type t) const { if (t != type_) @@ -206,7 +259,7 @@ void color::assert_type(color_type t) const } } -XLNT_API bool color::operator==(const xlnt::color &other) const +bool color::operator==(const xlnt::color &other) const { if (type_ != other.type_ || std::fabs(tint_ - other.tint_) != 0.0 || auto__ != other.auto__) { @@ -226,4 +279,9 @@ XLNT_API bool color::operator==(const xlnt::color &other) const return false; } +bool color::operator!=(const color &other) const +{ + return !(*this == other); +} + } // namespace xlnt diff --git a/source/styles/fill.cpp b/source/styles/fill.cpp index 2b4e68bb..69950046 100644 --- a/source/styles/fill.cpp +++ b/source/styles/fill.cpp @@ -73,35 +73,35 @@ pattern_fill &pattern_fill::background(const color &new_background) return *this; } -XLNT_API bool operator==(const pattern_fill &left, const pattern_fill &right) +bool pattern_fill::operator==(const pattern_fill &other) const { - if (left.background().is_set() != right.background().is_set()) + if (background().is_set() != other.background().is_set()) { return false; } - if (left.background().is_set()) + if (background().is_set()) { - if (left.background().get() != right.background().get()) + if (background().get() != other.background().get()) { return false; } } - if (left.foreground().is_set() != right.foreground().is_set()) + if (foreground().is_set() != other.foreground().is_set()) { return false; } - if (left.foreground().is_set()) + if (foreground().is_set()) { - if (left.foreground().get() != right.foreground().get()) + if (foreground().get() != other.foreground().get()) { return false; } } - if (left.type() != right.type()) + if (type() != other.type()) { return false; } @@ -109,10 +109,14 @@ XLNT_API bool operator==(const pattern_fill &left, const pattern_fill &right) return true; } +bool pattern_fill::operator!=(const pattern_fill &other) const +{ + return !(*this == other); +} + // gradient_fill -gradient_fill::gradient_fill() - : type_(gradient_fill_type::linear) +gradient_fill::gradient_fill() : type_(gradient_fill_type::linear) { } @@ -199,39 +203,39 @@ std::unordered_map gradient_fill::stops() const return stops_; } -XLNT_API bool operator==(const gradient_fill &left, const gradient_fill &right) +bool gradient_fill::operator==(const gradient_fill &other) const { - if (left.type() != right.type()) + if (type() != other.type()) { return false; } - if (std::fabs(left.degree() - right.degree()) != 0.) + if (std::fabs(degree() - other.degree()) != 0.) { return false; } - if (std::fabs(left.bottom() - right.bottom()) != 0.) + if (std::fabs(bottom() - other.bottom()) != 0.) { return false; } - if (std::fabs(left.right() - right.right()) != 0.) + if (std::fabs(right() - other.right()) != 0.) { return false; } - if (std::fabs(left.top() - right.top()) != 0.) + if (std::fabs(top() - other.top()) != 0.) { return false; } - if (std::fabs(left.left() - right.left()) != 0.) + if (std::fabs(left() - other.left()) != 0.) { return false; } - if (left.stops() != right.stops()) + if (stops() != other.stops()) { return false; } @@ -239,6 +243,11 @@ XLNT_API bool operator==(const gradient_fill &left, const gradient_fill &right) return true; } +bool gradient_fill::operator!=(const gradient_fill &other) const +{ + return !(*this == other); +} + // fill fill fill::solid(const color &fill_color) @@ -287,19 +296,24 @@ pattern_fill fill::pattern_fill() const return pattern_; } -XLNT_API bool operator==(const fill &left, const fill &right) +bool fill::operator==(const fill &other) const { - if (left.type() != right.type()) + if (type() != other.type()) { return false; } - if (left.type() == fill_type::gradient) + if (type() == fill_type::gradient) { - return left.gradient_fill() == right.gradient_fill(); + return gradient_fill() == other.gradient_fill(); } - return left.pattern_fill() == right.pattern_fill(); + return pattern_fill() == other.pattern_fill(); +} + +bool fill::operator!=(const fill &other) const +{ + return !(*this == other); } } // namespace xlnt diff --git a/source/styles/tests/test_color.hpp b/source/styles/tests/test_color.hpp index fe034694..be53d559 100644 --- a/source/styles/tests/test_color.hpp +++ b/source/styles/tests/test_color.hpp @@ -33,13 +33,13 @@ public: void test_non_rgb_colors() { xlnt::color indexed = xlnt::indexed_color(1); - TS_ASSERT(!indexed.is_auto()); + TS_ASSERT(!indexed.auto_()); TS_ASSERT_EQUALS(indexed.indexed().index(), 1); TS_ASSERT_THROWS(indexed.theme(), xlnt::invalid_attribute); TS_ASSERT_THROWS(indexed.rgb(), xlnt::invalid_attribute); xlnt::color theme = xlnt::theme_color(3); - TS_ASSERT(!theme.is_auto()); + TS_ASSERT(!theme.auto_()); TS_ASSERT_EQUALS(theme.theme().index(), 3); TS_ASSERT_THROWS(theme.indexed(), xlnt::invalid_attribute); TS_ASSERT_THROWS(theme.rgb(), xlnt::invalid_attribute);