From 605daa2b9dea7dfcda5e6bd3f68a67b44d285453 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Sun, 12 Apr 2026 17:15:59 +0800 Subject: [PATCH] css: text-decoration, such as 'underline, overline, line-through, none' --- examples/css.html | 2 + examples/style.css | 6 +- html/abc_css.c | 63 +++++++++- html/abc_css_position.c | 18 ++- html/abc_html.c | 259 +++++++++++++++++++++++++--------------- html/abc_obj.c | 10 +- html/abc_obj.h | 10 +- ui/Makefile | 2 - ui/abc_layout.c | 3 +- ui/abc_layout_a.c | 52 -------- ui/abc_layout_h1.c | 12 +- ui/abc_render.c | 3 +- ui/abc_render_a.c | 169 -------------------------- ui/abc_render_h1.c | 43 +++++-- 14 files changed, 294 insertions(+), 358 deletions(-) delete mode 100644 ui/abc_layout_a.c delete mode 100644 ui/abc_render_a.c diff --git a/examples/css.html b/examples/css.html index 2eb455e..47d68ec 100644 --- a/examples/css.html +++ b/examples/css.html @@ -9,6 +9,8 @@

Hello World!

这个段落采用CSS样式化。

这个段落采用CSS样式化。

+ +

链接到: runoob.com

diff --git a/examples/style.css b/examples/style.css index ae78f89..8754073 100644 --- a/examples/style.css +++ b/examples/style.css @@ -1,11 +1,13 @@ body { - background-color:#b0c4de; + background: #b0c4de url('img.png') no-repeat right top ; +/* background-color:#b0c4de; background-image:url('img.png'); background-position:right top; - background-repeat:no-repeat; + background-repeat:no-repeat; */ } h1 {background-color:#6495ed;} +a {text-decoration:none;} #a /*css comment*/ { diff --git a/html/abc_css.c b/html/abc_css.c index b04339d..e354f41 100644 --- a/html/abc_css.c +++ b/html/abc_css.c @@ -469,15 +469,74 @@ int abc_css_parse(abc_obj_t* css) return ret; } +static void __css_background(abc_obj_t* obj, abc_obj_t* attr) +{ + char* p0 = NULL; + char* p1 = attr->value->data; + int c0 = 0; + int i = 0; + int c; + + do { + c = *p1; + + if ('\0' == c || ' ' == c || '\t' == c || '\r' == c || '\n' == c) + { + if (!p0) + goto next; + + if (' ' == c0 || '\t' == c0 || '\r' == c0 || '\n' == c0) + goto next; + + switch (i) { + case 0: + abc_obj_set_attr(obj, ABC_HTML_ATTR_BG_COLOR, p0, (size_t)(p1 - p0)); + p0 = NULL; + i++; + break; + + case 1: + abc_obj_set_attr(obj, ABC_HTML_ATTR_BG_IMAGE, p0, (size_t)(p1 - p0)); + p0 = NULL; + i++; + break; + + case 2: + abc_obj_set_attr(obj, ABC_HTML_ATTR_BG_REPEAT, p0, (size_t)(p1 - p0)); + p0 = NULL; + i++; + break; + default: + abc_obj_set_attr(obj, ABC_HTML_ATTR_BG_POSITION, p0, (size_t)(p1 - p0)); + break; + }; + } else { + if (!p0) + p0 = p1; + } + +next: + c0 = c; + p1++; + } while (c); +} + static void __css_set_attr(abc_obj_t* obj, abc_obj_t* attr) { switch (attr->type) { + case ABC_HTML_ATTR_BG: + __css_background(obj, attr); + break; + case ABC_HTML_ATTR_BG_COLOR: - abc_obj_set_attr(obj, attr->type, attr->value->data); + case ABC_HTML_ATTR_BG_IMAGE: + case ABC_HTML_ATTR_BG_REPEAT: + case ABC_HTML_ATTR_BG_POSITION: + abc_obj_set_attr(obj, attr->type, attr->value->data, attr->value->len); break; default: - abc_recursive_set_attr(obj, attr->type, attr->value->data); + abc_recursive_set_attr(obj, attr->type, attr->value->data, attr->value->len); break; }; } diff --git a/html/abc_css_position.c b/html/abc_css_position.c index 18e1c54..88df2c2 100644 --- a/html/abc_css_position.c +++ b/html/abc_css_position.c @@ -47,7 +47,7 @@ int abc_css_position(float* x, float* y, float w, float h, abc_obj_t* obj, const int dot = 0; int percent = 0; int prev = 0; - int n = 0; + int i = 0; int c = 0; do { @@ -77,24 +77,19 @@ int abc_css_position(float* x, float* y, float w, float h, abc_obj_t* obj, const } else if ('\0' == c || ' ' == c || '\t' == c || '\r' == c || '\n' == c) { - if (c) { - if (' ' == prev || '\t' == prev || '\r' == prev || '\n' == prev) { - prev = c; - str++; - continue; - } - } + if (' ' == prev || '\t' == prev || '\r' == prev || '\n' == prev) + goto next; if (percent) { value *= 0.01; - if (n > 0) + if (i > 0) *y = value; else *x = value; } else if ('a' <= *p && *p <= 'z') { - if (n > 0) + if (i > 0) __css_pos_value(y, p, (size_t)(str - p)); else __css_pos_value(x, p, (size_t)(str - p)); @@ -108,9 +103,10 @@ int abc_css_position(float* x, float* y, float w, float h, abc_obj_t* obj, const value = 0.0; dot = 0; percent = 0; - n++; + i++; } +next: prev = c; str++; } while (c); diff --git a/html/abc_html.c b/html/abc_html.c index 855b2c2..5ef572d 100644 --- a/html/abc_html.c +++ b/html/abc_html.c @@ -11,11 +11,12 @@ static char* height_keys[] = {"height", "高度", NULL}; 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_style_keys[] = {"style", "字体风格", 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* text_align_keys[] = {"text-align", "对齐", NULL}; +static char* text_decoration_keys[] = {"text-decoration", "下划线", NULL}; +static char* text_transform_keys[] = {"text-transform", "大小写", NULL}; +static char* text_indent_keys[] = {"text-transform", "缩进", NULL}; static char* bg_keys[] = {"background", "背景", NULL}; static char* bg_color_keys[] = {"background-color", "背景颜色", NULL}; @@ -108,143 +109,211 @@ static html_attr_t meta_attrs[] = static html_attr_t body_attrs[] = { - {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0}, - {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0}, - - {bg_keys, "", ABC_HTML_ATTR_BG, ABC_HTML_FLAG_SHOW}, - {bg_color_keys, "white", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, - {bg_image_keys, "", ABC_HTML_ATTR_BG_IMAGE, ABC_HTML_FLAG_SHOW}, - {bg_repeat_keys, "", ABC_HTML_ATTR_BG_REPEAT, ABC_HTML_FLAG_SHOW}, - {bg_position_keys, "", ABC_HTML_ATTR_BG_POSITION, 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}, + {font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0}, + + {bg_keys, "", ABC_HTML_ATTR_BG, ABC_HTML_FLAG_SHOW}, + {bg_color_keys, "white", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, + {bg_image_keys, "", ABC_HTML_ATTR_BG_IMAGE, ABC_HTML_FLAG_SHOW}, + {bg_repeat_keys, "", ABC_HTML_ATTR_BG_REPEAT, ABC_HTML_FLAG_SHOW}, + {bg_position_keys, "", ABC_HTML_ATTR_BG_POSITION, 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}, + {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_FLAG_SHOW}, }; static html_attr_t h1_attrs[] = { - {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, "40", ABC_HTML_ATTR_FONT_SIZE, 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}, - - {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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, "40", 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}, + + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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}, + {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_FLAG_SHOW}, }; static html_attr_t h2_attrs[] = { - {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, "32", ABC_HTML_ATTR_FONT_SIZE, 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}, - - {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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, "32", 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}, + + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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}, + {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_FLAG_SHOW}, }; static html_attr_t h3_attrs[] = { - {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, "28", ABC_HTML_ATTR_FONT_SIZE, 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}, - - {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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, "28", 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}, + + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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}, + {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_FLAG_SHOW}, }; static html_attr_t h4_attrs[] = { - {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, "24", ABC_HTML_ATTR_FONT_SIZE, 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}, - - {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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, "24", 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}, + + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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}, + {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_FLAG_SHOW}, }; static html_attr_t h5_attrs[] = { - {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, "20", ABC_HTML_ATTR_FONT_SIZE, 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}, - - {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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, "20", 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}, + + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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}, + {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_FLAG_SHOW}, }; static html_attr_t h6_attrs[] = { - {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_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}, - - {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW}, + {font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0}, + + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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}, + {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_FLAG_SHOW}, }; static html_attr_t p_attrs[] = { - {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, "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}, - {text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW}, - - {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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, "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}, + {font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0}, + + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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}, + {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_FLAG_SHOW}, }; static html_attr_t css_id_attrs[] = { - {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}, - {text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, 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}, + {font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0}, + + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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}, + {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, 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}, + {font_keys, "SimHei", 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}, + {font_style_keys, "bold", ABC_HTML_ATTR_FONT_STYLE, 0}, - {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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}, + {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, 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}, + {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}, + {font_style_keys, "italic", ABC_HTML_ATTR_FONT_STYLE, 0}, + + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, - {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, 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}, + {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_FLAG_SHOW}, }; static html_attr_t a_attrs[] = { - {href_keys, "", ABC_HTML_ATTR_HREF, ABC_HTML_FLAG_SHOW}, - {font_keys, "SimHei", ABC_HTML_ATTR_FONT, 0}, - {font_size_keys, "24", ABC_HTML_ATTR_FONT_SIZE, 0}, - {font_color_keys, "blue", ABC_HTML_ATTR_FONT_COLOR, 0}, + {href_keys, "", ABC_HTML_ATTR_HREF, 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, "SimSong", ABC_HTML_ATTR_FONT, 0}, + {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0}, + {font_color_keys, "blue", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW}, + {font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0}, + + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, + + {text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW}, + {text_decoration_keys, "underline", ABC_HTML_ATTR_TEXT_DECORATION, ABC_HTML_FLAG_SHOW}, + {text_transform_keys, "", ABC_HTML_ATTR_TEXT_TRANSFORM, ABC_HTML_FLAG_SHOW}, + {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_FLAG_SHOW}, }; static html_attr_t link_attrs[] = diff --git a/html/abc_obj.c b/html/abc_obj.c index d97be6d..147cba0 100644 --- a/html/abc_obj.c +++ b/html/abc_obj.c @@ -106,7 +106,7 @@ abc_obj_t* abc_obj_find_type(abc_obj_t* root, int type) return NULL; } -int abc_obj_set_attr(abc_obj_t* obj, int key, const char* value) +int abc_obj_set_attr(abc_obj_t* obj, int key, const char* value, size_t len) { scf_string_t* s; scf_list_t* l; @@ -116,7 +116,7 @@ int abc_obj_set_attr(abc_obj_t* obj, int key, const char* value) attr = scf_list_data(l, abc_obj_t, list); if (attr->type == key) { - s = scf_string_cstr(value); + s = scf_string_cstr_len(value, len); if (s) { scf_string_free(attr->value); attr->value = s; @@ -129,17 +129,17 @@ 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) +int abc_recursive_set_attr(abc_obj_t* obj, int key, const char* value, size_t len) { scf_list_t* l; abc_obj_t* child; - abc_obj_set_attr(obj, key, value); + abc_obj_set_attr(obj, key, value, len); 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); + abc_recursive_set_attr(child, key, value, len); } return 0; diff --git a/html/abc_obj.h b/html/abc_obj.h index a7a680e..49dda16 100644 --- a/html/abc_obj.h +++ b/html/abc_obj.h @@ -83,10 +83,12 @@ 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_FONT_STYLE, ABC_HTML_ATTR_TEXT_ALIGN, + ABC_HTML_ATTR_TEXT_DECORATION, + ABC_HTML_ATTR_TEXT_TRANSFORM, + ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_ATTR_BG, ABC_HTML_ATTR_BG_COLOR, @@ -170,7 +172,7 @@ void abc_obj_free (abc_obj_t* obj); abc_obj_t* abc_obj_find (abc_obj_t* root, int x, int y); void abc_obj_print(abc_obj_t* obj); -int abc_obj_set_attr (abc_obj_t* obj, int key, const char* value); +int abc_obj_set_attr (abc_obj_t* obj, int key, const char* value, size_t len); abc_obj_t* abc_obj_get_attr (abc_obj_t* obj, int key); abc_obj_t* abc_obj_find_attr(abc_obj_t* obj, int key); @@ -178,6 +180,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); +int abc_recursive_set_attr(abc_obj_t* obj, int key, const char* value, size_t len); #endif diff --git a/ui/Makefile b/ui/Makefile index d154fd4..c2d8c9d 100644 --- a/ui/Makefile +++ b/ui/Makefile @@ -7,7 +7,6 @@ CFILES += abc_layout_head.c CFILES += abc_layout_body.c CFILES += abc_layout_div.c CFILES += abc_layout_h1.c -CFILES += abc_layout_a.c CFILES += abc_layout_img.c CFILES += abc_layout_form.c @@ -31,7 +30,6 @@ CFILES += abc_render_bg_image.c CFILES += abc_render_empty.c CFILES += abc_render_h1.c -CFILES += abc_render_a.c CFILES += abc_render_a_href.c CFILES += abc_render_img.c CFILES += abc_render_form.c diff --git a/ui/abc_layout.c b/ui/abc_layout.c index d8cb26d..6275c9c 100644 --- a/ui/abc_layout.c +++ b/ui/abc_layout.c @@ -7,7 +7,6 @@ int abc_layout_body (abc_layout_t* layout, abc_obj_t* obj, int width, int height int abc_layout_div (abc_layout_t* layout, abc_obj_t* obj, int width, int height); int abc_layout_h1 (abc_layout_t* layout, abc_obj_t* obj, int width, int height); -int abc_layout_a (abc_layout_t* layout, abc_obj_t* obj, int width, int height); int abc_layout_img (abc_layout_t* layout, abc_obj_t* obj, int width, int height); int abc_layout_form (abc_layout_t* layout, abc_obj_t* obj, int width, int height); @@ -44,7 +43,7 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] = [ABC_HTML_P] = abc_layout_h1, [ABC_HTML_BR] = abc_layout_h1, - [ABC_HTML_A] = abc_layout_a, + [ABC_HTML_A] = abc_layout_h1, [ABC_HTML_IMG] = abc_layout_img, [ABC_HTML_FORM] = abc_layout_form, diff --git a/ui/abc_layout_a.c b/ui/abc_layout_a.c deleted file mode 100644 index 1635893..0000000 --- a/ui/abc_layout_a.c +++ /dev/null @@ -1,52 +0,0 @@ -#include"abc.h" - -int abc_layout_a(abc_layout_t* layout, abc_obj_t* obj, int width, int height) -{ - cairo_text_extents_t extents; - cairo_surface_t* surface; - cairo_t* cr; - - scf_list_t* l; - abc_obj_t* attr; - - surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - cr = cairo_create(surface); - - 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); - - switch (attr->type) { - - case ABC_HTML_ATTR_FONT: - cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); - break; - - case ABC_HTML_ATTR_FONT_SIZE: - cairo_set_font_size(cr, atoi(attr->value->data)); - break; - default: - break; - }; - } - - cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); - - cairo_text_extents(cr, obj->text->data, &extents); - -// obj->x = 4; -// obj->y = 4; - obj->w = extents.width + extents.x_bearing; - obj->h = extents.height + extents.height / 2; - - obj->w = (obj->w + 3) & ~0x3; - obj->h = (obj->h + 3) & ~0x3; - - scf_logi("%s, w: %d, h: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg\n", - obj->text->data, obj->w, obj->h, - extents.x_bearing, extents.y_bearing, extents.width, extents.height, - extents.x_advance, extents.y_advance); - - cairo_destroy(cr); - cairo_surface_destroy(surface); - return 0; -} diff --git a/ui/abc_layout_h1.c b/ui/abc_layout_h1.c index ebc69a9..84e085a 100644 --- a/ui/abc_layout_h1.c +++ b/ui/abc_layout_h1.c @@ -3,6 +3,7 @@ int abc_layout_h1(abc_layout_t* layout, abc_obj_t* obj, int width, int height) { abc_obj_t* attr; + abc_obj_t* style; cairo_text_extents_t extents; cairo_surface_t* surface; cairo_t* cr; @@ -18,11 +19,14 @@ int abc_layout_h1(abc_layout_t* layout, abc_obj_t* obj, int width, int height) 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; + style = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_STYLE); + if (style) { + if (!strcmp(style->value->data, "bold")) + bold = CAIRO_FONT_WEIGHT_BOLD; - if (abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_ITALIC)) - italic = CAIRO_FONT_SLANT_OBLIQUE; + else if (!strcmp(style->value->data, "italic") || !strcmp(style->value->data, "oblique")) + italic = CAIRO_FONT_SLANT_OBLIQUE; + } cairo_select_font_face(cr, attr->value->data, italic, bold); } diff --git a/ui/abc_render.c b/ui/abc_render.c index bfdbd97..6811585 100644 --- a/ui/abc_render.c +++ b/ui/abc_render.c @@ -9,7 +9,6 @@ extern abc_render_t abc_render_meta; extern abc_render_t abc_render_div; extern abc_render_t abc_render_h1; -extern abc_render_t abc_render_a; extern abc_render_t abc_render_a_href; extern abc_render_t abc_render_img; @@ -45,7 +44,7 @@ static abc_render_t* abc_renders[ABC_HTML_NB] = [ABC_HTML_P] = &abc_render_h1, [ABC_HTML_BR] = &abc_render_h1, - [ABC_HTML_A] = &abc_render_a, + [ABC_HTML_A] = &abc_render_h1, [ABC_HTML_A_HREF] = &abc_render_a_href, [ABC_HTML_IMG] = &abc_render_img, diff --git a/ui/abc_render_a.c b/ui/abc_render_a.c deleted file mode 100644 index 81f9e4c..0000000 --- a/ui/abc_render_a.c +++ /dev/null @@ -1,169 +0,0 @@ -#include"abc.h" - -static const char* vert_shader = - "#version 330 core\n" - "layout(location = 0) in vec4 position; \n" - "layout(location = 1) in vec2 a_texCoord; \n" - "out vec2 v_texCoord; \n" - "uniform mat4 mvp; \n" - "void main() { \n" - "gl_Position = mvp * position; \n" - "v_texCoord = a_texCoord; \n" - "} \n"; - -static const char* frag_shader = - "#version 330 core\n" - "in vec2 v_texCoord; \n" - "out vec4 outputColor; \n" - "uniform sampler2D tex_rgba; \n" - "void main() { \n" - " vec2 xy = v_texCoord; \n" - " vec4 v = texture2D(tex_rgba, xy).rgba; \n" - " outputColor = vec4(v.b, v.g, v.r, 1.0); \n" - "} \n"; - - -static GLuint program = 0; - -static GLuint vao = 0; -static GLuint buffers[2] = {0}; -static GLuint texture_rgba = 0; - -static GLuint uniform_mvp; -static GLuint uniform_rgba; - - -static int _render_fini_a(abc_render_t* render) -{ - return 0; -} - -static int _render_draw_a(abc_render_t* render, abc_obj_t* obj, int width, int height) -{ - if (0 == program) - __init_program(&program, vert_shader, frag_shader); - - if (0 == vao) - __init_buffers(&vao, buffers); - - if (0 == texture_rgba) - __init_texture(&texture_rgba, GL_RGBA, obj->w, obj->h, NULL); - - cairo_text_extents_t extents; - cairo_surface_t* surface; - cairo_t* cr; - - scf_list_t* l; - abc_obj_t* attr; - - uint8_t* bgra = calloc(1, obj->w * obj->h * 4); - if (!bgra) - return -ENOMEM; - - surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4); - cr = cairo_create(surface); - - cairo_set_line_width(cr, 1); - cairo_set_source_rgb(cr, 1, 1, 1); - cairo_rectangle(cr, 0, 0, obj->w, obj->h); - cairo_fill(cr); - cairo_stroke(cr); - - 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); - - switch (attr->type) { - - case ABC_HTML_ATTR_FONT: - cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); - break; - - case ABC_HTML_ATTR_FONT_SIZE: - cairo_set_font_size(cr, atoi(attr->value->data)); - break; - - case ABC_HTML_ATTR_FONT_COLOR: - abc_css_color(&r, &g, &b, attr->value->data); - - cairo_set_source_rgba(cr, r, g, b, 1.0); - break; - default: - break; - }; - } - - cairo_set_line_width(cr, 1); - - 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_line_to (cr, extents.width, -extents.y_bearing); - cairo_stroke(cr); - - cairo_destroy(cr); - cairo_surface_destroy(surface); - surface = NULL; - cr = NULL; - - float mvp[16]; - __compute_mvp(mvp, 0, 0, 0); - - scf_logi("%s, x: %d, y: %d, w: %d, h: %d\n", obj->text->data, obj->x, obj->y, obj->w, obj->h); - - GLfloat vert_update[] = - { - 2.0 * obj->x / (float)width - 1.0, - -2.0 * (obj->y + obj->h) / (float)height + 1.0, - - 2.0 * (obj->x + obj->w) / (float)width - 1.0, - -2.0 * (obj->y + obj->h) / (float)height + 1.0, - - 2.0 * obj->x / (float)width - 1.0, - -2.0 * obj->y / (float)height + 1.0, - - 2.0 * (obj->x + obj->w) / (float)width - 1.0, - -2.0 * obj->y / (float)height + 1.0, - }; - - glUseProgram(program); - uniform_rgba = glGetUniformLocation(program, "tex_rgba"); - uniform_mvp = glGetUniformLocation(program, "mvp"); - - glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp); - - // board - glActiveTexture(GL_TEXTURE0); - glBindTexture (GL_TEXTURE_2D, texture_rgba); - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, obj->w, obj->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra); - glUniform1i(uniform_rgba, 0); - - // draw - glBindBuffer (GL_ARRAY_BUFFER, buffers[0]); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update); - - glBindVertexArray(vao); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - glBindVertexArray(0); - glUseProgram(0); - - free(bgra); - return 0; -} - -abc_render_t abc_render_a = -{ - .type = ABC_HTML_A, - - .draw = _render_draw_a, - .fini = _render_fini_a, -}; diff --git a/ui/abc_render_h1.c b/ui/abc_render_h1.c index 4993ed3..f33ba37 100644 --- a/ui/abc_render_h1.c +++ b/ui/abc_render_h1.c @@ -45,23 +45,29 @@ static int __init_text(cairo_t* cr, abc_obj_t* obj) 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; + abc_obj_t* style = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_STYLE); + if (style) { + if (!strcmp(style->value->data, "bold")) + bold = CAIRO_FONT_WEIGHT_BOLD; - if (abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_ITALIC)) - italic = CAIRO_FONT_SLANT_OBLIQUE; + else if (!strcmp(style->value->data, "italic") || !strcmp(style->value->data, "oblique")) + 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_text_extents_t extents; double r = 0.0; double g = 0.0; double b = 0.0; + double size = 16.0; + + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE); + if (attr) { + size = atoi(attr->value->data); + cairo_set_font_size(cr, size); + } attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR); if (attr) @@ -72,6 +78,27 @@ static int __init_text(cairo_t* cr, abc_obj_t* obj) cairo_move_to (cr, extents.x_bearing, -extents.y_bearing); cairo_show_text(cr, obj->text->data); + + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_TEXT_DECORATION); + if (attr) { + double line = 0.5 + size / 16.0; + cairo_set_line_width(cr, line); + + if (!strcmp(attr->value->data, "underline")) { + cairo_move_to(cr, extents.x_bearing, -extents.y_bearing + line + 1.0); + cairo_line_to(cr, extents.width, -extents.y_bearing + line + 1.0); + + } else if (!strcmp(attr->value->data, "overline")) { + cairo_move_to(cr, extents.x_bearing, 1.0); + cairo_line_to(cr, extents.width, 1.0); + + } else if (!strcmp(attr->value->data, "line-through")) { + cairo_move_to(cr, extents.x_bearing, -extents.y_bearing / 2.0 + line); + cairo_line_to(cr, extents.width, -extents.y_bearing / 2.0 + line); + } + cairo_stroke(cr); + } + return 0; } -- 2.25.1