differential code coverage report with master
Current view: top level - include/xlnt/styles - color.hpp (source / functions) Coverage Total Hit UBC CBC
Current: coverage.info Lines: 100.0 % 21 21 21
Current Date: 2025-12-07 02:01:22 Functions: 100.0 % 1 1 1
Baseline: coverage_master.info Branches: 95.0 % 20 19 2 38
Baseline Date: 2025-12-07 02:01:21

             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                 :                : #pragma once
      27                 :                : 
      28                 :                : #include <array>
      29                 :                : #include <cstring>
      30                 :                : #include <functional>
      31                 :                : 
      32                 :                : #include <xlnt/xlnt_config.hpp>
      33                 :                : #include <xlnt/utils/optional.hpp>
      34                 :                : #include <xlnt/utils/hash_combine.hpp>
      35                 :                : 
      36                 :                : namespace xlnt {
      37                 :                : 
      38                 :                : /// <summary>
      39                 :                : /// An indexed color encapsulates a simple index to a color in the indexedColors of the stylesheet.
      40                 :                : /// </summary>
      41                 :                : class XLNT_API indexed_color
      42                 :                : {
      43                 :                : public:
      44                 :                :     //TODO: should this be explicit?
      45                 :                :     /// <summary>
      46                 :                :     /// Constructs an indexed_color from an index.
      47                 :                :     /// </summary>
      48                 :                :     indexed_color(std::size_t index);
      49                 :                : 
      50                 :                :     /// <summary>
      51                 :                :     /// Returns the index this color points to.
      52                 :                :     /// </summary>
      53                 :                :     std::size_t index() const;
      54                 :                : 
      55                 :                :     /// <summary>
      56                 :                :     /// Sets the index to index.
      57                 :                :     /// </summary>
      58                 :                :     void index(std::size_t index);
      59                 :                : 
      60                 :                : private:
      61                 :                :     /// <summary>
      62                 :                :     /// The index of this color
      63                 :                :     /// </summary>
      64                 :                :     std::size_t index_;
      65                 :                : };
      66                 :                : 
      67                 :                : /// <summary>
      68                 :                : /// A theme color encapsulates a color derived from the theme.
      69                 :                : /// </summary>
      70                 :                : class XLNT_API theme_color
      71                 :                : {
      72                 :                : public:
      73                 :                :     /// <summary>
      74                 :                :     /// Constructs a theme_color from an index.
      75                 :                :     /// </summary>
      76                 :                :     theme_color(std::size_t index);
      77                 :                : 
      78                 :                :     /// <summary>
      79                 :                :     /// Returns the index of the color in the theme this points to.
      80                 :                :     /// </summary>
      81                 :                :     std::size_t index() const;
      82                 :                : 
      83                 :                :     /// <summary>
      84                 :                :     /// Sets the index of this color to index.
      85                 :                :     /// </summary>
      86                 :                :     void index(std::size_t index);
      87                 :                : 
      88                 :                : private:
      89                 :                :     /// <summary>
      90                 :                :     /// The index of the color
      91                 :                :     /// </summary>
      92                 :                :     std::size_t index_;
      93                 :                : };
      94                 :                : 
      95                 :                : /// <summary>
      96                 :                : /// An RGB color describes a color in terms of its red, green, blue, and alpha components.
      97                 :                : /// </summary>
      98                 :                : class XLNT_API rgb_color
      99                 :                : {
     100                 :                : public:
     101                 :                :     /// <summary>
     102                 :                :     /// Constructs an RGB color from a string in the form \#[aa]rrggbb
     103                 :                :     /// </summary>
     104                 :                :     rgb_color(const std::string &hex_string);
     105                 :                : 
     106                 :                :     /// <summary>
     107                 :                :     /// Constructs an RGB color from red, green, and blue values in the range 0 to 255
     108                 :                :     /// plus an optional alpha which defaults to fully opaque.
     109                 :                :     /// </summary>
     110                 :                :     rgb_color(std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a = 255);
     111                 :                : 
     112                 :                :     /// <summary>
     113                 :                :     /// Returns a string representation of this color in the form \#aarrggbb
     114                 :                :     /// </summary>
     115                 :                :     std::string hex_string() const;
     116                 :                : 
     117                 :                :     /// <summary>
     118                 :                :     /// Returns a byte representing the red component of this color
     119                 :                :     /// </summary>
     120                 :                :     std::uint8_t red() const;
     121                 :                : 
     122                 :                :     /// <summary>
     123                 :                :     /// Returns a byte representing the red component of this color
     124                 :                :     /// </summary>
     125                 :                :     std::uint8_t green() const;
     126                 :                : 
     127                 :                :     /// <summary>
     128                 :                :     /// Returns a byte representing the blue component of this color
     129                 :                :     /// </summary>
     130                 :                :     std::uint8_t blue() const;
     131                 :                : 
     132                 :                :     /// <summary>
     133                 :                :     /// Returns a byte representing the alpha component of this color
     134                 :                :     /// </summary>
     135                 :                :     std::uint8_t alpha() const;
     136                 :                : 
     137                 :                :     /// <summary>
     138                 :                :     /// Returns the red, green, and blue components of this color separately in an array in that order.
     139                 :                :     /// </summary>
     140                 :                :     std::array<std::uint8_t, 3> rgb() const;
     141                 :                : 
     142                 :                :     /// <summary>
     143                 :                :     /// Returns the red, green, blue, and alpha components of this color separately in an array in that order.
     144                 :                :     /// </summary>
     145                 :                :     std::array<std::uint8_t, 4> rgba() const;
     146                 :                : 
     147                 :                : private:
     148                 :                :     /// <summary>
     149                 :                :     /// The four bytes of this color
     150                 :                :     /// </summary>
     151                 :                :     std::array<std::uint8_t, 4> rgba_;
     152                 :                : };
     153                 :                : 
     154                 :                : /// <summary>
     155                 :                : /// Some colors are references to colors rather than having a particular RGB value.
     156                 :                : /// </summary>
     157                 :                : enum class color_type
     158                 :                : {
     159                 :                :     indexed,
     160                 :                :     theme,
     161                 :                :     rgb
     162                 :                : };
     163                 :                : 
     164                 :                : /// <summary>
     165                 :                : /// Colors can be applied to many parts of a cell's style.
     166                 :                : /// </summary>
     167                 :                : class XLNT_API color
     168                 :                : {
     169                 :                : public:
     170                 :                :     /// <summary>
     171                 :                :     /// Returns the color \#000000
     172                 :                :     /// </summary>
     173                 :                :     static const color black();
     174                 :                : 
     175                 :                :     /// <summary>
     176                 :                :     /// Returns the color \#ffffff
     177                 :                :     /// </summary>
     178                 :                :     static const color white();
     179                 :                : 
     180                 :                :     /// <summary>
     181                 :                :     /// Returns the color \#ff0000
     182                 :                :     /// </summary>
     183                 :                :     static const color red();
     184                 :                : 
     185                 :                :     /// <summary>
     186                 :                :     /// Returns the color \#8b0000
     187                 :                :     /// </summary>
     188                 :                :     static const color darkred();
     189                 :                : 
     190                 :                :     /// <summary>
     191                 :                :     /// Returns the color \#00ff00
     192                 :                :     /// </summary>
     193                 :                :     static const color blue();
     194                 :                : 
     195                 :                :     /// <summary>
     196                 :                :     /// Returns the color \#008b00
     197                 :                :     /// </summary>
     198                 :                :     static const color darkblue();
     199                 :                : 
     200                 :                :     /// <summary>
     201                 :                :     /// Returns the color \#0000ff
     202                 :                :     /// </summary>
     203                 :                :     static const color green();
     204                 :                : 
     205                 :                :     /// <summary>
     206                 :                :     /// Returns the color \#00008b
     207                 :                :     /// </summary>
     208                 :                :     static const color darkgreen();
     209                 :                : 
     210                 :                :     /// <summary>
     211                 :                :     /// Returns the color \#ffff00
     212                 :                :     /// </summary>
     213                 :                :     static const color yellow();
     214                 :                : 
     215                 :                :     /// <summary>
     216                 :                :     /// Returns the color \#cccc00
     217                 :                :     /// </summary>
     218                 :                :     static const color darkyellow();
     219                 :                : 
     220                 :                :     /// <summary>
     221                 :                :     /// Constructs a default color
     222                 :                :     /// </summary>
     223                 :                :     color();
     224                 :                : 
     225                 :                :     /// <summary>
     226                 :                :     /// Constructs a color from a given RGB color
     227                 :                :     /// </summary>
     228                 :                :     color(const rgb_color &rgb);
     229                 :                : 
     230                 :                :     /// <summary>
     231                 :                :     /// Constructs a color from a given indexed color
     232                 :                :     /// </summary>
     233                 :                :     color(const indexed_color &indexed);
     234                 :                : 
     235                 :                :     /// <summary>
     236                 :                :     /// Constructs a color from a given theme color
     237                 :                :     /// </summary>
     238                 :                :     color(const theme_color &theme);
     239                 :                : 
     240                 :                :     /// <summary>
     241                 :                :     /// Returns the type of this color
     242                 :                :     /// </summary>
     243                 :                :     color_type type() const;
     244                 :                : 
     245                 :                :     /// <summary>
     246                 :                :     /// Returns true if this color has been set to auto
     247                 :                :     /// </summary>
     248                 :                :     bool auto_() const;
     249                 :                : 
     250                 :                :     /// <summary>
     251                 :                :     /// Sets the auto property of this color to value
     252                 :                :     /// </summary>
     253                 :                :     void auto_(bool value);
     254                 :                : 
     255                 :                :     /// <summary>
     256                 :                :     /// Returns the internal indexed color representing this color. If this is not an RGB color,
     257                 :                :     /// an invalid_attribute exception will be thrown.
     258                 :                :     /// </summary>
     259                 :                :     const rgb_color &rgb() const;
     260                 :                : 
     261                 :                :     /// <summary>
     262                 :                :     /// Returns the internal indexed color representing this color. If this is not an RGB color,
     263                 :                :     /// an invalid_attribute exception will be thrown.
     264                 :                :     /// </summary>
     265                 :                :     rgb_color &rgb();
     266                 :                : 
     267                 :                :     /// <summary>
     268                 :                :     /// Returns the internal indexed color representing this color. If this is not an indexed color,
     269                 :                :     /// an invalid_attribute exception will be thrown.
     270                 :                :     /// </summary>
     271                 :                :     const indexed_color &indexed() const;
     272                 :                : 
     273                 :                :     /// <summary>
     274                 :                :     /// Returns the internal indexed color representing this color. If this is not an indexed color,
     275                 :                :     /// an invalid_attribute exception will be thrown.
     276                 :                :     /// </summary>
     277                 :                :     indexed_color &indexed();
     278                 :                : 
     279                 :                :     /// <summary>
     280                 :                :     /// Returns the internal indexed color representing this color. If this is not a theme color,
     281                 :                :     /// an invalid_attribute exception will be thrown.
     282                 :                :     /// </summary>
     283                 :                :     const theme_color &theme() const;
     284                 :                : 
     285                 :                :     /// <summary>
     286                 :                :     /// Returns the internal indexed color representing this color. If this is not a theme color,
     287                 :                :     /// an invalid_attribute exception will be thrown.
     288                 :                :     /// </summary>
     289                 :                :     theme_color &theme();
     290                 :                : 
     291                 :                :     /// <summary>
     292                 :                :     /// Returns true if tint is set
     293                 :                :     /// </summary>
     294                 :                :     bool has_tint() const;
     295                 :                : 
     296                 :                :     /// <summary>
     297                 :                :     /// Returns the tint of this color.
     298                 :                :     /// </summary>
     299                 :                :     double tint() const;
     300                 :                : 
     301                 :                :     /// <summary>
     302                 :                :     /// Sets the tint of this color to tint. Tints lighten or darken an existing color by multiplying the color with the tint.
     303                 :                :     /// </summary>
     304                 :                :     void tint(double tint);
     305                 :                : 
     306                 :                :     /// <summary>
     307                 :                :     /// Returns true if this color is equivalent to other
     308                 :                :     /// </summary>
     309                 :                :     bool operator==(const color &other) const;
     310                 :                : 
     311                 :                :     /// <summary>
     312                 :                :     /// Returns true if this color is not equivalent to other
     313                 :                :     /// </summary>
     314                 :                :     bool operator!=(const color &other) const;
     315                 :                : 
     316                 :                : private:
     317                 :                :     /// <summary>
     318                 :                :     /// Throws an invalid_attribute exception if the given type is different from this color's type
     319                 :                :     /// </summary>
     320                 :                :     void assert_type(color_type t) const;
     321                 :                : 
     322                 :                :     /// <summary>
     323                 :                :     /// The type of this color
     324                 :                :     /// </summary>
     325                 :                :     color_type type_;
     326                 :                : 
     327                 :                :     /// <summary>
     328                 :                :     /// The internal RGB color. Only valid when this color has a type of rgb
     329                 :                :     /// </summary>
     330                 :                :     rgb_color rgb_;
     331                 :                : 
     332                 :                :     /// <summary>
     333                 :                :     /// The internal RGB color. Only valid when this color has a type of indexed
     334                 :                :     /// </summary>
     335                 :                :     indexed_color indexed_;
     336                 :                : 
     337                 :                :     /// <summary>
     338                 :                :     /// The internal RGB color. Only valid when this color has a type of theme
     339                 :                :     /// </summary>
     340                 :                :     theme_color theme_;
     341                 :                : 
     342                 :                :     /// <summary>
     343                 :                :     /// The tint of this color
     344                 :                :     /// </summary>
     345                 :                :     optional<double> tint_;
     346                 :                : 
     347                 :                :     /// <summary>
     348                 :                :     /// Whether or not this is an auto color
     349                 :                :     /// </summary>
     350                 :                :     bool auto_color = false;
     351                 :                : };
     352                 :                : 
     353                 :                : } // namespace xlnt
     354                 :                : 
     355                 :                : namespace std {
     356                 :                : 
     357                 :                : template<>
     358                 :                : struct hash<xlnt::color>
     359                 :                : {
     360                 :CBC          45 :     size_t operator()(const xlnt::color& c) const
     361                 :                :     {
     362                 :             45 :         size_t seed = 0;
     363                 :                :         // Start by hashing the type to prevent collisions between different color types
     364                 :                :         // that might share an underlying value (e.g., theme(1) vs indexed(1)).
     365            [ + ]:             45 :         xlnt::detail::hash_combine(seed, static_cast<int>(c.type()));
     366                 :                : 
     367                 :                :         // Hash auto color flag
     368            [ + ]:             45 :         xlnt::detail::hash_combine(seed, c.auto_());
     369                 :                : 
     370                 :                :         // Hash tint if present
     371      [ +  +  + ]:             45 :         if (c.has_tint())
     372                 :                :         {
     373            [ + ]:              8 :             xlnt::detail::hash_combine(seed, c.tint());
     374                 :                :         }
     375                 :                : 
     376   [ +  +  +  +  :             45 :         switch (c.type())
                      - ]
     377                 :                :         {
     378                 :              6 :             case xlnt::color_type::indexed:
     379         [ +  + ]:              6 :                 xlnt::detail::hash_combine(seed, c.indexed().index());
     380                 :              6 :                 break;
     381                 :              6 :             case xlnt::color_type::theme:
     382         [ +  + ]:              6 :                 xlnt::detail::hash_combine(seed, c.theme().index());
     383                 :              6 :                 break;
     384                 :             33 :             case xlnt::color_type::rgb:
     385                 :                :             {
     386            [ + ]:             33 :                 const auto& rgb = c.rgb();
     387            [ + ]:             33 :                 xlnt::detail::hash_combine(seed, rgb.red());
     388            [ + ]:             33 :                 xlnt::detail::hash_combine(seed, rgb.green());
     389            [ + ]:             33 :                 xlnt::detail::hash_combine(seed, rgb.blue());
     390            [ + ]:             33 :                 xlnt::detail::hash_combine(seed, rgb.alpha());
     391                 :             33 :                 break;
     392                 :                :             }
     393                 :                :         }
     394                 :             45 :         return seed;
     395                 :                :     }
     396                 :                : };
     397                 :                : 
     398                 :                : } // namespace std
        

Generated by: LCOV version 2.3.1-beta