diff options
-rw-r--r-- | core/color.cpp | 103 | ||||
-rw-r--r-- | core/color.h | 2 | ||||
-rw-r--r-- | doc/classes/Color.xml | 20 | ||||
-rw-r--r-- | editor/plugins/theme_editor_plugin.cpp | 4 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs | 95 |
5 files changed, 112 insertions, 112 deletions
diff --git a/core/color.cpp b/core/color.cpp index 27a2d0af5c..0a4b98bf9e 100644 --- a/core/color.cpp +++ b/core/color.cpp @@ -261,33 +261,21 @@ Color Color::from_rgbe9995(uint32_t p_rgbe) { return Color(rd, gd, bd, 1.0f); } -static float _parse_col(const String &p_str, int p_ofs) { - int ig = 0; - - for (int i = 0; i < 2; i++) { - int c = p_str[i + p_ofs]; - int v = 0; - - if (c >= '0' && c <= '9') { - v = c - '0'; - } else if (c >= 'a' && c <= 'f') { - v = c - 'a'; - v += 10; - } else if (c >= 'A' && c <= 'F') { - v = c - 'A'; - v += 10; - } else { - return -1; - } - - if (i == 0) { - ig += v * 16; - } else { - ig += v; - } +static int _parse_col4(const String &p_str, int p_ofs) { + char character = p_str[p_ofs]; + + if (character >= '0' && character <= '9') { + return character - '0'; + } else if (character >= 'a' && character <= 'f') { + return character + (10 - 'a'); + } else if (character >= 'A' && character <= 'F') { + return character + (10 - 'A'); } + return -1; +} - return ig; +static int _parse_col8(const String &p_str, int p_ofs) { + return _parse_col4(p_str, p_ofs) * 16 + _parse_col4(p_str, p_ofs + 1); } Color Color::inverted() const { @@ -302,49 +290,54 @@ Color Color::contrasted() const { return c; } -Color Color::html(const String &p_color) { - String color = p_color; +Color Color::html(const String &p_rgba) { + String color = p_rgba; if (color.length() == 0) { return Color(); } if (color[0] == '#') { color = color.substr(1, color.length() - 1); } - if (color.length() == 3 || color.length() == 4) { - String exp_color; - for (int i = 0; i < color.length(); i++) { - exp_color += color[i]; - exp_color += color[i]; - } - color = exp_color; - } + // If enabled, use 1 hex digit per channel instead of 2. + // Other sizes aren't in the HTML/CSS spec but we could add them if desired. + bool is_shorthand = color.length() < 5; bool alpha = false; if (color.length() == 8) { alpha = true; } else if (color.length() == 6) { alpha = false; + } else if (color.length() == 4) { + alpha = true; + } else if (color.length() == 3) { + alpha = false; } else { - ERR_FAIL_V_MSG(Color(), "Invalid color code: " + p_color + "."); + ERR_FAIL_V_MSG(Color(), "Invalid color code: " + p_rgba + "."); } - int a = 255; - if (alpha) { - a = _parse_col(color, 0); - ERR_FAIL_COND_V_MSG(a < 0, Color(), "Invalid color code: " + p_color + "."); + float r, g, b, a = 1.0; + if (is_shorthand) { + r = _parse_col4(color, 0) / 15.0; + g = _parse_col4(color, 1) / 15.0; + b = _parse_col4(color, 2) / 15.0; + if (alpha) { + a = _parse_col4(color, 3) / 15.0; + } + } else { + r = _parse_col8(color, 0) / 255.0; + g = _parse_col8(color, 2) / 255.0; + b = _parse_col8(color, 4) / 255.0; + if (alpha) { + a = _parse_col8(color, 6) / 255.0; + } } + ERR_FAIL_COND_V_MSG(r < 0, Color(), "Invalid color code: " + p_rgba + "."); + ERR_FAIL_COND_V_MSG(g < 0, Color(), "Invalid color code: " + p_rgba + "."); + ERR_FAIL_COND_V_MSG(b < 0, Color(), "Invalid color code: " + p_rgba + "."); + ERR_FAIL_COND_V_MSG(a < 0, Color(), "Invalid color code: " + p_rgba + "."); - int from = alpha ? 2 : 0; - - int r = _parse_col(color, from + 0); - ERR_FAIL_COND_V_MSG(r < 0, Color(), "Invalid color code: " + p_color + "."); - int g = _parse_col(color, from + 2); - ERR_FAIL_COND_V_MSG(g < 0, Color(), "Invalid color code: " + p_color + "."); - int b = _parse_col(color, from + 4); - ERR_FAIL_COND_V_MSG(b < 0, Color(), "Invalid color code: " + p_color + "."); - - return Color(r / 255.0, g / 255.0, b / 255.0, a / 255.0); + return Color(r, g, b, a); } bool Color::html_is_valid(const String &p_color) { @@ -368,7 +361,7 @@ bool Color::html_is_valid(const String &p_color) { } if (alpha) { - int a = _parse_col(color, 0); + int a = _parse_col8(color, 0); if (a < 0) { return false; } @@ -376,15 +369,15 @@ bool Color::html_is_valid(const String &p_color) { int from = alpha ? 2 : 0; - int r = _parse_col(color, from + 0); + int r = _parse_col8(color, from + 0); if (r < 0) { return false; } - int g = _parse_col(color, from + 2); + int g = _parse_col8(color, from + 2); if (g < 0) { return false; } - int b = _parse_col(color, from + 4); + int b = _parse_col8(color, from + 4); if (b < 0) { return false; } @@ -438,7 +431,7 @@ String Color::to_html(bool p_alpha) const { txt += _to_hex(g); txt += _to_hex(b); if (p_alpha) { - txt = _to_hex(a) + txt; + txt += _to_hex(a); } return txt; } diff --git a/core/color.h b/core/color.h index 258965fd16..096e97e9ae 100644 --- a/core/color.h +++ b/core/color.h @@ -185,7 +185,7 @@ struct Color { static Color hex(uint32_t p_hex); static Color hex64(uint64_t p_hex); - static Color html(const String &p_color); + static Color html(const String &p_rgba); static bool html_is_valid(const String &p_color); static Color named(const String &p_name); String to_html(bool p_alpha = true) const; diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml index 240e70db9f..fcaba99eb7 100644 --- a/doc/classes/Color.xml +++ b/doc/classes/Color.xml @@ -18,13 +18,21 @@ <argument index="0" name="from" type="String"> </argument> <description> - Constructs a color from an HTML hexadecimal color string in ARGB or RGB format. See also [method @GDScript.ColorN]. + Constructs a color from an HTML hexadecimal color string in RGB or RGBA format. See also [method @GDScript.ColorN]. [codeblock] # Each of the following creates the same color RGBA(178, 217, 10, 255). - var c1 = Color("#ffb2d90a") # ARGB format with "#". - var c2 = Color("ffb2d90a") # ARGB format. var c3 = Color("#b2d90a") # RGB format with "#". var c4 = Color("b2d90a") # RGB format. + var c1 = Color("#b2d90aff") # RGBA format with "#". + var c2 = Color("b2d90aff") # RGBA format. + [/codeblock] + You can also use the "web color" short-hand form by only using 3 or 4 digits. + [codeblock] + # Each of the following creates the same color RGBA(17, 34, 51, 255). + var c3 = Color("#123") # RGB format with "#". + var c4 = Color("123") # RGB format. + var c1 = Color("#123f") # RGBA format with "#". + var c2 = Color("123f") # RGBA format. [/codeblock] </description> </method> @@ -243,11 +251,11 @@ <argument index="0" name="with_alpha" type="bool" default="true"> </argument> <description> - Returns the color's HTML hexadecimal color string in ARGB format (ex: [code]ff34f822[/code]). - Setting [code]with_alpha[/code] to [code]false[/code] excludes alpha from the hexadecimal string. + Returns the color's HTML hexadecimal color string in RGBA format (ex: [code]ff34f822[/code]). + Setting [code]with_alpha[/code] to [code]false[/code] excludes alpha from the hexadecimal string (and uses RGB instead of RGBA format). [codeblock] var c = Color(1, 1, 1, 0.5) - var s1 = c.to_html() # Returns "7fffffff" + var s1 = c.to_html() # Returns "ffffff7f" var s2 = c.to_html(false) # Returns "ffffff" [/codeblock] </description> diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 76dd6e38e0..932ded6938 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -206,8 +206,8 @@ void ThemeEditor::_save_template_cbk(String fname) { file->store_line("; [value] examples:"); file->store_line("; "); file->store_line("; Type.item = 6 ; numeric constant. "); - file->store_line("; Type.item = #FF00FF ; HTML color "); - file->store_line("; Type.item = #55FF00FF ; HTML color with alpha 55."); + file->store_line("; Type.item = #FF00FF ; HTML color (magenta)."); + file->store_line("; Type.item = #FF00FF55 ; HTML color (magenta with alpha 0x55)."); file->store_line("; Type.item = icon(image.png) ; icon in a png file (relative to theme file)."); file->store_line("; Type.item = font(font.xres) ; font in a resource (relative to theme file)."); file->store_line("; Type.item = sbox(stylebox.xres) ; stylebox in a resource (relative to theme file)."); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index d851abc6d3..238f10aaf1 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -565,6 +565,9 @@ namespace Godot rgba = rgba.Substring(1); } + // If enabled, use 1 hex digit per channel instead of 2. + // Other sizes aren't in the HTML/CSS spec but we could add them if desired. + bool isShorthand = rgba.Length < 5; bool alpha; if (rgba.Length == 8) @@ -575,47 +578,60 @@ namespace Godot { alpha = false; } + else if (rgba.Length == 4) + { + alpha = true; + } + else if (rgba.Length == 3) + { + alpha = false; + } else { throw new ArgumentOutOfRangeException("Invalid color code. Length is " + rgba.Length + " but a length of 6 or 8 is expected: " + rgba); } - if (alpha) + a = 1.0f; + if (isShorthand) { - a = ParseCol8(rgba, 6) / 255f; - - if (a < 0) + r = ParseCol4(rgba, 0) / 15f; + g = ParseCol4(rgba, 1) / 15f; + b = ParseCol4(rgba, 2) / 15f; + if (alpha) { - throw new ArgumentOutOfRangeException("Invalid color code. Alpha part is not valid hexadecimal: " + rgba); + a = ParseCol4(rgba, 3) / 15f; } } else { - a = 1.0f; + r = ParseCol8(rgba, 0) / 255f; + g = ParseCol8(rgba, 2) / 255f; + b = ParseCol8(rgba, 4) / 255f; + if (alpha) + { + a = ParseCol8(rgba, 6) / 255f; + } } - int from = alpha ? 2 : 0; - - r = ParseCol8(rgba, 0) / 255f; - if (r < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Red part is not valid hexadecimal: " + rgba); } - g = ParseCol8(rgba, 2) / 255f; - if (g < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Green part is not valid hexadecimal: " + rgba); } - b = ParseCol8(rgba, 4) / 255f; - if (b < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Blue part is not valid hexadecimal: " + rgba); } + + if (a < 0) + { + throw new ArgumentOutOfRangeException("Invalid color code. Alpha part is not valid hexadecimal: " + rgba); + } } /// <summary> @@ -751,45 +767,28 @@ namespace Godot value = max; } - private static int ParseCol8(string str, int ofs) + private static int ParseCol4(string str, int ofs) { - int ig = 0; + char character = str[ofs]; - for (int i = 0; i < 2; i++) + if (character >= '0' && character <= '9') { - int c = str[i + ofs]; - int v; - - if (c >= '0' && c <= '9') - { - v = c - '0'; - } - else if (c >= 'a' && c <= 'f') - { - v = c - 'a'; - v += 10; - } - else if (c >= 'A' && c <= 'F') - { - v = c - 'A'; - v += 10; - } - else - { - return -1; - } - - if (i == 0) - { - ig += v * 16; - } - else - { - ig += v; - } + return character - '0'; + } + else if (character >= 'a' && character <= 'f') + { + return character + (10 - 'a'); } + else if (character >= 'A' && character <= 'F') + { + return character + (10 - 'A'); + } + return -1; + } - return ig; + private static int ParseCol8(string str, int ofs) + { + return ParseCol4(str, ofs) * 16 + ParseCol4(str, ofs + 1); } private String ToHex32(float val) |