From dfd288732c6f664200e86a5e2f5a519108d4ac0e Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Fri, 29 May 2026 19:07:10 +0800 Subject: [PATCH] 1, css: support 'display & visibility', 2, support variable OpenGL resolution with a scale factor as OS vision config, --- examples/css_attr.html | 2 +- examples/css_attr_form.html | 33 ++++++++ examples/display_none.html | 18 ++++ examples/visibility.html | 16 ++++ html/Makefile | 1 + html/abc_css.c | 159 +++++++++++++++++++++++++++++------- html/abc_css_display.c | 51 ++++++++++++ html/abc_css_length.c | 6 -- html/abc_html.c | 123 +++++++++++++++++----------- html/abc_html.h | 2 + html/abc_obj.c | 8 +- html/abc_obj.h | 29 ++++++- ui/Makefile | 2 +- ui/__render_bg_image.c | 2 +- ui/__render_border.c | 11 ++- ui/__render_text.c | 42 ++++++---- ui/abc.h | 14 ++-- ui/abc_layout.c | 127 +++++++++++++++++----------- ui/abc_layout_form.c | 46 ++++++++--- ui/abc_layout_input.c | 9 +- ui/abc_layout_label.c | 11 +-- ui/abc_layout_table.c | 18 +++- ui/abc_layout_td.c | 7 +- ui/abc_render.c | 25 +++--- ui/abc_render_a_href.c | 2 +- ui/abc_render_audio.c | 2 +- ui/abc_render_body.c | 8 +- ui/abc_render_empty.c | 2 +- ui/abc_render_form.c | 147 --------------------------------- ui/abc_render_h1.c | 6 +- ui/abc_render_hr.c | 2 +- ui/abc_render_img.c | 2 +- ui/abc_render_input.c | 116 +++++++++++++++++++------- ui/abc_render_label.c | 103 ++++++++++++++++++----- ui/abc_render_li.c | 47 ++++++----- ui/abc_render_table.c | 4 +- ui/abc_render_td.c | 32 +++++--- ui/abc_render_text.c | 23 +++--- ui/abc_render_video.c | 2 +- ui/main.c | 35 +++++--- 40 files changed, 824 insertions(+), 471 deletions(-) create mode 100644 examples/css_attr_form.html create mode 100644 examples/display_none.html create mode 100644 examples/visibility.html create mode 100644 html/abc_css_display.c delete mode 100644 ui/abc_render_form.c diff --git a/examples/css_attr.html b/examples/css_attr.html index 4e8ce26..8850ffb 100644 --- a/examples/css_attr.html +++ b/examples/css_attr.html @@ -4,7 +4,7 @@ diff --git a/examples/css_attr_form.html b/examples/css_attr_form.html new file mode 100644 index 0000000..5c970fa --- /dev/null +++ b/examples/css_attr_form.html @@ -0,0 +1,33 @@ + + + + +菜鸟教程(runoob.com) + + + + +
+Firstname: +Lastname: + + +
+ + diff --git a/examples/display_none.html b/examples/display_none.html new file mode 100644 index 0000000..7cb46e5 --- /dev/null +++ b/examples/display_none.html @@ -0,0 +1,18 @@ + + + + +菜鸟教程(runoob.com) + + + + + +

这是一个可见标题

+

这是一个隐藏标题

+

注意, 实例中的隐藏标题不占用空间。

+ + + diff --git a/examples/visibility.html b/examples/visibility.html new file mode 100644 index 0000000..37001e8 --- /dev/null +++ b/examples/visibility.html @@ -0,0 +1,16 @@ + + + + +菜鸟教程(runoob.com) + + + + +

这是一个可见标题

+

这是一个隐藏标题

+

注意, 实例中的隐藏标题仍然占用空间。

