From: yu.dongliang <18588496441@163.com> Date: Sun, 22 Sep 2024 14:44:18 +0000 (+0800) Subject: support HTML

and
,
,
X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=9297780e6464bf4b241ccc96e119327d3bedf2bd;p=abc.git support HTML

and
,
,
--- diff --git a/examples/img.html b/examples/img.html index 47cfb78..6a3ac78 100644 --- a/examples/img.html +++ b/examples/img.html @@ -4,6 +4,9 @@ 图片 +

这是一张图片

+

这是一张图片

+

this is an image

diff --git a/examples/p.html b/examples/p.html new file mode 100644 index 0000000..f1e98c2 --- /dev/null +++ b/examples/p.html @@ -0,0 +1,8 @@ + +test + + +

这个段落
演示了分行的效果

+ + + diff --git a/html/abc_html.c b/html/abc_html.c index a49508b..146b53b 100644 --- a/html/abc_html.c +++ b/html/abc_html.c @@ -12,78 +12,90 @@ typedef struct { int n_attrs; html_attr_t* attrs; + + uint32_t flags; } html_label_t; +#define abc_number_of(__array) (sizeof(__array) / sizeof(__array[0])) static html_attr_t h1_attrs[] = { - {"font", "Liberation Serif", ABC_HTML_ATTR_FONT}, - {"font-size", "32", ABC_HTML_ATTR_FONT_SIZE}, + {"font", "SimHei", ABC_HTML_ATTR_FONT}, + {"font-size", "40", ABC_HTML_ATTR_FONT_SIZE}, }; static html_attr_t h2_attrs[] = { - {"font", "Liberation Serif", ABC_HTML_ATTR_FONT}, - {"font-size", "28", ABC_HTML_ATTR_FONT_SIZE}, + {"font", "SimHei", ABC_HTML_ATTR_FONT}, + {"font-size", "32", ABC_HTML_ATTR_FONT_SIZE}, }; static html_attr_t h3_attrs[] = { - {"font", "Liberation Serif", ABC_HTML_ATTR_FONT}, - {"font-size", "24", ABC_HTML_ATTR_FONT_SIZE}, + {"font", "SimHei", ABC_HTML_ATTR_FONT}, + {"font-size", "28", ABC_HTML_ATTR_FONT_SIZE}, }; static html_attr_t h4_attrs[] = { - {"font", "Liberation Serif", ABC_HTML_ATTR_FONT}, - {"font-size", "20", ABC_HTML_ATTR_FONT_SIZE}, + {"font", "SimHei", ABC_HTML_ATTR_FONT}, + {"font-size", "24", ABC_HTML_ATTR_FONT_SIZE}, }; static html_attr_t h5_attrs[] = { - {"font", "Liberation Serif", ABC_HTML_ATTR_FONT}, - {"font-size", "16", ABC_HTML_ATTR_FONT_SIZE}, + {"font", "SimHei", ABC_HTML_ATTR_FONT}, + {"font-size", "20", ABC_HTML_ATTR_FONT_SIZE}, }; static html_attr_t h6_attrs[] = { - {"font", "Liberation Serif", ABC_HTML_ATTR_FONT}, - {"font-size", "12", ABC_HTML_ATTR_FONT_SIZE}, + {"font", "SimHei", ABC_HTML_ATTR_FONT}, + {"font-size", "16", ABC_HTML_ATTR_FONT_SIZE}, +}; + +static html_attr_t p_attrs[] = +{ + {"font", "SimSong", ABC_HTML_ATTR_FONT}, + {"font-size", "16", ABC_HTML_ATTR_FONT_SIZE}, }; static html_attr_t a_attrs[] = { - {"href", "", ABC_HTML_ATTR_HREF}, - {"font", "serif", ABC_HTML_ATTR_FONT}, - {"font-size", "28", ABC_HTML_ATTR_FONT_SIZE}, - {"font-color", "blue", ABC_HTML_ATTR_FONT_COLOR}, + {"href", "", ABC_HTML_ATTR_HREF}, + {"font", "SimHei", ABC_HTML_ATTR_FONT}, + {"font-size", "24", ABC_HTML_ATTR_FONT_SIZE}, + {"font-color", "blue", ABC_HTML_ATTR_FONT_COLOR}, }; static html_attr_t img_attrs[] = { - {"src", "", ABC_HTML_ATTR_SRC}, - {"width", "100", ABC_HTML_ATTR_WIDTH}, - {"height", "100", ABC_HTML_ATTR_HEIGHT}, + {"src", "", ABC_HTML_ATTR_SRC}, + {"width", "100", ABC_HTML_ATTR_WIDTH}, + {"height", "100", ABC_HTML_ATTR_HEIGHT}, }; static html_label_t html_labels[] = { - {"html", ABC_HTML, 0, NULL}, - {"title", ABC_HTML_TITLE, 0, NULL}, - {"head", ABC_HTML_HEAD, 0, NULL}, - {"body", ABC_HTML_BODY, 0, NULL}, - - {"div", ABC_HTML_DIV, 0, NULL}, - - {"h1", ABC_HTML_H1, sizeof(h1_attrs) / sizeof(h1_attrs[0]), h1_attrs}, - {"h2", ABC_HTML_H2, sizeof(h2_attrs) / sizeof(h2_attrs[0]), h2_attrs}, - {"h3", ABC_HTML_H3, sizeof(h3_attrs) / sizeof(h3_attrs[0]), h3_attrs}, - {"h4", ABC_HTML_H4, sizeof(h4_attrs) / sizeof(h4_attrs[0]), h4_attrs}, - {"h5", ABC_HTML_H5, sizeof(h5_attrs) / sizeof(h5_attrs[0]), h5_attrs}, - {"h6", ABC_HTML_H6, sizeof(h6_attrs) / sizeof(h6_attrs[0]), h6_attrs}, - - {"a", ABC_HTML_A, sizeof(a_attrs) / sizeof(a_attrs[0]), a_attrs}, - {"img", ABC_HTML_IMG, sizeof(img_attrs) / sizeof(img_attrs[0]), img_attrs}, + {"html", ABC_HTML, 0, NULL, ABC_HTML_FLAG_CLOSE}, + {"title", ABC_HTML_TITLE, 0, NULL, ABC_HTML_FLAG_CLOSE}, + {"head", ABC_HTML_HEAD, 0, NULL, ABC_HTML_FLAG_CLOSE}, + {"body", ABC_HTML_BODY, 0, NULL, ABC_HTML_FLAG_CLOSE}, + + {"div", ABC_HTML_DIV, 0, NULL, ABC_HTML_FLAG_CLOSE}, + + {"h1", ABC_HTML_H1, abc_number_of(h1_attrs), h1_attrs, ABC_HTML_FLAG_CLOSE}, + {"h2", ABC_HTML_H2, abc_number_of(h2_attrs), h2_attrs, ABC_HTML_FLAG_CLOSE}, + {"h3", ABC_HTML_H3, abc_number_of(h3_attrs), h3_attrs, ABC_HTML_FLAG_CLOSE}, + {"h4", ABC_HTML_H4, abc_number_of(h4_attrs), h4_attrs, ABC_HTML_FLAG_CLOSE}, + {"h5", ABC_HTML_H5, abc_number_of(h5_attrs), h5_attrs, ABC_HTML_FLAG_CLOSE}, + {"h6", ABC_HTML_H6, abc_number_of(h6_attrs), h6_attrs, ABC_HTML_FLAG_CLOSE}, + + {"p", ABC_HTML_P, abc_number_of(p_attrs), p_attrs, ABC_HTML_FLAG_CLOSE}, + {"br", ABC_HTML_BR, 0, NULL, ABC_HTML_FLAG_OPEN}, + + {"a", ABC_HTML_A, abc_number_of(a_attrs), a_attrs, ABC_HTML_FLAG_CLOSE}, + {"img", ABC_HTML_IMG, abc_number_of(img_attrs), img_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SINGLE}, }; static int __html_parse_obj(abc_html_t* html, abc_char_t* c); @@ -104,30 +116,53 @@ static html_label_t* __html_find_label(const char* name) return NULL; } +static int __html_add_attr(abc_obj_t* obj, int type, const char* name, const char* value) +{ + abc_obj_t* attr = abc_obj_alloc(NULL, 0, 0, type); + if (!attr) + return -ENOMEM; + + attr->key = scf_string_cstr(name); + if (!attr->key) { + abc_obj_free(attr); + return -ENOMEM; + } + + attr->value = scf_string_cstr(value); + if (!attr->value) { + abc_obj_free(attr); + return -ENOMEM; + } + + scf_list_add_tail(&obj->attrs, &attr->list); + return 0; +} + static int __html_load_attrs(abc_obj_t* obj, html_attr_t* attrs, int n_attrs) { - abc_obj_t* attr; + scf_list_t* l; + abc_obj_t* attr; + int ret; int i; - for (i = 0; i < n_attrs; i++) { - attr = abc_obj_alloc(NULL, 0, 0, attrs[i].type); - if (!attr) - return -ENOMEM; + if (attrs && n_attrs > 0) { - attr->key = scf_string_cstr(attrs[i].name); - if (!attr->key) { - abc_obj_free(attr); - return -ENOMEM; + for (i = 0; i < n_attrs; i++) { + ret = __html_add_attr(obj, attrs[i].type, attrs[i].name, attrs[i].value); + if (ret < 0) + return ret; } - attr->value = scf_string_cstr(attrs[i].value); - if (!attr->value) { - abc_obj_free(attr); - return -ENOMEM; - } + } else if (obj->parent) { + + for (l = scf_list_head(&obj->parent->attrs); l != scf_list_sentinel(&obj->parent->attrs); l = scf_list_next(l)) { + attr = scf_list_data(l, abc_obj_t, list); - scf_list_add_tail(&obj->attrs, &attr->list); + ret = __html_add_attr(obj, attr->type, attr->key->data, attr->value->data); + if (ret < 0) + return ret; + } } return 0; @@ -190,125 +225,149 @@ void abc_html_close(abc_html_t* html) } } -static int __html_parse_text(abc_html_t* html, abc_obj_t* obj) +static int __html_parse_end(abc_html_t* html, abc_obj_t* obj) { - scf_string_t* text = scf_string_alloc(); - if (!text) + scf_string_t* end = scf_string_alloc(); + if (!end) return -ENOMEM; - abc_char_t* c; - abc_char_t* c2; + abc_char_t* c = NULL; while (1) { c = __html_pop_char(html); if (!c) { scf_loge("\n"); - scf_string_free(text); + scf_string_free(end); return -1; } html->pos += c->len; - if ('<' == c->c) + if ('>' == c->c) break; - if ('\n' == c->c) { - html->n_lines++; - html->pos = 0; - free(c); - continue; - } - - scf_string_cat_cstr_len(text, c->utf8, c->len); + scf_string_cat_cstr_len(end, c->utf8, c->len); free(c); c = NULL; } - c2 = __html_pop_char(html); - if (!c2) { - scf_loge("\n"); - free(c); - scf_string_free(text); - return -1; + free(c); + c = NULL; + + int ret = 0; + if (scf_string_cmp(obj->key, end)) { + ret = -1; + + scf_loge("end label '%s' file: %s, line: %d, NOT for label '%s' line: %d\n", + end->data, html->file->data, html->n_lines, obj->key->data, obj->line); } - if ('a' <= c2->c && c2->c <= 'z') { - free(c); - c = NULL; - scf_string_free(text); + scf_string_free(end); + return ret; +} + +static int __html_parse_text(abc_html_t* html, abc_obj_t* obj) +{ + scf_string_t* text = scf_string_alloc(); + if (!text) + return -ENOMEM; + + abc_char_t* c = NULL; - int ret = __html_parse_obj(html, c2); - if (ret < 0) { + while (1) { + c = __html_pop_char(html); + if (!c) { scf_loge("\n"); - return ret; + scf_string_free(text); + return -1; } - return __html_parse_text(html, obj); + if ('<' == c->c) + break; + + 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); + } - } else if ('/' != c2->c) { free(c); c = NULL; - scf_string_free(text); - - scf_loge("invalid char '%c:%#x' in HTML attribute, file: %s, line: %d\n", - c2->c, c2->c, html->file->data, html->n_lines); - - free(c2); - return -1; } - html->pos++; - - free(c2); - free(c); - c2 = NULL; - c = NULL; - if (text->len > 0) obj->text = text; else scf_string_free(text); text = NULL; - // check the end label - scf_string_t* end = scf_string_alloc(); - if (!end) - return -ENOMEM; - - while (1) { - c = __html_pop_char(html); - if (!c) { - scf_loge("\n"); - scf_string_free(end); - return -1; - } - - html->pos += c->len; - - if ('>' == c->c) - break; - scf_string_cat_cstr_len(end, c->utf8, c->len); - free(c); + if (ABC_HTML_BR == obj->type) { // single label + __html_push_char(html, c); c = NULL; + return 0; } html->pos++; - free(c); c = NULL; - int ret = 0; - if (scf_string_cmp(obj->key, end)) { - ret = -1; - scf_loge("end label '%s' file: %s, line: %d, NOT for label '%s' line: %d\n", - end->data, html->file->data, html->n_lines, obj->key->data, obj->line); + c = __html_pop_char(html); + if (!c) { + scf_loge("\n"); + free(c); + return -1; } - scf_string_free(end); - end = NULL; + if ('/' != c->c) { + abc_obj_t* mov = NULL; + + if (ABC_HTML_H1 == obj->type + || ABC_HTML_H2 == obj->type + || ABC_HTML_H3 == obj->type + || ABC_HTML_H4 == obj->type + || ABC_HTML_H5 == obj->type + || ABC_HTML_H6 == obj->type + || ABC_HTML_P == obj->type) { + + if (obj->text) { +#define HTML_MOV_TEXT() \ + do { \ + mov = abc_obj_alloc(NULL, obj->line, obj->pos, obj->type); \ + if (!mov) \ + return -ENOMEM; \ + mov->text = obj->text; \ + obj->text = NULL; \ + mov->parent = obj; \ + scf_list_add_tail(&obj->childs, &mov->list); \ + scf_logd("--- %s, %s\n", obj->key->data, mov->text->data); \ + } while (0) + + HTML_MOV_TEXT(); + } + } - return ret; + int ret = __html_parse_obj(html, c); + if (ret < 0) + return ret; + + ret = __html_parse_text(html, obj); + if (ret < 0) + return ret; + + if (mov && obj->text) + HTML_MOV_TEXT(); + + return ret; + } + + html->pos++; + free(c); + c = NULL; + + return __html_parse_end(html, obj); } static int __html_parse_value(abc_html_t* html, abc_obj_t* attr) @@ -317,7 +376,8 @@ static int __html_parse_value(abc_html_t* html, abc_obj_t* attr) if (!value) return -ENOMEM; - abc_char_t* c = NULL; + abc_char_t* c = NULL; + abc_char_t* c2 = NULL; int flag = 0; @@ -331,11 +391,25 @@ static int __html_parse_value(abc_html_t* html, abc_obj_t* attr) html->pos += c->len; - if ((!flag && ' ' == c->c) || '>' == c->c) - break; + if (!flag) { + if (' ' == c->c || '>' == c->c) + break; + + if ('/' == c->c) { + c2 = __html_pop_char(html); + + __html_push_char(html, c2); + if ('>' == c2->c) + break; + } + + if ('\"' == c->c || '\'' == c->c) + flag = c->c; + else + scf_string_cat_cstr_len(value, c->utf8, c->len); - if ('\"' == c->c) - flag = !flag; + } else if (flag == c->c) + flag = 0; else scf_string_cat_cstr_len(value, c->utf8, c->len); @@ -475,7 +549,7 @@ static int __html_parse_obj(abc_html_t* html, abc_char_t* c) html->pos += c->len; - if (' ' == c->c || '>' == c->c) + if (' ' == c->c || '>' == c->c || '/' == c->c) break; if ('\n' == c->c) { @@ -508,26 +582,36 @@ static int __html_parse_obj(abc_html_t* html, abc_char_t* c) return -ENOMEM; } - obj->key = key; + obj->flags = label->flags; + obj->key = key; key = NULL; + obj->parent = html->current; + int ret = __html_load_attrs(obj, label->attrs, label->n_attrs); if (ret < 0) { abc_obj_free(obj); return ret; } - ret = 0; - if (' ' == tmp) { - ret = __html_parse_attr(html, obj, label->attrs, label->n_attrs); - if (ret < 0) { - abc_obj_free(obj); - return ret; - } - } - scf_logi("key: %s\n", obj->key->data); + switch (tmp) { + case ' ': + ret = __html_parse_attr(html, obj, label->attrs, label->n_attrs); + if (ret < 0) { + abc_obj_free(obj); + return ret; + } + break; + case '/': + ret = tmp; + break; + default: + ret = 0; + break; + }; + if (!html->root) { html->root = obj; html->current = obj; @@ -536,7 +620,6 @@ static int __html_parse_obj(abc_html_t* html, abc_char_t* c) scf_list_add_tail(&html->current->childs, &obj->list); - obj->parent = html->current; html->current = obj; } @@ -553,8 +636,8 @@ static int __html_parse_obj(abc_html_t* html, abc_char_t* c) c = NULL; if ('>' != tmp) { - scf_loge("HTML label '%s' not closed, in file: %s, line: %d\n", - obj->key->data, html->file->data, html->n_lines); + scf_loge("HTML label '%s' (%d) not closed, in file: %s, line: %d\n", + obj->key->data, tmp, html->file->data, html->n_lines); return -1; } } else diff --git a/html/abc_obj.c b/html/abc_obj.c index f92dd19..bc436e7 100644 --- a/html/abc_obj.c +++ b/html/abc_obj.c @@ -36,6 +36,9 @@ void abc_obj_free(abc_obj_t* obj) if (obj->value) scf_string_free(obj->value); + if (obj->text) + scf_string_free(obj->text); + if (obj->file) scf_string_free(obj->file); @@ -107,28 +110,54 @@ abc_obj_t* abc_obj_get_attr(abc_obj_t* obj, int key) return NULL; } +abc_obj_t* abc_obj_find_attr(abc_obj_t* obj, int key) +{ + abc_obj_t* attr; + + while (obj) { + attr = abc_obj_get_attr(obj, key); + if (attr) + return attr; + + obj = obj->parent; + } + + return NULL; +} + void abc_obj_print(abc_obj_t* obj) { - scf_list_t* l; - abc_obj_t* attr; - abc_obj_t* child; + scf_list_t* l; + abc_obj_t* attr; + abc_obj_t* child; if (!obj) return; if (obj->value) printf(" %s=%s", obj->key->data, obj->value->data); - else + else if (obj->key) printf("<%s", obj->key->data); - 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); - abc_obj_print(attr); + if (ABC_HTML_FLAG_CLOSE & obj->flags) { + + 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); + + abc_obj_print(attr); + } } - if (!obj->value) - printf(">\n"); + if (!obj->value) { + if (obj->flags & ABC_HTML_FLAG_SINGLE) + printf(" />\n"); + else if (obj->key) + printf(">\n"); + } + + if (obj->text) + printf("%s\n", obj->text->data); 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); @@ -136,9 +165,8 @@ void abc_obj_print(abc_obj_t* obj) abc_obj_print(child); } - if (obj->text) - printf("%s\n", obj->text->data); - - if (!obj->value) - printf("\n", obj->key->data); + if (ABC_HTML_FLAG_CLOSE == (obj->flags & (ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SINGLE))) { + if (obj->key) + printf("\n", obj->key->data); + } } diff --git a/html/abc_obj.h b/html/abc_obj.h index f1babf8..eaad4a6 100644 --- a/html/abc_obj.h +++ b/html/abc_obj.h @@ -25,10 +25,13 @@ enum abc_objs ABC_HTML_H6, // 11 + ABC_HTML_P, + ABC_HTML_BR, + ABC_HTML_A, ABC_HTML_A_HREF, - // 13 + // 15 ABC_HTML_IMG, ABC_HTML_NB, // total HTML objects @@ -58,6 +61,11 @@ struct abc_obj_s int type; +#define ABC_HTML_FLAG_OPEN 0 +#define ABC_HTML_FLAG_CLOSE 1 +#define ABC_HTML_FLAG_SINGLE 2 + uint32_t flags; + int x; int y; int w; @@ -70,9 +78,6 @@ struct abc_obj_s scf_string_t* file; // file name int line; // line int pos; // position - - uint8_t move_flag :1; - uint8_t click_flag:1; }; abc_obj_t* abc_obj_alloc(scf_string_t* file, int line, int pos, int type); @@ -80,7 +85,8 @@ 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); -abc_obj_t* abc_obj_get_attr(abc_obj_t* obj, int key); +int abc_obj_set_attr (abc_obj_t* obj, int key, const char* value); +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); #endif diff --git a/ui/abc_layout.c b/ui/abc_layout.c index b205320..3dde5fb 100644 --- a/ui/abc_layout.c +++ b/ui/abc_layout.c @@ -1,14 +1,14 @@ #include"abc.h" -int abc_layout_html (abc_layout_t* layout, abc_obj_t* root, int width, int height); -int abc_layout_title(abc_layout_t* layout, abc_obj_t* root, int width, int height); -int abc_layout_head (abc_layout_t* layout, abc_obj_t* root, int width, int height); -int abc_layout_body (abc_layout_t* layout, abc_obj_t* root, int width, int height); +int abc_layout_html (abc_layout_t* layout, abc_obj_t* obj, int width, int height); +int abc_layout_title(abc_layout_t* layout, abc_obj_t* obj, int width, int height); +int abc_layout_head (abc_layout_t* layout, abc_obj_t* obj, int width, int height); +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* root, int width, int height); -int abc_layout_h1 (abc_layout_t* layout, abc_obj_t* root, int width, int height); -int abc_layout_a (abc_layout_t* layout, abc_obj_t* root, int width, int height); -int abc_layout_img (abc_layout_t* layout, abc_obj_t* root, 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); static abc_layout_pt abc_layouts[ABC_HTML_NB] = { @@ -20,6 +20,7 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] = // 4 abc_layout_div, + // 5 abc_layout_h1, abc_layout_h1, abc_layout_h1, @@ -28,6 +29,8 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] = abc_layout_h1, // 11 + abc_layout_h1, //

