Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
components.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
/*
5 * Authors: see git history
6 *
7 * Copyright (C) 2023 Authors
8 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
9 */
10
11#include "components.h"
12
13#include <algorithm>
14#include <cmath>
15#include <libintl.h> // avoid glib include
16#include <map>
17// #include <utility>
18#include <glib/gi18n.h>
19#include <glibmm/value.h>
20
21#include "enum.h"
22
24
25static const std::vector<Components> get_color_spaces() {
26
27static const std::vector<Components> color_spaces = {
28 {
30 {
31 { "r", _("_R"), _("Red"), Unit::EightBit },
32 { "g", _("_G"), _("Green"), Unit::EightBit },
33 { "b", _("_B"), _("Blue"), Unit::EightBit }
34 }
35 },
36 {
38 {
39 { "r", _("<sub>l</sub>_R"), _("Linear Red"), Unit::EightBit },
40 { "g", _("<sub>l</sub>_G"), _("Linear Green"), Unit::EightBit },
41 { "b", _("<sub>l</sub>_B"), _("Linear Blue"), Unit::EightBit }
42 }
43 },
44 {
46 {
47 { "h", _("_H"), _("Hue"), Unit::Degree },
48 { "s", _("_S"), _("Saturation"), Unit::Percent },
49 { "l", _("_L"), _("Lightness"), Unit::Percent }
50 }
51 },
52 {
54 {
55 { "h", _("_H"), _("Hue"), Unit::Degree },
56 { "s", _("_S"), _("Saturation"), Unit::Percent },
57 { "v", _("_V"), _("Value"), Unit::Percent }
58 }
59 },
60 {
62 {
63 { "c", _("_C"), C_("CMYK", "Cyan"), Unit::Percent },
64 { "m", _("_M"), C_("CMYK", "Magenta"), Unit::Percent },
65 { "y", _("_Y"), C_("CMYK", "Yellow"), Unit::Percent },
66 { "k", _("_K"), C_("CMYK", "Black"), Unit::Percent }
67 }
68 },
69 {
71 {
72 { "c", _("_C"), C_("CMYK", "Cyan"), Unit::Percent },
73 { "m", _("_M"), C_("CMYK", "Magenta"), Unit::Percent },
74 { "y", _("_Y"), C_("CMYK", "Yellow"), Unit::Percent },
75 }
76 },
77 {
79 {
80 { "h", _("_H*"), _("Hue"), Unit::Degree },
81 { "s", _("_S*"), _("Saturation"), Unit::Percent },
82 { "l", _("_L*"), _("Lightness"), Unit::Percent }
83 }
84 },
85 {
87 {
88 { "h", _("_H<sub>ok</sub>"), _("Hue"), Unit::Degree },
89 { "s", _("_S<sub>ok</sub>"), _("Saturation"), Unit::Percent },
90 { "l", _("_L<sub>ok</sub>"), _("Lightness"), Unit::Percent }
91 }
92 },
93 {
95 {
96 { "h", _("_H<sub>ok</sub>"), _("Hue"), Unit::Degree },
97 { "s", _("_S<sub>ok</sub>"), _("Saturation"), Unit::Percent },
98 { "v", _("_V<sub>ok</sub>"), _("Value"), Unit::Percent }
99 }
100 },
101 {
103 {
104 { "l", _("_L"), _("Luminance"), Unit::EightBit },
105 { "c", _("_C"), _("Chroma"), Unit::EightBit },
106 { "h", _("_H"), _("Hue"), Unit::Degree },
107 }
108 },
109 {
111 {
112 { "l", _("_L"), _("Luminance"), Unit::Percent },
113 { "u", _("_U"), _("Chroma U"), Unit::Percent },
114 { "v", _("_V"), _("Chroma V"), Unit::Percent },
115 }
116 },
117 {
119 {
120 { "l", _("_L<sub>ok</sub>"), _("Lightness"), Unit::Percent },
121 { "a", _("_A<sub>ok</sub>"), _("Component A"), Unit::Percent },
122 { "b", _("_B<sub>ok</sub>"), _("Component B"), Unit::Percent }
123 }
124 },
125 {
127 {
128 { "l", _("_L<sub>ok</sub>"), _("Lightness"), Unit::Percent },
129 { "c", _("_C<sub>ok</sub>"), _("Chroma"), Unit::Chroma40 }, // 100% is 0.4
130 { "h", _("_H<sub>ok</sub>"), _("Hue"), Unit::Degree }
131 }
132 },
133 {
135 {
136 { "l", _("_L"), _("Lightness"), Unit::Percent },
137 { "a", _("_A"), _("Component A"), Unit::EightBit },
138 { "b", _("_B"), _("Component B"), Unit::EightBit }
139 }
140 },
141 {
143 {
144 { "y", _("_Y"), _("Y"), Unit::EightBit },
145 { "cb", _("C_r"), _("Cb"), Unit::EightBit },
146 { "cr", _("C_b"), _("Cr"), Unit::EightBit }
147 }
148 },
149 {
151 {
152 { "x", "_X", "X", Unit::EightBit },
153 { "y", "_Y", "Y", Unit::EightBit },
154 { "z", "_Z", "Z", Unit::EightBit }
155 }
156 },
157 {
159 {
160 { "y1", "_Y", "Y", Unit::EightBit },
161 { "x", "_x", "x", Unit::EightBit },
162 { "y2", "y", "y", Unit::EightBit }
163 }
164 },
165 {
167 {
168 { "gray", _("G"), _("Gray"), Unit::Linear1024 }
169 }
170 }
171};
172 return color_spaces;
173}
174
175
176Component::Component(Type type, unsigned int index, std::string id, std::string name, std::string tip, Unit unit)
177 : type(type)
178 , index(index)
179 , id(std::move(id))
180 , name(std::move(name))
181 , tip(std::move(tip))
182 , unit(unit) {
183
184 switch (unit) {
185 case Unit::EightBit:
186 scale = 255;
187 break;
188 case Unit::Degree:
189 scale = 360;
190 break;
191 case Unit::Percent:
192 scale = 100;
193 break;
194 case Unit::Linear1024:
195 scale = 1024;
196 break;
197 case Unit::Chroma40:
198 scale = 40;
199 break;
200 default:
201 throw std::logic_error("Missing case statement in Component ctor.");
202 }
203}
204
205Component::Component(std::string id, std::string name, std::string tip, Unit unit)
206 : Component(Type::NONE, -1, id, name, tip, unit)
207{}
208
212double Component::normalize(double value) const
213{
214 if (unit == Unit::Degree && (value < 0.0 || value > 1.0)) {
215 return value - std::floor(value);
216 }
217 return std::clamp(value, 0.0, 1.0);
218}
219
220void Components::add(std::string id, std::string name, std::string tip, Unit unit)
221{
222 _components.emplace_back(_type, _components.size(), std::move(id), std::move(name), std::move(tip), unit);
223}
224
225std::map<Type, Components> _build(bool alpha)
226{
227 std::map<Type, Components> sets;
228 for (auto& components : get_color_spaces()) {
229 unsigned int index = 0;
230 for (auto& component : components.getAll()) {
231 // patch components
232 auto& rw = const_cast<Component&>(component);
233 rw.type = components.getType();
234 rw.index = index++;
235 }
236 sets[components.getType()] = components;
237 }
238
239 if (alpha) {
240 for (auto &[key, val] : sets) {
241 // alpha component with unique ID, so it doesn't clash with "a" in Lab
242 val.add("alpha", C_("Transparency (alpha)", "_A"), _("Alpha"), Unit::Percent);
243 }
244 }
245 return sets;
246}
247
248Components const &Components::get(Type space, bool alpha)
249{
250 static std::map<Type, Components> sets_no_alpha = _build(false);
251 static std::map<Type, Components> sets_with_alpha = _build(true);
252
253 auto &lookup_set = alpha ? sets_with_alpha : sets_no_alpha;
254 if (auto search = lookup_set.find(space); search != lookup_set.end()) {
255 return search->second;
256 }
257 return lookup_set[Type::NONE];
258}
259
261 return _wheel_type;
262}
263
264} // namespace Inkscape::Colors::Space
void add(std::string id, std::string name, std::string tip, Unit unit=Unit::EightBit)
std::vector< Component > _components
Definition components.h:93
static Components const & get(Type type, bool alpha=false)
static const std::vector< Components > get_color_spaces()
std::map< Type, Components > _build(bool alpha)
STL namespace.
static cairo_user_data_key_t key
Component(Type type, unsigned int index, std::string id, std::string name, std::string tip, Unit unit=Unit::EightBit)
double normalize(double value) const
Clamp the value to between 0.0 and 1.0, except for hue which is wrapped around.
int index
Glib::ustring name
Definition toolbars.cpp:55