css: parse css color like: red, #ff8000, rgb(0, 0, 255) master
authoryu.dongliang <18588496441@163.com>
Sun, 15 Mar 2026 10:43:47 +0000 (18:43 +0800)
committeryu.dongliang <18588496441@163.com>
Sun, 15 Mar 2026 10:43:47 +0000 (18:43 +0800)
html/Makefile
html/abc_css_color.c [new file with mode: 0644]
html/abc_html.h
ui/Makefile
ui/abc_layout.c
ui/abc_render_a.c
ui/abc_render_h1.c

index e404606a38188bf8efcf18443e1e0d6e2f309e41..51ddf3ea9e0036f976ce2ee50aca962be5367852 100644 (file)
@@ -2,6 +2,8 @@ CFILES += main.c
 CFILES += abc_obj.c
 CFILES += abc_html.c
 CFILES += abc_css.c
 CFILES += abc_obj.c
 CFILES += abc_html.c
 CFILES += abc_css.c
+CFILES += abc_css_color.c
+
 CFILES += abc_io_util.c
 CFILES += abc_io_file.c
 CFILES += abc_io_http.c
 CFILES += abc_io_util.c
 CFILES += abc_io_file.c
 CFILES += abc_io_http.c
diff --git a/html/abc_css_color.c b/html/abc_css_color.c
new file mode 100644 (file)
index 0000000..07cf730
--- /dev/null
@@ -0,0 +1,98 @@
+#include"abc_html.h"
+
+typedef struct css_color_s
+{
+       char**  names;
+       double  r;
+       double  g;
+       double  b;
+} css_color_t;
+
+static char* css_red[]   = {"red",   "红", NULL};
+static char* css_green[] = {"green", "绿", NULL};
+static char* css_blue[]  = {"blue",  "蓝", NULL};
+
+static char* css_white[] = {"white", "白", NULL};
+static char* css_black[] = {"black", "黑", NULL};
+
+static css_color_t  css_colors[] =
+{
+       {css_red,   1.0, 0.0, 0.0},
+       {css_green, 0.0, 1.0, 0.0},
+       {css_blue,  0.0, 0.0, 1.0},
+
+       {css_white, 1.0, 1.0, 1.0},
+       {css_black, 0.0, 0.0, 0.0},
+};
+
+int abc_css_color(double* r, double* g, double* b, const uint8_t* str)
+{
+       *r = 0.0;
+       *g = 0.0;
+       *b = 0.0;
+
+       if ('#' == *str) {
+               uint64_t value = 0;
+
+               while (*++str) {
+                       int c = *str;
+
+                       if ('0' <= c && '9' >= c) {
+                               value <<= 4;
+                               value += c - '0';
+                       } else {
+                               c |= 0x20;
+
+                               if ('a' <= c && 'f' >= c) {
+                                       value <<= 4;
+                                       value += c - 'a' + 10;
+                               }
+                       }
+               }
+
+               *r = ((value >> 16) & 0xff) / 255.0;
+               *g = ((value >>  8) & 0xff) / 255.0;
+               *b = ( value        & 0xff) / 255.0;
+
+       } else if (!strncmp(str, "rgb(", 4)) {
+               const uint8_t* p = str + 4;
+
+               str = p;
+               while (*str && ',' != *str)
+                       str++;
+               *r = atof(p) / 255.0;
+
+               if (*str) {
+                       p = ++str;
+                       while (*str && ',' != *str)
+                               str++;
+                       *g = atof(p) / 255.0;
+
+                       if (*str) {
+                               p = ++str;
+                               while (*str && ')' != *str)
+                                       str++;
+                               *b = atof(p) / 255.0;
+                       }
+               }
+       } else {
+               int i;
+               for (i = 0; i < sizeof(css_colors) / sizeof(css_colors[0]); i++) {
+                       css_color_t* c = &css_colors[i];
+
+                       int j;
+                       for (j = 0; c->names[j]; j++) {
+                               if (!strcmp(c->names[j], str)) {
+                                       *r = c->r;
+                                       *g = c->g;
+                                       *b = c->b;
+                                       return 0;
+                               }
+                       }
+               }
+
+               return -1;
+       }
+
+       return 0;
+}
index 4ecb379b5d23516b90b7fa050d94b55155aa6834..54aa23a72765b1742f8e6118098991d15b0c07b1 100644 (file)
@@ -52,4 +52,6 @@ int  abc_html_parse(abc_html_t* html);
 int  abc_css_parse (abc_obj_t*  css);
 int  abc_css_use   (abc_html_t* html, abc_obj_t* obj);
 
 int  abc_css_parse (abc_obj_t*  css);
 int  abc_css_use   (abc_html_t* html, abc_obj_t* obj);
 
