diff --git a/src/ast.cpp b/src/ast.cpp index 943168e73..681f059b4 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -511,6 +511,25 @@ namespace Sass { ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// + Expression::Expression(ParserState pstate, bool d, bool e, bool i, Type ct) + : AST_Node(pstate), + is_delayed_(d), + is_expanded_(e), + is_interpolant_(i), + concrete_type_(ct) + { } + + Expression::Expression(const Expression* ptr) + : AST_Node(ptr), + is_delayed_(ptr->is_delayed_), + is_expanded_(ptr->is_expanded_), + is_interpolant_(ptr->is_interpolant_), + concrete_type_(ptr->concrete_type_) + { } + + ///////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////// + Unary_Expression::Unary_Expression(ParserState pstate, Type t, Expression_Obj o) : Expression(pstate), optype_(t), operand_(o), hash_(0) { } diff --git a/src/ast.hpp b/src/ast.hpp index 30282e842..6718296c8 100644 --- a/src/ast.hpp +++ b/src/ast.hpp @@ -80,7 +80,7 @@ namespace Sass { case LT: return "lt"; case LTE: return "lte"; case ADD: return "plus"; - case SUB: return "sub"; + case SUB: return "minus"; case MUL: return "times"; case DIV: return "div"; case MOD: return "mod"; @@ -198,21 +198,7 @@ namespace Sass { ADD_PROPERTY(bool, is_interpolant) ADD_PROPERTY(Type, concrete_type) public: - Expression(ParserState pstate, - bool d = false, bool e = false, bool i = false, Type ct = NONE) - : AST_Node(pstate), - is_delayed_(d), - is_expanded_(e), - is_interpolant_(i), - concrete_type_(ct) - { } - Expression(const Expression* ptr) - : AST_Node(ptr), - is_delayed_(ptr->is_delayed_), - is_expanded_(ptr->is_expanded_), - is_interpolant_(ptr->is_interpolant_), - concrete_type_(ptr->concrete_type_) - { } + Expression(ParserState pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE); virtual operator bool() { return true; } virtual ~Expression() { } virtual bool is_invisible() const { return false; } @@ -441,7 +427,6 @@ namespace Sass { ADD_PROPERTY(bool, group_end) public: Statement(ParserState pstate, Type st = NONE, size_t t = 0); - Statement(const Statement* ptr); // copy constructor virtual ~Statement() = 0; // virtual destructor // needed for rearranging nested rulesets during CSS emission virtual bool bubbles(); diff --git a/src/ast2c.cpp b/src/ast2c.cpp index be9ea800f..6498c5d30 100644 --- a/src/ast2c.cpp +++ b/src/ast2c.cpp @@ -16,9 +16,12 @@ namespace Sass { union Sass_Value* AST2C::operator()(Custom_Error_Ptr e) { return sass_make_error(e->message().c_str()); } - union Sass_Value* AST2C::operator()(Color_Ptr c) + union Sass_Value* AST2C::operator()(Color_RGBA_Ptr c) { return sass_make_color(c->r(), c->g(), c->b(), c->a()); } + union Sass_Value* AST2C::operator()(Color_HSLA_Ptr c) + { return operator()(c->toRGBA()); } + union Sass_Value* AST2C::operator()(String_Constant_Ptr s) { if (s->quote_mark()) { diff --git a/src/ast2c.hpp b/src/ast2c.hpp index 428791619..a1b2dee40 100644 --- a/src/ast2c.hpp +++ b/src/ast2c.hpp @@ -16,7 +16,8 @@ namespace Sass { union Sass_Value* operator()(Boolean_Ptr); union Sass_Value* operator()(Number_Ptr); - union Sass_Value* operator()(Color_Ptr); + union Sass_Value* operator()(Color_RGBA_Ptr); + union Sass_Value* operator()(Color_HSLA_Ptr); union Sass_Value* operator()(String_Constant_Ptr); union Sass_Value* operator()(String_Quoted_Ptr); union Sass_Value* operator()(Custom_Warning_Ptr); diff --git a/src/ast_def_macros.hpp b/src/ast_def_macros.hpp index 75bb6fcde..cfe489daa 100644 --- a/src/ast_def_macros.hpp +++ b/src/ast_def_macros.hpp @@ -74,6 +74,7 @@ public: \ virtual klass##_Ptr clone(std::string, size_t) const = 0; \ #define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \ + klass(const klass* ptr); \ virtual klass##_Ptr copy(std::string, size_t) const override = 0; \ virtual klass##_Ptr clone(std::string, size_t) const override = 0; \ @@ -89,6 +90,7 @@ public: \ virtual klass##_Ptr clone() const = 0; \ #define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \ + klass(const klass* ptr); \ virtual klass##_Ptr copy() const override = 0; \ virtual klass##_Ptr clone() const override = 0; \ diff --git a/src/ast_fwd_decl.cpp b/src/ast_fwd_decl.cpp index c9c76727a..cd54fa240 100644 --- a/src/ast_fwd_decl.cpp +++ b/src/ast_fwd_decl.cpp @@ -19,6 +19,7 @@ namespace Sass { IMPLEMENT_BASE_CAST(Has_Block) IMPLEMENT_BASE_CAST(PreValue) IMPLEMENT_BASE_CAST(Value) + IMPLEMENT_BASE_CAST(Color) IMPLEMENT_BASE_CAST(List) IMPLEMENT_BASE_CAST(String) IMPLEMENT_BASE_CAST(String_Constant) diff --git a/src/ast_fwd_decl.hpp b/src/ast_fwd_decl.hpp index d68bedf5a..a66495985 100644 --- a/src/ast_fwd_decl.hpp +++ b/src/ast_fwd_decl.hpp @@ -166,6 +166,12 @@ namespace Sass { class Color; typedef Color* Color_Ptr; typedef Color const* Color_Ptr_Const; + class Color_RGBA; + typedef Color_RGBA* Color_RGBA_Ptr; + typedef Color_RGBA const* Color_RGBA_Ptr_Const; + class Color_HSLA; + typedef Color_HSLA* Color_HSLA_Ptr; + typedef Color_HSLA const* Color_HSLA_Ptr_Const; class Boolean; typedef Boolean* Boolean_Ptr; typedef Boolean const* Boolean_Ptr_Const; @@ -321,6 +327,8 @@ namespace Sass { IMPL_MEM_OBJ(Variable); IMPL_MEM_OBJ(Number); IMPL_MEM_OBJ(Color); + IMPL_MEM_OBJ(Color_RGBA); + IMPL_MEM_OBJ(Color_HSLA); IMPL_MEM_OBJ(Boolean); IMPL_MEM_OBJ(String_Schema); IMPL_MEM_OBJ(String); @@ -477,6 +485,7 @@ namespace Sass { DECLARE_BASE_CAST(PreValue) DECLARE_BASE_CAST(Value) DECLARE_BASE_CAST(List) + DECLARE_BASE_CAST(Color) DECLARE_BASE_CAST(String) DECLARE_BASE_CAST(String_Constant) DECLARE_BASE_CAST(Supports_Condition) diff --git a/src/ast_selectors.hpp b/src/ast_selectors.hpp index ee4c3a306..c8039dee5 100644 --- a/src/ast_selectors.hpp +++ b/src/ast_selectors.hpp @@ -50,7 +50,6 @@ namespace Sass { mutable size_t hash_; public: Selector(ParserState pstate); - Selector(const Selector* ptr); virtual ~Selector() = 0; size_t hash() const override = 0; virtual unsigned long specificity() const = 0; @@ -115,7 +114,6 @@ namespace Sass { HASH_PROPERTY(bool, has_ns) public: Simple_Selector(ParserState pstate, std::string n = ""); - Simple_Selector(const Simple_Selector* ptr); virtual std::string ns_name() const; size_t hash() const override; bool empty() const; diff --git a/src/ast_values.cpp b/src/ast_values.cpp index 633ec5ae4..ffcd27f86 100644 --- a/src/ast_values.cpp +++ b/src/ast_values.cpp @@ -210,7 +210,7 @@ namespace Sass { { return sass_op_to_name(optype()); } - + const std::string Binary_Expression::separator() { return sass_op_separator(optype()); @@ -221,7 +221,7 @@ namespace Sass { return is_left_interpolant() || is_right_interpolant(); } - + void Binary_Expression::set_delayed(bool delayed) { right()->set_delayed(delayed); @@ -485,24 +485,52 @@ namespace Sass { ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// - Color::Color(ParserState pstate, double r, double g, double b, double a, const std::string disp) - : Value(pstate), r_(r), g_(g), b_(b), a_(a), disp_(disp), + Color::Color(ParserState pstate, double a, const std::string disp) + : Value(pstate), + disp_(disp), a_(a), hash_(0) { concrete_type(COLOR); } Color::Color(const Color* ptr) - : Value(ptr), - r_(ptr->r_), - g_(ptr->g_), - b_(ptr->b_), + : Value(ptr->pstate()), + // reset on copy + disp_(""), a_(ptr->a_), - disp_(ptr->disp_), hash_(ptr->hash_) { concrete_type(COLOR); } bool Color::operator== (const Expression& rhs) const { - if (auto r = Cast(&rhs)) { + if (auto r = Cast(&rhs)) { + return *this == *r; + } + else if (auto r = Cast(&rhs)) { + return *this == *r; + } + else if (auto r = Cast(&rhs)) { + return a_ == r->a(); + } + return false; + } + + ///////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////// + + Color_RGBA::Color_RGBA(ParserState pstate, double r, double g, double b, double a, const std::string disp) + : Color(pstate, a, disp), + r_(r), g_(g), b_(b) + { concrete_type(COLOR); } + + Color_RGBA::Color_RGBA(const Color_RGBA* ptr) + : Color(ptr), + r_(ptr->r_), + g_(ptr->g_), + b_(ptr->b_) + { concrete_type(COLOR); } + + bool Color_RGBA::operator== (const Expression& rhs) const + { + if (auto r = Cast(&rhs)) { return r_ == r->r() && g_ == r->g() && b_ == r->b() && @@ -511,10 +539,11 @@ namespace Sass { return false; } - size_t Color::hash() const + size_t Color_RGBA::hash() const { if (hash_ == 0) { - hash_ = std::hash()(a_); + hash_ = std::hash()("RGBA"); + hash_combine(hash_, std::hash()(a_)); hash_combine(hash_, std::hash()(r_)); hash_combine(hash_, std::hash()(g_)); hash_combine(hash_, std::hash()(b_)); @@ -522,6 +551,128 @@ namespace Sass { return hash_; } + Color_HSLA_Ptr Color_RGBA::toHSLA(bool copy) + { + + // Algorithm from http://en.wikipedia.org/wiki/wHSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV + double r = r_ / 255.0; + double g = g_ / 255.0; + double b = b_ / 255.0; + + double max = std::max(r, std::max(g, b)); + double min = std::min(r, std::min(g, b)); + double delta = max - min; + + double h = 0; + double s; + double l = (max + min) / 2.0; + + if (NEAR_EQUAL(max, min)) { + h = s = 0; // achromatic + } + else { + if (l < 0.5) s = delta / (max + min); + else s = delta / (2.0 - max - min); + + if (r == max) h = (g - b) / delta + (g < b ? 6 : 0); + else if (g == max) h = (b - r) / delta + 2; + else if (b == max) h = (r - g) / delta + 4; + } + + // HSL hsl_struct; + h = h * 60; + s = s * 100; + l = l * 100; + + return SASS_MEMORY_NEW(Color_HSLA, + pstate(), h, s, l, a(), "" + ); + } + + Color_RGBA_Ptr Color_RGBA::toRGBA(bool copy) + { + return copy ? SASS_MEMORY_COPY(this) : this; + } + + ///////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////// + + Color_HSLA::Color_HSLA(ParserState pstate, double h, double s, double l, double a, const std::string disp) + : Color(pstate, a, disp), + h_(absmod(h, 360.0)), + s_(clip(s, 0.0, 100.0)), + l_(clip(l, 0.0, 100.0)) + // hash_(0) + { concrete_type(COLOR); } + + Color_HSLA::Color_HSLA(const Color_HSLA* ptr) + : Color(ptr), + h_(ptr->h_), + s_(ptr->s_), + l_(ptr->l_) + // hash_(ptr->hash_) + { concrete_type(COLOR); } + + bool Color_HSLA::operator== (const Expression& rhs) const + { + if (auto r = Cast(&rhs)) { + return h_ == r->h() && + s_ == r->s() && + l_ == r->l() && + a_ == r->a(); + } + return false; + } + + size_t Color_HSLA::hash() const + { + if (hash_ == 0) { + hash_ = std::hash()("HSLA"); + hash_combine(hash_, std::hash()(a_)); + hash_combine(hash_, std::hash()(h_)); + hash_combine(hash_, std::hash()(s_)); + hash_combine(hash_, std::hash()(l_)); + } + return hash_; + } + + // hue to RGB helper function + double h_to_rgb(double m1, double m2, double h) + { + h = absmod(h, 1.0); + if (h*6.0 < 1) return m1 + (m2 - m1)*h*6; + if (h*2.0 < 1) return m2; + if (h*3.0 < 2) return m1 + (m2 - m1) * (2.0/3.0 - h)*6; + return m1; + } + + Color_RGBA_Ptr Color_HSLA::toRGBA(bool copy) + { + + double h = absmod(h_ / 360.0, 1.0); + double s = clip(s_ / 100.0, 0.0, 1.0); + double l = clip(l_ / 100.0, 0.0, 1.0); + + // Algorithm from the CSS3 spec: http://www.w3.org/TR/css3-color/#hsl-color. + double m2; + if (l <= 0.5) m2 = l*(s+1.0); + else m2 = (l+s)-(l*s); + double m1 = (l*2.0)-m2; + // round the results -- consider moving this into the Color constructor + double r = (h_to_rgb(m1, m2, h + 1.0/3.0) * 255.0); + double g = (h_to_rgb(m1, m2, h) * 255.0); + double b = (h_to_rgb(m1, m2, h - 1.0/3.0) * 255.0); + + return SASS_MEMORY_NEW(Color_RGBA, + pstate(), r, g, b, a(), "" + ); + } + + Color_HSLA_Ptr Color_HSLA::toHSLA(bool copy) + { + return copy ? SASS_MEMORY_COPY(this) : this; + } + ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// @@ -796,7 +947,8 @@ namespace Sass { IMPLEMENT_AST_OPERATORS(Function_Call); IMPLEMENT_AST_OPERATORS(Variable); IMPLEMENT_AST_OPERATORS(Number); - IMPLEMENT_AST_OPERATORS(Color); + IMPLEMENT_AST_OPERATORS(Color_RGBA); + IMPLEMENT_AST_OPERATORS(Color_HSLA); IMPLEMENT_AST_OPERATORS(Custom_Error); IMPLEMENT_AST_OPERATORS(Custom_Warning); IMPLEMENT_AST_OPERATORS(Boolean); diff --git a/src/ast_values.hpp b/src/ast_values.hpp index ee49962e5..0df859199 100644 --- a/src/ast_values.hpp +++ b/src/ast_values.hpp @@ -39,7 +39,6 @@ namespace Sass { class PreValue : public Expression { public: PreValue(ParserState pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE); - PreValue(const PreValue* ptr); ATTACH_VIRTUAL_AST_OPERATIONS(PreValue); virtual ~PreValue() { } }; @@ -50,7 +49,6 @@ namespace Sass { class Value : public PreValue { public: Value(ParserState pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE); - Value(const Value* ptr); ATTACH_VIRTUAL_AST_OPERATIONS(Value); virtual bool operator== (const Expression& rhs) const override = 0; }; @@ -237,24 +235,71 @@ namespace Sass { ////////// // Colors. ////////// - class Color final : public Value { + class Color : public Value { + ADD_CONSTREF(std::string, disp) + HASH_PROPERTY(double, a) + protected: + mutable size_t hash_; + public: + Color(ParserState pstate, double a = 1, const std::string disp = ""); + + std::string type() const override { return "color"; } + static std::string type_name() { return "color"; } + + virtual size_t hash() const override = 0; + + bool operator== (const Expression& rhs) const override; + + virtual Color_RGBA_Ptr toRGBA(bool copy = false) = 0; + virtual Color_HSLA_Ptr toHSLA(bool copy = false) = 0; + + ATTACH_VIRTUAL_AST_OPERATIONS(Color) + }; + + ////////// + // Colors. + ////////// + class Color_RGBA final : public Color { HASH_PROPERTY(double, r) HASH_PROPERTY(double, g) HASH_PROPERTY(double, b) - HASH_PROPERTY(double, a) - ADD_CONSTREF(std::string, disp) - mutable size_t hash_; public: - Color(ParserState pstate, double r, double g, double b, double a = 1, const std::string disp = ""); + Color_RGBA(ParserState pstate, double r, double g, double b, double a = 1, const std::string disp = ""); + + std::string type() const override { return "color"; } + static std::string type_name() { return "color"; } + + size_t hash() const override; + Color_RGBA_Ptr toRGBA(bool copy = false) override; + Color_HSLA_Ptr toHSLA(bool copy = false) override; + + bool operator== (const Expression& rhs) const override; + + ATTACH_AST_OPERATIONS(Color_RGBA) + ATTACH_CRTP_PERFORM_METHODS() + }; + + + ////////// + // Colors. + ////////// + class Color_HSLA final : public Color { + HASH_PROPERTY(double, h) + HASH_PROPERTY(double, s) + HASH_PROPERTY(double, l) + public: + Color_HSLA(ParserState pstate, double h, double s, double l, double a = 1, const std::string disp = ""); std::string type() const override { return "color"; } static std::string type_name() { return "color"; } size_t hash() const override; + Color_RGBA_Ptr toRGBA(bool copy = false) override; + Color_HSLA_Ptr toHSLA(bool copy = false) override; bool operator== (const Expression& rhs) const override; - ATTACH_AST_OPERATIONS(Color) + ATTACH_AST_OPERATIONS(Color_HSLA) ATTACH_CRTP_PERFORM_METHODS() }; @@ -312,7 +357,6 @@ namespace Sass { class String : public Value { public: String(ParserState pstate, bool delayed = false); - String(const String* ptr); static std::string type_name() { return "string"; } virtual ~String() = 0; virtual void rtrim() = 0; diff --git a/src/c2ast.cpp b/src/c2ast.cpp index c766fa184..3bcbe09d1 100644 --- a/src/c2ast.cpp +++ b/src/c2ast.cpp @@ -21,7 +21,7 @@ namespace Sass { e = SASS_MEMORY_NEW(Number, pstate, sass_number_get_value(v), sass_number_get_unit(v)); } break; case SASS_COLOR: { - e = SASS_MEMORY_NEW(Color, pstate, sass_color_get_r(v), sass_color_get_g(v), sass_color_get_b(v), sass_color_get_a(v)); + e = SASS_MEMORY_NEW(Color_RGBA, pstate, sass_color_get_r(v), sass_color_get_g(v), sass_color_get_b(v), sass_color_get_a(v)); } break; case SASS_STRING: { if (sass_string_is_quoted(v)) diff --git a/src/color_maps.cpp b/src/color_maps.cpp index 129e47c5a..7ad0c3987 100644 --- a/src/color_maps.cpp +++ b/src/color_maps.cpp @@ -159,155 +159,155 @@ namespace Sass { namespace Colors { const ParserState color_table("[COLOR TABLE]"); - const Color aliceblue(color_table, 240, 248, 255, 1); - const Color antiquewhite(color_table, 250, 235, 215, 1); - const Color cyan(color_table, 0, 255, 255, 1); - const Color aqua(color_table, 0, 255, 255, 1); - const Color aquamarine(color_table, 127, 255, 212, 1); - const Color azure(color_table, 240, 255, 255, 1); - const Color beige(color_table, 245, 245, 220, 1); - const Color bisque(color_table, 255, 228, 196, 1); - const Color black(color_table, 0, 0, 0, 1); - const Color blanchedalmond(color_table, 255, 235, 205, 1); - const Color blue(color_table, 0, 0, 255, 1); - const Color blueviolet(color_table, 138, 43, 226, 1); - const Color brown(color_table, 165, 42, 42, 1); - const Color burlywood(color_table, 222, 184, 135, 1); - const Color cadetblue(color_table, 95, 158, 160, 1); - const Color chartreuse(color_table, 127, 255, 0, 1); - const Color chocolate(color_table, 210, 105, 30, 1); - const Color coral(color_table, 255, 127, 80, 1); - const Color cornflowerblue(color_table, 100, 149, 237, 1); - const Color cornsilk(color_table, 255, 248, 220, 1); - const Color crimson(color_table, 220, 20, 60, 1); - const Color darkblue(color_table, 0, 0, 139, 1); - const Color darkcyan(color_table, 0, 139, 139, 1); - const Color darkgoldenrod(color_table, 184, 134, 11, 1); - const Color darkgray(color_table, 169, 169, 169, 1); - const Color darkgrey(color_table, 169, 169, 169, 1); - const Color darkgreen(color_table, 0, 100, 0, 1); - const Color darkkhaki(color_table, 189, 183, 107, 1); - const Color darkmagenta(color_table, 139, 0, 139, 1); - const Color darkolivegreen(color_table, 85, 107, 47, 1); - const Color darkorange(color_table, 255, 140, 0, 1); - const Color darkorchid(color_table, 153, 50, 204, 1); - const Color darkred(color_table, 139, 0, 0, 1); - const Color darksalmon(color_table, 233, 150, 122, 1); - const Color darkseagreen(color_table, 143, 188, 143, 1); - const Color darkslateblue(color_table, 72, 61, 139, 1); - const Color darkslategray(color_table, 47, 79, 79, 1); - const Color darkslategrey(color_table, 47, 79, 79, 1); - const Color darkturquoise(color_table, 0, 206, 209, 1); - const Color darkviolet(color_table, 148, 0, 211, 1); - const Color deeppink(color_table, 255, 20, 147, 1); - const Color deepskyblue(color_table, 0, 191, 255, 1); - const Color dimgray(color_table, 105, 105, 105, 1); - const Color dimgrey(color_table, 105, 105, 105, 1); - const Color dodgerblue(color_table, 30, 144, 255, 1); - const Color firebrick(color_table, 178, 34, 34, 1); - const Color floralwhite(color_table, 255, 250, 240, 1); - const Color forestgreen(color_table, 34, 139, 34, 1); - const Color magenta(color_table, 255, 0, 255, 1); - const Color fuchsia(color_table, 255, 0, 255, 1); - const Color gainsboro(color_table, 220, 220, 220, 1); - const Color ghostwhite(color_table, 248, 248, 255, 1); - const Color gold(color_table, 255, 215, 0, 1); - const Color goldenrod(color_table, 218, 165, 32, 1); - const Color gray(color_table, 128, 128, 128, 1); - const Color grey(color_table, 128, 128, 128, 1); - const Color green(color_table, 0, 128, 0, 1); - const Color greenyellow(color_table, 173, 255, 47, 1); - const Color honeydew(color_table, 240, 255, 240, 1); - const Color hotpink(color_table, 255, 105, 180, 1); - const Color indianred(color_table, 205, 92, 92, 1); - const Color indigo(color_table, 75, 0, 130, 1); - const Color ivory(color_table, 255, 255, 240, 1); - const Color khaki(color_table, 240, 230, 140, 1); - const Color lavender(color_table, 230, 230, 250, 1); - const Color lavenderblush(color_table, 255, 240, 245, 1); - const Color lawngreen(color_table, 124, 252, 0, 1); - const Color lemonchiffon(color_table, 255, 250, 205, 1); - const Color lightblue(color_table, 173, 216, 230, 1); - const Color lightcoral(color_table, 240, 128, 128, 1); - const Color lightcyan(color_table, 224, 255, 255, 1); - const Color lightgoldenrodyellow(color_table, 250, 250, 210, 1); - const Color lightgray(color_table, 211, 211, 211, 1); - const Color lightgrey(color_table, 211, 211, 211, 1); - const Color lightgreen(color_table, 144, 238, 144, 1); - const Color lightpink(color_table, 255, 182, 193, 1); - const Color lightsalmon(color_table, 255, 160, 122, 1); - const Color lightseagreen(color_table, 32, 178, 170, 1); - const Color lightskyblue(color_table, 135, 206, 250, 1); - const Color lightslategray(color_table, 119, 136, 153, 1); - const Color lightslategrey(color_table, 119, 136, 153, 1); - const Color lightsteelblue(color_table, 176, 196, 222, 1); - const Color lightyellow(color_table, 255, 255, 224, 1); - const Color lime(color_table, 0, 255, 0, 1); - const Color limegreen(color_table, 50, 205, 50, 1); - const Color linen(color_table, 250, 240, 230, 1); - const Color maroon(color_table, 128, 0, 0, 1); - const Color mediumaquamarine(color_table, 102, 205, 170, 1); - const Color mediumblue(color_table, 0, 0, 205, 1); - const Color mediumorchid(color_table, 186, 85, 211, 1); - const Color mediumpurple(color_table, 147, 112, 219, 1); - const Color mediumseagreen(color_table, 60, 179, 113, 1); - const Color mediumslateblue(color_table, 123, 104, 238, 1); - const Color mediumspringgreen(color_table, 0, 250, 154, 1); - const Color mediumturquoise(color_table, 72, 209, 204, 1); - const Color mediumvioletred(color_table, 199, 21, 133, 1); - const Color midnightblue(color_table, 25, 25, 112, 1); - const Color mintcream(color_table, 245, 255, 250, 1); - const Color mistyrose(color_table, 255, 228, 225, 1); - const Color moccasin(color_table, 255, 228, 181, 1); - const Color navajowhite(color_table, 255, 222, 173, 1); - const Color navy(color_table, 0, 0, 128, 1); - const Color oldlace(color_table, 253, 245, 230, 1); - const Color olive(color_table, 128, 128, 0, 1); - const Color olivedrab(color_table, 107, 142, 35, 1); - const Color orange(color_table, 255, 165, 0, 1); - const Color orangered(color_table, 255, 69, 0, 1); - const Color orchid(color_table, 218, 112, 214, 1); - const Color palegoldenrod(color_table, 238, 232, 170, 1); - const Color palegreen(color_table, 152, 251, 152, 1); - const Color paleturquoise(color_table, 175, 238, 238, 1); - const Color palevioletred(color_table, 219, 112, 147, 1); - const Color papayawhip(color_table, 255, 239, 213, 1); - const Color peachpuff(color_table, 255, 218, 185, 1); - const Color peru(color_table, 205, 133, 63, 1); - const Color pink(color_table, 255, 192, 203, 1); - const Color plum(color_table, 221, 160, 221, 1); - const Color powderblue(color_table, 176, 224, 230, 1); - const Color purple(color_table, 128, 0, 128, 1); - const Color red(color_table, 255, 0, 0, 1); - const Color rosybrown(color_table, 188, 143, 143, 1); - const Color royalblue(color_table, 65, 105, 225, 1); - const Color saddlebrown(color_table, 139, 69, 19, 1); - const Color salmon(color_table, 250, 128, 114, 1); - const Color sandybrown(color_table, 244, 164, 96, 1); - const Color seagreen(color_table, 46, 139, 87, 1); - const Color seashell(color_table, 255, 245, 238, 1); - const Color sienna(color_table, 160, 82, 45, 1); - const Color silver(color_table, 192, 192, 192, 1); - const Color skyblue(color_table, 135, 206, 235, 1); - const Color slateblue(color_table, 106, 90, 205, 1); - const Color slategray(color_table, 112, 128, 144, 1); - const Color slategrey(color_table, 112, 128, 144, 1); - const Color snow(color_table, 255, 250, 250, 1); - const Color springgreen(color_table, 0, 255, 127, 1); - const Color steelblue(color_table, 70, 130, 180, 1); - const Color tan(color_table, 210, 180, 140, 1); - const Color teal(color_table, 0, 128, 128, 1); - const Color thistle(color_table, 216, 191, 216, 1); - const Color tomato(color_table, 255, 99, 71, 1); - const Color turquoise(color_table, 64, 224, 208, 1); - const Color violet(color_table, 238, 130, 238, 1); - const Color wheat(color_table, 245, 222, 179, 1); - const Color white(color_table, 255, 255, 255, 1); - const Color whitesmoke(color_table, 245, 245, 245, 1); - const Color yellow(color_table, 255, 255, 0, 1); - const Color yellowgreen(color_table, 154, 205, 50, 1); - const Color rebeccapurple(color_table, 102, 51, 153, 1); - const Color transparent(color_table, 0, 0, 0, 0); + const Color_RGBA aliceblue(color_table, 240, 248, 255, 1); + const Color_RGBA antiquewhite(color_table, 250, 235, 215, 1); + const Color_RGBA cyan(color_table, 0, 255, 255, 1); + const Color_RGBA aqua(color_table, 0, 255, 255, 1); + const Color_RGBA aquamarine(color_table, 127, 255, 212, 1); + const Color_RGBA azure(color_table, 240, 255, 255, 1); + const Color_RGBA beige(color_table, 245, 245, 220, 1); + const Color_RGBA bisque(color_table, 255, 228, 196, 1); + const Color_RGBA black(color_table, 0, 0, 0, 1); + const Color_RGBA blanchedalmond(color_table, 255, 235, 205, 1); + const Color_RGBA blue(color_table, 0, 0, 255, 1); + const Color_RGBA blueviolet(color_table, 138, 43, 226, 1); + const Color_RGBA brown(color_table, 165, 42, 42, 1); + const Color_RGBA burlywood(color_table, 222, 184, 135, 1); + const Color_RGBA cadetblue(color_table, 95, 158, 160, 1); + const Color_RGBA chartreuse(color_table, 127, 255, 0, 1); + const Color_RGBA chocolate(color_table, 210, 105, 30, 1); + const Color_RGBA coral(color_table, 255, 127, 80, 1); + const Color_RGBA cornflowerblue(color_table, 100, 149, 237, 1); + const Color_RGBA cornsilk(color_table, 255, 248, 220, 1); + const Color_RGBA crimson(color_table, 220, 20, 60, 1); + const Color_RGBA darkblue(color_table, 0, 0, 139, 1); + const Color_RGBA darkcyan(color_table, 0, 139, 139, 1); + const Color_RGBA darkgoldenrod(color_table, 184, 134, 11, 1); + const Color_RGBA darkgray(color_table, 169, 169, 169, 1); + const Color_RGBA darkgrey(color_table, 169, 169, 169, 1); + const Color_RGBA darkgreen(color_table, 0, 100, 0, 1); + const Color_RGBA darkkhaki(color_table, 189, 183, 107, 1); + const Color_RGBA darkmagenta(color_table, 139, 0, 139, 1); + const Color_RGBA darkolivegreen(color_table, 85, 107, 47, 1); + const Color_RGBA darkorange(color_table, 255, 140, 0, 1); + const Color_RGBA darkorchid(color_table, 153, 50, 204, 1); + const Color_RGBA darkred(color_table, 139, 0, 0, 1); + const Color_RGBA darksalmon(color_table, 233, 150, 122, 1); + const Color_RGBA darkseagreen(color_table, 143, 188, 143, 1); + const Color_RGBA darkslateblue(color_table, 72, 61, 139, 1); + const Color_RGBA darkslategray(color_table, 47, 79, 79, 1); + const Color_RGBA darkslategrey(color_table, 47, 79, 79, 1); + const Color_RGBA darkturquoise(color_table, 0, 206, 209, 1); + const Color_RGBA darkviolet(color_table, 148, 0, 211, 1); + const Color_RGBA deeppink(color_table, 255, 20, 147, 1); + const Color_RGBA deepskyblue(color_table, 0, 191, 255, 1); + const Color_RGBA dimgray(color_table, 105, 105, 105, 1); + const Color_RGBA dimgrey(color_table, 105, 105, 105, 1); + const Color_RGBA dodgerblue(color_table, 30, 144, 255, 1); + const Color_RGBA firebrick(color_table, 178, 34, 34, 1); + const Color_RGBA floralwhite(color_table, 255, 250, 240, 1); + const Color_RGBA forestgreen(color_table, 34, 139, 34, 1); + const Color_RGBA magenta(color_table, 255, 0, 255, 1); + const Color_RGBA fuchsia(color_table, 255, 0, 255, 1); + const Color_RGBA gainsboro(color_table, 220, 220, 220, 1); + const Color_RGBA ghostwhite(color_table, 248, 248, 255, 1); + const Color_RGBA gold(color_table, 255, 215, 0, 1); + const Color_RGBA goldenrod(color_table, 218, 165, 32, 1); + const Color_RGBA gray(color_table, 128, 128, 128, 1); + const Color_RGBA grey(color_table, 128, 128, 128, 1); + const Color_RGBA green(color_table, 0, 128, 0, 1); + const Color_RGBA greenyellow(color_table, 173, 255, 47, 1); + const Color_RGBA honeydew(color_table, 240, 255, 240, 1); + const Color_RGBA hotpink(color_table, 255, 105, 180, 1); + const Color_RGBA indianred(color_table, 205, 92, 92, 1); + const Color_RGBA indigo(color_table, 75, 0, 130, 1); + const Color_RGBA ivory(color_table, 255, 255, 240, 1); + const Color_RGBA khaki(color_table, 240, 230, 140, 1); + const Color_RGBA lavender(color_table, 230, 230, 250, 1); + const Color_RGBA lavenderblush(color_table, 255, 240, 245, 1); + const Color_RGBA lawngreen(color_table, 124, 252, 0, 1); + const Color_RGBA lemonchiffon(color_table, 255, 250, 205, 1); + const Color_RGBA lightblue(color_table, 173, 216, 230, 1); + const Color_RGBA lightcoral(color_table, 240, 128, 128, 1); + const Color_RGBA lightcyan(color_table, 224, 255, 255, 1); + const Color_RGBA lightgoldenrodyellow(color_table, 250, 250, 210, 1); + const Color_RGBA lightgray(color_table, 211, 211, 211, 1); + const Color_RGBA lightgrey(color_table, 211, 211, 211, 1); + const Color_RGBA lightgreen(color_table, 144, 238, 144, 1); + const Color_RGBA lightpink(color_table, 255, 182, 193, 1); + const Color_RGBA lightsalmon(color_table, 255, 160, 122, 1); + const Color_RGBA lightseagreen(color_table, 32, 178, 170, 1); + const Color_RGBA lightskyblue(color_table, 135, 206, 250, 1); + const Color_RGBA lightslategray(color_table, 119, 136, 153, 1); + const Color_RGBA lightslategrey(color_table, 119, 136, 153, 1); + const Color_RGBA lightsteelblue(color_table, 176, 196, 222, 1); + const Color_RGBA lightyellow(color_table, 255, 255, 224, 1); + const Color_RGBA lime(color_table, 0, 255, 0, 1); + const Color_RGBA limegreen(color_table, 50, 205, 50, 1); + const Color_RGBA linen(color_table, 250, 240, 230, 1); + const Color_RGBA maroon(color_table, 128, 0, 0, 1); + const Color_RGBA mediumaquamarine(color_table, 102, 205, 170, 1); + const Color_RGBA mediumblue(color_table, 0, 0, 205, 1); + const Color_RGBA mediumorchid(color_table, 186, 85, 211, 1); + const Color_RGBA mediumpurple(color_table, 147, 112, 219, 1); + const Color_RGBA mediumseagreen(color_table, 60, 179, 113, 1); + const Color_RGBA mediumslateblue(color_table, 123, 104, 238, 1); + const Color_RGBA mediumspringgreen(color_table, 0, 250, 154, 1); + const Color_RGBA mediumturquoise(color_table, 72, 209, 204, 1); + const Color_RGBA mediumvioletred(color_table, 199, 21, 133, 1); + const Color_RGBA midnightblue(color_table, 25, 25, 112, 1); + const Color_RGBA mintcream(color_table, 245, 255, 250, 1); + const Color_RGBA mistyrose(color_table, 255, 228, 225, 1); + const Color_RGBA moccasin(color_table, 255, 228, 181, 1); + const Color_RGBA navajowhite(color_table, 255, 222, 173, 1); + const Color_RGBA navy(color_table, 0, 0, 128, 1); + const Color_RGBA oldlace(color_table, 253, 245, 230, 1); + const Color_RGBA olive(color_table, 128, 128, 0, 1); + const Color_RGBA olivedrab(color_table, 107, 142, 35, 1); + const Color_RGBA orange(color_table, 255, 165, 0, 1); + const Color_RGBA orangered(color_table, 255, 69, 0, 1); + const Color_RGBA orchid(color_table, 218, 112, 214, 1); + const Color_RGBA palegoldenrod(color_table, 238, 232, 170, 1); + const Color_RGBA palegreen(color_table, 152, 251, 152, 1); + const Color_RGBA paleturquoise(color_table, 175, 238, 238, 1); + const Color_RGBA palevioletred(color_table, 219, 112, 147, 1); + const Color_RGBA papayawhip(color_table, 255, 239, 213, 1); + const Color_RGBA peachpuff(color_table, 255, 218, 185, 1); + const Color_RGBA peru(color_table, 205, 133, 63, 1); + const Color_RGBA pink(color_table, 255, 192, 203, 1); + const Color_RGBA plum(color_table, 221, 160, 221, 1); + const Color_RGBA powderblue(color_table, 176, 224, 230, 1); + const Color_RGBA purple(color_table, 128, 0, 128, 1); + const Color_RGBA red(color_table, 255, 0, 0, 1); + const Color_RGBA rosybrown(color_table, 188, 143, 143, 1); + const Color_RGBA royalblue(color_table, 65, 105, 225, 1); + const Color_RGBA saddlebrown(color_table, 139, 69, 19, 1); + const Color_RGBA salmon(color_table, 250, 128, 114, 1); + const Color_RGBA sandybrown(color_table, 244, 164, 96, 1); + const Color_RGBA seagreen(color_table, 46, 139, 87, 1); + const Color_RGBA seashell(color_table, 255, 245, 238, 1); + const Color_RGBA sienna(color_table, 160, 82, 45, 1); + const Color_RGBA silver(color_table, 192, 192, 192, 1); + const Color_RGBA skyblue(color_table, 135, 206, 235, 1); + const Color_RGBA slateblue(color_table, 106, 90, 205, 1); + const Color_RGBA slategray(color_table, 112, 128, 144, 1); + const Color_RGBA slategrey(color_table, 112, 128, 144, 1); + const Color_RGBA snow(color_table, 255, 250, 250, 1); + const Color_RGBA springgreen(color_table, 0, 255, 127, 1); + const Color_RGBA steelblue(color_table, 70, 130, 180, 1); + const Color_RGBA tan(color_table, 210, 180, 140, 1); + const Color_RGBA teal(color_table, 0, 128, 128, 1); + const Color_RGBA thistle(color_table, 216, 191, 216, 1); + const Color_RGBA tomato(color_table, 255, 99, 71, 1); + const Color_RGBA turquoise(color_table, 64, 224, 208, 1); + const Color_RGBA violet(color_table, 238, 130, 238, 1); + const Color_RGBA wheat(color_table, 245, 222, 179, 1); + const Color_RGBA white(color_table, 255, 255, 255, 1); + const Color_RGBA whitesmoke(color_table, 245, 245, 245, 1); + const Color_RGBA yellow(color_table, 255, 255, 0, 1); + const Color_RGBA yellowgreen(color_table, 154, 205, 50, 1); + const Color_RGBA rebeccapurple(color_table, 102, 51, 153, 1); + const Color_RGBA transparent(color_table, 0, 0, 0, 0); } const std::map colors_to_names { @@ -452,7 +452,7 @@ namespace Sass { { 102 * 0x10000 + 51 * 0x100 + 153, ColorNames::rebeccapurple } }; - const std::map names_to_colors + const std::map names_to_colors { { ColorNames::aliceblue, &Colors::aliceblue }, { ColorNames::antiquewhite, &Colors::antiquewhite }, @@ -605,12 +605,12 @@ namespace Sass { { ColorNames::transparent, &Colors::transparent } }; - Color_Ptr_Const name_to_color(const char* key) + Color_RGBA_Ptr_Const name_to_color(const char* key) { return name_to_color(std::string(key)); } - Color_Ptr_Const name_to_color(const std::string& key) + Color_RGBA_Ptr_Const name_to_color(const std::string& key) { // case insensitive lookup. See #2462 std::string lower{key}; @@ -637,7 +637,7 @@ namespace Sass { return color_to_name((int)key); } - const char* color_to_name(const Color& c) + const char* color_to_name(const Color_RGBA& c) { double key = c.r() * 0x10000 + c.g() * 0x100 diff --git a/src/color_maps.hpp b/src/color_maps.hpp index d4fd41607..1e1978f1e 100644 --- a/src/color_maps.hpp +++ b/src/color_maps.hpp @@ -169,161 +169,161 @@ namespace Sass { } namespace Colors { - extern const Color aliceblue; - extern const Color antiquewhite; - extern const Color cyan; - extern const Color aqua; - extern const Color aquamarine; - extern const Color azure; - extern const Color beige; - extern const Color bisque; - extern const Color black; - extern const Color blanchedalmond; - extern const Color blue; - extern const Color blueviolet; - extern const Color brown; - extern const Color burlywood; - extern const Color cadetblue; - extern const Color chartreuse; - extern const Color chocolate; - extern const Color coral; - extern const Color cornflowerblue; - extern const Color cornsilk; - extern const Color crimson; - extern const Color darkblue; - extern const Color darkcyan; - extern const Color darkgoldenrod; - extern const Color darkgray; - extern const Color darkgrey; - extern const Color darkgreen; - extern const Color darkkhaki; - extern const Color darkmagenta; - extern const Color darkolivegreen; - extern const Color darkorange; - extern const Color darkorchid; - extern const Color darkred; - extern const Color darksalmon; - extern const Color darkseagreen; - extern const Color darkslateblue; - extern const Color darkslategray; - extern const Color darkslategrey; - extern const Color darkturquoise; - extern const Color darkviolet; - extern const Color deeppink; - extern const Color deepskyblue; - extern const Color dimgray; - extern const Color dimgrey; - extern const Color dodgerblue; - extern const Color firebrick; - extern const Color floralwhite; - extern const Color forestgreen; - extern const Color magenta; - extern const Color fuchsia; - extern const Color gainsboro; - extern const Color ghostwhite; - extern const Color gold; - extern const Color goldenrod; - extern const Color gray; - extern const Color grey; - extern const Color green; - extern const Color greenyellow; - extern const Color honeydew; - extern const Color hotpink; - extern const Color indianred; - extern const Color indigo; - extern const Color ivory; - extern const Color khaki; - extern const Color lavender; - extern const Color lavenderblush; - extern const Color lawngreen; - extern const Color lemonchiffon; - extern const Color lightblue; - extern const Color lightcoral; - extern const Color lightcyan; - extern const Color lightgoldenrodyellow; - extern const Color lightgray; - extern const Color lightgrey; - extern const Color lightgreen; - extern const Color lightpink; - extern const Color lightsalmon; - extern const Color lightseagreen; - extern const Color lightskyblue; - extern const Color lightslategray; - extern const Color lightslategrey; - extern const Color lightsteelblue; - extern const Color lightyellow; - extern const Color lime; - extern const Color limegreen; - extern const Color linen; - extern const Color maroon; - extern const Color mediumaquamarine; - extern const Color mediumblue; - extern const Color mediumorchid; - extern const Color mediumpurple; - extern const Color mediumseagreen; - extern const Color mediumslateblue; - extern const Color mediumspringgreen; - extern const Color mediumturquoise; - extern const Color mediumvioletred; - extern const Color midnightblue; - extern const Color mintcream; - extern const Color mistyrose; - extern const Color moccasin; - extern const Color navajowhite; - extern const Color navy; - extern const Color oldlace; - extern const Color olive; - extern const Color olivedrab; - extern const Color orange; - extern const Color orangered; - extern const Color orchid; - extern const Color palegoldenrod; - extern const Color palegreen; - extern const Color paleturquoise; - extern const Color palevioletred; - extern const Color papayawhip; - extern const Color peachpuff; - extern const Color peru; - extern const Color pink; - extern const Color plum; - extern const Color powderblue; - extern const Color purple; - extern const Color red; - extern const Color rosybrown; - extern const Color royalblue; - extern const Color saddlebrown; - extern const Color salmon; - extern const Color sandybrown; - extern const Color seagreen; - extern const Color seashell; - extern const Color sienna; - extern const Color silver; - extern const Color skyblue; - extern const Color slateblue; - extern const Color slategray; - extern const Color slategrey; - extern const Color snow; - extern const Color springgreen; - extern const Color steelblue; - extern const Color tan; - extern const Color teal; - extern const Color thistle; - extern const Color tomato; - extern const Color turquoise; - extern const Color violet; - extern const Color wheat; - extern const Color white; - extern const Color whitesmoke; - extern const Color yellow; - extern const Color yellowgreen; - extern const Color rebeccapurple; - extern const Color transparent; + extern const Color_RGBA aliceblue; + extern const Color_RGBA antiquewhite; + extern const Color_RGBA cyan; + extern const Color_RGBA aqua; + extern const Color_RGBA aquamarine; + extern const Color_RGBA azure; + extern const Color_RGBA beige; + extern const Color_RGBA bisque; + extern const Color_RGBA black; + extern const Color_RGBA blanchedalmond; + extern const Color_RGBA blue; + extern const Color_RGBA blueviolet; + extern const Color_RGBA brown; + extern const Color_RGBA burlywood; + extern const Color_RGBA cadetblue; + extern const Color_RGBA chartreuse; + extern const Color_RGBA chocolate; + extern const Color_RGBA coral; + extern const Color_RGBA cornflowerblue; + extern const Color_RGBA cornsilk; + extern const Color_RGBA crimson; + extern const Color_RGBA darkblue; + extern const Color_RGBA darkcyan; + extern const Color_RGBA darkgoldenrod; + extern const Color_RGBA darkgray; + extern const Color_RGBA darkgrey; + extern const Color_RGBA darkgreen; + extern const Color_RGBA darkkhaki; + extern const Color_RGBA darkmagenta; + extern const Color_RGBA darkolivegreen; + extern const Color_RGBA darkorange; + extern const Color_RGBA darkorchid; + extern const Color_RGBA darkred; + extern const Color_RGBA darksalmon; + extern const Color_RGBA darkseagreen; + extern const Color_RGBA darkslateblue; + extern const Color_RGBA darkslategray; + extern const Color_RGBA darkslategrey; + extern const Color_RGBA darkturquoise; + extern const Color_RGBA darkviolet; + extern const Color_RGBA deeppink; + extern const Color_RGBA deepskyblue; + extern const Color_RGBA dimgray; + extern const Color_RGBA dimgrey; + extern const Color_RGBA dodgerblue; + extern const Color_RGBA firebrick; + extern const Color_RGBA floralwhite; + extern const Color_RGBA forestgreen; + extern const Color_RGBA magenta; + extern const Color_RGBA fuchsia; + extern const Color_RGBA gainsboro; + extern const Color_RGBA ghostwhite; + extern const Color_RGBA gold; + extern const Color_RGBA goldenrod; + extern const Color_RGBA gray; + extern const Color_RGBA grey; + extern const Color_RGBA green; + extern const Color_RGBA greenyellow; + extern const Color_RGBA honeydew; + extern const Color_RGBA hotpink; + extern const Color_RGBA indianred; + extern const Color_RGBA indigo; + extern const Color_RGBA ivory; + extern const Color_RGBA khaki; + extern const Color_RGBA lavender; + extern const Color_RGBA lavenderblush; + extern const Color_RGBA lawngreen; + extern const Color_RGBA lemonchiffon; + extern const Color_RGBA lightblue; + extern const Color_RGBA lightcoral; + extern const Color_RGBA lightcyan; + extern const Color_RGBA lightgoldenrodyellow; + extern const Color_RGBA lightgray; + extern const Color_RGBA lightgrey; + extern const Color_RGBA lightgreen; + extern const Color_RGBA lightpink; + extern const Color_RGBA lightsalmon; + extern const Color_RGBA lightseagreen; + extern const Color_RGBA lightskyblue; + extern const Color_RGBA lightslategray; + extern const Color_RGBA lightslategrey; + extern const Color_RGBA lightsteelblue; + extern const Color_RGBA lightyellow; + extern const Color_RGBA lime; + extern const Color_RGBA limegreen; + extern const Color_RGBA linen; + extern const Color_RGBA maroon; + extern const Color_RGBA mediumaquamarine; + extern const Color_RGBA mediumblue; + extern const Color_RGBA mediumorchid; + extern const Color_RGBA mediumpurple; + extern const Color_RGBA mediumseagreen; + extern const Color_RGBA mediumslateblue; + extern const Color_RGBA mediumspringgreen; + extern const Color_RGBA mediumturquoise; + extern const Color_RGBA mediumvioletred; + extern const Color_RGBA midnightblue; + extern const Color_RGBA mintcream; + extern const Color_RGBA mistyrose; + extern const Color_RGBA moccasin; + extern const Color_RGBA navajowhite; + extern const Color_RGBA navy; + extern const Color_RGBA oldlace; + extern const Color_RGBA olive; + extern const Color_RGBA olivedrab; + extern const Color_RGBA orange; + extern const Color_RGBA orangered; + extern const Color_RGBA orchid; + extern const Color_RGBA palegoldenrod; + extern const Color_RGBA palegreen; + extern const Color_RGBA paleturquoise; + extern const Color_RGBA palevioletred; + extern const Color_RGBA papayawhip; + extern const Color_RGBA peachpuff; + extern const Color_RGBA peru; + extern const Color_RGBA pink; + extern const Color_RGBA plum; + extern const Color_RGBA powderblue; + extern const Color_RGBA purple; + extern const Color_RGBA red; + extern const Color_RGBA rosybrown; + extern const Color_RGBA royalblue; + extern const Color_RGBA saddlebrown; + extern const Color_RGBA salmon; + extern const Color_RGBA sandybrown; + extern const Color_RGBA seagreen; + extern const Color_RGBA seashell; + extern const Color_RGBA sienna; + extern const Color_RGBA silver; + extern const Color_RGBA skyblue; + extern const Color_RGBA slateblue; + extern const Color_RGBA slategray; + extern const Color_RGBA slategrey; + extern const Color_RGBA snow; + extern const Color_RGBA springgreen; + extern const Color_RGBA steelblue; + extern const Color_RGBA tan; + extern const Color_RGBA teal; + extern const Color_RGBA thistle; + extern const Color_RGBA tomato; + extern const Color_RGBA turquoise; + extern const Color_RGBA violet; + extern const Color_RGBA wheat; + extern const Color_RGBA white; + extern const Color_RGBA whitesmoke; + extern const Color_RGBA yellow; + extern const Color_RGBA yellowgreen; + extern const Color_RGBA rebeccapurple; + extern const Color_RGBA transparent; } - Color_Ptr_Const name_to_color(const char*); - Color_Ptr_Const name_to_color(const std::string&); + Color_RGBA_Ptr_Const name_to_color(const char*); + Color_RGBA_Ptr_Const name_to_color(const std::string&); const char* color_to_name(const int); - const char* color_to_name(const Color&); + const char* color_to_name(const Color_RGBA&); const char* color_to_name(const double); } diff --git a/src/debugger.hpp b/src/debugger.hpp index dfad6817a..91d459523 100644 --- a/src/debugger.hpp +++ b/src/debugger.hpp @@ -612,14 +612,22 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env) std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; std::cerr << " [" << expression->value() << "]" << std::endl; - } else if (Cast(node)) { - Color_Ptr expression = Cast(node); + } else if (Cast(node)) { + Color_RGBA_Ptr expression = Cast(node); std::cerr << ind << "Color " << expression; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [name: " << expression->disp() << "] "; std::cerr << " [delayed: " << expression->is_delayed() << "] "; std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; - std::cerr << " [" << expression->r() << ":" << expression->g() << ":" << expression->b() << "@" << expression->a() << "]" << std::endl; + std::cerr << " rgba[" << expression->r() << ":" << expression->g() << ":" << expression->b() << "@" << expression->a() << "]" << std::endl; + } else if (Cast(node)) { + Color_HSLA_Ptr expression = Cast(node); + std::cerr << ind << "Color " << expression; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [name: " << expression->disp() << "] "; + std::cerr << " [delayed: " << expression->is_delayed() << "] "; + std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; + std::cerr << " hsla[" << expression->h() << ":" << expression->s() << ":" << expression->l() << "@" << expression->a() << "]" << std::endl; } else if (Cast(node)) { Number_Ptr expression = Cast(node); std::cerr << ind << "Number " << expression; diff --git a/src/eval.cpp b/src/eval.cpp index 44e0e49e1..777ffb4af 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -631,7 +631,9 @@ namespace Sass { } } // lhs is number and rhs is color - else if (Color_Ptr r_c = Cast(rhs)) { + // Todo: allow to work with HSLA colors + else if (Color_Ptr r_col = Cast(rhs)) { + Color_RGBA_Obj r_c = r_col->toRGBA(); try { switch (op_type) { case Sass_OP::EQ: return *l_n == *r_c ? bool_true : bool_false; @@ -648,9 +650,11 @@ namespace Sass { } } } - else if (Color_Ptr l_c = Cast(lhs)) { + else if (Color_Ptr l_col = Cast(lhs)) { + Color_RGBA_Obj l_c = l_col->toRGBA(); // lhs is color and rhs is color - if (Color_Ptr r_c = Cast(rhs)) { + if (Color_Ptr r_col = Cast(rhs)) { + Color_RGBA_Obj r_c = r_col->toRGBA(); try { switch (op_type) { case Sass_OP::EQ: return *l_c == *r_c ? bool_true : bool_false; @@ -834,17 +838,17 @@ namespace Sass { } else if (l_type == Expression::NUMBER && r_type == Expression::COLOR) { Number_Ptr l_n = Cast(lhs); - Color_Ptr r_c = Cast(rhs); + Color_RGBA_Obj r_c = Cast(rhs)->toRGBA(); rv = Operators::op_number_color(op_type, *l_n, *r_c, options(), pstate); } else if (l_type == Expression::COLOR && r_type == Expression::NUMBER) { - Color_Ptr l_c = Cast(lhs); + Color_RGBA_Obj l_c = Cast(lhs)->toRGBA(); Number_Ptr r_n = Cast(rhs); rv = Operators::op_color_number(op_type, *l_c, *r_n, options(), pstate); } else if (l_type == Expression::COLOR && r_type == Expression::COLOR) { - Color_Ptr l_c = Cast(lhs); - Color_Ptr r_c = Cast(rhs); + Color_RGBA_Obj l_c = Cast(lhs)->toRGBA(); + Color_RGBA_Obj r_c = Cast(rhs)->toRGBA(); rv = Operators::op_colors(op_type, *l_c, *r_c, options(), pstate); } else { @@ -1151,7 +1155,12 @@ namespace Sass { return value.detach(); } - Expression_Ptr Eval::operator()(Color_Ptr c) + Expression_Ptr Eval::operator()(Color_RGBA_Ptr c) + { + return c; + } + + Expression_Ptr Eval::operator()(Color_HSLA_Ptr c) { return c; } diff --git a/src/eval.hpp b/src/eval.hpp index 3ba431a85..61ed1e2fc 100644 --- a/src/eval.hpp +++ b/src/eval.hpp @@ -58,7 +58,8 @@ namespace Sass { Expression_Ptr operator()(Function_Call_Ptr); Expression_Ptr operator()(Variable_Ptr); Expression_Ptr operator()(Number_Ptr); - Expression_Ptr operator()(Color_Ptr); + Expression_Ptr operator()(Color_RGBA_Ptr); + Expression_Ptr operator()(Color_HSLA_Ptr); Expression_Ptr operator()(Boolean_Ptr); Expression_Ptr operator()(String_Schema_Ptr); Expression_Ptr operator()(String_Quoted_Ptr); diff --git a/src/fn_colors.cpp b/src/fn_colors.cpp index 66876acb3..f074528dc 100644 --- a/src/fn_colors.cpp +++ b/src/fn_colors.cpp @@ -9,20 +9,31 @@ namespace Sass { namespace Functions { - bool special_number(String_Constant_Ptr s) { + bool string_argument(AST_Node_Obj obj) { + String_Constant_Ptr s = Cast(obj); if (s == nullptr) return false; const std::string& str = s->value(); return starts_with(str, "calc(") || starts_with(str, "var("); } + void hsla_alpha_percent_deprecation(const ParserState& pstate, const std::string val) + { + + std::string msg("Passing a percentage as the alpha value to hsla() will be interpreted"); + std::string tail("differently in future versions of Sass. For now, use " + val + " instead."); + + deprecated(msg, tail, false, pstate); + + } + Signature rgb_sig = "rgb($red, $green, $blue)"; BUILT_IN(rgb) { if ( - special_number(Cast(env["$red"])) || - special_number(Cast(env["$green"])) || - special_number(Cast(env["$blue"])) + string_argument(env["$red"]) || + string_argument(env["$green"]) || + string_argument(env["$blue"]) ) { return SASS_MEMORY_NEW(String_Constant, pstate, "rgb(" + env["$red"]->to_string() @@ -34,7 +45,7 @@ namespace Sass { ); } - return SASS_MEMORY_NEW(Color, + return SASS_MEMORY_NEW(Color_RGBA, pstate, COLOR_NUM("$red"), COLOR_NUM("$green"), @@ -45,10 +56,10 @@ namespace Sass { BUILT_IN(rgba_4) { if ( - special_number(Cast(env["$red"])) || - special_number(Cast(env["$green"])) || - special_number(Cast(env["$blue"])) || - special_number(Cast(env["$alpha"])) + string_argument(env["$red"]) || + string_argument(env["$green"]) || + string_argument(env["$blue"]) || + string_argument(env["$alpha"]) ) { return SASS_MEMORY_NEW(String_Constant, pstate, "rgba(" + env["$red"]->to_string() @@ -62,7 +73,7 @@ namespace Sass { ); } - return SASS_MEMORY_NEW(Color, + return SASS_MEMORY_NEW(Color_RGBA, pstate, COLOR_NUM("$red"), COLOR_NUM("$green"), @@ -74,7 +85,7 @@ namespace Sass { BUILT_IN(rgba_2) { if ( - special_number(Cast(env["$color"])) + string_argument(env["$color"]) ) { return SASS_MEMORY_NEW(String_Constant, pstate, "rgba(" + env["$color"]->to_string() @@ -84,10 +95,10 @@ namespace Sass { ); } - Color_Ptr c_arg = ARG("$color", Color); + Color_RGBA_Obj c_arg = ARG("$color", Color)->toRGBA(); if ( - special_number(Cast(env["$alpha"])) + string_argument(env["$alpha"]) ) { std::stringstream strm; strm << "rgba(" @@ -99,7 +110,7 @@ namespace Sass { return SASS_MEMORY_NEW(String_Constant, pstate, strm.str()); } - Color_Obj new_c = SASS_MEMORY_COPY(c_arg); + Color_RGBA_Obj new_c = SASS_MEMORY_COPY(c_arg); new_c->a(ALPHA_NUM("$alpha")); new_c->disp(""); return new_c.detach(); @@ -111,30 +122,41 @@ namespace Sass { Signature red_sig = "red($color)"; BUILT_IN(red) - { return SASS_MEMORY_NEW(Number, pstate, ARG("$color", Color)->r()); } + { + Color_RGBA_Obj color = ARG("$color", Color)->toRGBA(); + return SASS_MEMORY_NEW(Number, pstate, color->r()); + } Signature green_sig = "green($color)"; BUILT_IN(green) - { return SASS_MEMORY_NEW(Number, pstate, ARG("$color", Color)->g()); } + { + Color_RGBA_Obj color = ARG("$color", Color)->toRGBA(); + return SASS_MEMORY_NEW(Number, pstate, color->g()); + } Signature blue_sig = "blue($color)"; BUILT_IN(blue) - { return SASS_MEMORY_NEW(Number, pstate, ARG("$color", Color)->b()); } + { + Color_RGBA_Obj color = ARG("$color", Color)->toRGBA(); + return SASS_MEMORY_NEW(Number, pstate, color->b()); + } - Color* colormix(Context& ctx, ParserState& pstate, Color* color1, Color* color2, double weight) { + Color_RGBA* colormix(Context& ctx, ParserState& pstate, Color* color1, Color* color2, double weight) { + Color_RGBA_Obj c1 = color1->toRGBA(); + Color_RGBA_Obj c2 = color2->toRGBA(); double p = weight/100; double w = 2*p - 1; - double a = color1->a() - color2->a(); + double a = c1->a() - c2->a(); double w1 = (((w * a == -1) ? w : (w + a)/(1 + w*a)) + 1)/2.0; double w2 = 1 - w1; - return SASS_MEMORY_NEW(Color, + return SASS_MEMORY_NEW(Color_RGBA, pstate, - Sass::round(w1*color1->r() + w2*color2->r(), ctx.c_options.precision), - Sass::round(w1*color1->g() + w2*color2->g(), ctx.c_options.precision), - Sass::round(w1*color1->b() + w2*color2->b(), ctx.c_options.precision), - color1->a()*p + color2->a()*(1-p)); + Sass::round(w1*c1->r() + w2*c2->r(), ctx.c_options.precision), + Sass::round(w1*c1->g() + w2*c2->g(), ctx.c_options.precision), + Sass::round(w1*c1->b() + w2*c2->b(), ctx.c_options.precision), + c1->a()*p + c2->a()*(1-p)); } Signature mix_sig = "mix($color-1, $color-2, $weight: 50%)"; @@ -151,91 +173,13 @@ namespace Sass { // HSL FUNCTIONS //////////////// - // RGB to HSL helper function - struct HSL { double h; double s; double l; }; - HSL rgb_to_hsl(double r, double g, double b) - { - - // Algorithm from http://en.wikipedia.org/wiki/wHSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV - r /= 255.0; g /= 255.0; b /= 255.0; - - double max = std::max(r, std::max(g, b)); - double min = std::min(r, std::min(g, b)); - double delta = max - min; - - double h = 0; - double s; - double l = (max + min) / 2.0; - - if (NEAR_EQUAL(max, min)) { - h = s = 0; // achromatic - } - else { - if (l < 0.5) s = delta / (max + min); - else s = delta / (2.0 - max - min); - - if (r == max) h = (g - b) / delta + (g < b ? 6 : 0); - else if (g == max) h = (b - r) / delta + 2; - else if (b == max) h = (r - g) / delta + 4; - } - - HSL hsl_struct; - hsl_struct.h = h / 6 * 360; - hsl_struct.s = s * 100; - hsl_struct.l = l * 100; - - return hsl_struct; - } - - // hue to RGB helper function - double h_to_rgb(double m1, double m2, double h) { - while (h < 0) h += 1; - while (h > 1) h -= 1; - if (h*6.0 < 1) return m1 + (m2 - m1)*h*6; - if (h*2.0 < 1) return m2; - if (h*3.0 < 2) return m1 + (m2 - m1) * (2.0/3.0 - h)*6; - return m1; - } - - Color_Ptr hsla_impl(double h, double s, double l, double a, Context& ctx, ParserState pstate) - { - h /= 360.0; - s /= 100.0; - l /= 100.0; - - if (l < 0) l = 0; - if (s < 0) s = 0; - if (l > 1) l = 1; - if (s > 1) s = 1; - while (h < 0) h += 1; - while (h > 1) h -= 1; - - // if saturation is exacly zero, we loose - // information for hue, since it will evaluate - // to zero if converted back from rgb. Setting - // saturation to a very tiny number solves this. - if (s == 0) s = 1e-10; - - // Algorithm from the CSS3 spec: http://www.w3.org/TR/css3-color/#hsl-color. - double m2; - if (l <= 0.5) m2 = l*(s+1.0); - else m2 = (l+s)-(l*s); - double m1 = (l*2.0)-m2; - // round the results -- consider moving this into the Color constructor - double r = (h_to_rgb(m1, m2, h + 1.0/3.0) * 255.0); - double g = (h_to_rgb(m1, m2, h) * 255.0); - double b = (h_to_rgb(m1, m2, h - 1.0/3.0) * 255.0); - - return SASS_MEMORY_NEW(Color, pstate, r, g, b, a); - } - Signature hsl_sig = "hsl($hue, $saturation, $lightness)"; BUILT_IN(hsl) { if ( - special_number(Cast(env["$hue"])) || - special_number(Cast(env["$saturation"])) || - special_number(Cast(env["$lightness"])) + string_argument(env["$hue"]) || + string_argument(env["$saturation"]) || + string_argument(env["$lightness"]) ) { return SASS_MEMORY_NEW(String_Constant, pstate, "hsl(" + env["$hue"]->to_string() @@ -247,22 +191,23 @@ namespace Sass { ); } - return hsla_impl(ARGVAL("$hue"), - ARGVAL("$saturation"), - ARGVAL("$lightness"), - 1.0, - ctx, - pstate); + return SASS_MEMORY_NEW(Color_HSLA, + pstate, + ARGVAL("$hue"), + ARGVAL("$saturation"), + ARGVAL("$lightness"), + 1.0); + } Signature hsla_sig = "hsla($hue, $saturation, $lightness, $alpha)"; BUILT_IN(hsla) { if ( - special_number(Cast(env["$hue"])) || - special_number(Cast(env["$saturation"])) || - special_number(Cast(env["$lightness"])) || - special_number(Cast(env["$alpha"])) + string_argument(env["$hue"]) || + string_argument(env["$saturation"]) || + string_argument(env["$lightness"]) || + string_argument(env["$alpha"]) ) { return SASS_MEMORY_NEW(String_Constant, pstate, "hsla(" + env["$hue"]->to_string() @@ -276,103 +221,82 @@ namespace Sass { ); } - return hsla_impl(ARGVAL("$hue"), - ARGVAL("$saturation"), - ARGVAL("$lightness"), - ARGVAL("$alpha"), - ctx, - pstate); + Number_Ptr alpha = ARG("$alpha", Number); + if (alpha && alpha->unit() == "%") { + Number_Obj val = SASS_MEMORY_COPY(alpha); + val->numerators.clear(); // convert + val->value(val->value() / 100.0); + std::string nr(val->to_string(ctx.c_options)); + hsla_alpha_percent_deprecation(pstate, nr); + } + + return SASS_MEMORY_NEW(Color_HSLA, + pstate, + ARGVAL("$hue"), + ARGVAL("$saturation"), + ARGVAL("$lightness"), + ARGVAL("$alpha")); + } + ///////////////////////////////////////////////////////////////////////// + // Query functions + ///////////////////////////////////////////////////////////////////////// + Signature hue_sig = "hue($color)"; BUILT_IN(hue) { - Color_Ptr rgb_color = ARG("$color", Color); - HSL hsl_color = rgb_to_hsl(rgb_color->r(), - rgb_color->g(), - rgb_color->b()); - return SASS_MEMORY_NEW(Number, pstate, hsl_color.h, "deg"); + Color_HSLA_Obj col = ARG("$color", Color)->toHSLA(); + return SASS_MEMORY_NEW(Number, pstate, col->h(), "deg"); } Signature saturation_sig = "saturation($color)"; BUILT_IN(saturation) { - Color_Ptr rgb_color = ARG("$color", Color); - HSL hsl_color = rgb_to_hsl(rgb_color->r(), - rgb_color->g(), - rgb_color->b()); - return SASS_MEMORY_NEW(Number, pstate, hsl_color.s, "%"); + Color_HSLA_Obj col = ARG("$color", Color)->toHSLA(); + return SASS_MEMORY_NEW(Number, pstate, col->s(), "%"); } Signature lightness_sig = "lightness($color)"; BUILT_IN(lightness) { - Color_Ptr rgb_color = ARG("$color", Color); - HSL hsl_color = rgb_to_hsl(rgb_color->r(), - rgb_color->g(), - rgb_color->b()); - return SASS_MEMORY_NEW(Number, pstate, hsl_color.l, "%"); + Color_HSLA_Obj col = ARG("$color", Color)->toHSLA(); + return SASS_MEMORY_NEW(Number, pstate, col->l(), "%"); } + ///////////////////////////////////////////////////////////////////////// + // HSL manipulation functions + ///////////////////////////////////////////////////////////////////////// + Signature adjust_hue_sig = "adjust-hue($color, $degrees)"; BUILT_IN(adjust_hue) { - Color_Ptr rgb_color = ARG("$color", Color); + Color_Ptr col = ARG("$color", Color); double degrees = ARGVAL("$degrees"); - HSL hsl_color = rgb_to_hsl(rgb_color->r(), - rgb_color->g(), - rgb_color->b()); - return hsla_impl(hsl_color.h + degrees, - hsl_color.s, - hsl_color.l, - rgb_color->a(), - ctx, - pstate); + Color_HSLA_Obj copy = col->toHSLA(true); + copy->h(absmod(copy->h() + degrees, 360.0)); + return copy.detach(); } Signature lighten_sig = "lighten($color, $amount)"; BUILT_IN(lighten) { - Color_Ptr rgb_color = ARG("$color", Color); + Color_Ptr col = ARG("$color", Color); double amount = DARG_U_PRCT("$amount"); - HSL hsl_color = rgb_to_hsl(rgb_color->r(), - rgb_color->g(), - rgb_color->b()); - //Check lightness is not negative before lighten it - double hslcolorL = hsl_color.l; - if (hslcolorL < 0) { - hslcolorL = 0; - } + Color_HSLA_Obj copy = col->toHSLA(true); + copy->l(clip(copy->l() + amount, 0.0, 100.0)); + return copy.detach(); - return hsla_impl(hsl_color.h, - hsl_color.s, - hslcolorL + amount, - rgb_color->a(), - ctx, - pstate); } Signature darken_sig = "darken($color, $amount)"; BUILT_IN(darken) { - Color_Ptr rgb_color = ARG("$color", Color); + Color_Ptr col = ARG("$color", Color); double amount = DARG_U_PRCT("$amount"); - HSL hsl_color = rgb_to_hsl(rgb_color->r(), - rgb_color->g(), - rgb_color->b()); - - //Check lightness if not over 100, before darken it - double hslcolorL = hsl_color.l; - if (hslcolorL > 100) { - hslcolorL = 100; - } - - return hsla_impl(hsl_color.h, - hsl_color.s, - hslcolorL - amount, - rgb_color->a(), - ctx, - pstate); + Color_HSLA_Obj copy = col->toHSLA(true); + copy->l(clip(copy->l() - amount, 0.0, 100.0)); + return copy.detach(); } Signature saturate_sig = "saturate($color, $amount: false)"; @@ -383,55 +307,21 @@ namespace Sass { return SASS_MEMORY_NEW(String_Quoted, pstate, "saturate(" + env["$color"]->to_string(ctx.c_options) + ")"); } + Color_Ptr col = ARG("$color", Color); double amount = DARG_U_PRCT("$amount"); - Color_Ptr rgb_color = ARG("$color", Color); - HSL hsl_color = rgb_to_hsl(rgb_color->r(), - rgb_color->g(), - rgb_color->b()); - - double hslcolorS = hsl_color.s + amount; - - // Saturation cannot be below 0 or above 100 - if (hslcolorS < 0) { - hslcolorS = 0; - } - if (hslcolorS > 100) { - hslcolorS = 100; - } - - return hsla_impl(hsl_color.h, - hslcolorS, - hsl_color.l, - rgb_color->a(), - ctx, - pstate); + Color_HSLA_Obj copy = col->toHSLA(true); + copy->s(clip(copy->s() + amount, 0.0, 100.0)); + return copy.detach(); } Signature desaturate_sig = "desaturate($color, $amount)"; BUILT_IN(desaturate) { - Color_Ptr rgb_color = ARG("$color", Color); + Color_Ptr col = ARG("$color", Color); double amount = DARG_U_PRCT("$amount"); - HSL hsl_color = rgb_to_hsl(rgb_color->r(), - rgb_color->g(), - rgb_color->b()); - - double hslcolorS = hsl_color.s - amount; - - // Saturation cannot be below 0 or above 100 - if (hslcolorS <= 0) { - hslcolorS = 0; - } - if (hslcolorS > 100) { - hslcolorS = 100; - } - - return hsla_impl(hsl_color.h, - hslcolorS, - hsl_color.l, - rgb_color->a(), - ctx, - pstate); + Color_HSLA_Obj copy = col->toHSLA(true); + copy->s(clip(copy->s() - amount, 0.0, 100.0)); + return copy.detach(); } Signature grayscale_sig = "grayscale($color)"; @@ -443,31 +333,23 @@ namespace Sass { return SASS_MEMORY_NEW(String_Quoted, pstate, "grayscale(" + amount->to_string(ctx.c_options) + ")"); } - Color_Ptr rgb_color = ARG("$color", Color); - HSL hsl_color = rgb_to_hsl(rgb_color->r(), - rgb_color->g(), - rgb_color->b()); - return hsla_impl(hsl_color.h, - 0.0, - hsl_color.l, - rgb_color->a(), - ctx, - pstate); + Color_Ptr col = ARG("$color", Color); + Color_HSLA_Obj copy = col->toHSLA(true); + copy->s(0.0); // just reset saturation + return copy.detach(); } + ///////////////////////////////////////////////////////////////////////// + // Misc manipulation functions + ///////////////////////////////////////////////////////////////////////// + Signature complement_sig = "complement($color)"; BUILT_IN(complement) { - Color_Ptr rgb_color = ARG("$color", Color); - HSL hsl_color = rgb_to_hsl(rgb_color->r(), - rgb_color->g(), - rgb_color->b()); - return hsla_impl(hsl_color.h - 180.0, - hsl_color.s, - hsl_color.l, - rgb_color->a(), - ctx, - pstate); + Color_Ptr col = ARG("$color", Color); + Color_HSLA_Obj copy = col->toHSLA(true); + copy->h(absmod(copy->h() - 180.0, 360.0)); + return copy.detach(); } Signature invert_sig = "invert($color, $weight: 100%)"; @@ -479,20 +361,19 @@ namespace Sass { return SASS_MEMORY_NEW(String_Quoted, pstate, "invert(" + amount->to_string(ctx.c_options) + ")"); } + Color_Ptr col = ARG("$color", Color); double weight = DARG_U_PRCT("$weight"); - Color_Ptr rgb_color = ARG("$color", Color); - Color_Obj inv = SASS_MEMORY_NEW(Color, - pstate, - 255 - rgb_color->r(), - 255 - rgb_color->g(), - 255 - rgb_color->b(), - rgb_color->a()); - return colormix(ctx, pstate, inv, rgb_color, weight); + Color_RGBA_Obj inv = col->toRGBA(true); + inv->r(clip(255.0 - inv->r(), 0.0, 255.0)); + inv->g(clip(255.0 - inv->g(), 0.0, 255.0)); + inv->b(clip(255.0 - inv->b(), 0.0, 255.0)); + return colormix(ctx, pstate, inv, col, weight); } - //////////////////// - // OPACITY FUNCTIONS - //////////////////// + ///////////////////////////////////////////////////////////////////////// + // Opacity functions + ///////////////////////////////////////////////////////////////////////// + Signature alpha_sig = "alpha($color)"; Signature opacity_sig = "opacity($color)"; BUILT_IN(alpha) @@ -515,30 +396,22 @@ namespace Sass { Signature fade_in_sig = "fade-in($color, $amount)"; BUILT_IN(opacify) { - Color_Ptr color = ARG("$color", Color); + Color_Ptr col = ARG("$color", Color); double amount = DARG_U_FACT("$amount"); - double alpha = std::min(color->a() + amount, 1.0); - return SASS_MEMORY_NEW(Color, - pstate, - color->r(), - color->g(), - color->b(), - alpha); + Color_Obj copy = SASS_MEMORY_COPY(col); + copy->a(clip(col->a() + amount, 0.0, 1.0)); + return copy.detach(); } Signature transparentize_sig = "transparentize($color, $amount)"; Signature fade_out_sig = "fade-out($color, $amount)"; BUILT_IN(transparentize) { - Color_Ptr color = ARG("$color", Color); + Color_Ptr col = ARG("$color", Color); double amount = DARG_U_FACT("$amount"); - double alpha = std::max(color->a() - amount, 0.0); - return SASS_MEMORY_NEW(Color, - pstate, - color->r(), - color->g(), - color->b(), - alpha); + Color_Obj copy = SASS_MEMORY_COPY(col); + copy->a(std::max(col->a() - amount, 0.0)); + return copy.detach(); } //////////////////////// @@ -548,7 +421,7 @@ namespace Sass { Signature adjust_color_sig = "adjust-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)"; BUILT_IN(adjust_color) { - Color_Ptr color = ARG("$color", Color); + Color_Ptr col = ARG("$color", Color); Number_Ptr r = Cast(env["$red"]); Number_Ptr g = Cast(env["$green"]); Number_Ptr b = Cast(env["$blue"]); @@ -563,47 +436,37 @@ namespace Sass { if (rgb && hsl) { error("Cannot specify HSL and RGB values for a color at the same time for `adjust-color'", pstate, traces); } - if (rgb) { - double rr = r ? DARG_R_BYTE("$red") : 0; - double gg = g ? DARG_R_BYTE("$green") : 0; - double bb = b ? DARG_R_BYTE("$blue") : 0; - double aa = a ? DARG_R_FACT("$alpha") : 0; - return SASS_MEMORY_NEW(Color, - pstate, - color->r() + rr, - color->g() + gg, - color->b() + bb, - color->a() + aa); - } - if (hsl) { - HSL hsl_struct = rgb_to_hsl(color->r(), color->g(), color->b()); - double ss = s ? DARG_R_PRCT("$saturation") : 0; - double ll = l ? DARG_R_PRCT("$lightness") : 0; - double aa = a ? DARG_R_FACT("$alpha") : 0; - return hsla_impl(hsl_struct.h + (h ? h->value() : 0), - hsl_struct.s + ss, - hsl_struct.l + ll, - color->a() + aa, - ctx, - pstate); - } - if (a) { - return SASS_MEMORY_NEW(Color, - pstate, - color->r(), - color->g(), - color->b(), - color->a() + (a ? a->value() : 0)); + else if (rgb) { + Color_RGBA_Obj c = col->toRGBA(true); + if (r) c->r(c->r() + DARG_R_BYTE("$red")); + if (g) c->g(c->g() + DARG_R_BYTE("$green")); + if (b) c->b(c->b() + DARG_R_BYTE("$blue")); + if (a) c->a(c->a() + DARG_R_FACT("$alpha")); + return c.detach(); + } + else if (hsl) { + Color_HSLA_Obj c = col->toHSLA(true); + if (h) c->h(c->h() + absmod(h->value(), 360.0)); + if (s) c->s(c->s() + DARG_R_PRCT("$saturation")); + if (l) c->l(c->l() + DARG_R_PRCT("$lightness")); + if (a) c->a(c->a() + DARG_R_FACT("$alpha")); + return c.detach(); + } + else if (a) { + Color_Obj c = SASS_MEMORY_COPY(col); + c->a(c->a() + DARG_R_FACT("$alpha")); + c->a(clip(c->a(), 0.0, 1.0)); + return c.detach(); } error("not enough arguments for `adjust-color'", pstate, traces); // unreachable - return color; + return col; } Signature scale_color_sig = "scale-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)"; BUILT_IN(scale_color) { - Color_Ptr color = ARG("$color", Color); + Color_Ptr col = ARG("$color", Color); Number_Ptr r = Cast(env["$red"]); Number_Ptr g = Cast(env["$green"]); Number_Ptr b = Cast(env["$blue"]); @@ -618,48 +481,46 @@ namespace Sass { if (rgb && hsl) { error("Cannot specify HSL and RGB values for a color at the same time for `scale-color'", pstate, traces); } - if (rgb) { + else if (rgb) { + Color_RGBA_Obj c = col->toRGBA(true); double rscale = (r ? DARG_R_PRCT("$red") : 0.0) / 100.0; double gscale = (g ? DARG_R_PRCT("$green") : 0.0) / 100.0; double bscale = (b ? DARG_R_PRCT("$blue") : 0.0) / 100.0; double ascale = (a ? DARG_R_PRCT("$alpha") : 0.0) / 100.0; - return SASS_MEMORY_NEW(Color, - pstate, - color->r() + rscale * (rscale > 0.0 ? 255 - color->r() : color->r()), - color->g() + gscale * (gscale > 0.0 ? 255 - color->g() : color->g()), - color->b() + bscale * (bscale > 0.0 ? 255 - color->b() : color->b()), - color->a() + ascale * (ascale > 0.0 ? 1.0 - color->a() : color->a())); - } - if (hsl) { + if (rscale) c->r(c->r() + rscale * (rscale > 0.0 ? 255.0 - c->r() : c->r())); + if (gscale) c->g(c->g() + gscale * (gscale > 0.0 ? 255.0 - c->g() : c->g())); + if (bscale) c->b(c->b() + bscale * (bscale > 0.0 ? 255.0 - c->b() : c->b())); + if (ascale) c->a(c->a() + ascale * (ascale > 0.0 ? 1.0 - c->a() : c->a())); + return c.detach(); + } + else if (hsl) { + Color_HSLA_Obj c = col->toHSLA(true); double hscale = (h ? DARG_R_PRCT("$hue") : 0.0) / 100.0; double sscale = (s ? DARG_R_PRCT("$saturation") : 0.0) / 100.0; double lscale = (l ? DARG_R_PRCT("$lightness") : 0.0) / 100.0; double ascale = (a ? DARG_R_PRCT("$alpha") : 0.0) / 100.0; - HSL hsl_struct = rgb_to_hsl(color->r(), color->g(), color->b()); - hsl_struct.h += hscale * (hscale > 0.0 ? 360.0 - hsl_struct.h : hsl_struct.h); - hsl_struct.s += sscale * (sscale > 0.0 ? 100.0 - hsl_struct.s : hsl_struct.s); - hsl_struct.l += lscale * (lscale > 0.0 ? 100.0 - hsl_struct.l : hsl_struct.l); - double alpha = color->a() + ascale * (ascale > 0.0 ? 1.0 - color->a() : color->a()); - return hsla_impl(hsl_struct.h, hsl_struct.s, hsl_struct.l, alpha, ctx, pstate); - } - if (a) { - double ascale = (DARG_R_PRCT("$alpha")) / 100.0; - return SASS_MEMORY_NEW(Color, - pstate, - color->r(), - color->g(), - color->b(), - color->a() + ascale * (ascale > 0.0 ? 1.0 - color->a() : color->a())); + if (hscale) c->h(c->h() + hscale * (hscale > 0.0 ? 360.0 - c->h() : c->h())); + if (sscale) c->s(c->s() + sscale * (sscale > 0.0 ? 100.0 - c->l() : c->s())); + if (lscale) c->l(c->l() + lscale * (lscale > 0.0 ? 100.0 - c->l() : c->l())); + if (ascale) c->a(c->a() + ascale * (ascale > 0.0 ? 1.0 - c->a() : c->a())); + return c.detach(); + } + else if (a) { + Color_Obj c = SASS_MEMORY_COPY(col); + double ascale = DARG_R_PRCT("$alpha") / 100.0; + c->a(c->a() + ascale * (ascale > 0.0 ? 1.0 - c->a() : c->a())); + c->a(clip(c->a(), 0.0, 1.0)); + return c.detach(); } error("not enough arguments for `scale-color'", pstate, traces); // unreachable - return color; + return col; } Signature change_color_sig = "change-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)"; BUILT_IN(change_color) { - Color_Ptr color = ARG("$color", Color); + Color_Ptr col = ARG("$color", Color); Number_Ptr r = Cast(env["$red"]); Number_Ptr g = Cast(env["$green"]); Number_Ptr b = Cast(env["$blue"]); @@ -674,51 +535,41 @@ namespace Sass { if (rgb && hsl) { error("Cannot specify HSL and RGB values for a color at the same time for `change-color'", pstate, traces); } - if (rgb) { - return SASS_MEMORY_NEW(Color, - pstate, - r ? DARG_U_BYTE("$red") : color->r(), - g ? DARG_U_BYTE("$green") : color->g(), - b ? DARG_U_BYTE("$blue") : color->b(), - a ? DARG_U_BYTE("$alpha") : color->a()); - } - if (hsl) { - HSL hsl_struct = rgb_to_hsl(color->r(), color->g(), color->b()); - if (h) hsl_struct.h = std::fmod(h->value(), 360.0); - if (s) hsl_struct.s = DARG_U_PRCT("$saturation"); - if (l) hsl_struct.l = DARG_U_PRCT("$lightness"); - double alpha = a ? DARG_U_FACT("$alpha") : color->a(); - return hsla_impl(hsl_struct.h, hsl_struct.s, hsl_struct.l, alpha, ctx, pstate); - } - if (a) { - double alpha = DARG_U_FACT("$alpha"); - return SASS_MEMORY_NEW(Color, - pstate, - color->r(), - color->g(), - color->b(), - alpha); + else if (rgb) { + Color_RGBA_Obj c = col->toRGBA(true); + if (r) c->r(DARG_U_BYTE("$red")); + if (g) c->g(DARG_U_BYTE("$green")); + if (b) c->b(DARG_U_BYTE("$blue")); + if (a) c->a(DARG_U_FACT("$alpha")); + return c.detach(); + } + else if (hsl) { + Color_HSLA_Obj c = col->toHSLA(true); + if (h) c->h(absmod(h->value(), 360.0)); + if (s) c->s(DARG_U_PRCT("$saturation")); + if (l) c->l(DARG_U_PRCT("$lightness")); + if (a) c->a(DARG_U_FACT("$alpha")); + return c.detach(); + } + else if (a) { + Color_Obj c = SASS_MEMORY_COPY(col); + c->a(clip(DARG_U_FACT("$alpha"), 0.0, 1.0)); + return c.detach(); } error("not enough arguments for `change-color'", pstate, traces); // unreachable - return color; - } - - template - static double cap_channel(double c) { - if (c > range) return range; - else if (c < 0) return 0; - else return c; + return col; } Signature ie_hex_str_sig = "ie-hex-str($color)"; BUILT_IN(ie_hex_str) { - Color_Ptr c = ARG("$color", Color); - double r = cap_channel<0xff>(c->r()); - double g = cap_channel<0xff>(c->g()); - double b = cap_channel<0xff>(c->b()); - double a = cap_channel<1> (c->a()) * 255; + Color_Ptr col = ARG("$color", Color); + Color_RGBA_Obj c = col->toRGBA(); + double r = clip(c->r(), 0.0, 255.0); + double g = clip(c->g(), 0.0, 255.0); + double b = clip(c->b(), 0.0, 255.0); + double a = clip(c->a(), 0.0, 1.0) * 255.0; std::stringstream ss; ss << '#' << std::setw(2) << std::setfill('0'); diff --git a/src/inspect.cpp b/src/inspect.cpp index 9d5ce1685..176d75bfc 100644 --- a/src/inspect.cpp +++ b/src/inspect.cpp @@ -571,7 +571,7 @@ namespace Sass { else return c; } - void Inspect::operator()(Color_Ptr c) + void Inspect::operator()(Color_RGBA_Ptr c) { // output the final token std::stringstream ss; @@ -590,7 +590,7 @@ namespace Sass { // get color from given name (if one was given at all) if (name != "" && name_to_color(name)) { - Color_Ptr_Const n = name_to_color(name); + Color_RGBA_Ptr_Const n = name_to_color(name); r = Sass::round(cap_channel<0xff>(n->r()), opt.precision); g = Sass::round(cap_channel<0xff>(n->g()), opt.precision); b = Sass::round(cap_channel<0xff>(n->b()), opt.precision); @@ -657,6 +657,12 @@ namespace Sass { } + void Inspect::operator()(Color_HSLA_Ptr c) + { + Color_RGBA_Obj rgba = c->toRGBA(); + operator()(rgba); + } + void Inspect::operator()(Boolean_Ptr b) { // output the final token diff --git a/src/inspect.hpp b/src/inspect.hpp index 223be17ce..cda9234a8 100644 --- a/src/inspect.hpp +++ b/src/inspect.hpp @@ -55,7 +55,8 @@ namespace Sass { // virtual void operator()(Custom_Error_Ptr); virtual void operator()(Variable_Ptr); virtual void operator()(Number_Ptr); - virtual void operator()(Color_Ptr); + virtual void operator()(Color_RGBA_Ptr); + virtual void operator()(Color_HSLA_Ptr); virtual void operator()(Boolean_Ptr); virtual void operator()(String_Schema_Ptr); virtual void operator()(String_Constant_Ptr); diff --git a/src/operation.hpp b/src/operation.hpp index 71e13dcf9..7d5a7a5b9 100644 --- a/src/operation.hpp +++ b/src/operation.hpp @@ -81,6 +81,8 @@ namespace Sass { virtual T operator()(Variable_Ptr x) = 0; virtual T operator()(Number_Ptr x) = 0; virtual T operator()(Color_Ptr x) = 0; + virtual T operator()(Color_RGBA_Ptr x) = 0; + virtual T operator()(Color_HSLA_Ptr x) = 0; virtual T operator()(Boolean_Ptr x) = 0; virtual T operator()(String_Schema_Ptr x) = 0; virtual T operator()(String_Quoted_Ptr x) = 0; @@ -162,6 +164,8 @@ namespace Sass { T operator()(Variable_Ptr x) { return static_cast(this)->fallback(x); } T operator()(Number_Ptr x) { return static_cast(this)->fallback(x); } T operator()(Color_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Color_RGBA_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Color_HSLA_Ptr x) { return static_cast(this)->fallback(x); } T operator()(Boolean_Ptr x) { return static_cast(this)->fallback(x); } T operator()(String_Schema_Ptr x) { return static_cast(this)->fallback(x); } T operator()(String_Constant_Ptr x) { return static_cast(this)->fallback(x); } diff --git a/src/operators.cpp b/src/operators.cpp index a1fd56235..8de59937b 100644 --- a/src/operators.cpp +++ b/src/operators.cpp @@ -57,12 +57,7 @@ namespace Sass { /* colour math deprecation warning */ void op_color_deprecation(enum Sass_OP op, std::string lsh, std::string rhs, const ParserState& pstate) { - std::string op_str( - op == Sass_OP::ADD ? "plus" : - op == Sass_OP::DIV ? "div" : - op == Sass_OP::SUB ? "minus" : - op == Sass_OP::MUL ? "times" : "" - ); + std::string op_str(sass_op_to_name(op)); std::string msg("The operation `" + lsh + " " + op_str + " " + rhs + "` is deprecated and will be an error in future versions."); std::string tail("Consider using Sass's color functions instead.\nhttp://sass-lang.com/documentation/Sass/Script/Functions.html#other_color_functions"); @@ -120,8 +115,9 @@ namespace Sass { return SASS_MEMORY_NEW(String_Constant, pstate, lstr + sep + rstr); } + /* ToDo: allow to operate also with hsla colors */ /* static function, throws OperationError, has no traces but optional pstate for returned value */ - Value_Ptr op_colors(enum Sass_OP op, const Color& lhs, const Color& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed) + Value_Ptr op_colors(enum Sass_OP op, const Color_RGBA& lhs, const Color_RGBA& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed) { if (lhs.a() != rhs.a()) { @@ -133,7 +129,7 @@ namespace Sass { op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate); - return SASS_MEMORY_NEW(Color, + return SASS_MEMORY_NEW(Color_RGBA, pstate, ops[op](lhs.r(), rhs.r()), ops[op](lhs.g(), rhs.g()), @@ -212,7 +208,7 @@ namespace Sass { } /* static function, throws OperationError, has no traces but optional pstate for returned value */ - Value_Ptr op_number_color(enum Sass_OP op, const Number& lhs, const Color& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed) + Value_Ptr op_number_color(enum Sass_OP op, const Number& lhs, const Color_RGBA& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed) { double lval = lhs.value(); @@ -220,7 +216,7 @@ namespace Sass { case Sass_OP::ADD: case Sass_OP::MUL: { op_color_deprecation(op, lhs.to_string(), rhs.to_string(opt), pstate); - return SASS_MEMORY_NEW(Color, + return SASS_MEMORY_NEW(Color_RGBA, pstate, ops[op](lval, rhs.r()), ops[op](lval, rhs.g()), @@ -243,7 +239,7 @@ namespace Sass { } /* static function, throws OperationError, has no traces but optional pstate for returned value */ - Value_Ptr op_color_number(enum Sass_OP op, const Color& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed) + Value_Ptr op_color_number(enum Sass_OP op, const Color_RGBA& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed) { double rval = rhs.value(); @@ -254,7 +250,7 @@ namespace Sass { op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate); - return SASS_MEMORY_NEW(Color, + return SASS_MEMORY_NEW(Color_RGBA, pstate, ops[op](lhs.r(), rval), ops[op](lhs.g(), rval), diff --git a/src/operators.hpp b/src/operators.hpp index f89eb4ee2..82387d266 100644 --- a/src/operators.hpp +++ b/src/operators.hpp @@ -18,10 +18,10 @@ namespace Sass { bool gte(Expression_Obj, Expression_Obj); // arithmetic for all the combinations that matter Value_Ptr op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false); - Value_Ptr op_colors(enum Sass_OP, const Color&, const Color&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false); + Value_Ptr op_colors(enum Sass_OP, const Color_RGBA&, const Color_RGBA&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false); Value_Ptr op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false); - Value_Ptr op_number_color(enum Sass_OP, const Number&, const Color&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false); - Value_Ptr op_color_number(enum Sass_OP, const Color&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false); + Value_Ptr op_number_color(enum Sass_OP, const Number&, const Color_RGBA&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false); + Value_Ptr op_color_number(enum Sass_OP, const Color_RGBA&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false); }; diff --git a/src/parser.cpp b/src/parser.cpp index c4ee0883f..f70f6f398 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1594,7 +1594,7 @@ namespace Sass { Value_Ptr Parser::lexed_hex_color(const ParserState& pstate, const std::string& parsed) { - Color_Ptr color = NULL; + Color_RGBA_Ptr color = NULL; if (parsed[0] != '#') { return SASS_MEMORY_NEW(String_Quoted, pstate, parsed); } @@ -1604,7 +1604,7 @@ namespace Sass { std::string r(2, parsed[1]); std::string g(2, parsed[2]); std::string b(2, parsed[3]); - color = SASS_MEMORY_NEW(Color, + color = SASS_MEMORY_NEW(Color_RGBA, pstate, static_cast(strtol(r.c_str(), NULL, 16)), static_cast(strtol(g.c_str(), NULL, 16)), @@ -1617,7 +1617,7 @@ namespace Sass { std::string g(2, parsed[2]); std::string b(2, parsed[3]); std::string a(2, parsed[4]); - color = SASS_MEMORY_NEW(Color, + color = SASS_MEMORY_NEW(Color_RGBA, pstate, static_cast(strtol(r.c_str(), NULL, 16)), static_cast(strtol(g.c_str(), NULL, 16)), @@ -1629,7 +1629,7 @@ namespace Sass { std::string r(parsed.substr(1,2)); std::string g(parsed.substr(3,2)); std::string b(parsed.substr(5,2)); - color = SASS_MEMORY_NEW(Color, + color = SASS_MEMORY_NEW(Color_RGBA, pstate, static_cast(strtol(r.c_str(), NULL, 16)), static_cast(strtol(g.c_str(), NULL, 16)), @@ -1642,7 +1642,7 @@ namespace Sass { std::string g(parsed.substr(3,2)); std::string b(parsed.substr(5,2)); std::string a(parsed.substr(7,2)); - color = SASS_MEMORY_NEW(Color, + color = SASS_MEMORY_NEW(Color_RGBA, pstate, static_cast(strtol(r.c_str(), NULL, 16)), static_cast(strtol(g.c_str(), NULL, 16)), @@ -1658,7 +1658,7 @@ namespace Sass { Value_Ptr Parser::color_or_string(const std::string& lexed) const { if (auto color = name_to_color(lexed)) { - auto c = SASS_MEMORY_NEW(Color, color); + auto c = SASS_MEMORY_NEW(Color_RGBA, color); c->is_delayed(true); c->pstate(pstate); c->disp(lexed); diff --git a/src/sass_values.cpp b/src/sass_values.cpp index 4927ee20d..5a007df25 100644 --- a/src/sass_values.cpp +++ b/src/sass_values.cpp @@ -318,17 +318,23 @@ extern "C" { } else if (sass_value_is_number(a) && sass_value_is_color(a)) { Number_Ptr_Const l_n = Cast(lhs); - Color_Ptr_Const r_c = Cast(rhs); + // Direct HSLA operations are not supported + // All color maths will be deprecated anyway + Color_RGBA_Obj r_c = Cast(rhs)->toRGBA(); rv = Operators::op_number_color(op, *l_n, *r_c, options, l_n->pstate()); } else if (sass_value_is_color(a) && sass_value_is_number(b)) { - Color_Ptr_Const l_c = Cast(lhs); + // Direct HSLA operations are not supported + // All color maths will be deprecated anyway + Color_RGBA_Obj l_c = Cast(lhs)->toRGBA(); Number_Ptr_Const r_n = Cast(rhs); rv = Operators::op_color_number(op, *l_c, *r_n, options, l_c->pstate()); } else if (sass_value_is_color(a) && sass_value_is_color(b)) { - Color_Ptr_Const l_c = Cast(lhs); - Color_Ptr_Const r_c = Cast(rhs); + // Direct HSLA operations are not supported + // All color maths will be deprecated anyway + Color_RGBA_Obj l_c = Cast(lhs)->toRGBA(); + Color_RGBA_Obj r_c = Cast(rhs)->toRGBA(); rv = Operators::op_colors(op, *l_c, *r_c, options, l_c->pstate()); } else /* convert other stuff to string and apply operation */ { diff --git a/src/to_value.cpp b/src/to_value.cpp index f94c09a69..fae6fffe3 100644 --- a/src/to_value.cpp +++ b/src/to_value.cpp @@ -29,7 +29,13 @@ namespace Sass { } // Color is a valid value - Value_Ptr To_Value::operator()(Color_Ptr c) + Value_Ptr To_Value::operator()(Color_RGBA_Ptr c) + { + return c; + } + + // Color is a valid value + Value_Ptr To_Value::operator()(Color_HSLA_Ptr c) { return c; } diff --git a/src/to_value.hpp b/src/to_value.hpp index ba422b3d4..625a6052e 100644 --- a/src/to_value.hpp +++ b/src/to_value.hpp @@ -24,7 +24,8 @@ namespace Sass { Value_Ptr operator()(Argument_Ptr); Value_Ptr operator()(Boolean_Ptr); Value_Ptr operator()(Number_Ptr); - Value_Ptr operator()(Color_Ptr); + Value_Ptr operator()(Color_RGBA_Ptr); + Value_Ptr operator()(Color_HSLA_Ptr); Value_Ptr operator()(String_Constant_Ptr); Value_Ptr operator()(String_Quoted_Ptr); Value_Ptr operator()(Custom_Warning_Ptr); diff --git a/src/util.hpp b/src/util.hpp index 3c463eed1..e98a74246 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -1,18 +1,32 @@ #ifndef SASS_UTIL_H #define SASS_UTIL_H +#include "sass.hpp" +#include "sass/base.h" +#include "ast_fwd_decl.hpp" + #include #include #include #include -#include "sass.hpp" -#include "sass/base.h" -#include "ast_fwd_decl.hpp" +#include #define SASS_ASSERT(cond, msg) assert(cond && msg) namespace Sass { + template + T clip(const T& n, const T& lower, const T& upper) { + return std::max(lower, std::min(n, upper)); + } + + template + T absmod(const T& n, const T& r) { + T m = std::fmod(n, r); + if (m < 0.0) m += r; + return m; + } + double round(double val, size_t precision = 0); double sass_strtod(const char* str); const char* safe_str(const char *, const char* = ""); diff --git a/src/values.cpp b/src/values.cpp index 0f2fd48d7..f840e6033 100644 --- a/src/values.cpp +++ b/src/values.cpp @@ -16,7 +16,8 @@ namespace Sass { } else if (val->concrete_type() == Expression::COLOR) { - Color_Ptr_Const col = Cast(val); + // ToDo: allow to also use HSLA colors!! + Color_RGBA_Obj col = Cast(val)->toRGBA(); return sass_make_color(col->r(), col->g(), col->b(), col->a()); } else if (val->concrete_type() == Expression::LIST) @@ -78,7 +79,8 @@ namespace Sass { ParserState("[C-VALUE]"), sass_boolean_get_value(val)); case SASS_COLOR: - return SASS_MEMORY_NEW(Color, + // ToDo: allow to also use HSLA colors!! + return SASS_MEMORY_NEW(Color_RGBA, ParserState("[C-VALUE]"), sass_color_get_r(val), sass_color_get_g(val),