Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
hsv.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
/*
4 * Authors: see git history
5 *
6 * Copyright (C) 2023 Authors
7 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
8 */
9
10#include "hsv.h"
11
12#include <cmath>
13
14#include "colors/color.h"
15#include "colors/printer.h"
16
18
22void HSV::spaceToProfile(std::vector<double> &output) const
23{
24 double v = output[2];
25 double d = output[0] * 5.99999999;
26 double f = d - std::floor(d);
27 double w = v * (1.0 - output[1]);
28 double q = v * (1.0 - (output[1] * f));
29 double t = v * (1.0 - (output[1] * (1.0 - f)));
30
31 if (d < 1.0) {
32 output[0] = v;
33 output[1] = t;
34 output[2] = w;
35 } else if (d < 2.0) {
36 output[0] = q;
37 output[1] = v;
38 output[2] = w;
39 } else if (d < 3.0) {
40 output[0] = w;
41 output[1] = v;
42 output[2] = t;
43 } else if (d < 4.0) {
44 output[0] = w;
45 output[1] = q;
46 output[2] = v;
47 } else if (d < 5.0) {
48 output[0] = t;
49 output[1] = w;
50 output[2] = v;
51 } else {
52 output[0] = v;
53 output[1] = w;
54 output[2] = q;
55 }
56}
57
61void HSV::profileToSpace(std::vector<double> &output) const
62{
63 double r = output[0];
64 double g = output[1];
65 double b = output[2];
66
67 double max = std::max(std::max(r, g), b);
68 double min = std::min(std::min(r, g), b);
69 double delta = max - min;
70
71 output[2] = max;
72 output[1] = max > 0 ? delta / max : 0.0;
73
74 if (output[1] != 0.0) {
75 if (r == max) {
76 output[0] = (g - b) / delta;
77 } else if (g == max) {
78 output[0] = 2.0 + (b - r) / delta;
79 } else {
80 output[0] = 4.0 + (r - g) / delta;
81 }
82 output[0] = output[0] / 6.0;
83 if (output[0] < 0)
84 output[0] += 1.0;
85 } else
86 output[0] = 0.0;
87}
88
92bool HSV::fromHwbParser::parse(std::istringstream &ss, std::vector<double> &output) const
93{
94 if (HueParser::parse(ss, output)) {
95 // See https://en.wikipedia.org/wiki/HWB_color_model#Converting_to_and_from_HSV
96 auto scale = output[1] + output[2];
97 if (scale > 1.0) {
98 output[1] /= scale;
99 output[2] /= scale;
100 }
101 output[1] = output[2] == 1.0 ? 0.0 : (1.0 - (output[1] / (1.0 - output[2])));
102 output[2] = 1.0 - output[2];
103 return true;
104 }
105 return false;
106}
107
114std::string HSV::toString(std::vector<double> const &values, bool opacity) const
115{
116 auto oo = CssLegacyPrinter(3, "hwb", opacity && values.size() == 4);
117 // First entry is Hue, which is in degrees, white and black are dirived
118 return oo << (int)(values[0] * 360) // Hue, degrees, 0..360
119 << (1.0 - values[1]) * values[2] // White
120 << 1.0 - values[2] // Black
121 << values.back(); // Opacity
122}
123
124}; // namespace Inkscape::Colors::Space
double scale
Definition aa.cpp:228
bool parse(std::istringstream &ss, std::vector< double > &output) const override
Definition parser.cpp:151
bool parse(std::istringstream &input, std::vector< double > &output) const override
Parse the hwb css string and convert to hsv inline, if it exists in the input string stream.
Definition hsv.cpp:92
std::string toString(std::vector< double > const &values, bool opacity) const override
Print the HSV color to a CSS hwb() string.
Definition hsv.cpp:114
void spaceToProfile(std::vector< double > &output) const override
Convert the HSV color into sRGB components used in the sRGB icc profile.
Definition hsv.cpp:22
void profileToSpace(std::vector< double > &output) const override
Convert from sRGB icc values to HSV values.
Definition hsv.cpp:61
const double w
Definition conic-4.cpp:19
int delta