+int  abc_css_color (double* r, double* g, double* b, const uint8_t* str);
+
 #endif
 #endif
index ed0856ec7216e43597333322f191d68af23ca96d..6aa23e1d430633da029f30466f8cf9dce285174b 100644 (file)
@@ -43,8 +43,10 @@ CFILES += abc_render_video.c
 CFILES += abc_render_audio.c
 
 CFILES += ../html/abc_html.c
 CFILES += abc_render_audio.c
 
 CFILES += ../html/abc_html.c
-CFILES += ../html/abc_css.c
 CFILES += ../html/abc_obj.c
 CFILES += ../html/abc_obj.c
+CFILES += ../html/abc_css.c
+CFILES += ../html/abc_css_color.c
+
 CFILES += ../html/abc_io_util.c
 CFILES += ../html/abc_io_file.c
 CFILES += ../html/abc_io_http.c
 CFILES += ../html/abc_io_util.c
 CFILES += ../html/abc_io_file.c
 CFILES += ../html/abc_io_http.c
index c8f61fa2d22313b6c8c8f31315f68e20ada3147d..b33897a8a863e6cff2f38a8795aedb1afd734a15 100644 (file)
@@ -121,7 +121,7 @@ int abc_layout_css(abc_obj_t* root)
                        root->x = parent->x + (parent->w - root->w) / 2 + 4;
 
                else if (!strcmp(attr->value->data, "right"))
                        root->x = parent->x + (parent->w - root->w) / 2 + 4;
 
                else if (!strcmp(attr->value->data, "right"))
-                       root->x = parent->x + parent->w - root->w - 4;
+                       root->x = parent->x + parent->w - root->w - 8;
 
                abc_css_update_xy(root, root->x - x, 0);
        }
 
                abc_css_update_xy(root, root->x - x, 0);
        }
@@ -188,6 +188,11 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                                y += h;
                                h  = 0;
                        default:
                                y += h;
                                h  = 0;
                        default:
+                               if (child->type == root->type && l == scf_list_head(&root->childs)) {
+                                       x = root->x;
+                                       y = root->y;
+                               }
+
                                child->x = x;
                                child->y = y;
 
                                child->x = x;
                                child->y = y;
 
@@ -196,7 +201,6 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                                        return ret;
 
                                if (x + child->w < width) {
                                        return ret;
 
                                if (x + child->w < width) {
-
                                        if (h < child->h)
                                                h = child->h;
 
                                        if (h < child->h)
                                                h = child->h;
 
@@ -223,9 +227,6 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                                break;
                };
 
                                break;
                };
 
-               if (child->keys)
-                       scf_logd("key: %s, x: %d, y: %d, w: %d, h: %d\n\n", child->keys[0], child->x, child->y, child->w, child->h);
-
                if (X < child->x + child->w)
                        X = child->x + child->w;
 
                if (X < child->x + child->w)
                        X = child->x + child->w;
 
@@ -244,9 +245,12 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                root->h = Y - root->y;
 
        abc_layout_css(root);
                root->h = Y - root->y;
 
        abc_layout_css(root);
-
+#if 0
        if (root->keys)
        if (root->keys)
