support HTML <p> and <br>, <br/>, <br />
authoryu.dongliang <18588496441@163.com>
Sun, 22 Sep 2024 14:44:18 +0000 (22:44 +0800)
committeryu.dongliang <18588496441@163.com>
Sun, 22 Sep 2024 14:44:18 +0000 (22:44 +0800)
13 files changed:
examples/img.html
examples/p.html [new file with mode: 0644]
html/abc_html.c
html/abc_obj.c
html/abc_obj.h
ui/abc_layout.c
ui/abc_layout_a.c
ui/abc_layout_h1.c
ui/abc_render.c
ui/abc_render_a.c
ui/abc_render_a_href.c
ui/abc_render_h1.c
ui/main.c

index 47cfb78e1cfcc2b3337d9da3a1327307cd770de3..6a3ac78633d2a37ba31fc8953b8dd6ff7c697adf 100644 (file)
@@ -4,6 +4,9 @@
 <title>图片</title>
 </head>
 <body>
+<h1>这是一张图片</h1>
+<h2>这是一张图片</h2>
+<h3>this is an image</h3>
 <img src="../examples/img.png" width="400" height="380" />
 </body>
 </html>
diff --git a/examples/p.html b/examples/p.html
new file mode 100644 (file)
index 0000000..f1e98c2
--- /dev/null
@@ -0,0 +1,8 @@
+<html>
+<title>test</title>
+<body>
+
+<p>这个段落<br/>演示了分行的效果</p>
+
+</body>
+</html>
index a49508b1d99ddafbe99da957b9d4bce954682e68..146b53b5c3a053370b2b4e1b0ef663ed5841900a 100644 (file)
@@ -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
index f92dd19b6363163e2c140d29b1ab5bc0b37566b6..bc436e752251034d9836c08082ac7044523e7e2b 100644 (file)
@@ -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("</%s>\n", obj->key->data);
+       if (ABC_HTML_FLAG_CLOSE == (obj->flags & (ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SINGLE))) {
+               if (obj->key)
+                       printf("</%s>\n", obj->key->data);
+       }
 }
index f1babf8a710dc7d20cde31be3dd92cf605ec1fd9..eaad4a6a61a7f52f5e7a5c63dc022f969901d9a6 100644 (file)
@@ -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
index b205320be1376a32d6e9e68779f2fc9a8dbfac04..3dde5fb3d0e1a04a37609c1770620dc6a27f8979 100644 (file)
@@ -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, // <p>
+       abc_layout_h1, // <br>
        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;
 }
index 0a917b4e142b85253ae5fef607c2b56f21771ea5..e7f66f34a989276ce0c97eed34aac3f6fd28a5f1 100644 (file)
@@ -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:
index e39d3c03037cac81588ebddd1b44c925e084d56a..6033f38fc0db0c9906cfbb7759d625d8aa61a934 100644 (file)
@@ -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);
index a1485efefd781f644cd67857fdabdafe956eabca..06c2d27de4e2e17a526ff0ac8b4e5f4d6d687efe 100644 (file)
@@ -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, // <p>
+       &abc_render_h1, // <br>
        &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;
 }
 
index a5eef25154f4674daf23374eb3e5d4e365536ca4..aa5b7ddb937ae6fba82bbbeadd02cef7b66e8d0c 100644 (file)
@@ -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:
index 4eaddf1ce6deab5b6cdea57ef61fc87226f6ed8d..1c3879c2fb64ac9eae0afce41c38524d96aa304b 100644 (file)
@@ -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);
 
index db72fc27dafcb78f8885f1aab518a3cad223a531..f954d887cb5d9c22f26421698d39fab2cb5b03a4 100644 (file)
@@ -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;
index 7181b543706643a26b3aa1026895fcef33969329..04e445eea91ce02023c9d2ae8a2b44b225cce152 100644 (file)
--- 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: