mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-01 10:13:22 +00:00
Add HSL color selection (related to #707)
This commit is contained in:
parent
c297031152
commit
29a49ad7fa
@ -50,9 +50,11 @@
|
|||||||
<value id="RGB" value="4" />
|
<value id="RGB" value="4" />
|
||||||
<value id="HSVA" value="5" />
|
<value id="HSVA" value="5" />
|
||||||
<value id="HSV" value="6" />
|
<value id="HSV" value="6" />
|
||||||
<value id="GRAYA" value="7" />
|
<value id="HSLA" value="7" />
|
||||||
<value id="GRAY" value="8" />
|
<value id="HSL" value="8" />
|
||||||
<value id="INDEX" value="9" />
|
<value id="GRAYA" value="9" />
|
||||||
|
<value id="GRAY" value="10" />
|
||||||
|
<value id="INDEX" value="11" />
|
||||||
</enum>
|
</enum>
|
||||||
<enum id="EyedropperSample">
|
<enum id="EyedropperSample">
|
||||||
<value id="ALL_LAYERS" value="0" />
|
<value id="ALL_LAYERS" value="0" />
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -12,11 +12,12 @@
|
|||||||
|
|
||||||
#include "app/color_utils.h"
|
#include "app/color_utils.h"
|
||||||
#include "app/modules/palettes.h"
|
#include "app/modules/palettes.h"
|
||||||
#include "gfx/hsv.h"
|
|
||||||
#include "gfx/rgb.h"
|
|
||||||
#include "doc/image.h"
|
#include "doc/image.h"
|
||||||
#include "doc/palette.h"
|
#include "doc/palette.h"
|
||||||
#include "doc/primitives.h"
|
#include "doc/primitives.h"
|
||||||
|
#include "gfx/hsl.h"
|
||||||
|
#include "gfx/hsv.h"
|
||||||
|
#include "gfx/rgb.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@ -56,6 +57,17 @@ Color Color::fromHsv(double h, double s, double v, int a)
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
Color Color::fromHsl(double h, double s, double l, int a)
|
||||||
|
{
|
||||||
|
Color color(Color::HslType);
|
||||||
|
color.m_value.hsl.h = h;
|
||||||
|
color.m_value.hsl.s = s;
|
||||||
|
color.m_value.hsl.l = l;
|
||||||
|
color.m_value.hsl.a = a;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Color Color::fromGray(int g, int a)
|
Color Color::fromGray(int g, int a)
|
||||||
{
|
{
|
||||||
@ -123,6 +135,7 @@ Color Color::fromString(const std::string& str)
|
|||||||
if (str != "mask") {
|
if (str != "mask") {
|
||||||
if (str.find("rgb{") == 0 ||
|
if (str.find("rgb{") == 0 ||
|
||||||
str.find("hsv{") == 0 ||
|
str.find("hsv{") == 0 ||
|
||||||
|
str.find("hsl{") == 0 ||
|
||||||
str.find("gray{") == 0) {
|
str.find("gray{") == 0) {
|
||||||
int c = 0;
|
int c = 0;
|
||||||
double table[4] = { 0.0, 0.0, 0.0, 255.0 };
|
double table[4] = { 0.0, 0.0, 0.0, 255.0 };
|
||||||
@ -139,8 +152,16 @@ Color Color::fromString(const std::string& str)
|
|||||||
|
|
||||||
if (str[0] == 'r')
|
if (str[0] == 'r')
|
||||||
color = Color::fromRgb(int(table[0]), int(table[1]), int(table[2]), int(table[3]));
|
color = Color::fromRgb(int(table[0]), int(table[1]), int(table[2]), int(table[3]));
|
||||||
else if (str[0] == 'h')
|
else if (str[0] == 'h' && str[1] == 's' && str[2] == 'v')
|
||||||
color = Color::fromHsv(table[0], table[1], table[2], int(table[3]));
|
color = Color::fromHsv(table[0],
|
||||||
|
table[1] / 100.0,
|
||||||
|
table[2] / 100.0,
|
||||||
|
int(table[3]));
|
||||||
|
else if (str[0] == 'h' && str[1] == 's' && str[2] == 'l')
|
||||||
|
color = Color::fromHsl(table[0],
|
||||||
|
table[1] / 100.0,
|
||||||
|
table[2] / 100.0,
|
||||||
|
int(table[3]));
|
||||||
else if (str[0] == 'g')
|
else if (str[0] == 'g')
|
||||||
color = Color::fromGray(int(table[0]), (c >= 2 ? int(table[1]): 255));
|
color = Color::fromGray(int(table[0]), (c >= 2 ? int(table[1]): 255));
|
||||||
}
|
}
|
||||||
@ -175,11 +196,21 @@ std::string Color::toString() const
|
|||||||
<< std::setprecision(2)
|
<< std::setprecision(2)
|
||||||
<< std::fixed
|
<< std::fixed
|
||||||
<< m_value.hsv.h << ","
|
<< m_value.hsv.h << ","
|
||||||
<< m_value.hsv.s << ","
|
<< MID(0.0, m_value.hsv.s*100.0, 100.0) << ","
|
||||||
<< m_value.hsv.v << ","
|
<< MID(0.0, m_value.hsv.v*100.0, 100.0) << ","
|
||||||
<< m_value.hsv.a << "}";
|
<< m_value.hsv.a << "}";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
result << "hsl{"
|
||||||
|
<< std::setprecision(2)
|
||||||
|
<< std::fixed
|
||||||
|
<< m_value.hsl.h << ","
|
||||||
|
<< MID(0.0, m_value.hsl.s*100.0, 100.0) << ","
|
||||||
|
<< MID(0.0, m_value.hsl.l*100.0, 100.0) << ","
|
||||||
|
<< m_value.hsl.a << "}";
|
||||||
|
break;
|
||||||
|
|
||||||
case Color::GrayType:
|
case Color::GrayType:
|
||||||
result << "gray{"
|
result << "gray{"
|
||||||
<< m_value.gray.g << ","
|
<< m_value.gray.g << ","
|
||||||
@ -227,10 +258,30 @@ std::string Color::toHumanReadableString(PixelFormat pixelFormat, HumanReadableS
|
|||||||
result << "Gray " << getGray();
|
result << "Gray " << getGray();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result << "HSB "
|
result << "HSV "
|
||||||
<< int(m_value.hsv.h) << "\xc2\xb0 "
|
<< int(m_value.hsv.h) << "\xc2\xb0 "
|
||||||
<< int(m_value.hsv.s) << "% "
|
<< MID(0, int(m_value.hsv.s*100.0), 100) << "% "
|
||||||
<< int(m_value.hsv.v) << "%";
|
<< MID(0, int(m_value.hsv.v*100.0), 100) << "%";
|
||||||
|
|
||||||
|
if (pixelFormat == IMAGE_INDEXED)
|
||||||
|
result << " Index " << color_utils::color_for_image(*this, pixelFormat);
|
||||||
|
|
||||||
|
result << " (RGB "
|
||||||
|
<< getRed() << " "
|
||||||
|
<< getGreen() << " "
|
||||||
|
<< getBlue() << ")";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
if (pixelFormat == IMAGE_GRAYSCALE) {
|
||||||
|
result << "Gray " << getGray();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result << "HSL "
|
||||||
|
<< int(m_value.hsl.h) << "\xc2\xb0 "
|
||||||
|
<< MID(0, int(m_value.hsl.s*100.0), 100) << "% "
|
||||||
|
<< MID(0, int(m_value.hsl.l*100.0), 100) << "%";
|
||||||
|
|
||||||
if (pixelFormat == IMAGE_INDEXED)
|
if (pixelFormat == IMAGE_INDEXED)
|
||||||
result << " Index " << color_utils::color_for_image(*this, pixelFormat);
|
result << " Index " << color_utils::color_for_image(*this, pixelFormat);
|
||||||
@ -299,8 +350,19 @@ std::string Color::toHumanReadableString(PixelFormat pixelFormat, HumanReadableS
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result << int(m_value.hsv.h) << "\xc2\xb0"
|
result << int(m_value.hsv.h) << "\xc2\xb0"
|
||||||
<< int(m_value.hsv.s) << ","
|
<< MID(0, int(m_value.hsv.s*100.0), 100) << ","
|
||||||
<< int(m_value.hsv.v);
|
<< MID(0, int(m_value.hsv.v*100.0), 100);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
if (pixelFormat == IMAGE_GRAYSCALE) {
|
||||||
|
result << "Gry-" << getGray();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result << int(m_value.hsl.h) << "\xc2\xb0"
|
||||||
|
<< MID(0, int(m_value.hsl.s*100.0), 100) << ","
|
||||||
|
<< MID(0, int(m_value.hsl.l*100.0), 100);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -341,10 +403,17 @@ bool Color::operator==(const Color& other) const
|
|||||||
case Color::HsvType:
|
case Color::HsvType:
|
||||||
return
|
return
|
||||||
(std::fabs(m_value.hsv.h - other.m_value.hsv.h) < 0.001) &&
|
(std::fabs(m_value.hsv.h - other.m_value.hsv.h) < 0.001) &&
|
||||||
(std::fabs(m_value.hsv.s - other.m_value.hsv.s) < 0.001) &&
|
(std::fabs(m_value.hsv.s - other.m_value.hsv.s) < 0.00001) &&
|
||||||
(std::fabs(m_value.hsv.v - other.m_value.hsv.v) < 0.001) &&
|
(std::fabs(m_value.hsv.v - other.m_value.hsv.v) < 0.00001) &&
|
||||||
(m_value.hsv.a == other.m_value.hsv.a);
|
(m_value.hsv.a == other.m_value.hsv.a);
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
return
|
||||||
|
(std::fabs(m_value.hsl.h - other.m_value.hsl.h) < 0.001) &&
|
||||||
|
(std::fabs(m_value.hsl.s - other.m_value.hsl.s) < 0.00001) &&
|
||||||
|
(std::fabs(m_value.hsl.l - other.m_value.hsl.l) < 0.00001) &&
|
||||||
|
(m_value.hsl.a == other.m_value.hsl.a);
|
||||||
|
|
||||||
case Color::GrayType:
|
case Color::GrayType:
|
||||||
return
|
return
|
||||||
m_value.gray.g == other.m_value.gray.g &&
|
m_value.gray.g == other.m_value.gray.g &&
|
||||||
@ -387,8 +456,13 @@ int Color::getRed() const
|
|||||||
|
|
||||||
case Color::HsvType:
|
case Color::HsvType:
|
||||||
return Rgb(Hsv(m_value.hsv.h,
|
return Rgb(Hsv(m_value.hsv.h,
|
||||||
m_value.hsv.s / 100.0,
|
m_value.hsv.s,
|
||||||
m_value.hsv.v / 100.0)).red();
|
m_value.hsv.v)).red();
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
return Rgb(Hsl(m_value.hsl.h,
|
||||||
|
m_value.hsl.s,
|
||||||
|
m_value.hsl.l)).red();
|
||||||
|
|
||||||
case Color::GrayType:
|
case Color::GrayType:
|
||||||
return m_value.gray.g;
|
return m_value.gray.g;
|
||||||
@ -419,8 +493,13 @@ int Color::getGreen() const
|
|||||||
|
|
||||||
case Color::HsvType:
|
case Color::HsvType:
|
||||||
return Rgb(Hsv(m_value.hsv.h,
|
return Rgb(Hsv(m_value.hsv.h,
|
||||||
m_value.hsv.s / 100.0,
|
m_value.hsv.s,
|
||||||
m_value.hsv.v / 100.0)).green();
|
m_value.hsv.v)).green();
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
return Rgb(Hsl(m_value.hsl.h,
|
||||||
|
m_value.hsl.s,
|
||||||
|
m_value.hsl.l)).green();
|
||||||
|
|
||||||
case Color::GrayType:
|
case Color::GrayType:
|
||||||
return m_value.gray.g;
|
return m_value.gray.g;
|
||||||
@ -451,8 +530,13 @@ int Color::getBlue() const
|
|||||||
|
|
||||||
case Color::HsvType:
|
case Color::HsvType:
|
||||||
return Rgb(Hsv(m_value.hsv.h,
|
return Rgb(Hsv(m_value.hsv.h,
|
||||||
m_value.hsv.s / 100.0,
|
m_value.hsv.s,
|
||||||
m_value.hsv.v / 100.0)).blue();
|
m_value.hsv.v)).blue();
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
return Rgb(Hsl(m_value.hsl.h,
|
||||||
|
m_value.hsl.s,
|
||||||
|
m_value.hsl.l)).blue();
|
||||||
|
|
||||||
case Color::GrayType:
|
case Color::GrayType:
|
||||||
return m_value.gray.g;
|
return m_value.gray.g;
|
||||||
@ -471,7 +555,7 @@ int Color::getBlue() const
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Color::getHue() const
|
double Color::getHsvHue() const
|
||||||
{
|
{
|
||||||
switch (getType()) {
|
switch (getType()) {
|
||||||
|
|
||||||
@ -486,6 +570,9 @@ double Color::getHue() const
|
|||||||
case Color::HsvType:
|
case Color::HsvType:
|
||||||
return m_value.hsv.h;
|
return m_value.hsv.h;
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
return m_value.hsl.h;
|
||||||
|
|
||||||
case Color::GrayType:
|
case Color::GrayType:
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
@ -507,7 +594,7 @@ double Color::getHue() const
|
|||||||
return -1.0;
|
return -1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Color::getSaturation() const
|
double Color::getHsvSaturation() const
|
||||||
{
|
{
|
||||||
switch (getType()) {
|
switch (getType()) {
|
||||||
|
|
||||||
@ -517,11 +604,16 @@ double Color::getSaturation() const
|
|||||||
case Color::RgbType:
|
case Color::RgbType:
|
||||||
return Hsv(Rgb(m_value.rgb.r,
|
return Hsv(Rgb(m_value.rgb.r,
|
||||||
m_value.rgb.g,
|
m_value.rgb.g,
|
||||||
m_value.rgb.b)).saturation() * 100.0;
|
m_value.rgb.b)).saturation();
|
||||||
|
|
||||||
case Color::HsvType:
|
case Color::HsvType:
|
||||||
return m_value.hsv.s;
|
return m_value.hsv.s;
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
return Hsv(Rgb(getRed(),
|
||||||
|
getGreen(),
|
||||||
|
getBlue())).saturation();
|
||||||
|
|
||||||
case Color::GrayType:
|
case Color::GrayType:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -531,7 +623,7 @@ double Color::getSaturation() const
|
|||||||
uint32_t c = get_current_palette()->getEntry(i);
|
uint32_t c = get_current_palette()->getEntry(i);
|
||||||
return Hsv(Rgb(rgba_getr(c),
|
return Hsv(Rgb(rgba_getr(c),
|
||||||
rgba_getg(c),
|
rgba_getg(c),
|
||||||
rgba_getb(c))).saturation() * 100.0;
|
rgba_getb(c))).saturation();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 0.0;
|
return 0.0;
|
||||||
@ -543,7 +635,7 @@ double Color::getSaturation() const
|
|||||||
return -1.0;
|
return -1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Color::getValue() const
|
double Color::getHsvValue() const
|
||||||
{
|
{
|
||||||
switch (getType()) {
|
switch (getType()) {
|
||||||
|
|
||||||
@ -553,13 +645,18 @@ double Color::getValue() const
|
|||||||
case Color::RgbType:
|
case Color::RgbType:
|
||||||
return Hsv(Rgb(m_value.rgb.r,
|
return Hsv(Rgb(m_value.rgb.r,
|
||||||
m_value.rgb.g,
|
m_value.rgb.g,
|
||||||
m_value.rgb.b)).value() * 100.0;
|
m_value.rgb.b)).value();
|
||||||
|
|
||||||
case Color::HsvType:
|
case Color::HsvType:
|
||||||
return m_value.hsv.v;
|
return m_value.hsv.v;
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
return Hsv(Rgb(getRed(),
|
||||||
|
getGreen(),
|
||||||
|
getBlue())).value();
|
||||||
|
|
||||||
case Color::GrayType:
|
case Color::GrayType:
|
||||||
return 100.0 * m_value.gray.g / 255.0;
|
return m_value.gray.g / 255.0;
|
||||||
|
|
||||||
case Color::IndexType: {
|
case Color::IndexType: {
|
||||||
int i = m_value.index;
|
int i = m_value.index;
|
||||||
@ -567,7 +664,128 @@ double Color::getValue() const
|
|||||||
uint32_t c = get_current_palette()->getEntry(i);
|
uint32_t c = get_current_palette()->getEntry(i);
|
||||||
return Hsv(Rgb(rgba_getr(c),
|
return Hsv(Rgb(rgba_getr(c),
|
||||||
rgba_getg(c),
|
rgba_getg(c),
|
||||||
rgba_getb(c))).value() * 100.0;
|
rgba_getb(c))).value();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(false);
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Color::getHslHue() const
|
||||||
|
{
|
||||||
|
switch (getType()) {
|
||||||
|
|
||||||
|
case Color::MaskType:
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
case Color::RgbType:
|
||||||
|
return Hsl(Rgb(m_value.rgb.r,
|
||||||
|
m_value.rgb.g,
|
||||||
|
m_value.rgb.b)).hue();
|
||||||
|
|
||||||
|
case Color::HsvType:
|
||||||
|
return m_value.hsv.h;
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
return m_value.hsl.h;
|
||||||
|
|
||||||
|
case Color::GrayType:
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
case Color::IndexType: {
|
||||||
|
int i = m_value.index;
|
||||||
|
if (i >= 0 && i < get_current_palette()->size()) {
|
||||||
|
uint32_t c = get_current_palette()->getEntry(i);
|
||||||
|
return Hsl(Rgb(rgba_getr(c),
|
||||||
|
rgba_getg(c),
|
||||||
|
rgba_getb(c))).hue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(false);
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Color::getHslSaturation() const
|
||||||
|
{
|
||||||
|
switch (getType()) {
|
||||||
|
|
||||||
|
case Color::MaskType:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case Color::RgbType:
|
||||||
|
return Hsl(Rgb(m_value.rgb.r,
|
||||||
|
m_value.rgb.g,
|
||||||
|
m_value.rgb.b)).saturation();
|
||||||
|
|
||||||
|
case Color::HsvType:
|
||||||
|
return Hsl(Rgb(getRed(),
|
||||||
|
getGreen(),
|
||||||
|
getBlue())).saturation();
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
return m_value.hsl.s;
|
||||||
|
|
||||||
|
case Color::GrayType:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case Color::IndexType: {
|
||||||
|
int i = m_value.index;
|
||||||
|
if (i >= 0 && i < get_current_palette()->size()) {
|
||||||
|
uint32_t c = get_current_palette()->getEntry(i);
|
||||||
|
return Hsl(Rgb(rgba_getr(c),
|
||||||
|
rgba_getg(c),
|
||||||
|
rgba_getb(c))).saturation();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(false);
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Color::getHslLightness() const
|
||||||
|
{
|
||||||
|
switch (getType()) {
|
||||||
|
|
||||||
|
case Color::MaskType:
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
case Color::RgbType:
|
||||||
|
return Hsl(Rgb(m_value.rgb.r,
|
||||||
|
m_value.rgb.g,
|
||||||
|
m_value.rgb.b)).lightness();
|
||||||
|
|
||||||
|
case Color::HsvType:
|
||||||
|
return Hsl(Rgb(getRed(),
|
||||||
|
getGreen(),
|
||||||
|
getBlue())).lightness();
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
return m_value.hsl.l;
|
||||||
|
|
||||||
|
case Color::GrayType:
|
||||||
|
return m_value.gray.g / 255.0;
|
||||||
|
|
||||||
|
case Color::IndexType: {
|
||||||
|
int i = m_value.index;
|
||||||
|
if (i >= 0 && i < get_current_palette()->size()) {
|
||||||
|
uint32_t c = get_current_palette()->getEntry(i);
|
||||||
|
return Hsl(Rgb(rgba_getr(c),
|
||||||
|
rgba_getg(c),
|
||||||
|
rgba_getb(c))).lightness();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 0.0;
|
return 0.0;
|
||||||
@ -587,12 +805,17 @@ int Color::getGray() const
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case Color::RgbType:
|
case Color::RgbType:
|
||||||
return int(255.0 * Hsv(Rgb(m_value.rgb.r,
|
return int(255.0 * Hsl(Rgb(m_value.rgb.r,
|
||||||
m_value.rgb.g,
|
m_value.rgb.g,
|
||||||
m_value.rgb.b)).value());
|
m_value.rgb.b)).lightness());
|
||||||
|
|
||||||
case Color::HsvType:
|
case Color::HsvType:
|
||||||
return int(255.0 * m_value.hsv.v / 100.0);
|
return int(255.0 * Hsl(Rgb(getRed(),
|
||||||
|
getGreen(),
|
||||||
|
getBlue())).lightness());
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
return int(255.0 * m_value.hsl.l);
|
||||||
|
|
||||||
case Color::GrayType:
|
case Color::GrayType:
|
||||||
return m_value.gray.g;
|
return m_value.gray.g;
|
||||||
@ -601,9 +824,9 @@ int Color::getGray() const
|
|||||||
int i = m_value.index;
|
int i = m_value.index;
|
||||||
if (i >= 0 && i < get_current_palette()->size()) {
|
if (i >= 0 && i < get_current_palette()->size()) {
|
||||||
uint32_t c = get_current_palette()->getEntry(i);
|
uint32_t c = get_current_palette()->getEntry(i);
|
||||||
return int(255.0 * Hsv(Rgb(rgba_getr(c),
|
return int(255.0 * Hsl(Rgb(rgba_getr(c),
|
||||||
rgba_getg(c),
|
rgba_getg(c),
|
||||||
rgba_getb(c))).value());
|
rgba_getb(c))).lightness());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
@ -624,6 +847,7 @@ int Color::getIndex() const
|
|||||||
|
|
||||||
case Color::RgbType:
|
case Color::RgbType:
|
||||||
case Color::HsvType:
|
case Color::HsvType:
|
||||||
|
case Color::HslType:
|
||||||
case Color::GrayType: {
|
case Color::GrayType: {
|
||||||
int i = get_current_palette()->findExactMatch(getRed(), getGreen(), getBlue(), getAlpha(), -1);
|
int i = get_current_palette()->findExactMatch(getRed(), getGreen(), getBlue(), getAlpha(), -1);
|
||||||
if (i >= 0)
|
if (i >= 0)
|
||||||
@ -654,6 +878,9 @@ int Color::getAlpha() const
|
|||||||
case Color::HsvType:
|
case Color::HsvType:
|
||||||
return m_value.hsv.a;
|
return m_value.hsv.a;
|
||||||
|
|
||||||
|
case Color::HslType:
|
||||||
|
return m_value.hsl.a;
|
||||||
|
|
||||||
case Color::GrayType:
|
case Color::GrayType:
|
||||||
return m_value.gray.a;
|
return m_value.gray.a;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -28,6 +28,7 @@ namespace app {
|
|||||||
MaskType,
|
MaskType,
|
||||||
RgbType,
|
RgbType,
|
||||||
HsvType,
|
HsvType,
|
||||||
|
HslType,
|
||||||
GrayType,
|
GrayType,
|
||||||
IndexType,
|
IndexType,
|
||||||
};
|
};
|
||||||
@ -42,7 +43,8 @@ namespace app {
|
|||||||
|
|
||||||
static Color fromMask();
|
static Color fromMask();
|
||||||
static Color fromRgb(int r, int g, int b, int a = 255);
|
static Color fromRgb(int r, int g, int b, int a = 255);
|
||||||
static Color fromHsv(double h, double s, double v, int a = 255); // h=[0,360], s=[0,100], v=[0,100]
|
static Color fromHsv(double h, double s, double v, int a = 255); // h=[0,360], s=[0,1], v=[0,1]
|
||||||
|
static Color fromHsl(double h, double s, double l, int a = 255); // h=[0,360], s=[0,1], v=[0,1]
|
||||||
static Color fromGray(int g, int a = 255);
|
static Color fromGray(int g, int a = 255);
|
||||||
static Color fromIndex(int index);
|
static Color fromIndex(int index);
|
||||||
|
|
||||||
@ -68,9 +70,12 @@ namespace app {
|
|||||||
int getRed() const;
|
int getRed() const;
|
||||||
int getGreen() const;
|
int getGreen() const;
|
||||||
int getBlue() const;
|
int getBlue() const;
|
||||||
double getHue() const;
|
double getHsvHue() const;
|
||||||
double getSaturation() const;
|
double getHsvSaturation() const;
|
||||||
double getValue() const;
|
double getHsvValue() const;
|
||||||
|
double getHslHue() const;
|
||||||
|
double getHslSaturation() const;
|
||||||
|
double getHslLightness() const;
|
||||||
int getGray() const;
|
int getGray() const;
|
||||||
int getIndex() const;
|
int getIndex() const;
|
||||||
int getAlpha() const;
|
int getAlpha() const;
|
||||||
@ -90,6 +95,10 @@ namespace app {
|
|||||||
double h, s, v;
|
double h, s, v;
|
||||||
int a;
|
int a;
|
||||||
} hsv;
|
} hsv;
|
||||||
|
struct {
|
||||||
|
double h, s, l;
|
||||||
|
int a;
|
||||||
|
} hsl;
|
||||||
struct {
|
struct {
|
||||||
int g, a;
|
int g, a;
|
||||||
} gray;
|
} gray;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -20,28 +20,37 @@ namespace app {
|
|||||||
|
|
||||||
TEST(Color, fromRgb)
|
TEST(Color, fromRgb)
|
||||||
{
|
{
|
||||||
EXPECT_EQ(32, Color::fromRgb(32, 16, 255).getRed());
|
EXPECT_EQ( 32, Color::fromRgb(32, 16, 255).getRed());
|
||||||
EXPECT_EQ(16, Color::fromRgb(32, 16, 255).getGreen());
|
EXPECT_EQ( 16, Color::fromRgb(32, 16, 255).getGreen());
|
||||||
EXPECT_EQ(255, Color::fromRgb(32, 16, 255).getBlue());
|
EXPECT_EQ(255, Color::fromRgb(32, 16, 255).getBlue());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Color, fromHsv)
|
TEST(Color, fromHsv)
|
||||||
{
|
{
|
||||||
EXPECT_EQ(60, Color::fromHsv(60, 5, 100).getHue());
|
EXPECT_EQ(60.0, Color::fromHsv(60, 0.05, 1.0).getHsvHue());
|
||||||
EXPECT_EQ(5, Color::fromHsv(60, 5, 100).getSaturation());
|
EXPECT_EQ(0.05, Color::fromHsv(60, 0.05, 1.0).getHsvSaturation());
|
||||||
EXPECT_EQ(100, Color::fromHsv(60, 5, 100).getValue());
|
EXPECT_EQ(1.00, Color::fromHsv(60, 0.05, 1.0).getHsvValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Color, fromHsl)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(60.0, Color::fromHsl(60, 0.05, 1.0).getHslHue());
|
||||||
|
EXPECT_EQ(0.05, Color::fromHsl(60, 0.05, 1.0).getHslSaturation());
|
||||||
|
EXPECT_EQ(1.00, Color::fromHsl(60, 0.05, 1.0).getHslLightness());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Color, fromString)
|
TEST(Color, fromString)
|
||||||
{
|
{
|
||||||
EXPECT_EQ(Color::fromRgb(0, 0, 0), Color::fromString("rgb{0,0.0,0}"));
|
EXPECT_EQ(Color::fromRgb(0, 0, 0), Color::fromString("rgb{0,0.0,0}"));
|
||||||
EXPECT_EQ(Color::fromRgb(32, 16, 255), Color::fromString("rgb{32,16,255}"));
|
EXPECT_EQ(Color::fromRgb(32, 16, 255), Color::fromString("rgb{32,16,255}"));
|
||||||
EXPECT_EQ(Color::fromHsv(32, 64, 99), Color::fromString("hsv{32,64,99}"));
|
EXPECT_EQ(Color::fromHsv(32, 0.64, 0.99), Color::fromString("hsv{32,64,99}"));
|
||||||
|
EXPECT_EQ(Color::fromHsl(32, 0.64, 0.99), Color::fromString("hsl{32,64,99}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Color, toString)
|
TEST(Color, toString)
|
||||||
{
|
{
|
||||||
EXPECT_EQ("rgb{0,0,0,255}", Color::fromRgb(0, 0, 0).toString());
|
EXPECT_EQ("rgb{0,0,0,255}", Color::fromRgb(0, 0, 0).toString());
|
||||||
EXPECT_EQ("rgb{32,16,255,255}", Color::fromRgb(32, 16, 255).toString());
|
EXPECT_EQ("rgb{32,16,255,255}", Color::fromRgb(32, 16, 255).toString());
|
||||||
EXPECT_EQ("hsv{32.00,64.00,99.00,255}", Color::fromHsv(32, 64, 99).toString());
|
EXPECT_EQ("hsv{32.00,64.00,99.00,255}", Color::fromHsv(32, 64/100.0, 99/100.0).toString());
|
||||||
|
EXPECT_EQ("hsl{32.00,64.00,99.00,255}", Color::fromHsl(32, 64/100.0, 99/100.0).toString());
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -48,6 +48,7 @@ gfx::Color color_utils::color_for_ui(const app::Color& color)
|
|||||||
|
|
||||||
case app::Color::RgbType:
|
case app::Color::RgbType:
|
||||||
case app::Color::HsvType:
|
case app::Color::HsvType:
|
||||||
|
case app::Color::HslType:
|
||||||
c = gfx::rgba(
|
c = gfx::rgba(
|
||||||
color.getRed(),
|
color.getRed(),
|
||||||
color.getGreen(),
|
color.getGreen(),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -90,9 +90,16 @@ void EyedropperCommand::pickSample(const doc::Site& site,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case app::Color::HsvType:
|
case app::Color::HsvType:
|
||||||
color = app::Color::fromHsv(color.getHue(),
|
color = app::Color::fromHsv(color.getHsvHue(),
|
||||||
color.getSaturation(),
|
color.getHsvSaturation(),
|
||||||
color.getValue(),
|
color.getHsvValue(),
|
||||||
|
picked.getAlpha());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case app::Color::HslType:
|
||||||
|
color = app::Color::fromHsl(color.getHslHue(),
|
||||||
|
color.getHslSaturation(),
|
||||||
|
color.getHslLightness(),
|
||||||
picked.getAlpha());
|
picked.getAlpha());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -123,16 +130,32 @@ void EyedropperCommand::pickSample(const doc::Site& site,
|
|||||||
if (picked.getType() == app::Color::HsvType)
|
if (picked.getType() == app::Color::HsvType)
|
||||||
color = picked;
|
color = picked;
|
||||||
else
|
else
|
||||||
color = app::Color::fromHsv(picked.getHue(),
|
color = app::Color::fromHsv(picked.getHsvHue(),
|
||||||
picked.getSaturation(),
|
picked.getHsvSaturation(),
|
||||||
picked.getValue(),
|
picked.getHsvValue(),
|
||||||
picked.getAlpha());
|
picked.getAlpha());
|
||||||
break;
|
break;
|
||||||
case app::gen::EyedropperChannel::HSV:
|
case app::gen::EyedropperChannel::HSV:
|
||||||
if (picked.getAlpha() > 0)
|
if (picked.getAlpha() > 0)
|
||||||
color = app::Color::fromHsv(picked.getHue(),
|
color = app::Color::fromHsv(picked.getHsvHue(),
|
||||||
picked.getSaturation(),
|
picked.getHsvSaturation(),
|
||||||
picked.getValue(),
|
picked.getHsvValue(),
|
||||||
|
color.getAlpha());
|
||||||
|
break;
|
||||||
|
case app::gen::EyedropperChannel::HSLA:
|
||||||
|
if (picked.getType() == app::Color::HslType)
|
||||||
|
color = picked;
|
||||||
|
else
|
||||||
|
color = app::Color::fromHsl(picked.getHslHue(),
|
||||||
|
picked.getHslSaturation(),
|
||||||
|
picked.getHslLightness(),
|
||||||
|
picked.getAlpha());
|
||||||
|
break;
|
||||||
|
case app::gen::EyedropperChannel::HSL:
|
||||||
|
if (picked.getAlpha() > 0)
|
||||||
|
color = app::Color::fromHsl(picked.getHslHue(),
|
||||||
|
picked.getHslSaturation(),
|
||||||
|
picked.getHslLightness(),
|
||||||
color.getAlpha());
|
color.getAlpha());
|
||||||
break;
|
break;
|
||||||
case app::gen::EyedropperChannel::GRAYA:
|
case app::gen::EyedropperChannel::GRAYA:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -39,6 +39,7 @@
|
|||||||
#include "doc/image.h"
|
#include "doc/image.h"
|
||||||
#include "doc/palette.h"
|
#include "doc/palette.h"
|
||||||
#include "doc/sprite.h"
|
#include "doc/sprite.h"
|
||||||
|
#include "gfx/hsl.h"
|
||||||
#include "gfx/hsv.h"
|
#include "gfx/hsv.h"
|
||||||
#include "gfx/rgb.h"
|
#include "gfx/rgb.h"
|
||||||
#include "gfx/size.h"
|
#include "gfx/size.h"
|
||||||
@ -54,7 +55,7 @@ namespace app {
|
|||||||
using namespace gfx;
|
using namespace gfx;
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
|
|
||||||
enum { RGB_MODE, HSV_MODE };
|
enum { RGB_MODE, HSV_MODE, HSL_MODE };
|
||||||
enum { ABS_MODE, REL_MODE };
|
enum { ABS_MODE, REL_MODE };
|
||||||
|
|
||||||
class PaletteEntryEditor : public Window {
|
class PaletteEntryEditor : public Window {
|
||||||
@ -97,6 +98,7 @@ private:
|
|||||||
Label m_entryLabel;
|
Label m_entryLabel;
|
||||||
RgbSliders m_rgbSliders;
|
RgbSliders m_rgbSliders;
|
||||||
HsvSliders m_hsvSliders;
|
HsvSliders m_hsvSliders;
|
||||||
|
HslSliders m_hslSliders;
|
||||||
|
|
||||||
// This variable is used to avoid updating the m_hexColorEntry text
|
// This variable is used to avoid updating the m_hexColorEntry text
|
||||||
// when the color change is generated from a
|
// when the color change is generated from a
|
||||||
@ -241,7 +243,7 @@ PaletteEntryEditor::PaletteEntryEditor()
|
|||||||
, m_vbox(VERTICAL)
|
, m_vbox(VERTICAL)
|
||||||
, m_topBox(HORIZONTAL)
|
, m_topBox(HORIZONTAL)
|
||||||
, m_bottomBox(HORIZONTAL)
|
, m_bottomBox(HORIZONTAL)
|
||||||
, m_colorType(2)
|
, m_colorType(3)
|
||||||
, m_changeMode(2)
|
, m_changeMode(2)
|
||||||
, m_entryLabel("")
|
, m_entryLabel("")
|
||||||
, m_disableHexUpdate(false)
|
, m_disableHexUpdate(false)
|
||||||
@ -252,7 +254,8 @@ PaletteEntryEditor::PaletteEntryEditor()
|
|||||||
, m_fromPalette(0, 0)
|
, m_fromPalette(0, 0)
|
||||||
{
|
{
|
||||||
m_colorType.addItem("RGB")->setFocusStop(false);
|
m_colorType.addItem("RGB")->setFocusStop(false);
|
||||||
m_colorType.addItem("HSB")->setFocusStop(false);
|
m_colorType.addItem("HSV")->setFocusStop(false);
|
||||||
|
m_colorType.addItem("HSL")->setFocusStop(false);
|
||||||
m_changeMode.addItem("Abs")->setFocusStop(false);
|
m_changeMode.addItem("Abs")->setFocusStop(false);
|
||||||
m_changeMode.addItem("Rel")->setFocusStop(false);
|
m_changeMode.addItem("Rel")->setFocusStop(false);
|
||||||
|
|
||||||
@ -273,6 +276,7 @@ PaletteEntryEditor::PaletteEntryEditor()
|
|||||||
m_vbox.addChild(&m_topBox);
|
m_vbox.addChild(&m_topBox);
|
||||||
m_vbox.addChild(&m_rgbSliders);
|
m_vbox.addChild(&m_rgbSliders);
|
||||||
m_vbox.addChild(&m_hsvSliders);
|
m_vbox.addChild(&m_hsvSliders);
|
||||||
|
m_vbox.addChild(&m_hslSliders);
|
||||||
m_vbox.addChild(&m_bottomBox);
|
m_vbox.addChild(&m_bottomBox);
|
||||||
addChild(&m_vbox);
|
addChild(&m_vbox);
|
||||||
|
|
||||||
@ -281,6 +285,7 @@ PaletteEntryEditor::PaletteEntryEditor()
|
|||||||
|
|
||||||
m_rgbSliders.ColorChange.connect(&PaletteEntryEditor::onColorSlidersChange, this);
|
m_rgbSliders.ColorChange.connect(&PaletteEntryEditor::onColorSlidersChange, this);
|
||||||
m_hsvSliders.ColorChange.connect(&PaletteEntryEditor::onColorSlidersChange, this);
|
m_hsvSliders.ColorChange.connect(&PaletteEntryEditor::onColorSlidersChange, this);
|
||||||
|
m_hslSliders.ColorChange.connect(&PaletteEntryEditor::onColorSlidersChange, this);
|
||||||
m_hexColorEntry.ColorChange.connect(&PaletteEntryEditor::onColorHexEntryChange, this);
|
m_hexColorEntry.ColorChange.connect(&PaletteEntryEditor::onColorHexEntryChange, this);
|
||||||
|
|
||||||
m_changeMode.setSelectedItem(ABS_MODE);
|
m_changeMode.setSelectedItem(ABS_MODE);
|
||||||
@ -309,6 +314,7 @@ void PaletteEntryEditor::setColor(const app::Color& color)
|
|||||||
{
|
{
|
||||||
m_rgbSliders.setColor(color);
|
m_rgbSliders.setColor(color);
|
||||||
m_hsvSliders.setColor(color);
|
m_hsvSliders.setColor(color);
|
||||||
|
m_hslSliders.setColor(color);
|
||||||
if (!m_disableHexUpdate)
|
if (!m_disableHexUpdate)
|
||||||
m_hexColorEntry.setColor(color);
|
m_hexColorEntry.setColor(color);
|
||||||
|
|
||||||
@ -455,6 +461,9 @@ void PaletteEntryEditor::onColorTypeClick()
|
|||||||
case HSV_MODE:
|
case HSV_MODE:
|
||||||
selectColorType(app::Color::HsvType);
|
selectColorType(app::Color::HsvType);
|
||||||
break;
|
break;
|
||||||
|
case HSL_MODE:
|
||||||
|
selectColorType(app::Color::HslType);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,10 +473,12 @@ void PaletteEntryEditor::onChangeModeClick()
|
|||||||
case ABS_MODE:
|
case ABS_MODE:
|
||||||
m_rgbSliders.setMode(ColorSliders::Absolute);
|
m_rgbSliders.setMode(ColorSliders::Absolute);
|
||||||
m_hsvSliders.setMode(ColorSliders::Absolute);
|
m_hsvSliders.setMode(ColorSliders::Absolute);
|
||||||
|
m_hslSliders.setMode(ColorSliders::Absolute);
|
||||||
break;
|
break;
|
||||||
case REL_MODE:
|
case REL_MODE:
|
||||||
m_rgbSliders.setMode(ColorSliders::Relative);
|
m_rgbSliders.setMode(ColorSliders::Relative);
|
||||||
m_hsvSliders.setMode(ColorSliders::Relative);
|
m_hsvSliders.setMode(ColorSliders::Relative);
|
||||||
|
m_hslSliders.setMode(ColorSliders::Relative);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,46 +552,86 @@ void PaletteEntryEditor::setAbsolutePaletteEntryChannel(ColorSliders::Channel ch
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case app::Color::HsvType:
|
case app::Color::HsvType: {
|
||||||
{
|
Hsv hsv;
|
||||||
Hsv hsv;
|
|
||||||
|
|
||||||
// Modify one entry
|
// Modify one entry
|
||||||
if (picksCount == 1) {
|
if (picksCount == 1) {
|
||||||
hsv.hue(color.getHue());
|
hsv.hue(color.getHsvHue());
|
||||||
hsv.saturation(double(color.getSaturation()) / 100.0);
|
hsv.saturation(color.getHsvSaturation());
|
||||||
hsv.value(double(color.getValue()) / 100.0);
|
hsv.value(color.getHsvValue());
|
||||||
a = color.getAlpha();
|
a = color.getAlpha();
|
||||||
}
|
|
||||||
// Modify one channel a set of entries
|
|
||||||
else {
|
|
||||||
// Convert RGB to HSV
|
|
||||||
hsv = Hsv(Rgb(r, g, b));
|
|
||||||
|
|
||||||
// Only modify the desired HSV channel
|
|
||||||
switch (channel) {
|
|
||||||
case ColorSliders::Hue:
|
|
||||||
hsv.hue(color.getHue());
|
|
||||||
break;
|
|
||||||
case ColorSliders::Saturation:
|
|
||||||
hsv.saturation(double(color.getSaturation()) / 100.0);
|
|
||||||
break;
|
|
||||||
case ColorSliders::Value:
|
|
||||||
hsv.value(double(color.getValue()) / 100.0);
|
|
||||||
break;
|
|
||||||
case ColorSliders::Alpha:
|
|
||||||
a = color.getAlpha();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert HSV back to RGB
|
|
||||||
Rgb rgb(hsv);
|
|
||||||
r = rgb.red();
|
|
||||||
g = rgb.green();
|
|
||||||
b = rgb.blue();
|
|
||||||
}
|
}
|
||||||
|
// Modify one channel a set of entries
|
||||||
|
else {
|
||||||
|
// Convert RGB to HSV
|
||||||
|
hsv = Hsv(Rgb(r, g, b));
|
||||||
|
|
||||||
|
// Only modify the desired HSV channel
|
||||||
|
switch (channel) {
|
||||||
|
case ColorSliders::HsvHue:
|
||||||
|
hsv.hue(color.getHsvHue());
|
||||||
|
break;
|
||||||
|
case ColorSliders::HsvSaturation:
|
||||||
|
hsv.saturation(color.getHsvSaturation());
|
||||||
|
break;
|
||||||
|
case ColorSliders::HsvValue:
|
||||||
|
hsv.value(color.getHsvValue());
|
||||||
|
break;
|
||||||
|
case ColorSliders::Alpha:
|
||||||
|
a = color.getAlpha();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert HSV back to RGB
|
||||||
|
Rgb rgb(hsv);
|
||||||
|
r = rgb.red();
|
||||||
|
g = rgb.green();
|
||||||
|
b = rgb.blue();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case app::Color::HslType: {
|
||||||
|
Hsl hsl;
|
||||||
|
|
||||||
|
// Modify one entry
|
||||||
|
if (picksCount == 1) {
|
||||||
|
hsl.hue(color.getHslHue());
|
||||||
|
hsl.saturation(color.getHslSaturation());
|
||||||
|
hsl.lightness(color.getHslLightness());
|
||||||
|
a = color.getAlpha();
|
||||||
|
}
|
||||||
|
// Modify one channel a set of entries
|
||||||
|
else {
|
||||||
|
// Convert RGB to HSL
|
||||||
|
hsl = Hsl(Rgb(r, g, b));
|
||||||
|
|
||||||
|
// Only modify the desired HSL channel
|
||||||
|
switch (channel) {
|
||||||
|
case ColorSliders::HslHue:
|
||||||
|
hsl.hue(color.getHslHue());
|
||||||
|
break;
|
||||||
|
case ColorSliders::HslSaturation:
|
||||||
|
hsl.saturation(color.getHslSaturation());
|
||||||
|
break;
|
||||||
|
case ColorSliders::HslLightness:
|
||||||
|
hsl.lightness(color.getHslLightness());
|
||||||
|
break;
|
||||||
|
case ColorSliders::Alpha:
|
||||||
|
a = color.getAlpha();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert HSL back to RGB
|
||||||
|
Rgb rgb(hsl);
|
||||||
|
r = rgb.red();
|
||||||
|
g = rgb.green();
|
||||||
|
b = rgb.blue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
palette->setEntry(c, doc::rgba(r, g, b, a));
|
palette->setEntry(c, doc::rgba(r, g, b, a));
|
||||||
@ -613,9 +664,9 @@ void PaletteEntryEditor::setRelativePaletteEntryChannel(ColorSliders::Channel ch
|
|||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
|
|
||||||
case app::Color::RgbType:
|
case app::Color::RgbType:
|
||||||
r = MID(0, r+m_relDeltas[ColorSliders::Red], 255);
|
r = MID(0, r+m_relDeltas[ColorSliders::Red], 255);
|
||||||
g = MID(0, g+m_relDeltas[ColorSliders::Green], 255);
|
g = MID(0, g+m_relDeltas[ColorSliders::Green], 255);
|
||||||
b = MID(0, b+m_relDeltas[ColorSliders::Blue], 255);
|
b = MID(0, b+m_relDeltas[ColorSliders::Blue], 255);
|
||||||
a = MID(0, a+m_relDeltas[ColorSliders::Alpha], 255);
|
a = MID(0, a+m_relDeltas[ColorSliders::Alpha], 255);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -623,16 +674,16 @@ void PaletteEntryEditor::setRelativePaletteEntryChannel(ColorSliders::Channel ch
|
|||||||
// Convert RGB to HSV
|
// Convert RGB to HSV
|
||||||
Hsv hsv(Rgb(r, g, b));
|
Hsv hsv(Rgb(r, g, b));
|
||||||
|
|
||||||
double h = hsv.hue()+m_relDeltas[ColorSliders::Hue];
|
double h = hsv.hue() +m_relDeltas[ColorSliders::HsvHue];
|
||||||
double s = 100.0*hsv.saturation()+m_relDeltas[ColorSliders::Saturation];
|
double s = hsv.saturation()+m_relDeltas[ColorSliders::HsvSaturation]/100.0;
|
||||||
double v = 100.0*hsv.value()+m_relDeltas[ColorSliders::Value];
|
double v = hsv.value() +m_relDeltas[ColorSliders::HsvValue] /100.0;
|
||||||
|
|
||||||
if (h < 0.0) h += 360.0;
|
if (h < 0.0) h += 360.0;
|
||||||
else if (h > 360.0) h -= 360.0;
|
else if (h > 360.0) h -= 360.0;
|
||||||
|
|
||||||
hsv.hue (MID(0.0, h, 360.0));
|
hsv.hue (MID(0.0, h, 360.0));
|
||||||
hsv.saturation(MID(0.0, s, 100.0) / 100.0);
|
hsv.saturation(MID(0.0, s, 1.0));
|
||||||
hsv.value (MID(0.0, v, 100.0) / 100.0);
|
hsv.value (MID(0.0, v, 1.0));
|
||||||
|
|
||||||
// Convert HSV back to RGB
|
// Convert HSV back to RGB
|
||||||
Rgb rgb(hsv);
|
Rgb rgb(hsv);
|
||||||
@ -643,6 +694,30 @@ void PaletteEntryEditor::setRelativePaletteEntryChannel(ColorSliders::Channel ch
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case app::Color::HslType: {
|
||||||
|
// Convert RGB to HSL
|
||||||
|
Hsl hsl(Rgb(r, g, b));
|
||||||
|
|
||||||
|
double h = hsl.hue() +m_relDeltas[ColorSliders::HslHue];
|
||||||
|
double s = hsl.saturation()+m_relDeltas[ColorSliders::HslSaturation]/100.0;
|
||||||
|
double l = hsl.lightness() +m_relDeltas[ColorSliders::HslLightness] /100.0;
|
||||||
|
|
||||||
|
if (h < 0.0) h += 360.0;
|
||||||
|
else if (h > 360.0) h -= 360.0;
|
||||||
|
|
||||||
|
hsl.hue (h);
|
||||||
|
hsl.saturation(MID(0.0, s, 1.0));
|
||||||
|
hsl.lightness (MID(0.0, l, 1.0));
|
||||||
|
|
||||||
|
// Convert HSL back to RGB
|
||||||
|
Rgb rgb(hsl);
|
||||||
|
r = rgb.red();
|
||||||
|
g = rgb.green();
|
||||||
|
b = rgb.blue();
|
||||||
|
a = MID(0, a+m_relDeltas[ColorSliders::Alpha], 255);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
palette->setEntry(c, doc::rgba(r, g, b, a));
|
palette->setEntry(c, doc::rgba(r, g, b, a));
|
||||||
@ -654,12 +729,14 @@ void PaletteEntryEditor::selectColorType(app::Color::Type type)
|
|||||||
m_type = type;
|
m_type = type;
|
||||||
m_rgbSliders.setVisible(type == app::Color::RgbType);
|
m_rgbSliders.setVisible(type == app::Color::RgbType);
|
||||||
m_hsvSliders.setVisible(type == app::Color::HsvType);
|
m_hsvSliders.setVisible(type == app::Color::HsvType);
|
||||||
|
m_hslSliders.setVisible(type == app::Color::HslType);
|
||||||
|
|
||||||
resetRelativeInfo();
|
resetRelativeInfo();
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case app::Color::RgbType: m_colorType.setSelectedItem(RGB_MODE); break;
|
case app::Color::RgbType: m_colorType.setSelectedItem(RGB_MODE); break;
|
||||||
case app::Color::HsvType: m_colorType.setSelectedItem(HSV_MODE); break;
|
case app::Color::HsvType: m_colorType.setSelectedItem(HSV_MODE); break;
|
||||||
|
case app::Color::HslType: m_colorType.setSelectedItem(HSL_MODE); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vbox.layout();
|
m_vbox.layout();
|
||||||
@ -747,6 +824,7 @@ void PaletteEntryEditor::resetRelativeInfo()
|
|||||||
{
|
{
|
||||||
m_rgbSliders.resetRelativeSliders();
|
m_rgbSliders.resetRelativeSliders();
|
||||||
m_hsvSliders.resetRelativeSliders();
|
m_hsvSliders.resetRelativeSliders();
|
||||||
|
m_hslSliders.resetRelativeSliders();
|
||||||
get_current_palette()->copyColorsTo(&m_fromPalette);
|
get_current_palette()->copyColorsTo(&m_fromPalette);
|
||||||
m_relDeltas.clear();
|
m_relDeltas.clear();
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@ private:
|
|||||||
m_filter.setHue(double(m_sliders.getRelSliderValue(0)));
|
m_filter.setHue(double(m_sliders.getRelSliderValue(0)));
|
||||||
m_filter.setSaturation(m_sliders.getRelSliderValue(1) / 100.0);
|
m_filter.setSaturation(m_sliders.getRelSliderValue(1) / 100.0);
|
||||||
m_filter.setLightness(m_sliders.getRelSliderValue(2) / 100.0);
|
m_filter.setLightness(m_sliders.getRelSliderValue(2) / 100.0);
|
||||||
|
m_filter.setAlpha(m_sliders.getRelSliderValue(3));
|
||||||
|
|
||||||
restartPreview();
|
restartPreview();
|
||||||
}
|
}
|
||||||
@ -90,7 +91,8 @@ void HueSaturationCommand::onExecute(Context* context)
|
|||||||
filterMgr.setTarget(TARGET_RED_CHANNEL |
|
filterMgr.setTarget(TARGET_RED_CHANNEL |
|
||||||
TARGET_GREEN_CHANNEL |
|
TARGET_GREEN_CHANNEL |
|
||||||
TARGET_BLUE_CHANNEL |
|
TARGET_BLUE_CHANNEL |
|
||||||
TARGET_GRAY_CHANNEL);
|
TARGET_GRAY_CHANNEL |
|
||||||
|
TARGET_ALPHA_CHANNEL);
|
||||||
|
|
||||||
HueSaturationWindow window(filter, filterMgr);
|
HueSaturationWindow window(filter, filterMgr);
|
||||||
window.doModal();
|
window.doModal();
|
||||||
|
@ -44,9 +44,11 @@ using namespace doc;
|
|||||||
enum {
|
enum {
|
||||||
INDEX_MODE,
|
INDEX_MODE,
|
||||||
RGB_MODE,
|
RGB_MODE,
|
||||||
HSB_MODE,
|
HSV_MODE,
|
||||||
|
HSL_MODE,
|
||||||
GRAY_MODE,
|
GRAY_MODE,
|
||||||
MASK_MODE
|
MASK_MODE,
|
||||||
|
COLOR_MODES
|
||||||
};
|
};
|
||||||
|
|
||||||
static base::UniquePtr<doc::Palette> g_simplePal(nullptr);
|
static base::UniquePtr<doc::Palette> g_simplePal(nullptr);
|
||||||
@ -124,7 +126,7 @@ ColorPopup::ColorPopup(const bool canPin,
|
|||||||
, m_color(app::Color::fromMask())
|
, m_color(app::Color::fromMask())
|
||||||
, m_colorPalette(false, PaletteView::SelectOneColor, this, 7*guiscale())
|
, m_colorPalette(false, PaletteView::SelectOneColor, this, 7*guiscale())
|
||||||
, m_simpleColors(nullptr)
|
, m_simpleColors(nullptr)
|
||||||
, m_colorType(5)
|
, m_colorType(COLOR_MODES)
|
||||||
, m_maskLabel("Transparent Color Selected")
|
, m_maskLabel("Transparent Color Selected")
|
||||||
, m_canPin(canPin)
|
, m_canPin(canPin)
|
||||||
, m_disableHexUpdate(false)
|
, m_disableHexUpdate(false)
|
||||||
@ -145,7 +147,8 @@ ColorPopup::ColorPopup(const bool canPin,
|
|||||||
|
|
||||||
m_colorType.addItem("Index")->setFocusStop(false);
|
m_colorType.addItem("Index")->setFocusStop(false);
|
||||||
m_colorType.addItem("RGB")->setFocusStop(false);
|
m_colorType.addItem("RGB")->setFocusStop(false);
|
||||||
m_colorType.addItem("HSB")->setFocusStop(false);
|
m_colorType.addItem("HSV")->setFocusStop(false);
|
||||||
|
m_colorType.addItem("HSL")->setFocusStop(false);
|
||||||
m_colorType.addItem("Gray")->setFocusStop(false);
|
m_colorType.addItem("Gray")->setFocusStop(false);
|
||||||
m_colorType.addItem("Mask")->setFocusStop(false);
|
m_colorType.addItem("Mask")->setFocusStop(false);
|
||||||
|
|
||||||
@ -156,6 +159,7 @@ ColorPopup::ColorPopup(const bool canPin,
|
|||||||
m_colorPaletteContainer.setExpansive(true);
|
m_colorPaletteContainer.setExpansive(true);
|
||||||
m_rgbSliders.setExpansive(true);
|
m_rgbSliders.setExpansive(true);
|
||||||
m_hsvSliders.setExpansive(true);
|
m_hsvSliders.setExpansive(true);
|
||||||
|
m_hslSliders.setExpansive(true);
|
||||||
m_graySlider.setExpansive(true);
|
m_graySlider.setExpansive(true);
|
||||||
|
|
||||||
m_topBox.addChild(&m_colorType);
|
m_topBox.addChild(&m_colorType);
|
||||||
@ -190,6 +194,7 @@ ColorPopup::ColorPopup(const bool canPin,
|
|||||||
m_vbox.addChild(&m_colorPaletteContainer);
|
m_vbox.addChild(&m_colorPaletteContainer);
|
||||||
m_vbox.addChild(&m_rgbSliders);
|
m_vbox.addChild(&m_rgbSliders);
|
||||||
m_vbox.addChild(&m_hsvSliders);
|
m_vbox.addChild(&m_hsvSliders);
|
||||||
|
m_vbox.addChild(&m_hslSliders);
|
||||||
m_vbox.addChild(&m_graySlider);
|
m_vbox.addChild(&m_graySlider);
|
||||||
m_vbox.addChild(&m_maskLabel);
|
m_vbox.addChild(&m_maskLabel);
|
||||||
addChild(&m_vbox);
|
addChild(&m_vbox);
|
||||||
@ -198,6 +203,7 @@ ColorPopup::ColorPopup(const bool canPin,
|
|||||||
|
|
||||||
m_rgbSliders.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
m_rgbSliders.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
||||||
m_hsvSliders.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
m_hsvSliders.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
||||||
|
m_hslSliders.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
||||||
m_graySlider.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
m_graySlider.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
||||||
m_hexColorEntry.ColorChange.connect(&ColorPopup::onColorHexEntryChange, this);
|
m_hexColorEntry.ColorChange.connect(&ColorPopup::onColorHexEntryChange, this);
|
||||||
|
|
||||||
@ -240,6 +246,7 @@ void ColorPopup::setColor(const app::Color& color, SetColorOptions options)
|
|||||||
|
|
||||||
m_rgbSliders.setColor(m_color);
|
m_rgbSliders.setColor(m_color);
|
||||||
m_hsvSliders.setColor(m_color);
|
m_hsvSliders.setColor(m_color);
|
||||||
|
m_hslSliders.setColor(m_color);
|
||||||
m_graySlider.setColor(m_color);
|
m_graySlider.setColor(m_color);
|
||||||
if (!m_disableHexUpdate)
|
if (!m_disableHexUpdate)
|
||||||
m_hexColorEntry.setColor(m_color);
|
m_hexColorEntry.setColor(m_color);
|
||||||
@ -340,10 +347,16 @@ void ColorPopup::onColorTypeClick()
|
|||||||
newColor.getBlue(),
|
newColor.getBlue(),
|
||||||
newColor.getAlpha());
|
newColor.getAlpha());
|
||||||
break;
|
break;
|
||||||
case HSB_MODE:
|
case HSV_MODE:
|
||||||
newColor = app::Color::fromHsv(newColor.getHue(),
|
newColor = app::Color::fromHsv(newColor.getHsvHue(),
|
||||||
newColor.getSaturation(),
|
newColor.getHsvSaturation(),
|
||||||
newColor.getValue(),
|
newColor.getHsvValue(),
|
||||||
|
newColor.getAlpha());
|
||||||
|
break;
|
||||||
|
case HSL_MODE:
|
||||||
|
newColor = app::Color::fromHsl(newColor.getHslHue(),
|
||||||
|
newColor.getHslSaturation(),
|
||||||
|
newColor.getHslLightness(),
|
||||||
newColor.getAlpha());
|
newColor.getAlpha());
|
||||||
break;
|
break;
|
||||||
case GRAY_MODE:
|
case GRAY_MODE:
|
||||||
@ -393,18 +406,20 @@ void ColorPopup::selectColorType(app::Color::Type type)
|
|||||||
m_colorPaletteContainer.setVisible(type == app::Color::IndexType);
|
m_colorPaletteContainer.setVisible(type == app::Color::IndexType);
|
||||||
m_rgbSliders.setVisible(type == app::Color::RgbType);
|
m_rgbSliders.setVisible(type == app::Color::RgbType);
|
||||||
m_hsvSliders.setVisible(type == app::Color::HsvType);
|
m_hsvSliders.setVisible(type == app::Color::HsvType);
|
||||||
|
m_hslSliders.setVisible(type == app::Color::HslType);
|
||||||
m_graySlider.setVisible(type == app::Color::GrayType);
|
m_graySlider.setVisible(type == app::Color::GrayType);
|
||||||
m_maskLabel.setVisible(type == app::Color::MaskType);
|
m_maskLabel.setVisible(type == app::Color::MaskType);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case app::Color::IndexType: m_colorType.setSelectedItem(INDEX_MODE); break;
|
case app::Color::IndexType: m_colorType.setSelectedItem(INDEX_MODE); break;
|
||||||
case app::Color::RgbType: m_colorType.setSelectedItem(RGB_MODE); break;
|
case app::Color::RgbType: m_colorType.setSelectedItem(RGB_MODE); break;
|
||||||
case app::Color::HsvType: m_colorType.setSelectedItem(HSB_MODE); break;
|
case app::Color::HsvType: m_colorType.setSelectedItem(HSV_MODE); break;
|
||||||
|
case app::Color::HslType: m_colorType.setSelectedItem(HSL_MODE); break;
|
||||||
case app::Color::GrayType: m_colorType.setSelectedItem(GRAY_MODE); break;
|
case app::Color::GrayType: m_colorType.setSelectedItem(GRAY_MODE); break;
|
||||||
case app::Color::MaskType: m_colorType.setSelectedItem(MASK_MODE); break;
|
case app::Color::MaskType: m_colorType.setSelectedItem(MASK_MODE); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove focus from hidden RGB/HSB text entries
|
// Remove focus from hidden RGB/HSV/HSL text entries
|
||||||
auto widget = manager()->getFocus();
|
auto widget = manager()->getFocus();
|
||||||
if (widget && !widget->isVisible()) {
|
if (widget && !widget->isVisible()) {
|
||||||
auto window = widget->window();
|
auto window = widget->window();
|
||||||
|
@ -71,6 +71,7 @@ namespace app {
|
|||||||
HexColorEntry m_hexColorEntry;
|
HexColorEntry m_hexColorEntry;
|
||||||
RgbSliders m_rgbSliders;
|
RgbSliders m_rgbSliders;
|
||||||
HsvSliders m_hsvSliders;
|
HsvSliders m_hsvSliders;
|
||||||
|
HslSliders m_hslSliders;
|
||||||
GraySlider m_graySlider;
|
GraySlider m_graySlider;
|
||||||
ui::Label m_maskLabel;
|
ui::Label m_maskLabel;
|
||||||
obs::scoped_connection m_onPaletteChangeConn;
|
obs::scoped_connection m_onPaletteChangeConn;
|
||||||
|
@ -53,7 +53,7 @@ bool ColorSelector::onProcessMessage(ui::Message* msg)
|
|||||||
scale = 15.0;
|
scale = 15.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double newHue = m_color.getHue()
|
double newHue = m_color.getHsvHue()
|
||||||
+ scale*(+ static_cast<MouseMessage*>(msg)->wheelDelta().x
|
+ scale*(+ static_cast<MouseMessage*>(msg)->wheelDelta().x
|
||||||
- static_cast<MouseMessage*>(msg)->wheelDelta().y);
|
- static_cast<MouseMessage*>(msg)->wheelDelta().y);
|
||||||
|
|
||||||
@ -61,12 +61,12 @@ bool ColorSelector::onProcessMessage(ui::Message* msg)
|
|||||||
newHue += 360.0;
|
newHue += 360.0;
|
||||||
newHue = std::fmod(newHue, 360.0);
|
newHue = std::fmod(newHue, 360.0);
|
||||||
|
|
||||||
if (newHue != m_color.getHue()) {
|
if (newHue != m_color.getHsvHue()) {
|
||||||
app::Color newColor =
|
app::Color newColor =
|
||||||
app::Color::fromHsv(
|
app::Color::fromHsv(
|
||||||
newHue,
|
newHue,
|
||||||
m_color.getSaturation(),
|
m_color.getHsvSaturation(),
|
||||||
m_color.getValue());
|
m_color.getHsvValue());
|
||||||
|
|
||||||
ColorChange(newColor, kButtonNone);
|
ColorChange(newColor, kButtonNone);
|
||||||
}
|
}
|
||||||
|
@ -62,18 +62,49 @@ namespace {
|
|||||||
case ColorSliders::Blue:
|
case ColorSliders::Blue:
|
||||||
color = gfx::rgba(m_color.getRed(), m_color.getGreen(), 255 * x / w);
|
color = gfx::rgba(m_color.getRed(), m_color.getGreen(), 255 * x / w);
|
||||||
break;
|
break;
|
||||||
case ColorSliders::Hue:
|
|
||||||
color = color_utils::color_for_ui(app::Color::fromHsv(360 * x / w, m_color.getSaturation(), m_color.getValue()));
|
case ColorSliders::HsvHue:
|
||||||
|
color = color_utils::color_for_ui(
|
||||||
|
app::Color::fromHsv(360.0 * x / w,
|
||||||
|
m_color.getHsvSaturation(),
|
||||||
|
m_color.getHsvValue()));
|
||||||
break;
|
break;
|
||||||
case ColorSliders::Saturation:
|
case ColorSliders::HsvSaturation:
|
||||||
color = color_utils::color_for_ui(app::Color::fromHsv(m_color.getHue(), 100 * x / w, m_color.getValue()));
|
color = color_utils::color_for_ui(
|
||||||
|
app::Color::fromHsv(m_color.getHsvHue(),
|
||||||
|
double(x) / double(w),
|
||||||
|
m_color.getHsvValue()));
|
||||||
break;
|
break;
|
||||||
case ColorSliders::Value:
|
case ColorSliders::HsvValue:
|
||||||
color = color_utils::color_for_ui(app::Color::fromHsv(m_color.getHue(), m_color.getSaturation(), 100 * x / w));
|
color = color_utils::color_for_ui(
|
||||||
|
app::Color::fromHsv(m_color.getHsvHue(),
|
||||||
|
m_color.getHsvSaturation(),
|
||||||
|
double(x) / double(w)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ColorSliders::HslHue:
|
||||||
|
color = color_utils::color_for_ui(
|
||||||
|
app::Color::fromHsl(360.0 * x / w,
|
||||||
|
m_color.getHslSaturation(),
|
||||||
|
m_color.getHslLightness()));
|
||||||
|
break;
|
||||||
|
case ColorSliders::HslSaturation:
|
||||||
|
color = color_utils::color_for_ui(
|
||||||
|
app::Color::fromHsl(m_color.getHslHue(),
|
||||||
|
double(x) / double(w),
|
||||||
|
m_color.getHslLightness()));
|
||||||
|
break;
|
||||||
|
case ColorSliders::HslLightness:
|
||||||
|
color = color_utils::color_for_ui(
|
||||||
|
app::Color::fromHsl(m_color.getHslHue(),
|
||||||
|
m_color.getHslSaturation(),
|
||||||
|
double(x) / double(w)));
|
||||||
|
break;
|
||||||
|
|
||||||
case ColorSliders::Gray:
|
case ColorSliders::Gray:
|
||||||
case ColorSliders::Alpha:
|
case ColorSliders::Alpha:
|
||||||
color = color_utils::color_for_ui(app::Color::fromGray(255 * x / w));
|
color = color_utils::color_for_ui(
|
||||||
|
app::Color::fromGray(255 * x / w));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
g->drawVLine(color, rc.x+x, rc.y, rc.h);
|
g->drawVLine(color, rc.x+x, rc.y, rc.h);
|
||||||
@ -390,25 +421,25 @@ app::Color RgbSliders::getColorFromSliders()
|
|||||||
HsvSliders::HsvSliders()
|
HsvSliders::HsvSliders()
|
||||||
: ColorSliders()
|
: ColorSliders()
|
||||||
{
|
{
|
||||||
addSlider(Hue, "H", 0, 360, -180, 180);
|
addSlider(HsvHue, "H", 0, 360, -180, 180);
|
||||||
addSlider(Saturation, "S", 0, 100, -100, 100);
|
addSlider(HsvSaturation, "S", 0, 100, -100, 100);
|
||||||
addSlider(Value, "B", 0, 100, -100, 100);
|
addSlider(HsvValue, "V", 0, 100, -100, 100);
|
||||||
addSlider(Alpha, "A", 0, 255, -255, 255);
|
addSlider(Alpha, "A", 0, 255, -255, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HsvSliders::onSetColor(const app::Color& color)
|
void HsvSliders::onSetColor(const app::Color& color)
|
||||||
{
|
{
|
||||||
setAbsSliderValue(0, int(color.getHue()));
|
setAbsSliderValue(0, int(color.getHsvHue()));
|
||||||
setAbsSliderValue(1, int(color.getSaturation()));
|
setAbsSliderValue(1, int(color.getHsvSaturation() * 100.0));
|
||||||
setAbsSliderValue(2, int(color.getValue()));
|
setAbsSliderValue(2, int(color.getHsvValue() * 100.0));
|
||||||
setAbsSliderValue(3, color.getAlpha());
|
setAbsSliderValue(3, color.getAlpha());
|
||||||
}
|
}
|
||||||
|
|
||||||
app::Color HsvSliders::getColorFromSliders()
|
app::Color HsvSliders::getColorFromSliders()
|
||||||
{
|
{
|
||||||
return app::Color::fromHsv(getAbsSliderValue(0),
|
return app::Color::fromHsv(getAbsSliderValue(0),
|
||||||
getAbsSliderValue(1),
|
getAbsSliderValue(1) / 100.0,
|
||||||
getAbsSliderValue(2),
|
getAbsSliderValue(2) / 100.0,
|
||||||
getAbsSliderValue(3));
|
getAbsSliderValue(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,31 +449,26 @@ app::Color HsvSliders::getColorFromSliders()
|
|||||||
HslSliders::HslSliders()
|
HslSliders::HslSliders()
|
||||||
: ColorSliders()
|
: ColorSliders()
|
||||||
{
|
{
|
||||||
addSlider(Hue, "H", 0, 360, -180, 180);
|
addSlider(HslHue, "H", 0, 360, -180, 180);
|
||||||
addSlider(Saturation, "S", 0, 100, -100, 100);
|
addSlider(HslSaturation, "S", 0, 100, -100, 100);
|
||||||
addSlider(Value, "L", 0, 100, -100, 100);
|
addSlider(HslLightness, "L", 0, 100, -100, 100);
|
||||||
|
addSlider(Alpha, "A", 0, 255, -255, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HslSliders::onSetColor(const app::Color& color)
|
void HslSliders::onSetColor(const app::Color& color)
|
||||||
{
|
{
|
||||||
gfx::Hsl hsl(gfx::Rgb(color.getRed(),
|
setAbsSliderValue(0, int(color.getHslHue()));
|
||||||
color.getGreen(),
|
setAbsSliderValue(1, int(color.getHslSaturation() * 100.0));
|
||||||
color.getBlue()));
|
setAbsSliderValue(2, int(color.getHslLightness() * 100.0));
|
||||||
|
setAbsSliderValue(3, color.getAlpha());
|
||||||
setAbsSliderValue(0, hsl.hue());
|
|
||||||
setAbsSliderValue(1, hsl.saturation() * 100.0);
|
|
||||||
setAbsSliderValue(2, hsl.lightness() * 100.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app::Color HslSliders::getColorFromSliders()
|
app::Color HslSliders::getColorFromSliders()
|
||||||
{
|
{
|
||||||
gfx::Hsl hsl(getAbsSliderValue(0),
|
return app::Color::fromHsl(getAbsSliderValue(0),
|
||||||
getAbsSliderValue(1) / 100.0,
|
getAbsSliderValue(1) / 100.0,
|
||||||
getAbsSliderValue(2) / 100.0);
|
getAbsSliderValue(2) / 100.0,
|
||||||
gfx::Rgb rgb(hsl);
|
getAbsSliderValue(3));
|
||||||
return app::Color::fromRgb(rgb.red(),
|
|
||||||
rgb.green(),
|
|
||||||
rgb.blue(), 255);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
@ -29,9 +29,9 @@ namespace app {
|
|||||||
class ColorSliders : public ui::Widget {
|
class ColorSliders : public ui::Widget {
|
||||||
public:
|
public:
|
||||||
enum Channel { Red, Green, Blue,
|
enum Channel { Red, Green, Blue,
|
||||||
Hue, Saturation, Value,
|
HsvHue, HsvSaturation, HsvValue,
|
||||||
Gray,
|
HslHue, HslSaturation, HslLightness,
|
||||||
Alpha };
|
Gray, Alpha };
|
||||||
enum Mode { Absolute, Relative };
|
enum Mode { Absolute, Relative };
|
||||||
|
|
||||||
ColorSliders();
|
ColorSliders();
|
||||||
|
@ -55,13 +55,13 @@ app::Color ColorSpectrum::getColorByPosition(const gfx::Point& pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
double hue = 360.0 * u / umax;
|
double hue = 360.0 * u / umax;
|
||||||
double sat = (v < vmid ? 100.0 * v / vmid : 100.0);
|
double sat = (v < vmid ? double(v) / double(vmid) : 1.0);
|
||||||
double val = (v < vmid ? 100.0 : 100.0-(100.0 * (v-vmid) / vmid));
|
double val = (v < vmid ? 1.0 : 1.0-(double(v-vmid) / double(vmid)));
|
||||||
|
|
||||||
return app::Color::fromHsv(
|
return app::Color::fromHsv(
|
||||||
MID(0.0, hue, 360.0),
|
MID(0.0, hue, 360.0),
|
||||||
MID(0.0, sat, 100.0),
|
MID(0.0, sat, 1.0),
|
||||||
MID(0.0, val, 100.0));
|
MID(0.0, val, 1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorSpectrum::onPaint(ui::PaintEvent& ev)
|
void ColorSpectrum::onPaint(ui::PaintEvent& ev)
|
||||||
@ -95,31 +95,31 @@ void ColorSpectrum::onPaint(ui::PaintEvent& ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
double hue = 360.0 * u / umax;
|
double hue = 360.0 * u / umax;
|
||||||
double sat = (v < vmid ? 100.0 * v / vmid : 100.0);
|
double sat = (v < vmid ? double(v) / double(vmid) : 1.0);
|
||||||
double val = (v < vmid ? 100.0 : 100.0-(100.0 * (v-vmid) / vmid));
|
double val = (v < vmid ? 1.0 : 1.0-(double(v-vmid) / double(vmid)));
|
||||||
|
|
||||||
gfx::Color color = color_utils::color_for_ui(
|
gfx::Color color = color_utils::color_for_ui(
|
||||||
app::Color::fromHsv(
|
app::Color::fromHsv(
|
||||||
MID(0.0, hue, 360.0),
|
MID(0.0, hue, 360.0),
|
||||||
MID(0.0, sat, 100.0),
|
MID(0.0, sat, 1.0),
|
||||||
MID(0.0, val, 100.0)));
|
MID(0.0, val, 1.0)));
|
||||||
|
|
||||||
g->putPixel(color, rc.x+x, rc.y+y);
|
g->putPixel(color, rc.x+x, rc.y+y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_color.getType() != app::Color::MaskType) {
|
if (m_color.getType() != app::Color::MaskType) {
|
||||||
double hue = m_color.getHue();
|
double hue = m_color.getHsvHue();
|
||||||
double sat = m_color.getSaturation();
|
double sat = m_color.getHsvSaturation();
|
||||||
double val = m_color.getValue();
|
double val = m_color.getHsvValue();
|
||||||
double lit = (200.0 - sat) * val / 200.0;
|
double lit = (2.0 - sat) * val / 2.0;
|
||||||
gfx::Point pos(rc.x + int(hue * rc.w / 360.0),
|
gfx::Point pos(rc.x + int(hue * rc.w / 360.0),
|
||||||
rc.y + rc.h - int(lit * rc.h / 100.0));
|
rc.y + rc.h - int(lit * rc.h));
|
||||||
|
|
||||||
she::Surface* icon = theme->parts.colorWheelIndicator()->bitmap(0);
|
she::Surface* icon = theme->parts.colorWheelIndicator()->bitmap(0);
|
||||||
g->drawColoredRgbaSurface(
|
g->drawColoredRgbaSurface(
|
||||||
icon,
|
icon,
|
||||||
lit > 50.0 ? gfx::rgba(0, 0, 0): gfx::rgba(255, 255, 255),
|
lit > 0.5 ? gfx::rgba(0, 0, 0): gfx::rgba(255, 255, 255),
|
||||||
pos.x-icon->width()/2,
|
pos.x-icon->width()/2,
|
||||||
pos.y-icon->height()/2);
|
pos.y-icon->height()/2);
|
||||||
}
|
}
|
||||||
|
@ -54,19 +54,19 @@ app::Color ColorTintShadeTone::getColorByPosition(const gfx::Point& pos)
|
|||||||
|
|
||||||
if (inHue) {
|
if (inHue) {
|
||||||
hue = (360.0 * u / umax);
|
hue = (360.0 * u / umax);
|
||||||
sat = m_color.getSaturation();
|
sat = m_color.getHsvSaturation();
|
||||||
val = m_color.getValue();
|
val = m_color.getHsvValue();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
hue = m_color.getHue();
|
hue = m_color.getHsvHue();
|
||||||
sat = (100.0 * u / umax);
|
sat = (1.0 * u / umax);
|
||||||
val = (100.0 - 100.0 * v / vmax);
|
val = (1.0 - double(v) / double(vmax));
|
||||||
}
|
}
|
||||||
|
|
||||||
return app::Color::fromHsv(
|
return app::Color::fromHsv(
|
||||||
MID(0.0, hue, 360.0),
|
MID(0.0, hue, 360.0),
|
||||||
MID(0.0, sat, 100.0),
|
MID(0.0, sat, 1.0),
|
||||||
MID(0.0, val, 100.0));
|
MID(0.0, val, 1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorTintShadeTone::onPaint(ui::PaintEvent& ev)
|
void ColorTintShadeTone::onPaint(ui::PaintEvent& ev)
|
||||||
@ -82,7 +82,7 @@ void ColorTintShadeTone::onPaint(ui::PaintEvent& ev)
|
|||||||
if (rc.isEmpty())
|
if (rc.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double hue = m_color.getHue();
|
double hue = m_color.getHsvHue();
|
||||||
int umax, vmax;
|
int umax, vmax;
|
||||||
int huebar = getHueBarSize();
|
int huebar = getHueBarSize();
|
||||||
umax = MAX(1, rc.w-1);
|
umax = MAX(1, rc.w-1);
|
||||||
@ -90,14 +90,14 @@ void ColorTintShadeTone::onPaint(ui::PaintEvent& ev)
|
|||||||
|
|
||||||
for (int y=0; y<rc.h-huebar; ++y) {
|
for (int y=0; y<rc.h-huebar; ++y) {
|
||||||
for (int x=0; x<rc.w; ++x) {
|
for (int x=0; x<rc.w; ++x) {
|
||||||
double sat = (100.0 * x / umax);
|
double sat = double(x) / double(umax);
|
||||||
double val = (100.0 - 100.0 * y / vmax);
|
double val = 1.0 - double(y) / double(vmax);
|
||||||
|
|
||||||
gfx::Color color = color_utils::color_for_ui(
|
gfx::Color color = color_utils::color_for_ui(
|
||||||
app::Color::fromHsv(
|
app::Color::fromHsv(
|
||||||
hue,
|
hue,
|
||||||
MID(0.0, sat, 100.0),
|
MID(0.0, sat, 1.0),
|
||||||
MID(0.0, val, 100.0)));
|
MID(0.0, val, 1.0)));
|
||||||
|
|
||||||
g->putPixel(color, rc.x+x, rc.y+y);
|
g->putPixel(color, rc.x+x, rc.y+y);
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ void ColorTintShadeTone::onPaint(ui::PaintEvent& ev)
|
|||||||
for (int x=0; x<rc.w; ++x) {
|
for (int x=0; x<rc.w; ++x) {
|
||||||
gfx::Color color = color_utils::color_for_ui(
|
gfx::Color color = color_utils::color_for_ui(
|
||||||
app::Color::fromHsv(
|
app::Color::fromHsv(
|
||||||
(360.0 * x / rc.w), 100.0, 100.0));
|
(360.0 * x / rc.w), 1.0, 1.0));
|
||||||
|
|
||||||
g->putPixel(color, rc.x+x, rc.y+y);
|
g->putPixel(color, rc.x+x, rc.y+y);
|
||||||
}
|
}
|
||||||
@ -116,15 +116,15 @@ void ColorTintShadeTone::onPaint(ui::PaintEvent& ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_color.getType() != app::Color::MaskType) {
|
if (m_color.getType() != app::Color::MaskType) {
|
||||||
double sat = m_color.getSaturation();
|
double sat = m_color.getHsvSaturation();
|
||||||
double val = m_color.getValue();
|
double val = m_color.getHsvValue();
|
||||||
gfx::Point pos(rc.x + int(sat * rc.w / 100.0),
|
gfx::Point pos(rc.x + int(sat * rc.w),
|
||||||
rc.y + int((100.0-val) * (rc.h-huebar) / 100.0));
|
rc.y + int((1.0-val) * (rc.h-huebar)));
|
||||||
|
|
||||||
she::Surface* icon = theme->parts.colorWheelIndicator()->bitmap(0);
|
she::Surface* icon = theme->parts.colorWheelIndicator()->bitmap(0);
|
||||||
g->drawColoredRgbaSurface(
|
g->drawColoredRgbaSurface(
|
||||||
icon,
|
icon,
|
||||||
val > 50.0 ? gfx::rgba(0, 0, 0): gfx::rgba(255, 255, 255),
|
val > 0.5 ? gfx::rgba(0, 0, 0): gfx::rgba(255, 255, 255),
|
||||||
pos.x-icon->width()/2,
|
pos.x-icon->width()/2,
|
||||||
pos.y-icon->height()/2);
|
pos.y-icon->height()/2);
|
||||||
|
|
||||||
|
@ -105,8 +105,8 @@ app::Color ColorWheel::getColorInClientPos(const gfx::Point& pos)
|
|||||||
|
|
||||||
return app::Color::fromHsv(
|
return app::Color::fromHsv(
|
||||||
MID(0, hue, 360),
|
MID(0, hue, 360),
|
||||||
MID(0, sat, 100),
|
MID(0, sat / 100.0, 1.0),
|
||||||
100);
|
1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pick harmonies
|
// Pick harmonies
|
||||||
@ -123,9 +123,9 @@ app::Color ColorWheel::getColorInClientPos(const gfx::Point& pos)
|
|||||||
boxsize, boxsize).contains(pos)) {
|
boxsize, boxsize).contains(pos)) {
|
||||||
m_harmonyPicked = true;
|
m_harmonyPicked = true;
|
||||||
|
|
||||||
color = app::Color::fromHsv(convertHueAngle(int(color.getHue()), 1),
|
color = app::Color::fromHsv(convertHueAngle(int(color.getHsvHue()), 1),
|
||||||
color.getSaturation(),
|
color.getHsvSaturation(),
|
||||||
color.getValue());
|
color.getHsvValue());
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,11 +168,11 @@ app::Color ColorWheel::getColorInHarmony(int j) const
|
|||||||
{
|
{
|
||||||
int i = MID(0, (int)m_harmony, (int)Harmony::LAST);
|
int i = MID(0, (int)m_harmony, (int)Harmony::LAST);
|
||||||
j = MID(0, j, harmonies[i].n-1);
|
j = MID(0, j, harmonies[i].n-1);
|
||||||
double hue = convertHueAngle(int(m_color.getHue()), -1) + harmonies[i].hues[j];
|
double hue = convertHueAngle(int(m_color.getHsvHue()), -1) + harmonies[i].hues[j];
|
||||||
double sat = m_color.getSaturation() * harmonies[i].sats[j] / 100.0;
|
double sat = m_color.getHsvSaturation() * harmonies[i].sats[j] / 100.0;
|
||||||
return app::Color::fromHsv(std::fmod(hue, 360),
|
return app::Color::fromHsv(std::fmod(hue, 360),
|
||||||
MID(0.0, sat, 100.0),
|
MID(0.0, sat, 1.0),
|
||||||
m_color.getValue());
|
m_color.getHsvValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorWheel::onResize(ui::ResizeEvent& ev)
|
void ColorWheel::onResize(ui::ResizeEvent& ev)
|
||||||
@ -230,17 +230,17 @@ void ColorWheel::onPaint(ui::PaintEvent& ev)
|
|||||||
|
|
||||||
for (int i=0; i<n; ++i) {
|
for (int i=0; i<n; ++i) {
|
||||||
app::Color color = getColorInHarmony(i);
|
app::Color color = getColorInHarmony(i);
|
||||||
double angle = color.getHue()-30.0;
|
double angle = color.getHsvHue()-30.0;
|
||||||
double dist = color.getSaturation();
|
double dist = color.getHsvSaturation();
|
||||||
|
|
||||||
color = app::Color::fromHsv(convertHueAngle(int(color.getHue()), 1),
|
color = app::Color::fromHsv(convertHueAngle(int(color.getHsvHue()), 1),
|
||||||
color.getSaturation(),
|
color.getHsvSaturation(),
|
||||||
color.getValue());
|
color.getHsvValue());
|
||||||
|
|
||||||
gfx::Point pos =
|
gfx::Point pos =
|
||||||
m_wheelBounds.center() +
|
m_wheelBounds.center() +
|
||||||
gfx::Point(int(+std::cos(PI*angle/180.0)*double(m_wheelRadius)*dist/100.0),
|
gfx::Point(int(+std::cos(PI*angle/180.0)*double(m_wheelRadius)*dist),
|
||||||
int(-std::sin(PI*angle/180.0)*double(m_wheelRadius)*dist/100.0));
|
int(-std::sin(PI*angle/180.0)*double(m_wheelRadius)*dist));
|
||||||
|
|
||||||
she::Surface* icon = theme->parts.colorWheelIndicator()->bitmap(0);
|
she::Surface* icon = theme->parts.colorWheelIndicator()->bitmap(0);
|
||||||
g->drawRgbaSurface(icon,
|
g->drawRgbaSurface(icon,
|
||||||
|
@ -1249,8 +1249,10 @@ public:
|
|||||||
m_channel.addItem("Alpha");
|
m_channel.addItem("Alpha");
|
||||||
m_channel.addItem("RGB+Alpha");
|
m_channel.addItem("RGB+Alpha");
|
||||||
m_channel.addItem("RGB");
|
m_channel.addItem("RGB");
|
||||||
m_channel.addItem("HSB+Alpha");
|
m_channel.addItem("HSV+Alpha");
|
||||||
m_channel.addItem("HSB");
|
m_channel.addItem("HSV");
|
||||||
|
m_channel.addItem("HSL+Alpha");
|
||||||
|
m_channel.addItem("HSL");
|
||||||
m_channel.addItem("Gray+Alpha");
|
m_channel.addItem("Gray+Alpha");
|
||||||
m_channel.addItem("Gray");
|
m_channel.addItem("Gray");
|
||||||
m_channel.addItem("Best fit Index");
|
m_channel.addItem("Best fit Index");
|
||||||
|
@ -951,6 +951,7 @@ int PaletteView::findExactIndex(const app::Color& color) const
|
|||||||
|
|
||||||
case Color::RgbType:
|
case Color::RgbType:
|
||||||
case Color::HsvType:
|
case Color::HsvType:
|
||||||
|
case Color::HslType:
|
||||||
case Color::GrayType:
|
case Color::GrayType:
|
||||||
return currentPalette()->findExactMatch(
|
return currentPalette()->findExactMatch(
|
||||||
color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha(), -1);
|
color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha(), -1);
|
||||||
|
@ -33,6 +33,7 @@ HueSaturationFilter::HueSaturationFilter()
|
|||||||
: m_h(0.0)
|
: m_h(0.0)
|
||||||
, m_s(0.0)
|
, m_s(0.0)
|
||||||
, m_l(0.0)
|
, m_l(0.0)
|
||||||
|
, m_a(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +52,11 @@ void HueSaturationFilter::setLightness(double l)
|
|||||||
m_l = l;
|
m_l = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HueSaturationFilter::setAlpha(int a)
|
||||||
|
{
|
||||||
|
m_a = a;
|
||||||
|
}
|
||||||
|
|
||||||
void HueSaturationFilter::applyToRgba(FilterManager* filterMgr)
|
void HueSaturationFilter::applyToRgba(FilterManager* filterMgr)
|
||||||
{
|
{
|
||||||
const uint32_t* src_address = (uint32_t*)filterMgr->getSourceAddress();
|
const uint32_t* src_address = (uint32_t*)filterMgr->getSourceAddress();
|
||||||
@ -95,6 +101,9 @@ void HueSaturationFilter::applyToRgba(FilterManager* filterMgr)
|
|||||||
if (target & TARGET_RED_CHANNEL ) r = rgb.red();
|
if (target & TARGET_RED_CHANNEL ) r = rgb.red();
|
||||||
if (target & TARGET_GREEN_CHANNEL) g = rgb.green();
|
if (target & TARGET_GREEN_CHANNEL) g = rgb.green();
|
||||||
if (target & TARGET_BLUE_CHANNEL ) b = rgb.blue();
|
if (target & TARGET_BLUE_CHANNEL ) b = rgb.blue();
|
||||||
|
|
||||||
|
if (a && (target & TARGET_ALPHA_CHANNEL))
|
||||||
|
a = MID(0, a+m_a, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
*(dst_address++) = rgba(r, g, b, a);
|
*(dst_address++) = rgba(r, g, b, a);
|
||||||
@ -131,6 +140,9 @@ void HueSaturationFilter::applyToGrayscale(FilterManager* filterMgr)
|
|||||||
gfx::Rgb rgb(hsl);
|
gfx::Rgb rgb(hsl);
|
||||||
|
|
||||||
if (target & TARGET_GRAY_CHANNEL) k = rgb.red();
|
if (target & TARGET_GRAY_CHANNEL) k = rgb.red();
|
||||||
|
|
||||||
|
if (a && (target & TARGET_ALPHA_CHANNEL))
|
||||||
|
a = MID(0, a+m_a, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
*(dst_address++) = graya(k, a);
|
*(dst_address++) = graya(k, a);
|
||||||
@ -182,6 +194,9 @@ void HueSaturationFilter::applyToIndexed(FilterManager* filterMgr)
|
|||||||
if (target & TARGET_RED_CHANNEL ) r = rgb.red();
|
if (target & TARGET_RED_CHANNEL ) r = rgb.red();
|
||||||
if (target & TARGET_GREEN_CHANNEL) g = rgb.green();
|
if (target & TARGET_GREEN_CHANNEL) g = rgb.green();
|
||||||
if (target & TARGET_BLUE_CHANNEL ) b = rgb.blue();
|
if (target & TARGET_BLUE_CHANNEL ) b = rgb.blue();
|
||||||
|
|
||||||
|
if (a && (target & TARGET_ALPHA_CHANNEL))
|
||||||
|
a = MID(0, a+m_a, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
c = rgbmap->mapColor(r, g, b, a);
|
c = rgbmap->mapColor(r, g, b, a);
|
||||||
|
@ -19,6 +19,7 @@ namespace filters {
|
|||||||
void setHue(double h);
|
void setHue(double h);
|
||||||
void setSaturation(double s);
|
void setSaturation(double s);
|
||||||
void setLightness(double v);
|
void setLightness(double v);
|
||||||
|
void setAlpha(int a);
|
||||||
|
|
||||||
// Filter implementation
|
// Filter implementation
|
||||||
const char* getName();
|
const char* getName();
|
||||||
@ -28,6 +29,7 @@ namespace filters {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
double m_h, m_s, m_l;
|
double m_h, m_s, m_l;
|
||||||
|
int m_a;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace filters
|
} // namespace filters
|
||||||
|
@ -18,16 +18,12 @@ using namespace std;
|
|||||||
|
|
||||||
Hsl::Hsl(double hue, double saturation, double lightness)
|
Hsl::Hsl(double hue, double saturation, double lightness)
|
||||||
: m_hue(hue)
|
: m_hue(hue)
|
||||||
, m_saturation(saturation)
|
, m_saturation(MID(0.0, saturation, 1.0))
|
||||||
, m_lightness(lightness)
|
, m_lightness(MID(0.0, lightness, 1.0))
|
||||||
{
|
{
|
||||||
while (m_hue < 0.0)
|
while (m_hue < 0.0)
|
||||||
m_hue += 360.0;
|
m_hue += 360.0;
|
||||||
m_hue = std::fmod(m_hue, 360.0);
|
m_hue = std::fmod(m_hue, 360.0);
|
||||||
|
|
||||||
assert(hue >= 0.0 && hue <= 360.0);
|
|
||||||
assert(saturation >= 0.0 && saturation <= 1.0);
|
|
||||||
assert(lightness >= 0.0 && lightness <= 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Hsl::Hsl(const Rgb& rgb)
|
Hsl::Hsl(const Rgb& rgb)
|
||||||
@ -76,17 +72,17 @@ Hsl::Hsl(const Rgb& rgb)
|
|||||||
|
|
||||||
int Hsl::hueInt() const
|
int Hsl::hueInt() const
|
||||||
{
|
{
|
||||||
return int(floor(m_hue + 0.5));
|
return int(std::floor(m_hue + 0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Hsl::saturationInt() const
|
int Hsl::saturationInt() const
|
||||||
{
|
{
|
||||||
return int(floor(m_saturation*100.0 + 0.5));
|
return int(std::floor(m_saturation*100.0 + 0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Hsl::lightnessInt() const
|
int Hsl::lightnessInt() const
|
||||||
{
|
{
|
||||||
return int(floor(m_lightness*100.0 + 0.5));
|
return int(std::floor(m_lightness*100.0 + 0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#define GFX_HSL_H_INCLUDED
|
#define GFX_HSL_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cassert>
|
#include "base/base.h" // MID
|
||||||
|
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
|
|
||||||
@ -48,18 +48,15 @@ public:
|
|||||||
int lightnessInt() const;
|
int lightnessInt() const;
|
||||||
|
|
||||||
void hue(double hue) {
|
void hue(double hue) {
|
||||||
assert(hue >= 0.0 && hue <= 360.0);
|
m_hue = MID(0.0, hue, 360.0);
|
||||||
m_hue = hue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void saturation(double saturation) {
|
void saturation(double saturation) {
|
||||||
assert(saturation >= 0.0 && saturation <= 1.0);
|
m_saturation = MID(0.0, saturation, 1.0);
|
||||||
m_saturation = saturation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lightness(double lightness) {
|
void lightness(double lightness) {
|
||||||
assert(lightness >= 0.0 && lightness <= 1.0);
|
m_lightness = MID(0.0, lightness, 1.0);
|
||||||
m_lightness = lightness;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The comparison is done through the integer value of each component.
|
// The comparison is done through the integer value of each component.
|
||||||
|
@ -18,16 +18,12 @@ using namespace std;
|
|||||||
|
|
||||||
Hsv::Hsv(double hue, double saturation, double value)
|
Hsv::Hsv(double hue, double saturation, double value)
|
||||||
: m_hue(hue)
|
: m_hue(hue)
|
||||||
, m_saturation(saturation)
|
, m_saturation(MID(0.0, saturation, 1.0))
|
||||||
, m_value(value)
|
, m_value(MID(0.0, value, 1.0))
|
||||||
{
|
{
|
||||||
while (m_hue < 0.0)
|
while (m_hue < 0.0)
|
||||||
m_hue += 360.0;
|
m_hue += 360.0;
|
||||||
m_hue = std::fmod(m_hue, 360.0);
|
m_hue = std::fmod(m_hue, 360.0);
|
||||||
|
|
||||||
assert(hue >= 0.0 && hue <= 360.0);
|
|
||||||
assert(saturation >= 0.0 && saturation <= 1.0);
|
|
||||||
assert(value >= 0.0 && value <= 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reference: http://en.wikipedia.org/wiki/HSL_and_HSV
|
// Reference: http://en.wikipedia.org/wiki/HSL_and_HSV
|
||||||
@ -77,17 +73,17 @@ Hsv::Hsv(const Rgb& rgb)
|
|||||||
|
|
||||||
int Hsv::hueInt() const
|
int Hsv::hueInt() const
|
||||||
{
|
{
|
||||||
return int(floor(m_hue + 0.5));
|
return int(std::floor(m_hue + 0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Hsv::saturationInt() const
|
int Hsv::saturationInt() const
|
||||||
{
|
{
|
||||||
return int(floor(m_saturation*100.0 + 0.5));
|
return int(std::floor(m_saturation*100.0 + 0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Hsv::valueInt() const
|
int Hsv::valueInt() const
|
||||||
{
|
{
|
||||||
return int(floor(m_value*100.0 + 0.5));
|
return int(std::floor(m_value*100.0 + 0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#define GFX_HSV_H_INCLUDED
|
#define GFX_HSV_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cassert>
|
#include "base/base.h" // MID
|
||||||
|
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
|
|
||||||
@ -48,18 +48,15 @@ public:
|
|||||||
int valueInt() const;
|
int valueInt() const;
|
||||||
|
|
||||||
void hue(double hue) {
|
void hue(double hue) {
|
||||||
assert(hue >= 0.0 && hue <= 360.0);
|
m_hue = MID(0.0, hue, 360.0);
|
||||||
m_hue = hue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void saturation(double saturation) {
|
void saturation(double saturation) {
|
||||||
assert(saturation >= 0.0 && saturation <= 1.0);
|
m_saturation = MID(0.0, saturation, 1.0);
|
||||||
m_saturation = saturation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void value(double value) {
|
void value(double value) {
|
||||||
assert(value >= 0.0 && value <= 1.0);
|
m_value = MID(0.0, value, 1.0);
|
||||||
m_value = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The comparison is done through the integer value of each component.
|
// The comparison is done through the integer value of each component.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user