+ abc_layout_h1, //
abc_layout_a, NULL, @@ -48,8 +51,9 @@ int abc_layout_obj(abc_layout_t* layout, abc_obj_t* obj, int width, int height) int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) { - scf_list_t* l; - abc_obj_t* child; + scf_string_t* key; + scf_list_t* l; + abc_obj_t* child; if (!root) return -EINVAL; @@ -59,9 +63,11 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) int x = 4; int y = 4; - int w = 0; int h = 0; + int __w = 0; + int __h = 0; + 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); @@ -69,30 +75,66 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) if (ret < 0) return ret; - child->x = x; - child->y = y; + switch (child->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_BR: + child->x = 4; + child->y = y + h; + + x = 4; + y = child->y + child->h; + h = 0; + break; + + default: + if (child->w + x < width) { + child->x = x; + child->y = y; - scf_logd("key: %s, x: %d, y: %d, w: %d, h: %d\n\n", child->key->data, child->x, child->y, child->w, child->h); + if (h < child->h) + h = child->h; - y = child->y + child->h; + x += child->w; + } else { + y += h; - if (w < child->x + child->w) - w = child->x + child->w; + child->x = 4; + child->y = y; - if (h < child->y + child->h) - h = child->y + child->h; + h = child->h; + x = child->x + child->w; + } + break; + }; + + if (child->key) + scf_logi("key: %s, x: %d, y: %d, w: %d, h: %d\n\n", child->key->data, child->x, child->y, child->w, child->h); + + if (__w < child->x + child->w) + __w = child->x + child->w; + + if (__h < child->y + child->h) + __h = child->y + child->h; } int ret = abc_layout_obj(NULL, root, width, height); if (ret < 0) return ret; - if (root->w < w) - root->w = w; + if (root->w < __w) + root->w = __w; + + if (root->h < __h) + root->h = __h; - if (root->h < h) - root->h = h; + if (root->key) + scf_logi("key: %s, x: %d, y: %d, w: %d, h: %d\n", root->key->data, root->x, root->y, root->w, root->h); - scf_logd("key: %s, x: %d, y: %d, w: %d, h: %d\n", root->key->data, root->x, root->y, root->w, root->h); return 0; } diff --git a/ui/abc_layout_a.c b/ui/abc_layout_a.c index 0a917b4..e7f66f3 100644 --- a/ui/abc_layout_a.c +++ b/ui/abc_layout_a.c @@ -18,7 +18,7 @@ int abc_layout_a(abc_layout_t* layout, abc_obj_t* obj, int width, int height) switch (attr->type) { case ABC_HTML_ATTR_FONT: - cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); break; case ABC_HTML_ATTR_FONT_SIZE: diff --git a/ui/abc_layout_h1.c b/ui/abc_layout_h1.c index e39d3c0..6033f38 100644 --- a/ui/abc_layout_h1.c +++ b/ui/abc_layout_h1.c @@ -2,35 +2,26 @@ int abc_layout_h1(abc_layout_t* layout, abc_obj_t* obj, int width, int height) { + abc_obj_t* attr; cairo_text_extents_t extents; cairo_surface_t* surface; cairo_t* cr; - scf_list_t* l; - abc_obj_t* attr; + if (!obj->text) + return 0; 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) { + 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); - case ABC_HTML_ATTR_FONT: - cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - break; - - case ABC_HTML_ATTR_FONT_SIZE: - cairo_set_font_size(cr, atoi(attr->value->data)); - break; - default: - break; - }; - } + 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); obj->x = 4; @@ -41,7 +32,7 @@ int abc_layout_h1(abc_layout_t* layout, abc_obj_t* obj, int width, int height) obj->w = (obj->w + 3) & ~0x3; obj->h = (obj->h + 3) & ~0x3; - scf_logd("%s, w: %d, h: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg\n", + 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); diff --git a/ui/abc_render.c b/ui/abc_render.c index a1485ef..06c2d27 100644 --- a/ui/abc_render.c +++ b/ui/abc_render.c @@ -7,6 +7,7 @@ extern abc_render_t abc_render_body; 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; @@ -29,6 +30,8 @@ static abc_render_t* abc_renders[ABC_HTML_NB] = &abc_render_h1, // 11 + &abc_render_h1, //