+ + diff --git a/html/Makefile b/html/Makefile index 276d458..d41e793 100644 --- a/html/Makefile +++ b/html/Makefile @@ -6,6 +6,7 @@ CFILES += abc_css_color.c CFILES += abc_css_position.c CFILES += abc_css_border.c CFILES += abc_css_length.c +CFILES += abc_css_display.c CFILES += abc_io_util.c CFILES += abc_io_file.c diff --git a/html/abc_css.c b/html/abc_css.c index a920336..ed6793d 100644 --- a/html/abc_css.c +++ b/html/abc_css.c @@ -108,10 +108,10 @@ static int __css_parse_str(abc_obj_t* css, scf_string_t* s, int (*end)(int c)) case ',': case ':': case '.': - case '[': - case ']': case '(': case ')': +// case '[': + case ']': // case '#': if (s->len > 0 && ' ' == s->data[s->len - 1]) { s->data[s->len - 1] = c->c; @@ -1242,11 +1242,79 @@ static abc_obj_t* __css_select_by_attr(abc_obj_t* css, abc_obj_t* current, scf_v assert(next >= 0 && next < vec->size); + if (len >= 2 + && '\"' == key[0] + && '\"' == key[len - 1]) { + key++; + len -= 2; + } + + char* value = NULL; + int vlen = 0; + int j = (intptr_t)vec->data[next]; - int k; + int k = css->text->len; + int m = k; + int n; + int eq = 0; + + if (j < css->text->len) + eq = css->text->data[j]; + + switch (eq) { + case '~': + case '|': + case '^': + case '$': + case '*': + if ('=' != css->text->data[++j]) + return NULL; + + case '=': + next--; + assert(next >= 0 && next < vec->size); + + k = (intptr_t) vec->data[next]; + if (k <= j) + return NULL; + + if (']' != css->text->data[k]) + return NULL; + + value = css->text->data + j + 1; + vlen = k - j - 1; + + if (vlen >= 2 + && '\"' == value[0] + && '\"' == value[vlen - 1]) { + value++; + vlen -= 2; + } + + scf_logd("current: %s, key: %.*s, value: %.*s, next: %d\n", + current->keys[0], len, key, vlen, value, next); + break; + + case ']': + k = j; + break; + default: + return NULL; + break; + }; + + scf_logd("current: %s, key: %.*s, next: %d\n", current->keys[0], len, key, next); + + if (next - 1 >= 0 && next - 1 < vec->size) + { + m = (intptr_t) vec->data[--next]; + if (m <= k) + return NULL; + } + int c = 0; - if (j < css->text->len) - c = css->text->data[j]; + if (m < css->text->len) + c = css->text->data[m]; switch (c) { case ' ': @@ -1254,7 +1322,12 @@ static abc_obj_t* __css_select_by_attr(abc_obj_t* css, abc_obj_t* current, scf_v { attr = abc_obj_get_attr2(current, key, len); - if (attr && attr->value && attr->value->len > 0) + if (!attr || !attr->value || 0 == attr->value->len) + continue; + + if (!value) + break; + if (vlen == attr->value->len && !__html_strncmp(attr->value->data, value, vlen)) break; } break; @@ -1266,6 +1339,11 @@ static abc_obj_t* __css_select_by_attr(abc_obj_t* css, abc_obj_t* current, scf_v if (!attr || !attr->value || 0 == attr->value->len) return NULL; + + if (value) { + if (vlen != attr->value->len || __html_strncmp(attr->value->data, value, vlen)) + return NULL; + } } break; @@ -1282,6 +1360,11 @@ static abc_obj_t* __css_select_by_attr(abc_obj_t* css, abc_obj_t* current, scf_v if (!attr || !attr->value || 0 == attr->value->len) return NULL; + + if (value) { + if (vlen != attr->value->len || __html_strncmp(attr->value->data, value, vlen)) + return NULL; + } break; case '~': @@ -1293,7 +1376,12 @@ static abc_obj_t* __css_select_by_attr(abc_obj_t* css, abc_obj_t* current, scf_v attr = abc_obj_get_attr2(tmp, key, len); - if (attr && attr->value && attr->value->len > 0) + if (!attr || !attr->value || 0 == attr->value->len) + continue; + + if (!value) + break; + if (vlen == attr->value->len && !__html_strncmp(attr->value->data, value, vlen)) break; } @@ -1308,15 +1396,15 @@ static abc_obj_t* __css_select_by_attr(abc_obj_t* css, abc_obj_t* current, scf_v scf_logd("current: %s, key: %.*s, j: %d, next: %s\n", current->keys[0], len, key, j, css->text->data + j); - k = (intptr_t) vec->data[next - 1]; - if (k <= j) + n = (intptr_t) vec->data[next - 1]; + if (n <= m) return NULL; current = __css_select_by_attr(css, current, vec, next - 1, key, len); if (!current) return NULL; - pse = abc_obj_get_attr2(current, css->text->data + j, k - j); + pse = abc_obj_get_attr2(current, css->text->data + m, k - n); if (!pse) return NULL; @@ -1338,14 +1426,19 @@ static abc_obj_t* __css_select_by_attr(abc_obj_t* css, abc_obj_t* current, scf_v css->css_pse_chain = pseLink; pseLink = NULL; - scf_logd("current: %s, key: %.*s, j: %d, k: %d, next: %.*s\n", current->keys[0], len, key, j, k, - k - j, css->text->data + j); + scf_logd("current: %s, key: %.*s, m: %d, n: %d, next: %.*s\n", current->keys[0], len, key, m, n, + n - m, css->text->data + m); break; default: attr = abc_obj_get_attr2(current, key, len); if (!attr || !attr->value || 0 == attr->value->len) return NULL; + + if (value) { + if (vlen != attr->value->len || __html_strncmp(attr->value->data, value, vlen)) + return NULL; + } break; }; @@ -1387,13 +1480,17 @@ static int __css_use_complex(abc_obj_t* css, abc_obj_t* obj) ret = 0; switch (c) { case '#': - current = __css_select_by_id_class(css, current, vec, vec->size - 1, ABC_CSS_ID, key, len); - j = i; + if (n_sqares <= 0) { + current = __css_select_by_id_class(css, current, vec, vec->size - 1, ABC_CSS_ID, key, len); + j = i; + } break; case '.': - current = __css_select_by_id_class(css, current, vec, vec->size - 1, ABC_CSS_CLASS, key, len); - j = i; + if (n_sqares <= 0) { + current = __css_select_by_id_class(css, current, vec, vec->size - 1, ABC_CSS_CLASS, key, len); + j = i; + } break; case ']': @@ -1431,30 +1528,34 @@ static int __css_use_complex(abc_obj_t* css, abc_obj_t* obj) goto end; } - scf_logw("i: %d, %.*s\n", i, len, key); + scf_logd("i: %d, %.*s\n", i, len, key); current = __css_select_by_attr(css, current, vec, vec->size - 1, key, len); j = i; break; case ':': - if (i > 0 && ':' == css->text->data[i - 1]) - { - if (j < css->text->len) { - scf_loge("pse element must be the last for combinators '%s', file: %s, line: %d\n", - css->text->data, css->file->data, css->text_line); - ret = 0; - goto end; - } - } else - j = i; + if (n_sqares <= 0) { + if (i > 0 && ':' == css->text->data[i - 1]) + { + if (j < css->text->len) { + scf_loge("pse element must be the last for combinators '%s', file: %s, line: %d\n", + css->text->data, css->file->data, css->text_line); + ret = 0; + goto end; + } + } else + j = i; + } break; case ' ': case '>': case '+': - current = __css_select_by_key(css, current, vec, vec->size - 1, key, len); - j = i; + if (n_sqares <= 0) { + current = __css_select_by_key(css, current, vec, vec->size - 1, key, len); + j = i; + } break; default: if (0 == i) diff --git a/html/abc_css_display.c b/html/abc_css_display.c new file mode 100644 index 0000000..d45d215 --- /dev/null +++ b/html/abc_css_display.c @@ -0,0 +1,51 @@ +#include"abc_html.h" + +int abc_css_display(const uint8_t* str) +{ + if (!__html_strcmp(str, "block")) + return ABC_DISPLAY_BLOCK; + + if (!__html_strcmp(str, "inline")) + return ABC_DISPLAY_INLINE; + + else if (!__html_strcmp(str, "inline-block")) + return ABC_DISPLAY_INLINE_BLOCK; + + else if (!__html_strcmp(str, "none")) + return ABC_DISPLAY_NONE; + + return ABC_DISPLAY_INLINE; +} + +static int __css_visible(abc_obj_t* obj) +{ + abc_attr_t* attr = abc_obj_get_attr(obj, ABC_CSS_VISIBILITY); + + if (attr && attr->value && attr->value->len > 0) + { + if (!__html_strcmp(attr->value->data, "visible")) + return ABC_VISIBLE_VISIBLE; + + else if (!__html_strcmp(attr->value->data, "hidden")) + return ABC_VISIBLE_HIDDEN; + + else if (!__html_strcmp(attr->value->data, "collapse")) + return ABC_VISIBLE_COLLAPSE; + } + + return ABC_VISIBLE_INHERIT; +} + +int abc_css_visible(abc_obj_t* obj) +{ + while (obj) { + int ret = __css_visible(obj); + + if (ABC_VISIBLE_INHERIT != ret) + return ret; + + obj = obj->parent; + } + + return ABC_VISIBLE_VISIBLE; +} diff --git a/html/abc_css_length.c b/html/abc_css_length.c index 59b5f57..6187e47 100644 --- a/html/abc_css_length.c +++ b/html/abc_css_length.c @@ -71,9 +71,6 @@ next: int abc_css_width(abc_obj_t* obj, int width) { - obj->left = obj->margin_left + obj->border_left + obj->padding_left; - obj->right = obj->margin_right + obj->border_right + obj->padding_right; - abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_WIDTH); if (attr && attr->value && attr->value->len > 0) { @@ -95,9 +92,6 @@ int abc_css_width(abc_obj_t* obj, int width) int abc_css_height(abc_obj_t* obj, int height) { - obj->top = obj->margin_top + obj->border_top + obj->padding_top; - obj->bottom = obj->margin_bottom + obj->border_bottom + obj->padding_bottom; - abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_HEIGHT); if (attr && attr->value && attr->value->len > 0) { diff --git a/html/abc_html.c b/html/abc_html.c index 70287b7..b193055 100644 --- a/html/abc_html.c +++ b/html/abc_html.c @@ -8,6 +8,9 @@ static char* href_keys[] = {"href", "地址", NULL}; static char* width_keys[] = {"width", "宽度", NULL}; static char* height_keys[] = {"height", "高度", NULL}; +static char* display_keys[] = {"display", "显示模式", NULL}; +static char* visible_keys[] = {"visibility", "可见性", NULL}; + static char* margin_keys[] = {"margin", "外边距", NULL}; static char* margin_top_keys[] = {"margin-top", "上边缘", NULL}; static char* margin_bottom_keys[] = {"margin-bottom", "下边缘", NULL}; @@ -67,6 +70,7 @@ static char* name_keys[] = {"name", "名字", NULL}; static char* for_keys[] = {"for", "关于", NULL}; static char* id_keys[] = {"id", "编号", NULL}; +static char* size_keys[] = {"size", NULL}; static char* value_keys[] = {"value", "值", NULL}; static char* action_keys[] = {"action", "动作", NULL}; static char* method_keys[] = {"method", "方法", NULL}; @@ -150,7 +154,9 @@ static char* css_first_child_keys[] = {":first-child", "第1个子元素", "第 static html_attr_t html_attrs[] = { -#define ABC_CSS_BOX(margin, border, padding) \ +#define ABC_CSS_BOX(display, margin, border, padding) \ + {display_keys, #display, ABC_CSS_DISPLAY, ABC_HTML_FLAG_SHOW}, \ + {visible_keys, "", ABC_CSS_VISIBILITY, ABC_HTML_FLAG_SHOW}, \ {border_keys, #border, ABC_CSS_BORDER, ABC_HTML_FLAG_SHOW}, \ {border_top_keys, #border, ABC_CSS_BORDER_TOP, ABC_HTML_FLAG_SHOW}, \ {border_bottom_keys, #border, ABC_CSS_BORDER_BOTTOM, ABC_HTML_FLAG_SHOW}, \ @@ -183,10 +189,12 @@ static html_attr_t html_attrs[] = {scroll_width_keys, #scroll_width, ABC_CSS_SCROLLBAR_WIDTH, ABC_HTML_FLAG_SHOW}, \ {scroll_color_keys, #scroll_color, ABC_CSS_SCROLLBAR_COLOR, ABC_HTML_FLAG_SHOW}, -#define ABC_CSS_SELECTOR() \ +#define ABC_CSS_SELECTOR(type) \ {style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW}, \ {class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW}, \ {title_keys, "", ABC_HTML_ATTR_TITLE, ABC_HTML_FLAG_SHOW}, \ + {type_keys, #type, ABC_HTML_ATTR_TYPE, ABC_HTML_FLAG_SHOW}, \ + {name_keys, "", ABC_HTML_ATTR_NAME, ABC_HTML_FLAG_SHOW}, \ {id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW}, #define ABC_CSS_BACK_GROUND(color) \ @@ -208,7 +216,7 @@ static html_attr_t html_attrs[] = {text_transform_keys, "", ABC_HTML_ATTR_TEXT_TRANSFORM, ABC_HTML_FLAG_SHOW}, \ {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_FLAG_SHOW}, - ABC_CSS_BOX( , , 12px) + ABC_CSS_BOX(block, , , 12px) ABC_CSS_SCROLL(scroll, 12px, orangeRed white) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND(white) @@ -230,7 +238,7 @@ static html_attr_t meta_attrs[] = static html_attr_t body_attrs[] = { - ABC_CSS_BOX( , , 8px) + ABC_CSS_BOX(block, , , 8px) ABC_CSS_SCROLL( , 8px, orangeRed white) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND(white) @@ -241,7 +249,7 @@ static html_attr_t body_attrs[] = static html_attr_t div_attrs[] = { - ABC_CSS_BOX(2px, , 2px) + ABC_CSS_BOX(block, 2px, , 2px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -252,7 +260,7 @@ static html_attr_t div_attrs[] = static html_attr_t h1_attrs[] = { - ABC_CSS_BOX(2px, , 2px) + ABC_CSS_BOX(block, 2px, , 2px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -263,7 +271,7 @@ static html_attr_t h1_attrs[] = static html_attr_t h2_attrs[] = { - ABC_CSS_BOX(2px, , 2px) + ABC_CSS_BOX(block, 2px, , 2px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -274,7 +282,7 @@ static html_attr_t h2_attrs[] = static html_attr_t h3_attrs[] = { - ABC_CSS_BOX(2px, , 2px) + ABC_CSS_BOX(block, 2px, , 2px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -285,7 +293,7 @@ static html_attr_t h3_attrs[] = static html_attr_t h4_attrs[] = { - ABC_CSS_BOX(2px, , 2px) + ABC_CSS_BOX(block, 2px, , 2px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -296,7 +304,7 @@ static html_attr_t h4_attrs[] = static html_attr_t h5_attrs[] = { - ABC_CSS_BOX(2px, , 2px) + ABC_CSS_BOX(block, 2px, , 2px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -307,7 +315,7 @@ static html_attr_t h5_attrs[] = static html_attr_t h6_attrs[] = { - ABC_CSS_BOX(2px, , 2px) + ABC_CSS_BOX(block, 2px, , 2px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -318,7 +326,7 @@ static html_attr_t h6_attrs[] = static html_attr_t hr_attrs[] = { - ABC_CSS_BOX( , , ) + ABC_CSS_BOX(, , , ) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -329,7 +337,7 @@ static html_attr_t hr_attrs[] = static html_attr_t p_attrs[] = { - ABC_CSS_BOX(2px, , 2px) + ABC_CSS_BOX(block, 2px, , 2px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -348,7 +356,7 @@ static html_attr_t css_id_attrs[] = {list_style_image_keys, "", ABC_CSS_LIST_STYLE_IMAGE, ABC_HTML_FLAG_SHOW}, \ {list_style_pos_keys, "", ABC_CSS_LIST_STYLE_POSITION, ABC_HTML_FLAG_SHOW}, - ABC_CSS_BOX(2px, , 2px) + ABC_CSS_BOX( , 2px, , 2px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -362,7 +370,7 @@ static html_attr_t css_id_attrs[] = static html_attr_t b_attrs[] = { - ABC_CSS_BOX( , , ) + ABC_CSS_BOX(inline, , , ) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -375,7 +383,7 @@ static html_attr_t b_attrs[] = static html_attr_t i_attrs[] = { - ABC_CSS_BOX( , , ) + ABC_CSS_BOX(inline, , , ) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -388,7 +396,7 @@ static html_attr_t i_attrs[] = static html_attr_t a_attrs[] = { - ABC_CSS_BOX( , , ) + ABC_CSS_BOX(inline, , , ) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -412,7 +420,7 @@ static html_attr_t link_attrs[] = static html_attr_t img_attrs[] = { - ABC_CSS_BOX( , , ) + ABC_CSS_BOX(inline-block, , , ) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() @@ -421,7 +429,7 @@ static html_attr_t img_attrs[] = static html_attr_t video_attrs[] = { - ABC_CSS_BOX( , , ) + ABC_CSS_BOX(block, , , ) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() @@ -441,22 +449,21 @@ static html_attr_t source_attrs[] = static html_attr_t input_attrs[] = { - ABC_CSS_BOX(1px, 1px, 1px) + ABC_CSS_BOX(inline-block, 1px, 2px, 1px) ABC_CSS_SCROLL( , , ) - ABC_CSS_SELECTOR() - ABC_CSS_BACK_GROUND() + ABC_CSS_SELECTOR(text) + ABC_CSS_BACK_GROUND(lightGray) ABC_CSS_FONT(SimSong, 16, black, ) ABC_CSS_TEXT(left, ) - {type_keys, "text", ABC_HTML_ATTR_TYPE, ABC_HTML_FLAG_SHOW}, - {name_keys, "", ABC_HTML_ATTR_NAME, ABC_HTML_FLAG_SHOW}, + {size_keys, "", ABC_HTML_ATTR_SIZE, ABC_HTML_FLAG_SHOW}, {value_keys, "", ABC_HTML_ATTR_VALUE, ABC_HTML_FLAG_SHOW}, }; static html_attr_t label_attrs[] = { - ABC_CSS_BOX(1px, 1px, 1px) + ABC_CSS_BOX(inline, 1px, , 1px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -469,7 +476,7 @@ static html_attr_t label_attrs[] = static html_attr_t form_attrs[] = { - ABC_CSS_BOX(1px, 1px, 1px) + ABC_CSS_BOX(block, 2px, , 2px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -484,7 +491,7 @@ static html_attr_t form_attrs[] = static html_attr_t ol_attrs[] = { - ABC_CSS_BOX(2px, , 2px) + ABC_CSS_BOX(block, 2px, , 2px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -496,7 +503,7 @@ static html_attr_t ol_attrs[] = static html_attr_t table_attrs[] = { - ABC_CSS_BOX(2px, 2px, 4px) + ABC_CSS_BOX(block, 2px, 2px, 4px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -509,7 +516,7 @@ static html_attr_t table_attrs[] = static html_attr_t th_attrs[] = { - ABC_CSS_BOX(2px, 2px, 4px) + ABC_CSS_BOX(block, 2px, 2px, 4px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -520,9 +527,22 @@ static html_attr_t th_attrs[] = {vertical_align_keys, "", ABC_HTML_ATTR_VERTICAL_ALIGN, ABC_HTML_FLAG_SHOW}, }; +static html_attr_t tr_attrs[] = +{ + ABC_CSS_BOX(block, , , ) + ABC_CSS_SCROLL( , , ) + ABC_CSS_SELECTOR() + ABC_CSS_BACK_GROUND() + + ABC_CSS_FONT(SimSong, 16, black, ) + ABC_CSS_TEXT( , ) + + {vertical_align_keys, "", ABC_HTML_ATTR_VERTICAL_ALIGN, ABC_HTML_FLAG_SHOW}, +}; + static html_attr_t td_attrs[] = { - ABC_CSS_BOX(2px, 2px, 4px) + ABC_CSS_BOX(inline-block, 2px, 2px, 4px) ABC_CSS_SCROLL( , , ) ABC_CSS_SELECTOR() ABC_CSS_BACK_GROUND() @@ -572,7 +592,7 @@ static html_label_t html_labels[] = {center_keys, ABC_HTML_CENTER, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, {table_keys, ABC_HTML_TABLE, abc_number_of(table_attrs), table_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, - {tr_keys, ABC_HTML_TR, abc_number_of(td_attrs), td_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, + {tr_keys, ABC_HTML_TR, abc_number_of(tr_attrs), tr_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, {td_keys, ABC_HTML_TD, abc_number_of(td_attrs), td_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, {th_keys, ABC_HTML_TH, abc_number_of(th_attrs), th_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, @@ -931,6 +951,9 @@ static int __html_parse_end(abc_html_t* html, abc_obj_t* obj) static int __html_parse_text(abc_html_t* html, abc_obj_t* obj) { + if (ABC_HTML_FLAG_OPEN == (obj->flags & 0x1)) // single labels + return 0; + scf_string_t* text = scf_string_alloc(); if (!text) return -ENOMEM; @@ -968,30 +991,36 @@ static int __html_parse_text(abc_html_t* html, abc_obj_t* obj) } } - if ('\n' == c->c) { - html->n_lines++; - html->pos = 0; - } else { - html->pos += c->len; - scf_string_cat_cstr_len(text, c->utf8, c->len); - } + html->pos += c->len; + + switch (c->c) + { + case '\n': + html->n_lines++; + html->pos = 0; + case '\t': + case '\r': + c->utf8[0] = ' '; + break; + default: + break; + }; + + scf_string_cat_cstr_len(text, c->utf8, c->len); free(c); c = NULL; } + while (text->len > 0 && ' ' == text->data[text->len - 1]) + text->data[--text->len] = '\0'; + if (text->len > 0) obj->text = text; else scf_string_free(text); text = NULL; - if (ABC_HTML_FLAG_OPEN == (obj->flags & 0x1)) { // single labels - __io_push_char(&html->io, c); - c = NULL; - return 0; - }; - html->pos++; free(c); c = NULL; @@ -1016,8 +1045,8 @@ static int __html_parse_text(abc_html_t* html, abc_obj_t* obj) obj->text = NULL; \ mov->parent = obj; \ mov->flags = obj->flags; \ - mov->index = obj->n_childs++; \ scf_list_add_tail(&obj->childs, &mov->list); \ + obj->n_texts++; \ scf_logd("--- %s, %s\n", obj->keys[0], mov->text->data); \ } while (0) @@ -1447,8 +1476,8 @@ static int __html_parse_obj(abc_html_t* html, abc_char_t* c) scf_list_add_tail(&html->current->childs, &obj->list); - obj ->index = html->current->n_childs++; - html->current = obj; + obj ->list_order = html->current->n_childs++; + html->current = obj; } if ('/' == ret) { diff --git a/html/abc_html.h b/html/abc_html.h index 6885a51..760e3f6 100644 --- a/html/abc_html.h +++ b/html/abc_html.h @@ -65,12 +65,14 @@ int abc_css_length (abc_obj_t* obj, int width, const uint8_t* str); void abc_css_margin (abc_obj_t* obj, int width); void abc_css_border (abc_obj_t* obj, int width); void abc_css_padding(abc_obj_t* obj, int width); +int abc_css_visible(abc_obj_t* obj); int abc_css_width (abc_obj_t* obj, int width); int abc_css_height (abc_obj_t* obj, int height); int abc_css_position(const uint8_t* str); int abc_css_overflow(const uint8_t* str); +int abc_css_display (const uint8_t* str); int abc_css_scrollbar_width(const uint8_t* str); int abc_css_scrollbar_color(double thumb[3], double track[3], const uint8_t* str); diff --git a/html/abc_obj.c b/html/abc_obj.c index c6a661b..f3ca27f 100644 --- a/html/abc_obj.c +++ b/html/abc_obj.c @@ -356,14 +356,20 @@ void abc_obj_print(abc_obj_t* obj) if (obj->keys) printf("<%s", obj->keys[0]); + int n = 0; int i; for (i = 0; i < sizeof(obj->attrs) / sizeof(obj->attrs[0]); i++) { attr = obj->attrs[i]; if (!attr) continue; - if (ABC_HTML_FLAG_SHOW & attr->flags) + if (attr && attr->value && attr->value->len > 0 && (ABC_HTML_FLAG_SHOW & attr->flags)) { + n++; abc_attr_print(attr); + + if (0 == (n & 0x3)) + printf("\n"); + } } if (obj->flags & ABC_HTML_FLAG_SINGLE) diff --git a/html/abc_obj.h b/html/abc_obj.h index 6b6faad..6d98d44 100644 --- a/html/abc_obj.h +++ b/html/abc_obj.h @@ -89,6 +89,8 @@ enum abc_objs ABC_HTML_ATTR_ACTION, ABC_HTML_ATTR_METHOD, + ABC_HTML_ATTR_SIZE, + ABC_HTML_ATTR_FONT, ABC_HTML_ATTR_FONT_SIZE, ABC_HTML_ATTR_FONT_COLOR, @@ -124,6 +126,9 @@ enum abc_objs ABC_HTML_ATTR_CONTROLS, // css attrs + ABC_CSS_DISPLAY, + ABC_CSS_VISIBILITY, + ABC_CSS_MARGIN, ABC_CSS_MARGIN_TOP, ABC_CSS_MARGIN_BOTTOM, @@ -180,8 +185,24 @@ enum abc_objs ABC_CSS_COMBINATOR, // css selectors from html attrs above - ABC_CSS_ID = ABC_HTML_ATTR_ID, - ABC_CSS_CLASS = ABC_HTML_ATTR_CLASS, + ABC_CSS_ID = ABC_HTML_ATTR_ID, + ABC_CSS_CLASS = ABC_HTML_ATTR_CLASS, +}; + +enum abc_display_type +{ + ABC_DISPLAY_NONE, + ABC_DISPLAY_BLOCK, + ABC_DISPLAY_INLINE, + ABC_DISPLAY_INLINE_BLOCK, +}; + +enum abc_visible_type +{ + ABC_VISIBLE_VISIBLE, + ABC_VISIBLE_HIDDEN, + ABC_VISIBLE_COLLAPSE, + ABC_VISIBLE_INHERIT, }; enum abc_border_type @@ -264,7 +285,7 @@ struct abc_obj_s scf_list_t list; scf_list_t childs; int n_childs; - int index; + int n_texts; abc_attr_t* attrs[ABC_HTML_CSS_NB - ABC_HTML_ATTR_ID]; @@ -311,6 +332,7 @@ struct abc_obj_s int w; int h; + int display_type; int overflow_type; int position_type; @@ -335,6 +357,7 @@ struct abc_obj_s int content_w; int content_h; + int list_order; int list_order_width; double y_bearing; diff --git a/ui/Makefile b/ui/Makefile index 36f96a1..44553a7 100644 --- a/ui/Makefile +++ b/ui/Makefile @@ -32,7 +32,6 @@ CFILES += abc_render_h1.c CFILES += abc_render_hr.c CFILES += abc_render_a_href.c CFILES += abc_render_img.c -CFILES += abc_render_form.c CFILES += abc_render_label.c CFILES += abc_render_input.c @@ -50,6 +49,7 @@ CFILES += ../html/abc_css_color.c CFILES += ../html/abc_css_position.c CFILES += ../html/abc_css_border.c CFILES += ../html/abc_css_length.c +CFILES += ../html/abc_css_display.c CFILES += ../html/abc_io_util.c CFILES += ../html/abc_io_file.c diff --git a/ui/__render_bg_image.c b/ui/__render_bg_image.c index ba0325b..9e13429 100644 --- a/ui/__render_bg_image.c +++ b/ui/__render_bg_image.c @@ -59,7 +59,7 @@ static int __render_fini_bg_image(abc_render_t* render) return 0; } -static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_IMAGE); if (!attr) diff --git a/ui/__render_border.c b/ui/__render_border.c index 8031486..734c9a6 100644 --- a/ui/__render_border.c +++ b/ui/__render_border.c @@ -166,10 +166,19 @@ static int __scroll_move_x(abc_obj_t* obj, int x0, int x1, int y0, int y1, int s obj->mouse_move_x, y0, y1, x0, x1, scroll_width, scroll_tri); } -static int __render_draw_border(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int __render_draw_border(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { abc_obj_t* parent = obj->parent; + if (ABC_HTML_TD == obj->type || ABC_HTML_TH == obj->type) + { + while (parent && ABC_HTML_TABLE != parent->type) + parent = parent->parent; + + if (!parent) + return 0; + } + if (0 == program) __init_program(&program, vert_shader, frag_shader); diff --git a/ui/__render_text.c b/ui/__render_text.c index 91651de..ec7db0f 100644 --- a/ui/__render_text.c +++ b/ui/__render_text.c @@ -38,7 +38,9 @@ static int __render_fini_text(abc_render_t* render) return 0; } -void __draw_text(cairo_text_extents_t* extents, cairo_t* cr, const char* text, double x, double y, double y_bearing, int line_type, int line_width) +void __draw_text(cairo_text_extents_t* extents, cairo_t* cr, const char* text, + double x, + double y, double y_bearing, int line_type, double line_width) { cairo_text_extents(cr, text, extents); double w = extents->width; @@ -49,7 +51,7 @@ void __draw_text(cairo_text_extents_t* extents, cairo_t* cr, const char* text, d x += extents->x_bearing; y -= extents->y_bearing; - cairo_set_line_width(cr, 1); + cairo_set_line_width(cr, 1.0); cairo_move_to(cr, x, y); cairo_show_text(cr, text); cairo_stroke(cr); @@ -77,7 +79,7 @@ void __draw_text(cairo_text_extents_t* extents, cairo_t* cr, const char* text, d cairo_stroke(cr); } -int __init_text(cairo_t* cr, abc_obj_t* obj, int num_flag) +int __init_text(cairo_t* cr, abc_obj_t* obj, int num_flag, double scale) { abc_attr_t* attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT); if (attr) { @@ -110,14 +112,17 @@ int __init_text(cairo_t* cr, abc_obj_t* obj, int num_flag) if (attr) abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); - cairo_set_font_size (cr, size); + cairo_set_font_size (cr, size * scale); cairo_set_source_rgba(cr, r, g, b, 1.0); if (ABC_HTML_OL == obj->parent->type && num_flag) { cairo_text_extents(cr, obj->text->data, &extents); - cairo_move_to (cr, obj->parent->list_order_width - (extents.x_bearing + extents.width + size / 2), -obj->y_bearing); + double x_bearing = obj->parent->list_order_width * scale - (extents.x_bearing + extents.width + size * scale / 2); + double y_bearing = obj->y_bearing * scale; + + cairo_move_to (cr, x_bearing, -y_bearing); cairo_show_text(cr, obj->text->data); cairo_stroke(cr); return 0; @@ -138,17 +143,17 @@ int __init_text(cairo_t* cr, abc_obj_t* obj, int num_flag) line_type = ABC_LINE_THROUGH; } + double x = obj->parent->list_order_width; + double y = 0.0; + if (!obj->text_splits) { - __draw_text(&extents, cr, obj->text->data, obj->parent->list_order_width, 0.0, obj->y_bearing, line_type, line_width); + __draw_text(&extents, cr, obj->text->data, x * scale, 0.0, obj->y_bearing * scale, line_type, line_width * scale); return 0; } scf_string_t* s; abc_text_t* t; - double x = obj->parent->list_order_width; - double y = 0.0; - while (obj->text_splits) { t = obj->text_splits; @@ -158,7 +163,7 @@ int __init_text(cairo_t* cr, abc_obj_t* obj, int num_flag) return -ENOMEM; } - __draw_text(&extents, cr, s->data, x, y, obj->y_bearing, line_type, line_width); + __draw_text(&extents, cr, s->data, x * scale, y, obj->y_bearing * scale, line_type, line_width * scale); y += extents.height; obj->text_splits = t->next; @@ -170,7 +175,7 @@ int __init_text(cairo_t* cr, abc_obj_t* obj, int num_flag) return 0; } -static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { if (obj->w <= 0 || obj->h <= 0) return 0; @@ -180,6 +185,9 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i int w = obj->w - obj->left - obj->right; int h = obj->h - obj->top - obj->bottom; + int w_text = w * ctx->gl_scale; + int h_text = h * ctx->gl_scale; + scf_logd("obj->type: %d, obj->w: %d, obj->h: %d, w: %d, h: %d\n", obj->type, obj->w, obj->h, w, h); if (0 == program) @@ -189,13 +197,13 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i __init_buffers(&vao, buffers); if (0 == texture_rgba) - __init_texture(&texture_rgba, GL_RGBA, w, h, NULL); + __init_texture(&texture_rgba, GL_RGBA, w_text, h_text, NULL); abc_attr_t* attr; cairo_surface_t* surface; cairo_t* cr; - uint8_t* bgra = calloc(1, w * h * 4); + uint8_t* bgra = calloc(1, w_text * h_text * 4); if (!bgra) return -ENOMEM; @@ -206,17 +214,17 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i if (attr) abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); - surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w, h, w * 4); + surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4); cr = cairo_create(surface); cairo_set_line_width(cr, 1); cairo_set_source_rgba(cr, r, g, b, 0.0); - cairo_rectangle(cr, 0, 0, w, h); + cairo_rectangle(cr, 0, 0, w_text, h_text); cairo_fill(cr); cairo_stroke(cr); if (obj->text) - __init_text(cr, obj, 0); + __init_text(cr, obj, 0, ctx->gl_scale); // cairo_surface_write_to_png(surface, "tmp.png"); cairo_destroy(cr); @@ -286,7 +294,7 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i // board glActiveTexture(GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, texture_rgba); - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra); + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra); glUniform1i(uniform_rgba, 0); // draw diff --git a/ui/abc.h b/ui/abc.h index 50174ee..61a0ec3 100644 --- a/ui/abc.h +++ b/ui/abc.h @@ -24,7 +24,7 @@ struct abc_render_s { int type; - int (*draw)(abc_render_t* render, abc_obj_t* obj, int width, int height); + int (*draw)(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx); int (*fini)(abc_render_t* render); void *priv; @@ -38,6 +38,9 @@ struct abc_ctx_s GtkBuilder* builder; GtkGLArea* gl_area; + double gl_scale; + int gl_width; + int gl_height; GtkButton* back; GtkButton* forward; @@ -46,7 +49,7 @@ struct abc_ctx_s GtkIMContext* im; }; -#define ABC_CTX_INIT(__ctx) {SCF_LIST_INIT((__ctx).html_list), NULL, NULL, NULL, NULL, NULL, NULL} +#define ABC_CTX_INIT(__ctx) {SCF_LIST_INIT((__ctx).html_list), NULL, NULL, NULL, 1.0, 0, 0, NULL, NULL, NULL} static const GLfloat vert_array[] = { -1.0f, -1.0f, @@ -63,8 +66,7 @@ static const GLfloat texture_array[] = { }; int abc_renders_fini(); -int abc_render_draw(abc_obj_t* obj, int width, int height); - +int abc_render_draw(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height); int abc_render_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height); int abc_layout_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height); @@ -76,9 +78,9 @@ int __init_program(GLuint* pprog, const char* vert_shader, const char* frag_sha int __init_buffers(GLuint* vao, GLuint buffers[2]); -void __draw_text(cairo_text_extents_t* extents, cairo_t* cr, const char* text, double x, double y, double y_bearing, int line_type, int line_width); +void __draw_text(cairo_text_extents_t* extents, cairo_t* cr, const char* text, double x, double y, double y_bearing, int line_type, double line_width); -int __init_text (cairo_t* cr, abc_obj_t* obj, int num_flag); +int __init_text (cairo_t* cr, abc_obj_t* obj, int num_flag, double scale); int __layout_text(cairo_t* cr, abc_obj_t* obj, int x, int width, cairo_text_extents_t* extents); extern abc_render_t __render_border; diff --git a/ui/abc_layout.c b/ui/abc_layout.c index 01d01f3..1a348a0 100644 --- a/ui/abc_layout.c +++ b/ui/abc_layout.c @@ -39,6 +39,7 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] = [ABC_HTML_HEAD] = abc_layout_empty, [ABC_HTML_BODY] = abc_layout_body, [ABC_HTML_DIV] = abc_layout_div, + [ABC_HTML_FORM] = abc_layout_div, [ABC_CORE_TEXT] = abc_layout_text, [ABC_HTML_B] = abc_layout_text, @@ -58,7 +59,6 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] = [ABC_HTML_IMG] = abc_layout_img, - [ABC_HTML_FORM] = abc_layout_form, [ABC_HTML_LABEL] = abc_layout_label, [ABC_HTML_INPUT] = abc_layout_input, @@ -243,22 +243,73 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) if (width <= 0 || height <= 0) return -EINVAL; + if (ABC_HTML_SCRIPT == root->type + || ABC_HTML_STYLE == root->type + || ABC_HTML_LINK == root->type) + return 0; + + abc_attr_t* attr; + int root_w = width; int root_h = height; - switch (root->type) + abc_css_margin (root, width); + abc_css_border (root, width); + abc_css_padding(root, width); + + if (ABC_HTML == root->type) + root->display_type = ABC_DISPLAY_BLOCK; + + switch (root->display_type) { - case ABC_HTML_SCRIPT: - case ABC_HTML_STYLE: - case ABC_HTML_LINK: + case ABC_DISPLAY_BLOCK: + case ABC_DISPLAY_INLINE_BLOCK: + root->top = root->margin_top + root->border_top + root->padding_top; + root->bottom = root->margin_bottom + root->border_bottom + root->padding_bottom; + root->left = root->margin_left + root->border_left + root->padding_left; + root->right = root->margin_right + root->border_right + root->padding_right; + break; + + case ABC_DISPLAY_INLINE: + root->margin_top = 0; + root->margin_bottom = 0; + + root->top = root->margin_top + root->border_top + root->padding_top; + root->bottom = root->margin_bottom + root->border_bottom + root->padding_bottom; + root->left = root->margin_left + root->border_left + root->padding_left; + root->right = root->margin_right + root->border_right + root->padding_right; + break; + + default: // display: none + root->margin_top = 0; + root->margin_bottom = 0; + root->margin_left = 0; + root->margin_right = 0; + + root->border_top = 0; + root->border_bottom = 0; + root->border_left = 0; + root->border_right = 0; + + root->padding_top = 0; + root->padding_bottom = 0; + root->padding_left = 0; + root->padding_right = 0; + + root->top = 0; + root->bottom = 0; + root->left = 0; + root->right = 0; + + root->w = 0; + root->h = 0; return 0; break; + }; + switch (root->type) + { case ABC_HTML: - abc_css_margin (root, width); - abc_css_border (root, width); - abc_css_padding(root, width); - root->w = width; root->h = height; @@ -271,10 +322,6 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) case ABC_HTML_BODY: case ABC_HTML_DIV: - abc_css_margin (root, width); - abc_css_border (root, width); - abc_css_padding(root, width); - root->w_set = abc_css_width (root, width); root->h_set = abc_css_height(root, height); @@ -292,29 +339,22 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) } break; default: - abc_css_margin (root, width); - abc_css_border (root, width); - abc_css_padding(root, width); break; }; - root->top = root->margin_top + root->border_top + root->padding_top; - root->bottom = root->margin_bottom + root->border_bottom + root->padding_bottom; - root->left = root->margin_left + root->border_left + root->padding_left; - root->right = root->margin_right + root->border_right + root->padding_right; - root->overflow_type = ABC_OVERFLOW_VISIBLE; root->position_type = ABC_POSITION_STATIC; - scf_list_t* l; - abc_obj_t* child; - abc_attr_t* attr = abc_obj_get_attr(root, ABC_CSS_POSITION); + attr = abc_obj_get_attr(root, ABC_CSS_POSITION); if (attr && attr->value && attr->value->len > 0) { root->position_type = abc_css_position(attr->value->data); } + scf_list_t* l; + abc_obj_t* child; + int x = root->x + root->left; int y = root->y + root->top; int h = 0; @@ -331,19 +371,16 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) { child = scf_list_data(l, abc_obj_t, list); + attr = abc_obj_get_attr(child, ABC_CSS_DISPLAY); + if (attr) + child->display_type = abc_css_display(attr->value->data); + else + child->display_type = ABC_DISPLAY_INLINE; + int ret; - switch (child->type) + switch (child->display_type) { - case ABC_HTML_H1: - case ABC_HTML_H2: - case ABC_HTML_H3: - case ABC_HTML_H4: - case ABC_HTML_H5: - case ABC_HTML_H6: - case ABC_HTML_DIV: - case ABC_HTML_OL: - case ABC_HTML_UL: - case ABC_HTML_LI: + case ABC_DISPLAY_BLOCK: child->x = root->x + root->left; child->y = y + h; @@ -360,13 +397,15 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) h = 0; break; - case ABC_HTML_BR: - case ABC_HTML_HR: - case ABC_HTML_TR: - x = root->x + root->left; - y += h; - h = 0; + case ABC_DISPLAY_INLINE_BLOCK: + case ABC_DISPLAY_INLINE: default: + if (ABC_HTML_BR == child->type) { + y += h; + h = 0; + x = root->x + root->left; + } + child->x = x; child->y = y; @@ -419,12 +458,6 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) h = child->h; x = child->x + child->w; } - - if (ABC_HTML_P == child->type) { - x = root->x + root->left; - y += h; - h = 0; - } break; }; diff --git a/ui/abc_layout_form.c b/ui/abc_layout_form.c index 0df5f87..a51e25e 100644 --- a/ui/abc_layout_form.c +++ b/ui/abc_layout_form.c @@ -3,6 +3,7 @@ int abc_layout_form(abc_layout_t* layout, abc_obj_t* obj, int width, int height) { abc_attr_t* attr; + abc_attr_t* style; cairo_text_extents_t extents; cairo_surface_t* surface; cairo_t* cr; @@ -14,28 +15,47 @@ int abc_layout_form(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; + + style = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_STYLE); + if (style) { + if (!__html_strcmp(style->value->data, "bold")) + bold = CAIRO_FONT_WEIGHT_BOLD; + + else if (!__html_strcmp(style->value->data, "italic") || !__html_strcmp(style->value->data, "oblique")) + italic = CAIRO_FONT_SLANT_OBLIQUE; + } + + cairo_select_font_face(cr, attr->value->data, italic, bold); + } + int size = 16; attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE); if (attr) - cairo_set_font_size(cr, atoi(attr->value->data)); + size = atoi(attr->value->data); + + cairo_set_font_size(cr, size); + + int w_set = abc_css_width (obj, width); + int h_set = abc_css_height(obj, height); + + int w = (width - obj->left - obj->right) / size * size; - cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); - cairo_text_extents(cr, obj->text->data, &extents); + int ret = __layout_text(cr, obj, 0, w, &extents); + if (ret < 0) + scf_loge("ret: %d\n", ret); -// obj->x = 4; -// obj->y = 4; - obj->w = extents.width + extents.x_bearing; - obj->h = extents.height + extents.height / 2; + obj->y_bearing = extents.y_bearing; - obj->w = (obj->w + 3) & ~0x3; - obj->h = (obj->h + 3) & ~0x3; + obj->w = extents.width + obj->left + obj->right; + obj->h = extents.height + extents.height / 2 + obj->top + obj->bottom; - scf_logi("%s, w: %d, h: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg\n", + scf_logd("%s, w: %d, h: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg, width: %d, height: %d\n", obj->text->data, obj->w, obj->h, extents.x_bearing, extents.y_bearing, extents.width, extents.height, - extents.x_advance, extents.y_advance); + extents.x_advance, extents.y_advance, width, height); cairo_destroy(cr); cairo_surface_destroy(surface); diff --git a/ui/abc_layout_input.c b/ui/abc_layout_input.c index 0cd7b6c..28bf15c 100644 --- a/ui/abc_layout_input.c +++ b/ui/abc_layout_input.c @@ -32,16 +32,13 @@ int abc_layout_input(abc_layout_t* layout, abc_obj_t* obj, int width, int height if (attr) cairo_set_font_size(cr, atoi(attr->value->data)); - cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); cairo_text_extents(cr, text, &extents); -// obj->x = 4; -// obj->y = 4; - obj->w = extents.width + extents.x_bearing; + obj->w = extents.x_advance + extents.x_bearing; obj->h = extents.height; - obj->w = ((obj->w + 3) & ~0x3) + 8; - obj->h = ((obj->h + 3) & ~0x3) + 8; + obj->w = ((obj->w + 3) & ~0x3) + obj->left + obj->right; + obj->h = ((obj->h + 3) & ~0x3) + obj->top + obj->bottom; scf_logd("%s, w: %d, h: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg\n", text, obj->w, obj->h, diff --git a/ui/abc_layout_label.c b/ui/abc_layout_label.c index ba578cd..8e4d8e7 100644 --- a/ui/abc_layout_label.c +++ b/ui/abc_layout_label.c @@ -21,19 +21,16 @@ int abc_layout_label(abc_layout_t* layout, abc_obj_t* obj, int width, int height if (attr) cairo_set_font_size(cr, atoi(attr->value->data)); - 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->w = extents.x_advance + extents.x_bearing; obj->h = extents.height; - obj->w = ((obj->w + 3) & ~0x3) + 4; - obj->h = ((obj->h + 3) & ~0x3) + 4; + obj->w = obj->w + obj->left + obj->right; + obj->h = obj->h + obj->top + obj->bottom; scf_logd("%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, + text, obj->w, obj->h, extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance, extents.y_advance); diff --git a/ui/abc_layout_table.c b/ui/abc_layout_table.c index 69cb910..95e6ee3 100644 --- a/ui/abc_layout_table.c +++ b/ui/abc_layout_table.c @@ -19,9 +19,10 @@ int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height abc_obj_set_attr(obj, ABC_CSS_PADDING_LEFT, "0", 1); abc_obj_set_attr(obj, ABC_CSS_PADDING_RIGHT, "0", 1); - abc_css_margin (obj, width); - abc_css_border (obj, width); - abc_css_padding(obj, width); + obj->padding_top = 0; + obj->padding_bottom = 0; + obj->padding_left = 0; + obj->padding_right = 0; obj->top = obj->margin_top + obj->border_top; obj->bottom = obj->margin_bottom + obj->border_bottom; @@ -39,6 +40,9 @@ int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height 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); + if (ABC_VISIBLE_COLLAPSE == abc_css_visible(tr)) + continue; + int left = obj->left; int right = obj->right; int top = obj->top; @@ -50,12 +54,20 @@ int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height 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 (ABC_VISIBLE_COLLAPSE == abc_css_visible(td)) + continue; + if (collapse) { abc_obj_set_attr(td, ABC_CSS_MARGIN_TOP, "0", 1); abc_obj_set_attr(td, ABC_CSS_MARGIN_BOTTOM, "0", 1); abc_obj_set_attr(td, ABC_CSS_MARGIN_LEFT, "0", 1); abc_obj_set_attr(td, ABC_CSS_MARGIN_RIGHT, "0", 1); + td->margin_top = 0; + td->margin_bottom = 0; + td->margin_left = 0; + td->margin_right = 0; + td->top = td->border_top + td->padding_top; td->bottom = td->border_bottom + td->padding_bottom; td->left = td->border_left + td->padding_left; diff --git a/ui/abc_layout_td.c b/ui/abc_layout_td.c index faa808f..a770ec3 100644 --- a/ui/abc_layout_td.c +++ b/ui/abc_layout_td.c @@ -22,13 +22,10 @@ int abc_layout_td(abc_layout_t* layout, abc_obj_t* obj, int width, int height) if (attr) cairo_set_font_size(cr, atoi(attr->value->data)); - 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 = extents.x_advance + extents.x_bearing; + obj->h = extents.height + extents.height / 2; obj->w = (obj->w + 3) & ~0x3; obj->h = (obj->h + 3) & ~0x3; diff --git a/ui/abc_render.c b/ui/abc_render.c index a5e774a..287a5a3 100644 --- a/ui/abc_render.c +++ b/ui/abc_render.c @@ -10,7 +10,6 @@ extern abc_render_t abc_render_hr; extern abc_render_t abc_render_a_href; extern abc_render_t abc_render_img; -extern abc_render_t abc_render_form; extern abc_render_t abc_render_label; extern abc_render_t abc_render_input; @@ -29,8 +28,10 @@ static abc_render_t* abc_renders[ABC_HTML_NB] = [ABC_HTML_HEAD] = &abc_render_empty, [ABC_HTML_META] = &abc_render_empty, [ABC_HTML_TITLE] = &abc_render_empty, + [ABC_HTML_BODY] = &abc_render_body, [ABC_HTML_DIV] = &abc_render_body, + [ABC_HTML_FORM] = &abc_render_body, [ABC_CORE_TEXT] = &abc_render_text, [ABC_HTML_B] = &abc_render_text, @@ -51,7 +52,6 @@ static abc_render_t* abc_renders[ABC_HTML_NB] = [ABC_HTML_A_HREF] = &abc_render_a_href, [ABC_HTML_IMG] = &abc_render_img, - [ABC_HTML_FORM] = &abc_render_form, [ABC_HTML_LABEL] = &abc_render_label, [ABC_HTML_INPUT] = &abc_render_input, @@ -94,7 +94,7 @@ int abc_renders_fini() return 0; } -int abc_render_draw(abc_obj_t* obj, int width, int height) +int abc_render_draw(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height) { if (obj->type >= ABC_HTML_NB) return 0; @@ -103,7 +103,7 @@ int abc_render_draw(abc_obj_t* obj, int width, int height) if (!render) return -EINVAL; - return render->draw(render, obj, width, height); + return render->draw(render, obj, width, height, ctx); } static int __obj_render_cmp(const void* v0, const void* v1) @@ -135,11 +135,16 @@ static int __render_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height) abc_obj_t* child; abc_obj_t** childs; - int ret = abc_render_draw(root, width, height); - if (ret < 0) - return ret; + int ret = 0; + + if (ABC_VISIBLE_VISIBLE == abc_css_visible(root)) { + + ret = abc_render_draw(ctx, root, width, height); + if (ret < 0) + return ret; + } - childs = calloc(root->n_childs + 1, sizeof(abc_obj_t*)); + childs = calloc(root->n_childs + root->n_texts + 1, sizeof(abc_obj_t*)); if (!childs) return -ENOMEM; @@ -150,7 +155,7 @@ static int __render_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height) childs[n++] = child; - assert(n <= root->n_childs); + assert(n <= root->n_childs + root->n_texts); } qsort(childs, n, sizeof(abc_obj_t*), __obj_render_cmp); @@ -186,7 +191,7 @@ int abc_render_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height) if (!render) return -EINVAL; - ret = render->draw(render, ctx->current->current, width, height); + ret = render->draw(render, ctx->current->current, width, height, ctx); if (ret < 0) return ret; } diff --git a/ui/abc_render_a_href.c b/ui/abc_render_a_href.c index 7dff92c..fb15cc3 100644 --- a/ui/abc_render_a_href.c +++ b/ui/abc_render_a_href.c @@ -38,7 +38,7 @@ static int _render_fini_a_href(abc_render_t* render) return 0; } -static int _render_draw_a_href(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int _render_draw_a_href(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_HREF); diff --git a/ui/abc_render_audio.c b/ui/abc_render_audio.c index 6ba7dce..79e0c60 100644 --- a/ui/abc_render_audio.c +++ b/ui/abc_render_audio.c @@ -39,7 +39,7 @@ static int _render_fini_audio(abc_render_t* render) return 0; } -static int _render_draw_audio(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int _render_draw_audio(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_SRC); if (!attr) { diff --git a/ui/abc_render_body.c b/ui/abc_render_body.c index 3e3f364..15acd77 100644 --- a/ui/abc_render_body.c +++ b/ui/abc_render_body.c @@ -5,18 +5,18 @@ static int _render_fini_body(abc_render_t* render) return 0; } -static int _render_draw_body(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int _render_draw_body(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { - __render_border.draw(&__render_border, obj, width, height); + __render_border.draw(&__render_border, obj, width, height, ctx); abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_IMAGE); if (attr && attr->value && attr->value->len > 0) { - __render_bg_image.draw(&__render_bg_image, obj, width, height); + __render_bg_image.draw(&__render_bg_image, obj, width, height, ctx); } if (obj->text) - __render_text.draw(&__render_text, obj, width, height); + __render_text.draw(&__render_text, obj, width, height, ctx); return 0; } diff --git a/ui/abc_render_empty.c b/ui/abc_render_empty.c index 7677b9d..0ae5520 100644 --- a/ui/abc_render_empty.c +++ b/ui/abc_render_empty.c @@ -5,7 +5,7 @@ static int _render_fini_empty(abc_render_t* render) return 0; } -static int _render_draw_empty(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int _render_draw_empty(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { return 0; } diff --git a/ui/abc_render_form.c b/ui/abc_render_form.c deleted file mode 100644 index 6e86482..0000000 --- a/ui/abc_render_form.c +++ /dev/null @@ -1,147 +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_form(abc_render_t* render) -{ - return 0; -} - -static int _render_draw_form(abc_render_t* render, abc_obj_t* obj, int width, int height) -{ - if (!obj->text) - return 0; - - 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); - - abc_attr_t* attr; - cairo_text_extents_t extents; - cairo_surface_t* surface; - cairo_t* cr; - - 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); - - 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); - - attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE); - if (attr) - cairo_set_font_size(cr, atoi(attr->value->data)); - - cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 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_surface_write_to_png(surface, "tmp.png"); - - 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_form = -{ - .type = ABC_HTML_FORM, - - .draw = _render_draw_form, - .fini = _render_fini_form, -}; diff --git a/ui/abc_render_h1.c b/ui/abc_render_h1.c index ce28db5..c4c30cc 100644 --- a/ui/abc_render_h1.c +++ b/ui/abc_render_h1.c @@ -5,15 +5,15 @@ static int _render_fini_h1(abc_render_t* render) return 0; } -static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { if (obj->w <= 0 || obj->h <= 0) return 0; - __render_border.draw(&__render_border, obj, width, height); + __render_border.draw(&__render_border, obj, width, height, ctx); if (obj->text) - __render_text.draw(&__render_text, obj, width, height); + __render_text.draw(&__render_text, obj, width, height, ctx); return 0; } diff --git a/ui/abc_render_hr.c b/ui/abc_render_hr.c index 168ecf3..374bc6f 100644 --- a/ui/abc_render_hr.c +++ b/ui/abc_render_hr.c @@ -45,7 +45,7 @@ static int __render_fini_hr(abc_render_t* render) return 0; } -static int __render_draw_hr(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int __render_draw_hr(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { abc_obj_t* parent = obj->parent; diff --git a/ui/abc_render_img.c b/ui/abc_render_img.c index a968c7c..8c4fede 100644 --- a/ui/abc_render_img.c +++ b/ui/abc_render_img.c @@ -39,7 +39,7 @@ static int _render_fini_img(abc_render_t* render) return 0; } -static int _render_draw_img(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int _render_draw_img(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { abc_attr_t* attr; abc_img_t* img = NULL; diff --git a/ui/abc_render_input.c b/ui/abc_render_input.c index 95db757..8bb74d6 100644 --- a/ui/abc_render_input.c +++ b/ui/abc_render_input.c @@ -38,8 +38,18 @@ static int _render_fini_input(abc_render_t* render) return 0; } -static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { + __render_border.draw(&__render_border, obj, width, height, ctx); + + int x = obj->x + obj->left; + int y = obj->y + obj->top; + int w = obj->w - obj->left - obj->right; + int h = obj->h - obj->top - obj->bottom; + + int w_text = w * ctx->gl_scale; + int h_text = h * ctx->gl_scale; + if (0 == program) __init_program(&program, vert_shader, frag_shader); @@ -47,7 +57,7 @@ static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, i __init_buffers(&vao, buffers); if (0 == texture_rgba) - __init_texture(&texture_rgba, GL_RGBA, obj->w, obj->h, NULL); + __init_texture(&texture_rgba, GL_RGBA, w_text, h_text, NULL); abc_attr_t* type; abc_attr_t* attr; @@ -55,33 +65,43 @@ static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, i cairo_surface_t* surface; cairo_t* cr; - uint8_t* bgra = calloc(1, obj->w * obj->h * 4); + uint8_t* bgra = calloc(1, w_text * h_text * 4); if (!bgra) return -ENOMEM; - surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4); + surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 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); + double r = 0.0; + double g = 0.0; + double b = 0.0; + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR); + if (attr) + abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); + + cairo_set_line_width (cr, 1); + cairo_set_source_rgba(cr, r, g, b, 1.0); + cairo_rectangle(cr, 0, 0, w_text, h_text); cairo_fill(cr); cairo_stroke(cr); - cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); - cairo_set_line_width (cr, 2); - cairo_rectangle(cr, 2, 2, obj->w - 4, obj->h - 4); - 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); + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR); + if (attr) + abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); + + int size = 16; attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE); if (attr) - cairo_set_font_size(cr, atoi(attr->value->data)); + size = atoi(attr->value->data); - int x_cursor = 6; + cairo_set_font_size (cr, size * ctx->gl_scale); + cairo_set_source_rgba(cr, r, g, b, 1.0); + + int x_cursor = 2; attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_VALUE); type = abc_obj_find_attr(obj, ABC_HTML_ATTR_TYPE); @@ -99,36 +119,54 @@ static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, i memset(passwd, '*', attr->value->len); cairo_text_extents(cr, passwd, &extents); - cairo_move_to (cr, extents.x_bearing + 4, -extents.y_bearing + (obj->h - extents.height) / 2); + cairo_move_to (cr, extents.x_bearing, -extents.y_bearing + (h_text - extents.height) / 2); cairo_show_text(cr, passwd); free(passwd); passwd = NULL; } else { cairo_text_extents(cr, attr->value->data, &extents); - cairo_move_to (cr, extents.x_bearing + 4, -extents.y_bearing + (obj->h - extents.height) / 2); + cairo_move_to (cr, extents.x_bearing, -extents.y_bearing + (h_text - extents.height) / 2); cairo_show_text(cr, attr->value->data); } cairo_stroke(cr); - x_cursor = 6 + extents.x_bearing + extents.width; + x_cursor = 2 * ctx->gl_scale + extents.x_bearing + extents.x_advance; } - if (obj->clicked && obj->jiffies % 72 < 36) { + if (obj->clicked && obj->jiffies % 1024 < 512) { cairo_set_line_width (cr, 1); - cairo_move_to(cr, x_cursor, 4); - cairo_line_to(cr, x_cursor, obj->h - 4); + cairo_move_to(cr, x_cursor, 0); + cairo_line_to(cr, x_cursor, h_text); cairo_stroke (cr); } - cairo_surface_write_to_png(surface, "tmp.png"); +// cairo_surface_write_to_png(surface, "tmp.png"); cairo_destroy(cr); cairo_surface_destroy(surface); surface = NULL; cr = NULL; + int view_x = x; + int view_y = y; + int view_w = w; + int view_h = h; + + switch (obj->overflow_type) + { + case ABC_OVERFLOW_HIDDEN: + case ABC_OVERFLOW_SCROLL: + case ABC_OVERFLOW_AUTO: + abc_overflow_show(&view_x, &view_y, &view_w, &view_h, + obj->view_x, + obj->view_y, obj->view_w, obj->view_h); + break; + default: + break; + }; + float mvp[16]; __compute_mvp(mvp, 0, 0, 0); @@ -136,17 +174,32 @@ static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, i GLfloat vert_update[] = { - 2.0 * obj->x / (float)width - 1.0, - -2.0 * (obj->y + obj->h) / (float)height + 1.0, + 2.0 * view_x / (float)width - 1.0, + -2.0 * (view_y + view_h) / (float)height + 1.0, + + 2.0 * (view_x + view_w) / (float)width - 1.0, + -2.0 * (view_y + view_h) / (float)height + 1.0, + + 2.0 * view_x / (float)width - 1.0, + -2.0 * view_y / (float)height + 1.0, + + 2.0 * (view_x + view_w) / (float)width - 1.0, + -2.0 * view_y / (float)height + 1.0, + }; + + GLfloat texture_update[] = + { + (view_x - x) / (float)w, + (view_y + view_h - y) / (float)h, - 2.0 * (obj->x + obj->w) / (float)width - 1.0, - -2.0 * (obj->y + obj->h) / (float)height + 1.0, + (view_x + view_w - x) / (float)w, + (view_y + view_h - y) / (float)h, - 2.0 * obj->x / (float)width - 1.0, - -2.0 * obj->y / (float)height + 1.0, + (view_x - x) / (float)w, + (view_y - y) / (float)h, - 2.0 * (obj->x + obj->w) / (float)width - 1.0, - -2.0 * obj->y / (float)height + 1.0, + (view_x + view_w - x) / (float)w, + (view_y - y) / (float)h, }; glUseProgram(program); @@ -158,13 +211,16 @@ static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, i // 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); + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 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); + glBindBuffer (GL_ARRAY_BUFFER, buffers[1]); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_update), texture_update); + glBindVertexArray(vao); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); diff --git a/ui/abc_render_label.c b/ui/abc_render_label.c index dcea464..e1394bf 100644 --- a/ui/abc_render_label.c +++ b/ui/abc_render_label.c @@ -38,11 +38,21 @@ static int _render_fini_label(abc_render_t* render) return 0; } -static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { + __render_border.draw(&__render_border, obj, width, height, ctx); + if (!obj->text) return 0; + int x = obj->x + obj->left; + int y = obj->y + obj->top; + int w = obj->w - obj->left - obj->right; + int h = obj->h - obj->top - obj->bottom; + + int w_text = w * ctx->gl_scale; + int h_text = h * ctx->gl_scale; + if (0 == program) __init_program(&program, vert_shader, frag_shader); @@ -50,23 +60,31 @@ static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, i __init_buffers(&vao, buffers); if (0 == texture_rgba) - __init_texture(&texture_rgba, GL_RGBA, obj->w, obj->h, NULL); + __init_texture(&texture_rgba, GL_RGBA, w_text, h_text, NULL); + abc_attr_t* type; abc_attr_t* attr; cairo_text_extents_t extents; cairo_surface_t* surface; cairo_t* cr; - uint8_t* bgra = calloc(1, obj->w * obj->h * 4); + uint8_t* bgra = calloc(1, w_text * h_text * 4); if (!bgra) return -ENOMEM; - surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4); + surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 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); + double r = 0.0; + double g = 0.0; + double b = 0.0; + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR); + if (attr) + abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); + + cairo_set_line_width (cr, 1); + cairo_set_source_rgba(cr, r, g, b, 1.0); + cairo_rectangle(cr, 0, 0, w_text, h_text); cairo_fill(cr); cairo_stroke(cr); @@ -74,15 +92,22 @@ static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, i if (attr) cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR); + if (attr) + abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); + + int size = 16; attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE); if (attr) - cairo_set_font_size(cr, atoi(attr->value->data)); + size = atoi(attr->value->data); - cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); - cairo_text_extents(cr, obj->text->data, &extents); + cairo_set_font_size (cr, size * ctx->gl_scale); + cairo_set_source_rgba(cr, r, g, b, 1.0); - cairo_move_to (cr, extents.x_bearing + 2, -extents.y_bearing + 2); + cairo_text_extents(cr, obj->text->data, &extents); + cairo_move_to (cr, extents.x_bearing, -extents.y_bearing + (h_text - extents.height) / 2); cairo_show_text(cr, obj->text->data); + cairo_stroke(cr); // cairo_surface_write_to_png(surface, "tmp.png"); @@ -91,24 +116,57 @@ static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, i surface = NULL; cr = NULL; + int view_x = x; + int view_y = y; + int view_w = w; + int view_h = h; + + switch (obj->overflow_type) + { + case ABC_OVERFLOW_HIDDEN: + case ABC_OVERFLOW_SCROLL: + case ABC_OVERFLOW_AUTO: + abc_overflow_show(&view_x, &view_y, &view_w, &view_h, + obj->view_x, + obj->view_y, obj->view_w, obj->view_h); + break; + default: + break; + }; + float mvp[16]; __compute_mvp(mvp, 0, 0, 0); - scf_logd("%s, x: %d, y: %d, w: %d, h: %d\n", obj->text->data, obj->x, obj->y, obj->w, obj->h); + scf_logd("x: %d, y: %d, w: %d, h: %d\n", 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 * view_x / (float)width - 1.0, + -2.0 * (view_y + view_h) / (float)height + 1.0, + + 2.0 * (view_x + view_w) / (float)width - 1.0, + -2.0 * (view_y + view_h) / (float)height + 1.0, + + 2.0 * view_x / (float)width - 1.0, + -2.0 * view_y / (float)height + 1.0, + + 2.0 * (view_x + view_w) / (float)width - 1.0, + -2.0 * view_y / (float)height + 1.0, + }; + + GLfloat texture_update[] = + { + (view_x - x) / (float)w, + (view_y + view_h - y) / (float)h, - 2.0 * (obj->x + obj->w) / (float)width - 1.0, - -2.0 * (obj->y + obj->h) / (float)height + 1.0, + (view_x + view_w - x) / (float)w, + (view_y + view_h - y) / (float)h, - 2.0 * obj->x / (float)width - 1.0, - -2.0 * obj->y / (float)height + 1.0, + (view_x - x) / (float)w, + (view_y - y) / (float)h, - 2.0 * (obj->x + obj->w) / (float)width - 1.0, - -2.0 * obj->y / (float)height + 1.0, + (view_x + view_w - x) / (float)w, + (view_y - y) / (float)h, }; glUseProgram(program); @@ -120,13 +178,16 @@ static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, i // 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); + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 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); + glBindBuffer (GL_ARRAY_BUFFER, buffers[1]); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_update), texture_update); + glBindVertexArray(vao); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); diff --git a/ui/abc_render_li.c b/ui/abc_render_li.c index 232110f..0a83184 100644 --- a/ui/abc_render_li.c +++ b/ui/abc_render_li.c @@ -50,13 +50,16 @@ static int _render_fini_li(abc_render_t* render) return 0; } -static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { abc_attr_t* attr; cairo_surface_t* surface; cairo_t* cr; - uint8_t* bgra = calloc(1, obj->w * obj->h * 4); + int w_text = obj->w * ctx->gl_scale; + int h_text = obj->h * ctx->gl_scale; + + uint8_t* bgra = calloc(1, w_text * h_text * 4); if (!bgra) return -ENOMEM; @@ -73,18 +76,18 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int if (attr) abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); - surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4); + surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4); cr = cairo_create(surface); cairo_set_line_width(cr, 1); cairo_set_source_rgb(cr, r, g, b); - cairo_rectangle(cr, 0, 0, obj->w, obj->h); + cairo_rectangle(cr, 0, 0, w_text, h_text); cairo_fill(cr); cairo_stroke(cr); int offset = obj->parent->list_order_width; if (obj->text) - __init_text(cr, obj, 0); + __init_text(cr, obj, 0, ctx->gl_scale); cairo_destroy(cr); cairo_surface_destroy(surface); @@ -101,26 +104,29 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int attr = abc_obj_find_attr(obj, ABC_CSS_LIST_STYLE_IMAGE); + int w_order = offset * ctx->gl_scale; + int h_order = size * ctx->gl_scale; + if (ABC_HTML_OL == obj->parent->type || !attr || !attr->value || attr->value->len <= 0) { - bgra1 = calloc(1, offset * size * 4); + bgra1 = calloc(1, w_order * h_order * 4); if (!bgra1) { free(bgra); return -ENOMEM; } - surface = cairo_image_surface_create_for_data(bgra1, CAIRO_FORMAT_ARGB32, offset, size, offset * 4); + surface = cairo_image_surface_create_for_data(bgra1, CAIRO_FORMAT_ARGB32, w_order, h_order, w_order * 4); cr = cairo_create(surface); - cairo_set_line_width(cr, 1); + cairo_set_line_width(cr, 1.0 * ctx->gl_scale); cairo_set_source_rgb(cr, r, g, b); - cairo_rectangle(cr, 0, 0, offset, size); + cairo_rectangle(cr, 0, 0, w_order, h_order); cairo_fill(cr); cairo_stroke(cr); if (ABC_HTML_OL == obj->parent->type) { - scf_string_t* s = abc_ol_list_style(obj, obj->index); + scf_string_t* s = abc_ol_list_style(obj, obj->list_order); if (!s) { free(bgra1); free(bgra); @@ -128,7 +134,7 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int } SCF_XCHG(obj->text, s); - __init_text(cr, obj, 1); + __init_text(cr, obj, 1, ctx->gl_scale); SCF_XCHG(obj->text, s); scf_string_free(s); @@ -146,18 +152,18 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int attr = abc_obj_find_attr(obj, ABC_CSS_LIST_STYLE_TYPE); if (attr) { if (!strcmp(attr->value->data, "circle")) - cairo_arc (cr, offset / 2, size / 2, size / 4, 0, 2 * M_PI); + cairo_arc (cr, w_order / 2, h_order / 2, h_order / 4, 0, 2 * M_PI); else if (!strcmp(attr->value->data, "square")) { - cairo_rectangle(cr, offset / 4, size / 4, size / 2, size / 2); + cairo_rectangle(cr, w_order / 4, h_order / 4, h_order / 2, h_order / 2); cairo_fill(cr); } else if (!strcmp(attr->value->data, "disc")) { - cairo_arc (cr, offset / 2, size / 2, size / 4, 0, 2 * M_PI); + cairo_arc (cr, w_order / 2, h_order / 2, h_order / 4, 0, 2 * M_PI); cairo_fill(cr); } } else { - cairo_arc (cr, offset / 2, size / 2, size / 4, 0, 2 * M_PI); + cairo_arc (cr, w_order / 2, h_order / 2, h_order / 4, 0, 2 * M_PI); cairo_fill(cr); } @@ -217,10 +223,10 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int __init_buffers(&vao, buffers); if (0 == texture_rgba) - __init_texture(&texture_rgba, GL_RGBA, obj->w, obj->h, NULL); + __init_texture(&texture_rgba, GL_RGBA, w_text, h_text, NULL); if (0 == texture_img) - __init_texture(&texture_img, GL_RGBA, offset, size, NULL); + __init_texture(&texture_img, GL_RGBA, w_order, h_order, NULL); float mvp[16]; __compute_mvp(mvp, 0, 0, 0); @@ -253,7 +259,7 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int 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); + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra); glUniform1i(uniform_rgba, 0); glActiveTexture(GL_TEXTURE1); @@ -261,7 +267,7 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int if (img) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img->width, img->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra1); else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, offset, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w_order, h_order, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra1); glUniform1i(uniform_img, 1); glUniform4f(uniform_rect, x, y, w, h); @@ -270,6 +276,9 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int glBindBuffer (GL_ARRAY_BUFFER, buffers[0]); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update); + glBindBuffer (GL_ARRAY_BUFFER, buffers[1]); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_array), texture_array); + glBindVertexArray(vao); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); diff --git a/ui/abc_render_table.c b/ui/abc_render_table.c index ed783e2..0409a62 100644 --- a/ui/abc_render_table.c +++ b/ui/abc_render_table.c @@ -7,9 +7,9 @@ static int _render_fini_table(abc_render_t* render) return 0; } -static int _render_draw_table(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int _render_draw_table(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { - __render_border.draw(&__render_border, obj, width, height); + __render_border.draw(&__render_border, obj, width, height, ctx); return 0; } diff --git a/ui/abc_render_td.c b/ui/abc_render_td.c index f4176bf..59dc044 100644 --- a/ui/abc_render_td.c +++ b/ui/abc_render_td.c @@ -38,9 +38,9 @@ static int _render_fini_td(abc_render_t* render) return 0; } -static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { - __render_border.draw(&__render_border, obj, width, height); + __render_border.draw(&__render_border, obj, width, height, ctx); if (!obj->text) return 0; @@ -52,6 +52,9 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int int w = obj->w - obj->left - obj->right; int h = obj->h - obj->top - obj->bottom; + int w_text = w * ctx->gl_scale; + int h_text = h * ctx->gl_scale; + if (0 == program) __init_program(&program, vert_shader, frag_shader); @@ -59,9 +62,9 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int __init_buffers(&vao, buffers); if (0 == texture_rgba) - __init_texture(&texture_rgba, GL_RGBA, w, h, NULL); + __init_texture(&texture_rgba, GL_RGBA, w_text, h_text, NULL); - uint8_t* bgra = calloc(1, w * h * 4); + uint8_t* bgra = calloc(1, w_text * h_text * 4); if (!bgra) return -ENOMEM; @@ -69,7 +72,7 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int cairo_surface_t* surface; cairo_t* cr; - surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w, h, w * 4); + surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4); cr = cairo_create(surface); cairo_set_line_width(cr, 1); @@ -83,7 +86,7 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); cairo_set_source_rgb(cr, r, g, b); - cairo_rectangle(cr, 0, 0, w, h); + cairo_rectangle(cr, 0, 0, w_text, h_text); cairo_fill(cr); cairo_stroke(cr); @@ -101,30 +104,33 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int if (attr) cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + int size = 16; attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE); if (attr) - cairo_set_font_size(cr, atoi(attr->value->data)); + size = atoi(attr->value->data); + + cairo_set_font_size(cr, size * ctx->gl_scale); + cairo_text_extents (cr, obj->text->data, &extents); - cairo_text_extents(cr, obj->text->data, &extents); double x_bearing = extents.x_bearing; double y_bearing = -extents.y_bearing; attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_TEXT_ALIGN); if (attr) { if (!__html_strcmp(attr->value->data, "right")) - x_bearing = w - extents.width - x_bearing; + x_bearing = w_text - extents.width - x_bearing; else if (!__html_strcmp(attr->value->data, "center")) - x_bearing = (w - extents.width) / 2 - x_bearing; + x_bearing = (w_text - extents.width) / 2 - x_bearing; } attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_VERTICAL_ALIGN); if (attr) { if (!__html_strcmp(attr->value->data, "bottom")) - y_bearing += h - extents.height; + y_bearing += h_text - extents.height; else if (!__html_strcmp(attr->value->data, "center")) - y_bearing += (h - extents.height) / 2; + y_bearing += (h_text - extents.height) / 2; } cairo_move_to (cr, x_bearing, y_bearing); @@ -165,7 +171,7 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int glActiveTexture(GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, texture_rgba); - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra); + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra); glUniform1i(uniform_rgba, 0); // draw diff --git a/ui/abc_render_text.c b/ui/abc_render_text.c index 457b312..ba04295 100644 --- a/ui/abc_render_text.c +++ b/ui/abc_render_text.c @@ -41,9 +41,12 @@ static int _render_fini_text(abc_render_t* render) static int _draw_text_line(abc_obj_t* obj, const char* text, int x, int y, int w, int h, int width, int height, float mvp[16], - double bcolor[3], double fcolor[3], int font_size, int bold, int italic, int line_type, int line_width) + double bcolor[3], double fcolor[3], int font_size, int bold, int italic, int line_type, double line_width, double scale) { - uint8_t* bgra = calloc(1, w * h * 4); + int w_text = w * scale; + int h_text = h * scale; + + uint8_t* bgra = calloc(1, w_text * h_text * 4); if (!bgra) return -ENOMEM; @@ -51,12 +54,12 @@ static int _draw_text_line(abc_obj_t* obj, const char* text, cairo_surface_t* surface; cairo_t* cr; - surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w, h, w * 4); + surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4); cr = cairo_create(surface); cairo_set_line_width(cr, 1); cairo_set_source_rgba(cr, bcolor[0], bcolor[1], bcolor[2], 0.0); - cairo_rectangle(cr, 0, 0, w, h); + cairo_rectangle(cr, 0, 0, w_text, h_text); cairo_fill(cr); cairo_stroke(cr); @@ -64,10 +67,10 @@ static int _draw_text_line(abc_obj_t* obj, const char* text, if (attr) cairo_select_font_face(cr, attr->value->data, italic, bold); - cairo_set_font_size (cr, font_size); + cairo_set_font_size (cr, font_size * scale); cairo_set_source_rgba(cr, fcolor[0], fcolor[1], fcolor[2], 1.0); - __draw_text(&extents, cr, text, 0, 0, obj->y_bearing, line_type, line_width); + __draw_text(&extents, cr, text, 0, 0, obj->y_bearing * scale, line_type, line_width * scale); // cairo_surface_write_to_png(surface, "tmp.png"); @@ -102,7 +105,7 @@ static int _draw_text_line(abc_obj_t* obj, const char* text, // board glActiveTexture(GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, texture_rgba); - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra); + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra); glUniform1i(uniform_rgba, 0); // draw @@ -127,7 +130,7 @@ static int _draw_text_line(abc_obj_t* obj, const char* text, return 0; } -static int _render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int _render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { if (obj->w <= 0 || obj->h <= 0) return 0; @@ -198,7 +201,7 @@ static int _render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, in if (!obj->text_splits) return _draw_text_line(obj, obj->text->data, x, y, w, h, width, height, mvp, - bcolor, fcolor, size, bold, italic, line_type, line_width); + bcolor, fcolor, size, bold, italic, line_type, line_width, ctx->gl_scale); while (obj->text_splits) { t = obj->text_splits; @@ -216,7 +219,7 @@ static int _render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, in _draw_text_line(obj, s->data, x, y, w, h, width, height, mvp, - bcolor, fcolor, size, bold, italic, line_type, line_width); + bcolor, fcolor, size, bold, italic, line_type, line_width, ctx->gl_scale); scf_string_free(s); s = NULL; diff --git a/ui/abc_render_video.c b/ui/abc_render_video.c index 877abca..7652b70 100644 --- a/ui/abc_render_video.c +++ b/ui/abc_render_video.c @@ -52,7 +52,7 @@ static int _render_fini_video(abc_render_t* render) return 0; } -static int _render_draw_video(abc_render_t* render, abc_obj_t* obj, int width, int height) +static int _render_draw_video(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx) { scf_list_t* l; abc_frame_t* f; diff --git a/ui/main.c b/ui/main.c index a5a2e99..a0a64af 100644 --- a/ui/main.c +++ b/ui/main.c @@ -2,7 +2,8 @@ static void resize(GtkGLArea* self, gint width, gint height, gpointer user_data) { - GdkGLContext *context; + GdkGLContext* context; + abc_ctx_t* ctx = user_data; gtk_gl_area_make_current(self); @@ -13,6 +14,9 @@ static void resize(GtkGLArea* self, gint width, gint height, gpointer user_data) scf_logi("width: %d, height: %d\n", width, height); + ctx->gl_width = width; + ctx->gl_height = height; + context = gtk_gl_area_get_context(self); if (gdk_gl_context_get_use_es(context)) @@ -37,9 +41,11 @@ static gboolean render(GtkGLArea* self, GdkGLContext* context, gpointer user_dat int width = gtk_widget_get_allocated_width (GTK_WIDGET(self)); int height = gtk_widget_get_allocated_height(GTK_WIDGET(self)); - scf_logd("root: %p, width: %d, height: %d\n\n", root, width, height); + ctx->gl_scale = ctx->gl_width / (double)width; + + scf_logi("root: %p, width: %d, height: %d, scale: %lg\n\n", root, width, height, ctx->gl_scale); - glViewport(0, 0, width, height); + glViewport(0, 0, width * ctx->gl_scale, height * ctx->gl_scale); glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); @@ -346,8 +352,10 @@ static gboolean button_release_event(GtkWidget* self, GdkEventButton* event, gpo if (gtk_widget_get_window(GTK_WIDGET(ctx->gl_area)) == event->window) { - scf_logw("event x_root: %f, y_root: %f, x: %f, y: %f\n", - event->x_root, event->y_root, event->x, event->y); + int scale = gtk_widget_get_scale_factor(self); + + scf_logw("event x_root: %f, y_root: %f, x: %f, y: %f, scale: %d\n", + event->x_root, event->y_root, event->x, event->y, scale); int ret = __do_button_release(ctx, event->x, event->y); if (ret > 0) @@ -363,8 +371,8 @@ static gboolean button_press_event(GtkWidget* self, GdkEventButton* event, gpoin if (gtk_widget_get_window(GTK_WIDGET(ctx->gl_area)) == event->window) { - scf_logw("event x_root: %f, y_root: %f, x: %f, y: %f\n", - event->x_root, event->y_root, event->x, event->y); + scf_logw("event x_root: %f, y_root: %f, x: %f, y: %f, ctx->gl_scale: %lg\n", + event->x_root, event->y_root, event->x, event->y, ctx->gl_scale); abc_html_t* html; abc_obj_t* obj = abc_obj_find(ctx->current->root, event->x, event->y); @@ -492,7 +500,9 @@ static gboolean timer_handler(gpointer user_data) obj = ctx->current->current; if (obj) { obj->jiffies++; -// gtk_gl_area_queue_render(ctx->gl_area); + + if (ABC_HTML_INPUT == obj->type && 0 == obj->jiffies % 64) + gtk_gl_area_queue_render(ctx->gl_area); } if (ctx->current->has_video) @@ -611,9 +621,10 @@ int main(int argc, char *argv[]) forward = gtk_builder_get_object(builder, "button_forward"); refresh = gtk_builder_get_object(builder, "button_refresh"); - ctx.current = html; - ctx.builder = builder; - ctx.gl_area = GTK_GL_AREA(gl_area); + ctx.current = html; + ctx.builder = builder; + ctx.gl_area = GTK_GL_AREA(gl_area); + ctx.gl_scale = 1.0; ctx.back = GTK_BUTTON(back); ctx.forward = GTK_BUTTON(forward); @@ -625,7 +636,7 @@ int main(int argc, char *argv[]) g_signal_connect(forward, "clicked", G_CALLBACK(forward_clicked), &ctx); g_signal_connect(refresh, "clicked", G_CALLBACK(refresh_clicked), &ctx); - g_signal_connect(gl_area, "resize", G_CALLBACK(resize), NULL); + g_signal_connect(gl_area, "resize", G_CALLBACK(resize), &ctx); g_signal_connect(gl_area, "unrealize", G_CALLBACK(unrealize), NULL); g_signal_connect(gl_area, "render", G_CALLBACK(render), &ctx); -- 2.25.1