Scroom  0.14
color.hh
Go to the documentation of this file.
1 /*
2  * Scroom - Generic viewer for 2D data
3  * Copyright (C) 2009-2022 Kees-Jan Dijkzeul
4  *
5  * SPDX-License-Identifier: LGPL-2.1
6  */
7 
8 #pragma once
9 
10 #include <cmath>
11 #include <cstdint>
12 #include <iomanip>
13 #include <sstream>
14 
15 #include <boost/operators.hpp>
16 
17 #include <gdk/gdk.h>
18 
19 #include <cairo.h>
20 
21 inline uint8_t byteFromDouble(double d) { return uint8_t(255 * d); }
22 inline double doubleFromByte(uint8_t b) { return b / 255.0; }
23 inline uint16_t shortFromDouble(double d) { return uint16_t(0xFFFF * d); }
24 
25 namespace Detail
26 {
27  // see http://stackoverflow.com/a/3943023
28  inline double computeC(double c) { return c <= 0.03928 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4); }
29 } // namespace Detail
30 
34 class Color
35  : public boost::addable<Color>
36  , public boost::multiplicative<Color, double>
37 {
38 public:
39  double alpha{1.0};
40  double red{0.0};
41  double green{0.0};
42  double blue{0.0};
44 public:
46  Color() = default;
47 
49  Color(double red_, double green_, double blue_, double alpha_ = 1.0)
50  : alpha(alpha_)
51  , red(red_)
52  , green(green_)
53  , blue(blue_)
54  {
55  }
56 
58  explicit Color(double gray, double alpha_ = 1.0)
59  : alpha(alpha_)
60  , red(gray)
61  , green(gray)
62  , blue(gray)
63  {
64  }
65 
66  Color& operator+=(const Color& rhs)
67  {
68  alpha += rhs.alpha;
69  red += rhs.red;
70  green += rhs.green;
71  blue += rhs.blue;
72  return *this;
73  }
74 
75  Color& operator/=(double d)
76  {
77  alpha /= d;
78  red /= d;
79  green /= d;
80  blue /= d;
81  return *this;
82  }
83 
84  Color& operator*=(double d)
85  {
86  alpha *= d;
87  red *= d;
88  green *= d;
89  blue *= d;
90  return *this;
91  }
92 
93  [[nodiscard]] std::string getHex() const
94  {
95  std::stringstream ss;
96 
97  ss << std::hex << std::setfill('0');
98 
99 
100  ss << std::hex << std::setw(2) << static_cast<int>(byteFromDouble(red));
101  ss << std::hex << std::setw(2) << static_cast<int>(byteFromDouble(green));
102  ss << std::hex << std::setw(2) << static_cast<int>(byteFromDouble(blue));
103 
104  return ss.str();
105  }
106 
107  [[nodiscard]] uint32_t getRGB24() const
108  {
109  return 0xFF000000 | byteFromDouble(red) << 16 | byteFromDouble(green) << 8 | byteFromDouble(blue) << 0;
110  }
111 
112  [[nodiscard]] uint32_t getARGB32() const
113  {
114  return byteFromDouble(alpha) << 24 | byteFromDouble(red) << 16 | byteFromDouble(green) << 8 | byteFromDouble(blue) << 0;
115  }
116 
117  void setColor(cairo_t* cr) const { cairo_set_source_rgba(cr, red, green, blue, alpha); }
118 
119  [[nodiscard]] GdkColor getGdkColor() const { return {0, shortFromDouble(red), shortFromDouble(green), shortFromDouble(blue)}; }
120 
121  [[nodiscard]] Color getContrastingBlackOrWhite() const
122  {
123  // see http://stackoverflow.com/a/3943023
124  const double L = 0.2126 * Detail::computeC(red) + 0.7152 * Detail::computeC(green) + 0.0722 * Detail::computeC(blue);
125  return Color(L > 0.179 ? 0 : 1);
126  }
127 
128  Color& setAlpha(double alpha_) { return *this *= alpha_; }
129 
130  [[nodiscard]] Color setAlpha(double alpha_) const { return Color(*this).setAlpha(alpha_); }
131 };
132 
133 inline Color mix(const Color& a, const Color& b, double alpha) { return a * alpha + b * (1.0 - alpha); }
Color::setAlpha
Color setAlpha(double alpha_) const
Definition: color.hh:130
byteFromDouble
uint8_t byteFromDouble(double d)
Definition: color.hh:21
Color::Color
Color(double gray, double alpha_=1.0)
Definition: color.hh:58
Color::setColor
void setColor(cairo_t *cr) const
Definition: color.hh:117
Color::operator+=
Color & operator+=(const Color &rhs)
Definition: color.hh:66
shortFromDouble
uint16_t shortFromDouble(double d)
Definition: color.hh:23
Color::alpha
double alpha
Definition: color.hh:39
Color::blue
double blue
Definition: color.hh:42
Color::Color
Color()=default
mix
Color mix(const Color &a, const Color &b, double alpha)
Definition: color.hh:133
Color::getARGB32
uint32_t getARGB32() const
Definition: color.hh:112
Color::red
double red
Definition: color.hh:40
Color::getGdkColor
GdkColor getGdkColor() const
Definition: color.hh:119
doubleFromByte
double doubleFromByte(uint8_t b)
Definition: color.hh:22
Color::getRGB24
uint32_t getRGB24() const
Definition: color.hh:107
Color::getHex
std::string getHex() const
Definition: color.hh:93
Detail::computeC
double computeC(double c)
Definition: color.hh:28
Color::operator*=
Color & operator*=(double d)
Definition: color.hh:84
b
static void b(const B::Ptr &)
Definition: gtkhelper-tests.cc:32
Detail
Definition: async-deleter.hh:12
Color::Color
Color(double red_, double green_, double blue_, double alpha_=1.0)
Definition: color.hh:49
Color::getContrastingBlackOrWhite
Color getContrastingBlackOrWhite() const
Definition: color.hh:121
Color::setAlpha
Color & setAlpha(double alpha_)
Definition: color.hh:128
Color
Definition: color.hh:34
Color::green
double green
Definition: color.hh:41
Color::operator/=
Color & operator/=(double d)
Definition: color.hh:75