+ &abc_render_h1, //
&abc_render_a, &abc_render_a_href, @@ -110,6 +113,7 @@ int abc_render_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height) } } + scf_logi("-----------------\n\n"); return 0; } diff --git a/ui/abc_render_a.c b/ui/abc_render_a.c index a5eef25..aa5b7dd 100644 --- a/ui/abc_render_a.c +++ b/ui/abc_render_a.c @@ -77,7 +77,7 @@ static int _render_draw_a(abc_render_t* render, abc_obj_t* obj, int width, int h switch (attr->type) { case ABC_HTML_ATTR_FONT: - cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); break; case ABC_HTML_ATTR_FONT_SIZE: diff --git a/ui/abc_render_a_href.c b/ui/abc_render_a_href.c index 4eaddf1..1c3879c 100644 --- a/ui/abc_render_a_href.c +++ b/ui/abc_render_a_href.c @@ -63,7 +63,7 @@ static int _render_draw_a_href(abc_render_t* render, abc_obj_t* obj, int width, surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, width, 32, width * 4); cr = cairo_create(surface); - cairo_select_font_face(cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + cairo_select_font_face(cr, "SimSong", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (cr, 24); cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0); @@ -116,7 +116,7 @@ static int _render_draw_a_href(abc_render_t* render, abc_obj_t* obj, int width, cairo_fill(cr); cairo_stroke(cr); - cairo_select_font_face(cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + cairo_select_font_face(cr, "SimSong", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (cr, 24); cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0); diff --git a/ui/abc_render_h1.c b/ui/abc_render_h1.c index db72fc2..f954d88 100644 --- a/ui/abc_render_h1.c +++ b/ui/abc_render_h1.c @@ -40,6 +40,9 @@ static int _render_fini_h1(abc_render_t* render) static int _render_draw_h1(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); @@ -49,13 +52,11 @@ static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int if (0 == texture_rgba) __init_texture(&texture_rgba, GL_RGBA, obj->w, obj->h, NULL); + abc_obj_t* attr; 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; @@ -69,30 +70,22 @@ static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int cairo_fill(cr); cairo_stroke(cr); - 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); + 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); - switch (attr->type) { - - case ABC_HTML_ATTR_FONT: - cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - break; - - case ABC_HTML_ATTR_FONT_SIZE: - cairo_set_font_size(cr, atoi(attr->value->data)); - break; - default: - break; - }; - } + 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; diff --git a/ui/main.c b/ui/main.c index 7181b54..04e445e 100644 --- a/ui/main.c +++ b/ui/main.c @@ -65,7 +65,6 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y) if (prev && prev != obj) { ctx->current->current = NULL; - prev->move_flag = 0; display = gtk_widget_get_display(GTK_WIDGET(ctx->gl_area)); window = gtk_widget_get_window (GTK_WIDGET(ctx->gl_area)); @@ -92,7 +91,6 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y) gdk_window_set_cursor(window, cursor); g_object_unref(cursor); - obj->move_flag = 1; ret = 1; break; default: