From: yu.dongliang <18588496441@163.com> Date: Fri, 13 Mar 2026 06:13:18 +0000 (+0800) Subject: css: text-align X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=d2bd57f36868f0dd78b6ef66e6c87710d13c7c1f;p=abc.git css: text-align --- diff --git a/examples/css.html b/examples/css.html index bf8095a..5a0be37 100644 --- a/examples/css.html +++ b/examples/css.html @@ -12,7 +12,7 @@ p

Hello World!

-

这个段落采用CSS样式化。

+

这个段落采用CSS样式化。

diff --git a/html/abc_css.c b/html/abc_css.c index ebcbb13..66ecf58 100644 --- a/html/abc_css.c +++ b/html/abc_css.c @@ -318,7 +318,7 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj) for (l = scf_list_head(&label->attrs); l != scf_list_sentinel(&label->attrs); l = scf_list_next(l)) { attr = scf_list_data(l, abc_obj_t, list); - abc_obj_set_attr(obj, attr->type, attr->value->data); + abc_recursive_set_attr(obj, attr->type, attr->value->data); } } diff --git a/html/abc_html.c b/html/abc_html.c index 63a68fb..5485100 100644 --- a/html/abc_html.c +++ b/html/abc_html.c @@ -11,6 +11,9 @@ static char* font_keys[] = {"font", "字体", NULL}; static char* font_size_keys[] = {"font-size", "字号", NULL}; static char* font_color_keys[] = {"font-color", "字体颜色", "color", "颜色", NULL}; +static char* font_bold_keys[] = {"bold", "加粗", NULL}; +static char* font_italic_keys[] = {"italic", "斜体", NULL}; + static char* text_align_keys[] = {"text-align", "对齐", NULL}; static char* type_keys[] = {"type", "类型", NULL}; @@ -68,6 +71,8 @@ static char* h5_keys[] = {"h5", "标题5", NULL}; static char* h6_keys[] = {"h6", "标题6", NULL}; static char* p_keys[] = {"p", "段落", NULL}; static char* a_keys[] = {"a", "超链接", NULL}; +static char* b_keys[] = {"b", "加粗", NULL}; +static char* i_keys[] = {"i", "斜体", NULL}; static char* play_keys[] = {"play", "播放", NULL}; static char* progress_keys[] = {"progress", "进度条", NULL}; @@ -139,6 +144,24 @@ static html_attr_t p_attrs[] = {text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW}, }; +static html_attr_t b_attrs[] = +{ + {font_keys, "SimHei", ABC_HTML_ATTR_FONT, 0}, + {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0}, + {font_bold_keys, "true", ABC_HTML_ATTR_FONT_BOLD, 0}, + {font_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW}, + {text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW}, +}; + +static html_attr_t i_attrs[] = +{ + {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0}, + {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0}, + {font_italic_keys, "true", ABC_HTML_ATTR_FONT_ITALIC, 0}, + {font_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW}, + {text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW}, +}; + static html_attr_t a_attrs[] = { {href_keys, "", ABC_HTML_ATTR_HREF, ABC_HTML_FLAG_SHOW}, @@ -252,6 +275,9 @@ static html_label_t html_labels[] = {script_keys, ABC_HTML_SCRIPT, abc_number_of(script_attrs), script_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, {style_keys, ABC_HTML_STYLE, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, + + {b_keys, ABC_HTML_B, abc_number_of(b_attrs), b_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, + {i_keys, ABC_HTML_I, abc_number_of(i_attrs), i_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, }; static int __html_parse_obj(abc_html_t* html, abc_char_t* c); diff --git a/html/abc_obj.c b/html/abc_obj.c index b2ada1f..b026202 100644 --- a/html/abc_obj.c +++ b/html/abc_obj.c @@ -129,6 +129,22 @@ int abc_obj_set_attr(abc_obj_t* obj, int key, const char* value) return -EINVAL; } +int abc_recursive_set_attr(abc_obj_t* obj, int key, const char* value) +{ + scf_list_t* l; + abc_obj_t* child; + + abc_obj_set_attr(obj, key, value); + + for (l = scf_list_head(&obj->childs); l != scf_list_sentinel(&obj->childs); l = scf_list_next(l)) { + child = scf_list_data(l, abc_obj_t, list); + + abc_recursive_set_attr(child, key, value); + } + + return 0; +} + abc_obj_t* abc_obj_get_attr(abc_obj_t* obj, int key) { scf_list_t* l; diff --git a/html/abc_obj.h b/html/abc_obj.h index 66663b7..812b694 100644 --- a/html/abc_obj.h +++ b/html/abc_obj.h @@ -56,9 +56,11 @@ enum abc_objs ABC_HTML_PROGRESS, ABC_HTML_SCRIPT, - ABC_HTML_STYLE, + ABC_HTML_B, + ABC_HTML_I, + ABC_HTML_NB, // total HTML objects ABC_HTML_ATTR_ID, @@ -77,6 +79,8 @@ enum abc_objs ABC_HTML_ATTR_FONT, ABC_HTML_ATTR_FONT_SIZE, ABC_HTML_ATTR_FONT_COLOR, + ABC_HTML_ATTR_FONT_BOLD, + ABC_HTML_ATTR_FONT_ITALIC, ABC_HTML_ATTR_TEXT_ALIGN, @@ -158,4 +162,6 @@ abc_obj_t* abc_obj_find_type(abc_obj_t* root, int type); scf_string_t* abc_obj_to_string(abc_obj_t* obj); +int abc_recursive_set_attr(abc_obj_t* obj, int key, const char* value); + #endif diff --git a/ui/abc_layout.c b/ui/abc_layout.c index 63c0a94..c8f61fa 100644 --- a/ui/abc_layout.c +++ b/ui/abc_layout.c @@ -64,6 +64,9 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] = [ABC_HTML_SCRIPT] = abc_layout_empty, [ABC_HTML_STYLE] = abc_layout_empty, + + [ABC_HTML_B] = abc_layout_h1, + [ABC_HTML_I] = abc_layout_h1, }; int abc_layout_obj(abc_layout_t* layout, abc_obj_t* obj, int width, int height) @@ -78,6 +81,54 @@ int abc_layout_obj(abc_layout_t* layout, abc_obj_t* obj, int width, int height) return f(layout, obj, width, height); } +void abc_css_update_xy(abc_obj_t* root, int dx, int dy) +{ + scf_list_t* l; + abc_obj_t* obj; + + for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) { + obj = scf_list_data(l, abc_obj_t, list); + + obj->x += dx; + obj->y += dy; + + abc_css_update_xy(obj, dx, dy); + } +} + +int abc_layout_css(abc_obj_t* root) +{ + abc_obj_t* parent = root->parent; + abc_obj_t* attr; + + attr = abc_obj_get_attr(root, ABC_HTML_ATTR_TEXT_ALIGN); + if (attr) { + if (!parent || parent->w <= 0 || parent->h <= 0) + return 0; + + switch (parent->type) + { + case ABC_HTML_BODY: + break; + default: + return 0; + break; + } + + int x = root->x; + + if (!strcmp(attr->value->data, "center")) + 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; + + abc_css_update_xy(root, root->x - x, 0); + } + + return 0; +} + int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) { scf_string_t* key; @@ -90,6 +141,16 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) if (width <= 0 || height <= 0) return -EINVAL; + switch (root->type) + { + case ABC_HTML_BODY: + root->w = width; + root->h = height; + break; + default: + break; + }; + int x = root->x + 4; int y = root->y + 4; int h = 0; @@ -101,8 +162,8 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) child = scf_list_data(l, abc_obj_t, list); int ret; - switch (child->type) { - + switch (child->type) + { case ABC_HTML_H1: case ABC_HTML_H2: case ABC_HTML_H3: @@ -182,6 +243,8 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) if (root->h < Y - root->y) root->h = Y - root->y; + abc_layout_css(root); + 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); diff --git a/ui/abc_layout_h1.c b/ui/abc_layout_h1.c index 56f7032..ebc69a9 100644 --- a/ui/abc_layout_h1.c +++ b/ui/abc_layout_h1.c @@ -14,13 +14,30 @@ int abc_layout_h1(abc_layout_t* layout, abc_obj_t* obj, int width, int height) cr = cairo_create(surface); attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT); - if (attr) - cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + if (attr) { + int bold = CAIRO_FONT_WEIGHT_NORMAL; + int italic = CAIRO_FONT_SLANT_NORMAL; + + if (abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_BOLD)) + bold = CAIRO_FONT_WEIGHT_BOLD; + + if (abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_ITALIC)) + italic = CAIRO_FONT_SLANT_OBLIQUE; + + cairo_select_font_face(cr, attr->value->data, italic, bold); + } attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE); 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); cairo_text_extents(cr, obj->text->data, &extents); diff --git a/ui/abc_render.c b/ui/abc_render.c index 2784190..0ed4fde 100644 --- a/ui/abc_render.c +++ b/ui/abc_render.c @@ -66,6 +66,9 @@ static abc_render_t* abc_renders[ABC_HTML_NB] = [ABC_HTML_SCRIPT] = &abc_render_empty, [ABC_HTML_STYLE] = &abc_render_empty, + + [ABC_HTML_B] = &abc_render_h1, + [ABC_HTML_I] = &abc_render_h1, }; int abc_renders_fini() diff --git a/ui/abc_render_h1.c b/ui/abc_render_h1.c index 810f6ef..06a9834 100644 --- a/ui/abc_render_h1.c +++ b/ui/abc_render_h1.c @@ -71,13 +71,30 @@ static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int cairo_stroke(cr); attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT); - if (attr) - cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + if (attr) { + int bold = CAIRO_FONT_WEIGHT_NORMAL; + int italic = CAIRO_FONT_SLANT_NORMAL; + + if (abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_BOLD)) + bold = CAIRO_FONT_WEIGHT_BOLD; + + if (abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_ITALIC)) + italic = CAIRO_FONT_SLANT_OBLIQUE; + + cairo_select_font_face(cr, attr->value->data, italic, bold); + } attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE); 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); attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR); if (attr) { @@ -96,7 +113,7 @@ static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int 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);