From: yu.dongliang <18588496441@163.com> Date: Sat, 25 Apr 2026 10:39:41 +0000 (+0800) Subject: css: border, margin, padding of X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=58af1588b87682b86900deccf94f08258b5ff495;p=abc.git css: border, margin, padding of
--- diff --git a/examples/table.html b/examples/table.html index 326065b..5c73bda 100644 --- a/examples/table.html +++ b/examples/table.html @@ -2,9 +2,13 @@ diff --git a/html/Makefile b/html/Makefile index 7e04712..88b0972 100644 --- a/html/Makefile +++ b/html/Makefile @@ -4,6 +4,7 @@ CFILES += abc_html.c CFILES += abc_css.c CFILES += abc_css_color.c CFILES += abc_css_position.c +CFILES += abc_css_border.c CFILES += abc_io_util.c CFILES += abc_io_file.c diff --git a/html/abc_css.c b/html/abc_css.c index b00f26b..fe9ca42 100644 --- a/html/abc_css.c +++ b/html/abc_css.c @@ -56,6 +56,7 @@ static int __css_parse_value(abc_obj_t* css, abc_obj_t* attr) abc_char_t* c = NULL; abc_char_t* c2 = NULL; + int c0 = ' '; while (1) { c = __io_pop_char(&css->io); @@ -87,8 +88,17 @@ static int __css_parse_value(abc_obj_t* css, abc_obj_t* attr) if (';' == c->c || '}' == c->c || EOF == c->c) break; - else - scf_string_cat_cstr_len(value, c->utf8, c->len); + + if (' ' == c0) { + if (' ' == c->c || '\t' == c->c || '\r' == c->c || '\n' == c->c) { + free(c); + continue; + } + + c0 = c->c; + } + + scf_string_cat_cstr_len(value, c->utf8, c->len); free(c); c = NULL; @@ -798,6 +808,37 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj) continue; } + } else if (ABC_CSS_COMMA == css->type) { + int c; + int c0 = ' '; + uint8_t* p0 = NULL; + uint8_t* p = css->text->data; + + do { + c = *p; + + if (!c || ' ' == c || '\t' == c || '\r' == c || '\n' == c || ',' == c) { + if ( ' ' == c0 || '\t' == c0 || '\r' == c0 || '\n' == c0 || ',' == c0) + goto next; + + if (__html_strncmp(obj->keys[0], p0, (size_t)(p - p0))) { + p0 = NULL; + goto next; + } + + abc_obj_set_css(obj, css); + break; + } else { + if (!p0) + p0 = p; + } +next: + c0 = c; + p++; + } while (c); + + continue; + } else if (ABC_CSS_LINK == css->type || ABC_CSS_VISITED == css->type || ABC_CSS_HOVER == css->type diff --git a/html/abc_css_border.c b/html/abc_css_border.c new file mode 100644 index 0000000..f2ef57b --- /dev/null +++ b/html/abc_css_border.c @@ -0,0 +1,154 @@ +#include"abc_html.h" + +typedef struct css_border_s +{ + char** names; + int type; +} css_border_t; + +static char* css_solid [] = {"solid", "实线", NULL}; +static char* css_dotted[] = {"dotted", "点线", NULL}; +static char* css_dashed[] = {"dashed", "虚线", NULL}; + +static css_border_t css_borders[] = +{ + {css_solid, ABC_BORDER_SOLID}, + {css_dotted, ABC_BORDER_DOTTED}, + {css_dashed, ABC_BORDER_DASHED}, +}; + +static void __css_border_type(int* type, const char* name, size_t name_len) +{ + int i; + for (i = 0; i < sizeof(css_borders) / sizeof(css_borders[0]); i++) { + css_border_t* b = &css_borders[i]; + + int j; + for (j = 0; b->names[j]; j++) { + if (!__html_strncmp(b->names[j], name, name_len)) { + *type = b->type; + return; + } + } + } +} + +int abc_css_border(double* r, double* g, double* b, int* width, int* type, abc_obj_t* obj, const uint8_t* str) +{ + *r = 0.0; + *g = 0.0; + *b = 0.0; + *width = 1; + *type = ABC_BORDER_SOLID; + + const uint8_t* p = str; + const uint8_t* unit = NULL; + + double value = 0.0; + int dot = 0; + int percent = 0; + int prev = 0; + int i = 0; + int c = 0; + + do { + c = *str; + + if ('.' == c) + dot = 10; + else if ('%' == c) + percent++; + + else if ('#' == c) { + if (' ' == prev || '\t' == prev || '\r' == prev || '\n' == prev) + p = str; + + } else if ('a' <= c && 'z' >= c) { + + if (' ' == prev || '\t' == prev || '\r' == prev || '\n' == prev) + p = str; + else if (!unit) + unit = str; + + } else if ('0' <= c && '9' >= c) { + + if (dot > 0) { + value += (c - '0') / (double)dot; + dot *= 10; + } else { + value *= 10.0; + value += c - '0'; + } + + } else if ('\0' == c || ' ' == c || '\t' == c || '\r' == c || '\n' == c) { + + if (' ' == prev || '\t' == prev || '\r' == prev || '\n' == prev) + goto next; + + if (percent) { + value *= 0.01; + + if (0 == i) + *width = value; + + } else if ('a' <= *p && *p <= 'z') { + if (1 == i) + __css_border_type(type, p, (size_t)(str - p)); + else if (i > 1) + abc_css_color(r, g, b, p); + + } else if ('#' == *p) { + if (i > 1) + abc_css_color(r, g, b, p); + + } else if (unit) { + // for other css units, ignore + + if (0 == i) + *width = value; + } + + p = str; + unit = NULL; + value = 0.0; + dot = 0; + percent = 0; + i++; + + if (i > 2) + break; + } + +next: + prev = c; + str++; + } while (c); + + return 0; +} + +int abc_css_margin(abc_obj_t* obj) +{ + int type = ABC_BORDER_SOLID; + int margin = 2; + int border = 0; + int padding = 2; + + double r = 0.0; + double g = 0.0; + double b = 0.0; + + abc_obj_t* attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_MARGIN); + if (attr) + margin = atoi(attr->value->data); + + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BORDER); + if (attr) + abc_css_border(&r, &g, &b, &border, &type, obj, attr->value->data); + + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_PADDING); + if (attr) + padding = atoi(attr->value->data); + + return margin + border + padding; +} diff --git a/html/abc_html.c b/html/abc_html.c index c33a917..1fc771a 100644 --- a/html/abc_html.c +++ b/html/abc_html.c @@ -32,6 +32,8 @@ static char* list_style_type_keys[] = {"list-style-type", "列表标记", static char* list_style_image_keys[] = {"list-style-image", "列表标记图片", NULL}; static char* list_style_pos_keys[] = {"list-style-position", "列表标记位置", NULL}; +static char* border_collapse_keys[] = {"border-collapse", "边框折叠", NULL}; + static char* class_keys[] = {"class", "类名", NULL}; static char* type_keys[] = {"type", "类型", NULL}; static char* name_keys[] = {"name", "名字", NULL}; @@ -255,6 +257,10 @@ static html_attr_t h6_attrs[] = static html_attr_t p_attrs[] = { + {margin_keys, "", ABC_HTML_ATTR_MARGIN, ABC_HTML_FLAG_SHOW}, + {border_keys, "", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, + {padding_keys, "", ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW}, + {class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW}, {style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW}, {id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW}, @@ -273,6 +279,10 @@ static html_attr_t p_attrs[] = static html_attr_t css_id_attrs[] = { + {margin_keys, "2", ABC_HTML_ATTR_MARGIN, ABC_HTML_FLAG_SHOW}, + {border_keys, "1", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, + {padding_keys, "4", ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW}, + {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0}, {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0}, {font_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW}, @@ -280,8 +290,6 @@ static html_attr_t css_id_attrs[] = {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, - {border_keys, "", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, - {text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW}, {text_decoration_keys, "", ABC_HTML_ATTR_TEXT_DECORATION, ABC_HTML_FLAG_SHOW}, {text_transform_keys, "", ABC_HTML_ATTR_TEXT_TRANSFORM, ABC_HTML_FLAG_SHOW}, @@ -352,13 +360,21 @@ static html_attr_t link_attrs[] = static html_attr_t img_attrs[] = { - {src_keys, "", ABC_HTML_ATTR_SRC, ABC_HTML_FLAG_SHOW}, - {width_keys, "100", ABC_HTML_ATTR_WIDTH, ABC_HTML_FLAG_SHOW}, - {height_keys, "100", ABC_HTML_ATTR_HEIGHT, ABC_HTML_FLAG_SHOW}, + {margin_keys, "", ABC_HTML_ATTR_MARGIN, ABC_HTML_FLAG_SHOW}, + {border_keys, "", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, + {padding_keys, "", ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW}, + + {src_keys, "", ABC_HTML_ATTR_SRC, ABC_HTML_FLAG_SHOW}, + {width_keys, "100", ABC_HTML_ATTR_WIDTH, ABC_HTML_FLAG_SHOW}, + {height_keys, "100", ABC_HTML_ATTR_HEIGHT, ABC_HTML_FLAG_SHOW}, }; static html_attr_t video_attrs[] = { + {margin_keys, "", ABC_HTML_ATTR_MARGIN, ABC_HTML_FLAG_SHOW}, + {border_keys, "", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, + {padding_keys, "", ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW}, + {width_keys, "100", ABC_HTML_ATTR_WIDTH, ABC_HTML_FLAG_SHOW}, {height_keys, "100", ABC_HTML_ATTR_HEIGHT, ABC_HTML_FLAG_SHOW}, {control_keys, "", ABC_HTML_ATTR_CONTROLS, 0}, @@ -424,6 +440,10 @@ static html_attr_t ol_attrs[] = static html_attr_t table_attrs[] = { + {margin_keys, "2", ABC_HTML_ATTR_MARGIN, ABC_HTML_FLAG_SHOW}, + {border_keys, "1", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, + {padding_keys, "4", ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW}, + {class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW}, {style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW}, {id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW}, @@ -434,18 +454,20 @@ static html_attr_t table_attrs[] = {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, - {margin_keys, "2", ABC_HTML_ATTR_MARGIN, ABC_HTML_FLAG_SHOW}, - {border_keys, "1", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, - {padding_keys, "4", ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW}, + {border_collapse_keys, "", ABC_CSS_BORDER_COLLAPSE, ABC_HTML_FLAG_SHOW}, }; static html_attr_t th_attrs[] = { + {margin_keys, "2", ABC_HTML_ATTR_MARGIN, ABC_HTML_FLAG_SHOW}, + {border_keys, "1", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, + {padding_keys, "4", ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW}, + {class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW}, {style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW}, {id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW}, {font_keys, "SimHei", ABC_HTML_ATTR_FONT, 0}, - {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0}, + {font_size_keys, "18", ABC_HTML_ATTR_FONT_SIZE, 0}, {font_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW}, {font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0}, @@ -454,6 +476,10 @@ static html_attr_t th_attrs[] = static html_attr_t td_attrs[] = { + {margin_keys, "2", ABC_HTML_ATTR_MARGIN, ABC_HTML_FLAG_SHOW}, + {border_keys, "1", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, + {padding_keys, "4", ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW}, + {class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW}, {style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW}, {id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW}, diff --git a/html/abc_html.h b/html/abc_html.h index 4f59ebe..2058468 100644 --- a/html/abc_html.h +++ b/html/abc_html.h @@ -57,4 +57,7 @@ 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); int abc_css_position(float* x, float* y, float w, float h, abc_obj_t* obj, const uint8_t* str); +int abc_css_border(double* r, double* g, double* b, int* width, int* type, abc_obj_t* obj, const uint8_t* str); +int abc_css_margin(abc_obj_t* obj); + #endif diff --git a/html/abc_obj.h b/html/abc_obj.h index f157ec8..816fa7b 100644 --- a/html/abc_obj.h +++ b/html/abc_obj.h @@ -131,6 +131,8 @@ enum abc_objs ABC_CSS_LIST_STYLE_IMAGE, ABC_CSS_LIST_STYLE_POSITION, + ABC_CSS_BORDER_COLLAPSE, + ABC_CSS_COMMA, // ... new css add here @@ -140,6 +142,13 @@ enum abc_objs ABC_CSS_CLASS = ABC_HTML_ATTR_CLASS, }; +enum abc_border_style +{ + ABC_BORDER_SOLID, + ABC_BORDER_DOTTED, + ABC_BORDER_DASHED, +}; + struct abc_obj_s { scf_list_t list; diff --git a/ui/Makefile b/ui/Makefile index 7962f38..7ca2bea 100644 --- a/ui/Makefile +++ b/ui/Makefile @@ -49,6 +49,7 @@ CFILES += ../html/abc_obj.c CFILES += ../html/abc_css.c CFILES += ../html/abc_css_color.c CFILES += ../html/abc_css_position.c +CFILES += ../html/abc_css_border.c CFILES += ../html/abc_io_util.c CFILES += ../html/abc_io_file.c diff --git a/ui/abc_layout_table.c b/ui/abc_layout_table.c index 41da221..8c4124d 100644 --- a/ui/abc_layout_table.c +++ b/ui/abc_layout_table.c @@ -8,36 +8,37 @@ int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height abc_obj_t* td; abc_obj_t* attr; - int margin = 0; - int border = 1; - int padding = 4; + int collapse = 0; - attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_MARGIN); - if (attr) - margin = atoi(attr->value->data); - - attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BORDER); - if (attr) - border = atoi(attr->value->data); - - attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_PADDING); - if (attr) - padding = atoi(attr->value->data); + attr = abc_obj_find_attr(obj, ABC_CSS_BORDER_COLLAPSE); + if (attr) { + if (!__html_strcmp(attr->value->data, "collapse")) { + collapse = 1; + abc_obj_set_attr(obj, ABC_HTML_ATTR_PADDING, "0", 1); + } + } - int d = margin + border + padding; + int d = abc_css_margin(obj); int x = obj->x + d; int y = obj->y + d; for (l = scf_list_head(&obj->childs); l != scf_list_sentinel(&obj->childs); l = scf_list_next(l)) { tr = scf_list_data(l, abc_obj_t, list); + int d2 = d; + for (l2 = scf_list_head(&tr->childs); l2 != scf_list_sentinel(&tr->childs); l2 = scf_list_next(l2)) { td = scf_list_data(l2, abc_obj_t, list); + if (collapse) + abc_obj_set_attr(td, ABC_HTML_ATTR_MARGIN, "0", 1); + + d2 = abc_css_margin(td); + td->x = x; td->y = y; - td->w = obj->td_width + d * 2; - td->h = obj->td_height + d * 2; + td->w = obj->td_width + d2 * 2; + td->h = obj->td_height + d2 * 2; x += td->w; } @@ -45,7 +46,7 @@ int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height obj->w = x + d - obj->x; x = obj->x + d; - y += obj->td_height + d * 2; + y += obj->td_height + d2 * 2; } obj->h = y + d - obj->y; diff --git a/ui/abc_render_table.c b/ui/abc_render_table.c index 295ddf0..732d3f7 100644 --- a/ui/abc_render_table.c +++ b/ui/abc_render_table.c @@ -63,8 +63,9 @@ static int _render_draw_table(abc_render_t* render, abc_obj_t* obj, int width, i if (0 == vao) __init_buffers(&vao, buffers); - double margin = 0.0; - double border = 1.0; + int margin = 0; + int border = 1; + int border_type = ABC_BORDER_SOLID; double r0 = 0.0; double g0 = 0.0; @@ -74,21 +75,22 @@ static int _render_draw_table(abc_render_t* render, abc_obj_t* obj, int width, i double g1 = 0.0; double b1 = 0.0; - abc_obj_t* attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR); - if (attr) - abc_css_color(&r0, &g0, &b0, attr->value->data); - - attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR); + abc_obj_t* attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR); if (attr) abc_css_color(&r1, &g1, &b1, attr->value->data); attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_MARGIN); if (attr) - margin = atof(attr->value->data); + margin = atoi(attr->value->data); attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BORDER); if (attr) - border = atof(attr->value->data); + abc_css_border(&r0, &g0, &b0, &border, &border_type, obj, attr->value->data); + else { + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR); + if (attr) + abc_css_color(&r0, &g0, &b0, attr->value->data); + } float mvp[16]; __compute_mvp(mvp, 0, 0, 0);