From 8bad367d084ab75fbea42a254438ec8bcda1cc24 Mon Sep 17 00:00:00 2001 From: Alec Murphy Date: Thu, 24 Apr 2025 21:09:30 -0400 Subject: [PATCH] System/Libraries/Html/Renderer: Parse rgb,rgba color tuples --- System/Libraries/Html/Renderer.HC | 99 ++++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 22 deletions(-) diff --git a/System/Libraries/Html/Renderer.HC b/System/Libraries/Html/Renderer.HC index c156f26..824bf96 100644 --- a/System/Libraries/Html/Renderer.HC +++ b/System/Libraries/Html/Renderer.HC @@ -283,6 +283,76 @@ U32 @css_resolve_color_from_rrggbb(U8* str) } } +U32 @css_resolve_color_from_rgba_tuple(U8* str) +{ + U8 buffer[128]; + + I64 i; + I64 comp[4]; + I64 cnt; + while (*str < '0' || *str > '9') { + ++str; + } + StrCpy(buffer, str); + String.Trim(buffer, ')'); + U8** channel = String.Split(buffer, ',', &cnt); + + for (i = 0; i < 4; i++) { + if (StrOcc(channel[i], '%')) { + String.Trim(channel[i], '%'); + comp[i] = ToI64(2.55 * Str2F64(channel[i])); + } else if (StrOcc(channel[i], '.')) { + // FIXME: Do alpha blending when we eventually support transparency + comp[i] = 255; + } else { + comp[i] = Str2I64(i); + } + } + Free(channel); + return Color(comp[0], comp[1], comp[2], comp[3]); +} + +U32 @css_resolve_color_from_rgb_tuple(U8* str) +{ + U8 buffer[128]; + + I64 i; + I64 comp[3]; + I64 cnt; + while (*str < '0' || *str > '9') { + ++str; + } + StrCpy(buffer, str); + String.Trim(buffer, ')'); + U8** channel = String.Split(buffer, ',', &cnt); + + for (i = 0; i < 3; i++) { + if (StrOcc(channel[i], '%')) { + String.Trim(channel[i], '%'); + comp[i] = ToI64(2.55 * Str2F64(channel[i])); + } else { + comp[i] = Str2I64(i); + } + } + Free(channel); + return Color(comp[0], comp[1], comp[2]); +} + +U0 @css_resolve_color(U32* dst, U8* str) +{ + if (@css_named_colors->@(str)) { + *dst = @css_resolve_color_from_rrggbb(@css_named_colors->@(str)); + } else if (*str == '#') { + *dst = @css_resolve_color_from_rrggbb(str); + } else if (!MemCmp(str, "rgba", 4)) { + *dst = @css_resolve_color_from_rgba_tuple(str); + } else if (!MemCmp(str, "rgb", 3)) { + *dst = @css_resolve_color_from_rgb_tuple(str); + } else { + // unsupported; do nothing + } +} + Bool @apply_css_properties_to_node(@html_dom_node* node, JsonObject* properties) { Bool should_display = TRUE; @@ -316,23 +386,16 @@ Bool @apply_css_properties_to_node(@html_dom_node* node, JsonObject* properties) } if (!StrICmp(key->name, "background") || !StrICmp(key->name, "background-color")) { - if (@css_named_colors->@(values->@(0))) { - node->backgroundColor = @css_resolve_color_from_rrggbb(@css_named_colors->@(values->@(0))); - } else if (values->@(0)(U8*)[0] == '#') { - node->backgroundColor = @css_resolve_color_from_rrggbb(values->@(0)); + if (!StrICmp(values->@(0), "transparent")) { + // FIXME: Actually do transparency + node->backgroundColor = node->parentNode->backgroundColor; } else { - // unsupported + @css_resolve_color(&node->backgroundColor, values->@(0)); } } if (!StrICmp(key->name, "color")) { - if (@css_named_colors->@(values->@(0))) { - node->color = @css_resolve_color_from_rrggbb(@css_named_colors->@(values->@(0))); - } else if (values->@(0)(U8*)[0] == '#') { - node->color = @css_resolve_color_from_rrggbb(values->@(0)); - } else { - // unsupported - } + @css_resolve_color(&node->color, values->@(0)); } if (!StrICmp(key->name, "width") && !StrICmp(values->@(0) + StrLen(values->@(0)) - 2, "px")) { @@ -1123,19 +1186,11 @@ U0 @apply_attribute_values_to_node(@html_dom_node* node) return; if (node->attributes->@("bgcolor")) { - if (@css_named_colors->@(node->attributes->@("bgcolor"))) { - node->backgroundColor = @css_resolve_color_from_rrggbb(@css_named_colors->@(node->attributes->@("bgcolor"))); - } else if (node->attributes->@("bgcolor")(U8*)[0] == '#') { - node->backgroundColor = @css_resolve_color_from_rrggbb(node->attributes->@("bgcolor")); - } + @css_resolve_color(&node->backgroundColor, node->attributes->@("bgcolor")); } if (node->attributes->@("color")) { - if (@css_named_colors->@(node->attributes->@("color"))) { - node->color = @css_resolve_color_from_rrggbb(@css_named_colors->@(node->attributes->@("color"))); - } else if (node->attributes->@("color")(U8*)[0] == '#') { - node->color = @css_resolve_color_from_rrggbb(node->attributes->@("color")); - } + @css_resolve_color(&node->color, node->attributes->@("color")); } if (node->attributes->@("align")) {