-               scf_logd("key: %s, x: %d, y: %d, w: %d, h: %d\n", root->keys[0], root->x, root->y, root->w, root->h);
-
+               scf_logw("key: %s, ", root->keys[0]);
+       if (root->text)
+               printf("%s, ", root->text->data);
+       printf("x: %d, y: %d, w: %d, h: %d\n", root->x, root->y, root->w, root->h);
+#endif
        return 0;
 }
        return 0;
 }
index aa5b7ddb937ae6fba82bbbeadd02cef7b66e8d0c..81f9e4c6dc9c4638039b205654dfb8e1609c2c39 100644 (file)
@@ -69,7 +69,10 @@ static int _render_draw_a(abc_render_t* render, abc_obj_t* obj, int width, int h
        cairo_fill(cr);
        cairo_stroke(cr);
 
        cairo_fill(cr);
        cairo_stroke(cr);
 
-       cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
+       double r = 0.0;
+       double g = 0.0;
+       double b = 0.0;
+       cairo_set_source_rgba(cr, r, g, b, 1.0);
 
        for (l   = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
                attr = scf_list_data(l, abc_obj_t, list);
 
        for (l   = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
                attr = scf_list_data(l, abc_obj_t, list);
@@ -85,8 +88,9 @@ static int _render_draw_a(abc_render_t* render, abc_obj_t* obj, int width, int h
                                break;
 
                        case ABC_HTML_ATTR_FONT_COLOR:
                                break;
 
                        case ABC_HTML_ATTR_FONT_COLOR:
-                               if (!strcmp(attr->value->data, "blue"))
-                                       cairo_set_source_rgba(cr, 0.0, 0.0, 1.0, 1.0);
+                               abc_css_color(&r, &g, &b, attr->value->data);
+
+                               cairo_set_source_rgba(cr, r, g, b, 1.0);
                                break;
                        default:
                                break;
                                break;
                        default:
                                break;
index 06a983464c4dd3c608f346f12550d60be3dda3bb..beb45e1e194f1308441c8d10e7faabac22c59112 100644 (file)
@@ -88,32 +88,20 @@ static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int
        if (attr)
                cairo_set_font_size(cr, atoi(attr->value->data));
 
        if (attr)
                cairo_set_font_size(cr, atoi(attr->value->data));
 
-       cairo_font_options_t *options = cairo_font_options_create();
-       cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_SUBPIXEL);
-       cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_FULL);
-       cairo_font_options_set_hint_metrics(options, CAIRO_HINT_METRICS_ON);
-       cairo_set_font_options(cr, options);
-       cairo_font_options_destroy(options);
-
-       cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
+       double r = 0.0;
+       double g = 0.0;
+       double b = 0.0;
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
-       if (attr) {
-               if (!strcmp(attr->value->data, "red"))
-                       cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 1.0);
-
-               else if (!strcmp(attr->value->data, "green"))
-                       cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 1.0);
-
-               else if (!strcmp(attr->value->data, "blue"))
-                       cairo_set_source_rgba(cr, 0.0, 0.0, 1.0, 1.0);
-       }
+       if (attr)
+               abc_css_color(&r, &g, &b, attr->value->data);
 
 
-       cairo_text_extents(cr, obj->text->data, &extents);
+       cairo_set_source_rgba(cr, r, g, b, 1.0);
+       cairo_text_extents   (cr, obj->text->data, &extents);
 
        cairo_move_to  (cr, extents.x_bearing, -extents.y_bearing);
        cairo_show_text(cr, obj->text->data);
 
 
        cairo_move_to  (cr, extents.x_bearing, -extents.y_bearing);
        cairo_show_text(cr, obj->text->data);
 
-       cairo_surface_write_to_png(surface, "tmp.png");
+//     cairo_surface_write_to_png(surface, "tmp.png");
 
        cairo_destroy(cr);
        cairo_surface_destroy(surface);
 
        cairo_destroy(cr);
        cairo_surface_destroy(surface);