differential code coverage report with master
Current view: top level - source/styles - color.cpp (source / functions) Coverage Total Hit UBC CBC
Current: coverage.info Lines: 97.2 % 142 138 4 138
Current Date: 2025-12-15 23:01:28 Functions: 97.8 % 45 44 1 44
Baseline: coverage_master.info Branches: 83.3 % 48 40 16 80
Baseline Date: 2025-12-15 23:01:27

             Branch data    TLA  Line data    Source code
       1                 :                : // Copyright (c) 2014-2022 Thomas Fussell
       2                 :                : // Copyright (c) 2010-2015 openpyxl
       3                 :                : // Copyright (c) 2024-2025 xlnt-community
       4                 :                : //
       5                 :                : // Permission is hereby granted, free of charge, to any person obtaining a copy
       6                 :                : // of this software and associated documentation files (the "Software"), to deal
       7                 :                : // in the Software without restriction, including without limitation the rights
       8                 :                : // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9                 :                : // copies of the Software, and to permit persons to whom the Software is
      10                 :                : // furnished to do so, subject to the following conditions:
      11                 :                : //
      12                 :                : // The above copyright notice and this permission notice shall be included in
      13                 :                : // all copies or substantial portions of the Software.
      14                 :                : //
      15                 :                : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16                 :                : // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17                 :                : // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18                 :                : // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19                 :                : // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20                 :                : // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21                 :                : // THE SOFTWARE
      22                 :                : //
      23                 :                : // @license: http://www.opensource.org/licenses/mit-license.php
      24                 :                : // @author: see AUTHORS file
      25                 :                : 
      26                 :                : #include <cmath>
      27                 :                : #include <cstdlib>
      28                 :                : 
      29                 :                : #include <xlnt/styles/color.hpp>
      30                 :                : #include <xlnt/utils/exceptions.hpp>
      31                 :                : #include <detail/serialization/parsers.hpp>
      32                 :                : 
      33                 :                : namespace {
      34                 :                : 
      35                 :CBC         534 : std::array<std::uint8_t, 4> decode_hex_string(const std::string &hex_string)
      36                 :                : {
      37                 :            534 :     unsigned int x = 0;
      38            [ + ]:            534 :     xlnt::detail::parse(hex_string, x, nullptr, 16);
      39                 :                : 
      40                 :            534 :     auto a = static_cast<std::uint8_t>(x >> 24);
      41                 :            534 :     auto r = static_cast<std::uint8_t>((x >> 16) & 0xff);
      42                 :            534 :     auto g = static_cast<std::uint8_t>((x >> 8) & 0xff);
      43                 :            534 :     auto b = static_cast<std::uint8_t>(x & 0xff);
      44                 :                : 
      45                 :            534 :     return {{r, g, b, a}};
      46                 :                : }
      47                 :                : 
      48                 :                : } // namespace
      49                 :                : 
      50                 :                : namespace xlnt {
      51                 :                : 
      52                 :                : // indexed_color implementation
      53                 :                : 
      54                 :           3717 : indexed_color::indexed_color(std::size_t index)
      55                 :           3717 :     : index_(index)
      56                 :                : {
      57                 :           3717 : }
      58                 :                : 
      59                 :            189 : std::size_t indexed_color::index() const
      60                 :                : {
      61                 :            189 :     return index_;
      62                 :                : }
      63                 :                : 
      64                 :              1 : void indexed_color::index(std::size_t index)
      65                 :                : {
      66                 :              1 :     index_ = index;
      67                 :              1 : }
      68                 :                : 
      69                 :                : // theme_color implementation
      70                 :                : 
      71                 :           3717 : theme_color::theme_color(std::size_t index)
      72                 :           3717 :     : index_(index)
      73                 :                : {
      74                 :           3717 : }
      75                 :                : 
      76                 :           1470 : std::size_t theme_color::index() const
      77                 :                : {
      78                 :           1470 :     return index_;
      79                 :                : }
      80                 :                : 
      81                 :              1 : void theme_color::index(std::size_t index)
      82                 :                : {
      83                 :              1 :     index_ = index;
      84                 :              1 : }
      85                 :                : 
      86                 :                : // rgb_color implementation
      87                 :                : 
      88                 :            364 : std::string rgb_color::hex_string() const
      89                 :                : {
      90                 :                :     static const char *digits = "0123456789ABCDEF";
      91            [ + ]:            182 :     std::string hex_string(8, '0');
      92                 :            182 :     auto out_iter = hex_string.begin();
      93                 :                : 
      94         [ +  + ]:            910 :     for (auto byte : {rgba_[3], rgba_[0], rgba_[1], rgba_[2]})
      95                 :                :     {
      96         [ +  + ]:           2184 :         for (auto i = 0; i < 2; ++i)
      97                 :                :         {
      98                 :           1456 :             auto nibble = byte >> (4 * (1 - i)) & 0xf;
      99                 :           1456 :             *(out_iter++) = digits[nibble];
     100                 :                :         }
     101                 :                :     }
     102                 :                : 
     103                 :            182 :     return hex_string;
     104                 :                : }
     105                 :                : 
     106                 :            534 : rgb_color::rgb_color(const std::string &hex_string)
     107                 :            534 :     : rgba_(decode_hex_string(hex_string))
     108                 :                : {
     109                 :            534 : }
     110                 :                : 
     111                 :           3183 : rgb_color::rgb_color(std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a)
     112                 :           3183 :     : rgba_({{r, g, b, a}})
     113                 :                : {
     114                 :           3183 : }
     115                 :                : 
     116                 :             33 : std::uint8_t rgb_color::red() const
     117                 :                : {
     118                 :             33 :     return rgba_[0];
     119                 :                : }
     120                 :                : 
     121                 :             33 : std::uint8_t rgb_color::green() const
     122                 :                : {
     123                 :             33 :     return rgba_[1];
     124                 :                : }
     125                 :                : 
     126                 :             33 : std::uint8_t rgb_color::blue() const
     127                 :                : {
     128                 :             33 :     return rgba_[2];
     129                 :                : }
     130                 :                : 
     131                 :             33 : std::uint8_t rgb_color::alpha() const
     132                 :                : {
     133                 :             33 :     return rgba_[3];
     134                 :                : }
     135                 :                : 
     136                 :UBC           0 : std::array<std::uint8_t, 3> rgb_color::rgb() const
     137                 :                : {
     138                 :              0 :     return {{red(), green(), blue()}};
     139                 :                : }
     140                 :                : 
     141                 :CBC          22 : std::array<std::uint8_t, 4> rgb_color::rgba() const
     142                 :                : {
     143                 :             22 :     return rgba_;
     144                 :                : }
     145                 :                : 
     146                 :                : // color implementation
     147                 :                : 
     148                 :              4 : const color color::black()
     149                 :                : {
     150         [ +  + ]:              8 :     return color(rgb_color("ff000000"));
     151                 :                : }
     152                 :                : 
     153                 :              2 : const color color::white()
     154                 :                : {
     155         [ +  + ]:              4 :     return color(rgb_color("ffffffff"));
     156                 :                : }
     157                 :                : 
     158                 :             19 : const color color::red()
     159                 :                : {
     160         [ +  + ]:             38 :     return color(rgb_color("ffff0000"));
     161                 :                : }
     162                 :                : 
     163                 :              1 : const color color::darkred()
     164                 :                : {
     165         [ +  + ]:              2 :     return color(rgb_color("ff8b0000"));
     166                 :                : }
     167                 :                : 
     168                 :              7 : const color color::blue()
     169                 :                : {
     170         [ +  + ]:             14 :     return color(rgb_color("ff0000ff"));
     171                 :                : }
     172                 :                : 
     173                 :              2 : const color color::darkblue()
     174                 :                : {
     175         [ +  + ]:              4 :     return color(rgb_color("ff00008b"));
     176                 :                : }
     177                 :                : 
     178                 :              7 : const color color::green()
     179                 :                : {
     180         [ +  + ]:             14 :     return color(rgb_color("ff00ff00"));
     181                 :                : }
     182                 :                : 
     183                 :              1 : const color color::darkgreen()
     184                 :                : {
     185         [ +  + ]:              2 :     return color(rgb_color("ff008b00"));
     186                 :                : }
     187                 :                : 
     188                 :              4 : const color color::yellow()
     189                 :                : {
     190         [ +  + ]:              8 :     return color(rgb_color("ffffff00"));
     191                 :                : }
     192                 :                : 
     193                 :              1 : const color color::darkyellow()
     194                 :                : {
     195         [ +  + ]:              2 :     return color(rgb_color("ffcccc00"));
     196                 :                : }
     197                 :                : 
     198                 :           1449 : color::color()
     199                 :           1449 :     : color(indexed_color(0))
     200                 :                : {
     201                 :           1449 : }
     202                 :                : 
     203                 :            534 : color::color(const rgb_color &rgb)
     204                 :            534 :     : type_(color_type::rgb),
     205                 :            534 :       rgb_(rgb),
     206                 :            534 :       indexed_(0),
     207                 :            534 :       theme_(0)
     208                 :                : {
     209                 :            534 : }
     210                 :                : 
     211                 :           2139 : color::color(const indexed_color &indexed)
     212                 :           2139 :     : type_(color_type::indexed),
     213                 :           2139 :       rgb_(rgb_color(0, 0, 0, 0)),
     214                 :           2139 :       indexed_(indexed),
     215                 :           2139 :       theme_(0)
     216                 :                : {
     217                 :           2139 : }
     218                 :                : 
     219                 :           1044 : color::color(const theme_color &theme)
     220                 :           1044 :     : type_(color_type::theme),
     221                 :           1044 :       rgb_(rgb_color(0, 0, 0, 0)),
     222                 :           1044 :       indexed_(0),
     223                 :           1044 :       theme_(theme)
     224                 :                : {
     225                 :           1044 : }
     226                 :                : 
     227                 :            665 : color_type color::type() const
     228                 :                : {
     229                 :            665 :     return type_;
     230                 :                : }
     231                 :                : 
     232                 :            624 : bool color::auto_() const
     233                 :                : {
     234                 :            624 :     return auto_color;
     235                 :                : }
     236                 :                : 
     237                 :              6 : void color::auto_(bool value)
     238                 :                : {
     239                 :              6 :     auto_color = value;
     240                 :              6 : }
     241                 :                : 
     242                 :            179 : const indexed_color &color::indexed() const
     243                 :                : {
     244                 :            179 :     assert_type(color_type::indexed);
     245                 :            179 :     return indexed_;
     246                 :                : }
     247                 :                : 
     248                 :              4 : indexed_color &color::indexed()
     249                 :                : {
     250                 :              4 :     assert_type(color_type::indexed);
     251                 :              3 :     return indexed_;
     252                 :                : }
     253                 :                : 
     254                 :            262 : const theme_color &color::theme() const
     255                 :                : {
     256                 :            262 :     assert_type(color_type::theme);
     257                 :            262 :     return theme_;
     258                 :                : }
     259                 :                : 
     260                 :              4 : theme_color &color::theme()
     261                 :                : {
     262                 :              4 :     assert_type(color_type::theme);
     263                 :              3 :     return theme_;
     264                 :                : }
     265                 :                : 
     266                 :            194 : const rgb_color &color::rgb() const
     267                 :                : {
     268                 :            194 :     assert_type(color_type::rgb);
     269                 :            194 :     return rgb_;
     270                 :                : }
     271                 :                : 
     272                 :             23 : rgb_color &color::rgb()
     273                 :                : {
     274                 :             23 :     assert_type(color_type::rgb);
     275                 :             21 :     return rgb_;
     276                 :                : }
     277                 :                : 
     278                 :            620 : bool color::has_tint() const
     279                 :                : {
     280                 :            620 :     return tint_.is_set();
     281                 :                : }
     282                 :                : 
     283                 :            204 : void color::tint(double tint)
     284                 :                : {
     285                 :            204 :     tint_ = tint;
     286                 :            204 : }
     287                 :                : 
     288                 :             88 : double color::tint() const
     289                 :                : {
     290         [ +  - ]:             88 :     return tint_.is_set() ? tint_.get() : 0.0;
     291                 :                : }
     292                 :                : 
     293                 :            666 : void color::assert_type(color_type t) const
     294                 :                : {
     295         [ +  + ]:            666 :     if (t != type_)
     296                 :                :     {
     297            [ + ]:              4 :         throw invalid_attribute();
     298                 :                :     }
     299                 :            662 : }
     300                 :                : 
     301                 :            644 : bool color::operator==(const xlnt::color &other) const
     302                 :                : {
     303   [ +  +  -  + ]:            644 :     if (type_ != other.type_ || auto_color != other.auto_color)
     304                 :                :     {
     305                 :             26 :         return false;
     306                 :                :     }
     307   [ +  -  -  +  :            618 :     if (tint_.is_set() != other.tint_.is_set() || (tint_.is_set() && std::fabs(tint_.get() - other.tint_.get()) != 0.0))
             -  -  -  + ]
     308                 :                :     {
     309                 :UBC           0 :         return false;
     310                 :                :     }
     311                 :                : 
     312   [ +  +  +  - ]:CBC         618 :     switch (type_)
     313                 :                :     {
     314                 :              4 :     case color_type::indexed:
     315                 :              4 :         return indexed_.index() == other.indexed_.index();
     316                 :            603 :     case color_type::theme:
     317                 :            603 :         return theme_.index() == other.theme_.index();
     318                 :             11 :     case color_type::rgb:
     319            [ + ]:             11 :         return rgb_.rgba() == other.rgb_.rgba();
     320                 :                :     }
     321                 :                : 
     322                 :UBC           0 :     return false;
     323                 :                : }
     324                 :                : 
     325                 :CBC         632 : bool color::operator!=(const color &other) const
     326                 :                : {
     327                 :            632 :     return !(*this == other);
     328                 :                : }
     329                 :                : 
     330                 :                : } // namespace xlnt
        

Generated by: LCOV version 2.3.1-beta