html: add <ol>, <ul>, <li> for list master
authoryu.dongliang <18588496441@163.com>
Fri, 17 Apr 2026 15:38:52 +0000 (23:38 +0800)
committeryu.dongliang <18588496441@163.com>
Fri, 17 Apr 2026 15:38:52 +0000 (23:38 +0800)
20 files changed:
examples/list.html [new file with mode: 0644]
examples/style.css
ffmpeg/abc_avio.c
ffmpeg/abc_ffmpeg.h
ffmpeg/abc_ffmpeg_alsa.c
ffmpeg/abc_ffmpeg_img.c
html/abc_css.c
html/abc_css_color.c
html/abc_html.c
html/abc_obj.h
ui/Makefile
ui/abc.h
ui/abc_layout.c
ui/abc_layout_video.c
ui/abc_render.c
ui/abc_render_a_href.c
ui/abc_render_bg_image.c
ui/abc_render_h1.c
ui/abc_render_li.c [new file with mode: 0644]
ui/main.c

diff --git a/examples/list.html b/examples/list.html
new file mode 100644 (file)
index 0000000..6e12ce1
--- /dev/null
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+ul.a {list-style-type:circle;}
+ul.b {list-style-type:square;}
+ol.c {list-style-type:upper-roman;}
+ol.d {list-style-type:lower-alpha;}
+</style>
+</head>
+
+<body>
+<p>无序列表实例:</p>
+
+<ul class="a">
+  <li>Coffee</li>
+  <li>Tea</li>
+  <li>Coca Cola</li>
+</ul>
+
+<ul class="b">
+  <li>Coffee</li>
+  <li>Tea</li>
+  <li>Coca Cola</li>
+</ul>
+
+<p>有序列表实例:</p>
+
+<ol class="c">
+  <li>Coffee</li>
+  <li>Tea</li>
+  <li>Coca Cola</li>
+</ol>
+
+<ol class="d">
+  <li>Coffee</li>
+  <li>Tea</li>
+  <li>Coca Cola</li>
+</ol>
+
+</body>
+</html>
index f853881dd416a35edaee243aebe71f9c1406b1be..ddfedd42570a8ff096b979b84c27694a94ae687c 100644 (file)
@@ -1,13 +1,13 @@
 body
 {
        background: #b0c4de  url('img.png')     no-repeat right top ;
 body
 {
        background: #b0c4de  url('img.png')     no-repeat right top ;
-/*     background-color:#b0c4de;
-       background-image:url('img.png');
-       background-position:right top;
-       background-repeat:no-repeat; */
 }
 h1 {background-color:#6495ed;}
 }
 h1 {background-color:#6495ed;}
-a {text-decoration:none;}
+
+a:link    {text-decoration:none;      color:#000000;} /* unvisited link */
+a:visited {text-decoration:none;      color:#00ff00;} /* visited link */
+a:hover   {text-decoration:underline; color:#ff00ff;} /* mouse over link */
+a:active  {text-decoration:underline; color:#0000ff;} /* selected link */
 
 #a /*css comment*/
 {
 
 #a /*css comment*/
 {
index 7874fcc4df6ec66a0d0bf95b3fb7aed5922d298c..1fc572972fb44f71fa90461804b8b3b4fa14c918 100644 (file)
@@ -78,7 +78,6 @@ int abc_avio_open(abc_avio_t** pio, const char* type, const char* in, const char
 
        io->ops = ops;
        if (ops->open) {
 
        io->ops = ops;
        if (ops->open) {
-
                int ret = ops->open(io, in, out);
                if (ret < 0) {
                        free(io);
                int ret = ops->open(io, in, out);
                if (ret < 0) {
                        free(io);
index 577020f466326218f832f103499e2d86c0782021..6843377933e911c9b0e06a4d7a6cf2f00cb89e23 100644 (file)
@@ -85,6 +85,8 @@ typedef struct {
        int                  idx_out;
 
        int                  nb_samples;
        int                  idx_out;
 
        int                  nb_samples;
+
+       uint8_t              write_header:1;
 } abc_audio_t;
 
 struct abc_avio_s
 } abc_audio_t;
 
 struct abc_avio_s
index 47671a628f4b3137896c433cfd1e6e7f02b5e53e..9eb8aae86c3c8bccc65d8a0246ffcd17a7786c76 100644 (file)
@@ -90,7 +90,7 @@ end:
 
 static int _audio_input_init(abc_audio_t* priv, const char* path)
 {
 
 static int _audio_input_init(abc_audio_t* priv, const char* path)
 {
-       const AVInputFormat* in = av_find_input_format("alsa");
+       const AVInputFormat* in = av_find_input_format("pulse");
        if (!in)
                return -EINVAL;
 
        if (!in)
                return -EINVAL;
 
@@ -151,7 +151,7 @@ static int _audio_input_init(abc_audio_t* priv, const char* path)
 
 static int _audio_output_init(abc_audio_t* priv, const char* path)
 {
 
 static int _audio_output_init(abc_audio_t* priv, const char* path)
 {
-       const AVOutputFormat* out = av_guess_format("alsa", NULL, NULL);
+       const AVOutputFormat* out = av_guess_format("pulse", NULL, NULL);
 
        scf_logi("out: %p, path: %s\n", out, path);
 
 
        scf_logi("out: %p, path: %s\n", out, path);
 
@@ -163,6 +163,15 @@ static int _audio_output_init(abc_audio_t* priv, const char* path)
 
        priv->ctx_out->flags |= AVFMT_FLAG_NONBLOCK;
 
 
        priv->ctx_out->flags |= AVFMT_FLAG_NONBLOCK;
 
+       if (priv->ctx_out->oformat->priv_class) {
+               AVDictionary* options = NULL;
+
+               av_dict_set(&options, "buffer_duration", "50", 0);
+
+               av_opt_set_dict2(priv->ctx_out->priv_data, &options, AV_OPT_SEARCH_CHILDREN);
+               av_dict_free(&options);
+       }
+
        const AVCodec* c = avcodec_find_encoder(out->audio_codec);
        if (!c)
                return -EINVAL;
        const AVCodec* c = avcodec_find_encoder(out->audio_codec);
        if (!c)
                return -EINVAL;
@@ -435,10 +444,8 @@ static int __output_audio(abc_avio_t* io, AVCodecContext* c, AVPacket* pkt, AVFr
 
                        av_packet_unref(pkt);
 
 
                        av_packet_unref(pkt);
 
-                       if (ret < 0) {
-                               scf_loge("av_write_frame error, ret: %s\n", av_err2str(ret));
-                               return ret;
-                       }
+                       if (ret < 0)
+                               scf_logw("av_write_frame error, ret: %s\n", av_err2str(ret));
                }
        }
 
                }
        }
 
@@ -507,7 +514,7 @@ static void* __ffmpeg_alsa_run(void* arg)
 {
        abc_avio_t*    io   = arg;
        abc_audio_t*   priv = io->priv;
 {
        abc_avio_t*    io   = arg;
        abc_audio_t*   priv = io->priv;
-       scf_list_t      ih;
+       scf_list_t     ih;
 
        int ret;
 
 
        int ret;
 
@@ -525,18 +532,25 @@ static void* __ffmpeg_alsa_run(void* arg)
                                goto end;
                        }
                }
                                goto end;
                        }
                }
-
-               ret = avformat_write_header(priv->ctx_out, NULL);
-               if (ret < 0) {
-                       scf_loge("avformat_write_header error, ret: %s\n", av_err2str(ret));
-                       io->error = ret;
-                       goto end;
-               }
        }
 
        while (!io->exit) {
 
        }
 
        while (!io->exit) {
 
-               if (priv->ctx_out) {
+               if (priv->ctx_out)
+               {
+                       if (!priv->write_header) {
+                               ret = avformat_write_header(priv->ctx_out, NULL);
+                               if (ret < 0) {
+                                       scf_loge("avformat_write_header error, ret: %s\n", av_err2str(ret));
+
+                                       io->error = ret;
+                                       usleep(100);
+                                       continue;
+                               }
+
+                               priv->write_header = 1;
+                       }
+
                        ret = __output_audio(io, priv->codec_out, priv->opkt, priv->oframe);
                        if (ret < 0) {
                                io->error = ret;
                        ret = __output_audio(io, priv->codec_out, priv->opkt, priv->oframe);
                        if (ret < 0) {
                                io->error = ret;
index 39380c880ad62aa68febfcd919b9003f9636a705..2ff3d89b08a9d58a33fa75f2d1fdfbfc0871c313 100644 (file)
@@ -244,7 +244,7 @@ int abc_img_read(abc_img_t* img, uint8_t* bgra, int size)
                        assert(img->width  == frame2->width);
                        assert(img->height == frame2->height);
 
                        assert(img->width  == frame2->width);
                        assert(img->height == frame2->height);
 
-                       scf_logi("frame2->linesize[0]: %d\n", frame2->linesize[0]);
+                       scf_logd("frame2->linesize[0]: %d\n", frame2->linesize[0]);
 
                        int i;
                        for (i = 0; i < frame2->height; i++)
 
                        int i;
                        for (i = 0; i < frame2->height; i++)
index 859e07f3bd15d9a28da0b9bd39bd1acafca2949f..1cd5527b3ae44b4c1b9fa1ab74f8976f7de39538 100644 (file)
@@ -85,7 +85,7 @@ static int __css_parse_value(abc_obj_t* css, abc_obj_t* attr)
                        css->text_pos = 0;
                }
 
                        css->text_pos = 0;
                }
 
-               if (';' == c->c || EOF == c->c)
+               if (';' == c->c || '}' == c->c || EOF == c->c)
                        break;
                else
                        scf_string_cat_cstr_len(value, c->utf8, c->len);
                        break;
                else
                        scf_string_cat_cstr_len(value, c->utf8, c->len);
@@ -249,7 +249,8 @@ static int __css_parse_obj(abc_obj_t* css, abc_char_t* c)
                return -ENOMEM;
 
        int ret;
                return -ENOMEM;
 
        int ret;
-       int dot = -1;
+       int dot   = -1;
+       int colon = -1;
 
        while (1) {
                c = __io_pop_char(&css->io);
 
        while (1) {
                c = __io_pop_char(&css->io);
@@ -286,6 +287,9 @@ static int __css_parse_obj(abc_obj_t* css, abc_char_t* c)
                        if (dot < 0 && '.' == c->c)
                                dot = key->len;
 
                        if (dot < 0 && '.' == c->c)
                                dot = key->len;
 
+                       if (colon < 0 && ':' == c->c)
+                               colon = key->len;
+
                        scf_string_cat_cstr_len(key, c->utf8, c->len);
                }
 
                        scf_string_cat_cstr_len(key, c->utf8, c->len);
                }
 
@@ -311,6 +315,8 @@ static int __css_parse_obj(abc_obj_t* css, abc_char_t* c)
                default:
                        if (dot >= 0)
                                label = __html_find_label2(ABC_CSS_CLASS);
                default:
                        if (dot >= 0)
                                label = __html_find_label2(ABC_CSS_CLASS);
+                       else if (colon >= 0)
+                               label = __html_find_label(key->data + colon);
                        else
                                label = __html_find_label(key->data);
                        break;
                        else
                                label = __html_find_label(key->data);
                        break;
@@ -328,15 +334,27 @@ static int __css_parse_obj(abc_obj_t* css, abc_char_t* c)
                return -ENOMEM;
        }
 
                return -ENOMEM;
        }
 
-       obj->css_dot = dot;
-       obj->flags   = label->flags;
-       obj->keys    = label->names;
-       obj->parent  = css;
+       obj->css_dot   = dot;
+       obj->css_colon = colon;
+       obj->flags     = label->flags;
+       obj->keys      = label->names;
+       obj->parent    = css;
+
+       switch (obj->type) {
+               case ABC_CSS_ID:
+               case ABC_CSS_CLASS:
+
+               case ABC_CSS_LINK:
+               case ABC_CSS_VISITED:
+               case ABC_CSS_HOVER:
+               case ABC_CSS_ACTIVE:
+                       obj->text = key;
+                       break;
 
 
-       if (ABC_CSS_ID == obj->type || ABC_CSS_CLASS == obj->type)
-               obj->text = key;
-       else
-               scf_string_free(key);
+               default:
+                       scf_string_free(key);
+                       break;
+       };
        key = NULL;
 
        switch (tmp) {
        key = NULL;
 
        switch (tmp) {
@@ -595,6 +613,53 @@ static void __css_set_attr(abc_obj_t* obj, abc_obj_t* attr)
        };
 }
 
        };
 }
 
+static void __css_set_status(abc_obj_t* obj, abc_obj_t* status)
+{
+       scf_list_t*  l;
+       abc_obj_t*   attr;
+       abc_obj_t*   attr2;
+       abc_obj_t*   status2;
+
+       if (scf_list_empty(&status->attrs))
+               return;
+
+       status2 = abc_obj_alloc(status->file, status->line, status->pos, status->type);
+       if (!status2)
+               return;
+       status2->flags = status->flags;
+       status2->keys  = status->keys;
+
+       for (l = scf_list_head(&status->attrs); l != scf_list_sentinel(&status->attrs); l = scf_list_next(l)) {
+               attr = scf_list_data(l, abc_obj_t, list);
+
+               if (attr->value && attr->value->len > 0)
+               {
+                       if (ABC_CSS_LINK == status->type)
+                               __css_set_attr(obj, attr);
+
+                       attr2 = abc_obj_alloc(attr->file, attr->line, attr->pos, attr->type);
+                       if (!attr2) {
+                               abc_obj_free(status2);
+                               return;
+                       }
+
+                       attr2->value = scf_string_clone(attr->value);
+                       if (!attr2->value) {
+                               abc_obj_free(attr2);
+                               abc_obj_free(status2);
+                               return;
+                       }
+
+                       attr2->keys  = attr->keys;
+                       attr2->flags = attr->flags;
+
+                       scf_list_add_tail(&status2->attrs, &attr2->list);
+               }
+       }
+
+       scf_list_add_tail(&obj->attrs, &status2->list);
+}
+
 static void __css_merge(abc_obj_t* dst, abc_obj_t* src)
 {
        scf_list_t*  l;
 static void __css_merge(abc_obj_t* dst, abc_obj_t* src)
 {
        scf_list_t*  l;
@@ -646,8 +711,14 @@ int abc_css_merge(abc_html_t* html, abc_obj_t* css)
                        switch (dst->type) {
                                case ABC_CSS_ID:
                                case ABC_CSS_CLASS:
                        switch (dst->type) {
                                case ABC_CSS_ID:
                                case ABC_CSS_CLASS:
+
+                               case ABC_CSS_LINK:
+                               case ABC_CSS_VISITED:
+                               case ABC_CSS_HOVER:
+                               case ABC_CSS_ACTIVE:
                                        ret = scf_string_cmp(src->text, dst->text);
                                        break;
                                        ret = scf_string_cmp(src->text, dst->text);
                                        break;
+
                                default:
                                        ret = __html_strcmp(src->keys[0], dst->keys[0]);
                                        break;
                                default:
                                        ret = __html_strcmp(src->keys[0], dst->keys[0]);
                                        break;
@@ -669,10 +740,20 @@ int abc_css_merge(abc_html_t* html, abc_obj_t* css)
                src = scf_list_data(s, abc_obj_t, list);
                s   = scf_list_next(s);
 
                src = scf_list_data(s, abc_obj_t, list);
                s   = scf_list_next(s);
 
-               if (ABC_CSS_ID == src->type || ABC_CSS_CLASS == src->type) {
-                       scf_list_del(&src->list);
-                       scf_list_add_tail(&h, &src->list);
-               }
+               switch (src->type) {
+                       case ABC_CSS_ID:
+                       case ABC_CSS_CLASS:
+
+                       case ABC_CSS_LINK:
+                       case ABC_CSS_VISITED:
+                       case ABC_CSS_HOVER:
+                       case ABC_CSS_ACTIVE:
+                               scf_list_del(&src->list);
+                               scf_list_add_tail(&h, &src->list);
+                               break;
+                       default:
+                               break;
+               };
        }
 
        scf_list_mov2(&html->css->childs, &h);
        }
 
        scf_list_mov2(&html->css->childs, &h);
@@ -690,6 +771,7 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj)
        scf_list_t*  l;
        scf_list_t*  l2;
        abc_obj_t*   css;
        scf_list_t*  l;
        scf_list_t*  l2;
        abc_obj_t*   css;
+       abc_obj_t*   __obj;
        abc_obj_t*   attr;
 
        for (l  = scf_list_head(&html->css->childs); l != scf_list_sentinel(&html->css->childs); l = scf_list_next(l)) {
        abc_obj_t*   attr;
 
        for (l  = scf_list_head(&html->css->childs); l != scf_list_sentinel(&html->css->childs); l = scf_list_next(l)) {
@@ -709,14 +791,21 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj)
                                        continue;
                        }
 
                                        continue;
                        }
 
-               } else if (css->type != obj->type)
+               } else if (ABC_CSS_LINK    == css->type
+                               || ABC_CSS_VISITED == css->type
+                               || ABC_CSS_HOVER   == css->type
+                               || ABC_CSS_ACTIVE  == css->type) {
+
+                       if (css->css_colon > 0) {
+                               if (!__html_strncmp (obj->keys[0], css->text->data, css->css_colon))
+                                       __css_set_status(obj, css);
+                       }
                        continue;
 
                        continue;
 
-               for (l2  = scf_list_head(&css->attrs); l2 != scf_list_sentinel(&css->attrs); l2 = scf_list_next(l2)) {
-                       attr = scf_list_data(l2, abc_obj_t, list);
+               } else if (css->type != obj->type)
+                       continue;
 
 
-                       __css_set_attr(obj, attr);
-               }
+               abc_obj_set_css(obj, css);
        }
 
        // for inline css below
        }
 
        // for inline css below
@@ -760,3 +849,15 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj)
 
        return 0;
 }
 
        return 0;
 }
+
+void abc_obj_set_css(abc_obj_t* obj, abc_obj_t* css)
+{
+       scf_list_t*  l;
+       abc_obj_t*   attr;
+
+       for (l   = scf_list_head(&css->attrs); l != scf_list_sentinel(&css->attrs); l = scf_list_next(l)) {
+               attr = scf_list_data(l, abc_obj_t, list);
+
+               __css_set_attr(obj, attr);
+       }
+}
index 974b8ba0442b49dfaecc0b2265fabfcb74c59663..e2c29453c9b42ac026b5f7d337e29e42f0d6981c 100644 (file)
@@ -92,7 +92,7 @@ static char* css_Lime[]           = {"Lime",                   NULL};
 static char* css_LimeGreen[]      = {"LimeGreen",              NULL};
 static char* css_Linen[]          = {"Linen",                  NULL};
 
 static char* css_LimeGreen[]      = {"LimeGreen",              NULL};
 static char* css_Linen[]          = {"Linen",                  NULL};
 
-static char* css_magenta[]           = {"Magenta",           "品红",   "洋红", NULL};
+static char* css_magenta[]           = {"Magenta",           "品红",   NULL};
 static char* css_Maroon[]            = {"Maroon",                      NULL};
 static char* css_MediumAquaMarine[]  = {"MediumAquaMarine",            NULL};
 static char* css_MediumBlue[]        = {"MediumBlue",        "中蓝",   NULL};
 static char* css_Maroon[]            = {"Maroon",                      NULL};
 static char* css_MediumAquaMarine[]  = {"MediumAquaMarine",            NULL};
 static char* css_MediumBlue[]        = {"MediumBlue",        "中蓝",   NULL};
index 353892710ea858ab836be381f35b6483d8d4c85b..10cf7edf2926934d246ea2a12a7cc031e0094694 100644 (file)
@@ -13,16 +13,21 @@ static char* font_size_keys[]  = {"font-size",  "字号",     NULL};
 static char* font_color_keys[] = {"font-color", "字体颜色", "color", "颜色", NULL};
 static char* font_style_keys[] = {"style",      "字体风格", NULL};
 
 static char* font_color_keys[] = {"font-color", "字体颜色", "color", "颜色", NULL};
 static char* font_style_keys[] = {"style",      "字体风格", NULL};
 
-static char* text_align_keys[]      = {"text-align",      "对齐",     NULL};
-static char* text_decoration_keys[] = {"text-decoration", "下划线",   NULL};
-static char* text_transform_keys[]  = {"text-transform",  "大小写",   NULL};
-static char* text_indent_keys[]     = {"text-transform",  "缩进",     NULL};
-
-static char* bg_keys[]          = {"background",          "背景",     NULL};
-static char* bg_color_keys[]    = {"background-color",    "背景颜色", NULL};
-static char* bg_image_keys[]    = {"background-image",    "背景图片", NULL};
-static char* bg_repeat_keys[]   = {"background-repeat",   "背景重复", NULL};
-static char* bg_position_keys[] = {"background-position", "背景位置", NULL};
+static char* text_align_keys[]       = {"text-align",          "对齐",         NULL};
+static char* text_decoration_keys[]  = {"text-decoration",     "下划线",       NULL};
+static char* text_transform_keys[]   = {"text-transform",      "大小写",       NULL};
+static char* text_indent_keys[]      = {"text-transform",      "缩进",         NULL};
+
+static char* bg_keys[]               = {"background",          "背景",         NULL};
+static char* bg_color_keys[]         = {"background-color",    "背景颜色",     NULL};
+static char* bg_image_keys[]         = {"background-image",    "背景图片",     NULL};
+static char* bg_repeat_keys[]        = {"background-repeat",   "背景重复",     NULL};
+static char* bg_position_keys[]      = {"background-position", "背景位置",     NULL};
+
+static char* list_style_keys[]       = {"list-style",          "列表风格",     NULL};
+static char* list_style_type_keys[]  = {"list-style-type",     "列表标记",     NULL};
+static char* list_style_image_keys[] = {"list-style-image",    "列表标记图片", NULL};
+static char* list_style_pos_keys[]   = {"list-style-position", "列表标记位置", NULL};
 
 static char* class_keys[]      = {"class",      "类名",     NULL};
 static char* type_keys[]       = {"type",       "类型",     NULL};
 
 static char* class_keys[]      = {"class",      "类名",     NULL};
 static char* type_keys[]       = {"type",       "类型",     NULL};
@@ -70,6 +75,10 @@ static char* table_keys[]      = {"table",      "表格",     NULL};
 static char* tr_keys[]         = {"tr",         "行",       NULL};
 static char* td_keys[]         = {"td",         "列",       NULL};
 
 static char* tr_keys[]         = {"tr",         "行",       NULL};
 static char* td_keys[]         = {"td",         "列",       NULL};
 
+static char* ol_keys[]         = {"ol",         "有序列表", NULL};
+static char* ul_keys[]         = {"ul",         "无序列表", NULL};
+static char* li_keys[]         = {"li",         "列表项",   NULL};
+
 static char* br_keys[]         = {"br",         "换行",     NULL};
 static char* hr_keys[]         = {"hr",         "标题换行", NULL};
 
 static char* br_keys[]         = {"br",         "换行",     NULL};
 static char* hr_keys[]         = {"hr",         "标题换行", NULL};
 
@@ -90,8 +99,13 @@ static char* progress_keys[]   = {"progress",   "进度条",   NULL};
 static char* script_keys[]     = {"script",     "脚本",     NULL};
 static char* style_keys[]      = {"style",      "样式",     NULL};
 
 static char* script_keys[]     = {"script",     "脚本",     NULL};
 static char* style_keys[]      = {"style",      "样式",     NULL};
 
-static char* css_id_keys[]     = {"#",          NULL};
-static char* css_class_keys[]  = {".",          NULL};
+static char* css_id_keys[]      = {"#",          NULL};
+static char* css_class_keys[]   = {".",          NULL};
+
+static char* css_link_keys[]    = {":link",     ":未访问",  NULL};
+static char* css_visited_keys[] = {":visited",  ":已访问",  NULL};
+static char* css_hover_keys[]   = {":hover",    ":已关注",  NULL};
+static char* css_active_keys[]  = {":active",   ":已激活",  NULL};
 
 static html_attr_t  html_attrs[] =
 {
 
 static html_attr_t  html_attrs[] =
 {
@@ -254,17 +268,22 @@ static html_attr_t  p_attrs[] =
 
 static html_attr_t  css_id_attrs[] =
 {
 
 static html_attr_t  css_id_attrs[] =
 {
-       {font_keys,        "SimSong",  ABC_HTML_ATTR_FONT,            0},
-       {font_size_keys,   "16",       ABC_HTML_ATTR_FONT_SIZE,       0},
-       {font_color_keys,  "black",    ABC_HTML_ATTR_FONT_COLOR,      ABC_HTML_FLAG_SHOW},
-       {font_style_keys,  "",         ABC_HTML_ATTR_FONT_STYLE,      0},
-
-       {bg_color_keys,    "",         ABC_HTML_ATTR_BG_COLOR,        ABC_HTML_FLAG_SHOW},
-
-       {text_align_keys,      "left", ABC_HTML_ATTR_TEXT_ALIGN,      ABC_HTML_FLAG_SHOW},
-       {text_decoration_keys, "",     ABC_HTML_ATTR_TEXT_DECORATION, ABC_HTML_FLAG_SHOW},
-       {text_transform_keys,  "",     ABC_HTML_ATTR_TEXT_TRANSFORM,  ABC_HTML_FLAG_SHOW},
-       {text_indent_keys,     "",     ABC_HTML_ATTR_TEXT_INDENT,     ABC_HTML_FLAG_SHOW},
+       {font_keys,         "SimSong",  ABC_HTML_ATTR_FONT,            0},
+       {font_size_keys,    "16",       ABC_HTML_ATTR_FONT_SIZE,       0},
+       {font_color_keys,   "black",    ABC_HTML_ATTR_FONT_COLOR,      ABC_HTML_FLAG_SHOW},
+       {font_style_keys,   "",         ABC_HTML_ATTR_FONT_STYLE,      0},
+
+       {bg_color_keys,     "",         ABC_HTML_ATTR_BG_COLOR,        ABC_HTML_FLAG_SHOW},
+
+       {text_align_keys,       "left", ABC_HTML_ATTR_TEXT_ALIGN,      ABC_HTML_FLAG_SHOW},
+       {text_decoration_keys,  "",     ABC_HTML_ATTR_TEXT_DECORATION, ABC_HTML_FLAG_SHOW},
+       {text_transform_keys,   "",     ABC_HTML_ATTR_TEXT_TRANSFORM,  ABC_HTML_FLAG_SHOW},
+       {text_indent_keys,      "",     ABC_HTML_ATTR_TEXT_INDENT,     ABC_HTML_FLAG_SHOW},
+
+       {list_style_keys,       "",     ABC_CSS_LIST_STYLE,            ABC_HTML_FLAG_SHOW},
+       {list_style_type_keys,  "",     ABC_CSS_LIST_STYLE_TYPE,       ABC_HTML_FLAG_SHOW},
+       {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},
 };
 
 static html_attr_t  b_attrs[] =
 };
 
 static html_attr_t  b_attrs[] =
@@ -303,6 +322,7 @@ static html_attr_t  a_attrs[] =
        {class_keys,       "",         ABC_HTML_ATTR_CLASS,           ABC_HTML_FLAG_SHOW},
        {style_keys,       "",         ABC_HTML_ATTR_STYLE,           ABC_HTML_FLAG_SHOW},
        {id_keys,          "",         ABC_HTML_ATTR_ID,              ABC_HTML_FLAG_SHOW},
        {class_keys,       "",         ABC_HTML_ATTR_CLASS,           ABC_HTML_FLAG_SHOW},
        {style_keys,       "",         ABC_HTML_ATTR_STYLE,           ABC_HTML_FLAG_SHOW},
        {id_keys,          "",         ABC_HTML_ATTR_ID,              ABC_HTML_FLAG_SHOW},
+
        {font_keys,        "SimSong",  ABC_HTML_ATTR_FONT,            0},
        {font_size_keys,   "16",       ABC_HTML_ATTR_FONT_SIZE,       0},
        {font_color_keys,  "blue",     ABC_HTML_ATTR_FONT_COLOR,      ABC_HTML_FLAG_SHOW},
        {font_keys,        "SimSong",  ABC_HTML_ATTR_FONT,            0},
        {font_size_keys,   "16",       ABC_HTML_ATTR_FONT_SIZE,       0},
        {font_color_keys,  "blue",     ABC_HTML_ATTR_FONT_COLOR,      ABC_HTML_FLAG_SHOW},
@@ -378,6 +398,23 @@ static html_attr_t  form_attrs[] =
        {enctype_keys,     "",           ABC_HTML_ATTR_ENCTYPE,    0},
 };
 
        {enctype_keys,     "",           ABC_HTML_ATTR_ENCTYPE,    0},
 };
 
+static html_attr_t  ol_attrs[] =
+{
+       {class_keys,       "",         ABC_HTML_ATTR_CLASS,           ABC_HTML_FLAG_SHOW},
+       {style_keys,       "",         ABC_HTML_ATTR_STYLE,           ABC_HTML_FLAG_SHOW},
+       {id_keys,          "",         ABC_HTML_ATTR_ID,              ABC_HTML_FLAG_SHOW},
+       {font_keys,        "SimSong",  ABC_HTML_ATTR_FONT,            0},
+       {font_size_keys,   "16",       ABC_HTML_ATTR_FONT_SIZE,       0},
+       {font_color_keys,  "black",    ABC_HTML_ATTR_FONT_COLOR,      ABC_HTML_FLAG_SHOW},
+       {font_style_keys,  "",         ABC_HTML_ATTR_FONT_STYLE,      0},
+
+       {bg_color_keys,    "",         ABC_HTML_ATTR_BG_COLOR,        ABC_HTML_FLAG_SHOW},
+
+       {list_style_type_keys,  "",    ABC_CSS_LIST_STYLE_TYPE,       ABC_HTML_FLAG_SHOW},
+       {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},
+};
+
 static html_attr_t  script_attrs[] =
 {
        {font_keys,        "SimSong",    ABC_HTML_ATTR_FONT,      0},
 static html_attr_t  script_attrs[] =
 {
        {font_keys,        "SimSong",    ABC_HTML_ATTR_FONT,      0},
@@ -420,6 +457,10 @@ static html_label_t  html_labels[] =
        {tr_keys,         ABC_HTML_TR,       0,                            NULL,          ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {td_keys,         ABC_HTML_TD,       0,                            NULL,          ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
 
        {tr_keys,         ABC_HTML_TR,       0,                            NULL,          ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {td_keys,         ABC_HTML_TD,       0,                            NULL,          ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
 
+       {ol_keys,         ABC_HTML_OL,       abc_number_of(ol_attrs),      ol_attrs,      ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+       {ul_keys,         ABC_HTML_UL,       abc_number_of(ol_attrs),      ol_attrs,      ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+       {li_keys,         ABC_HTML_LI,       0,                            NULL,          ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+
        {video_keys,      ABC_HTML_VIDEO,    abc_number_of(video_attrs),   video_attrs,   ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {audio_keys,      ABC_HTML_AUDIO,    abc_number_of(audio_attrs),   audio_attrs,   ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {source_keys,     ABC_HTML_SOURCE,   abc_number_of(source_attrs),  source_attrs,  ABC_HTML_FLAG_OPEN  | ABC_HTML_FLAG_SHOW},
        {video_keys,      ABC_HTML_VIDEO,    abc_number_of(video_attrs),   video_attrs,   ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {audio_keys,      ABC_HTML_AUDIO,    abc_number_of(audio_attrs),   audio_attrs,   ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {source_keys,     ABC_HTML_SOURCE,   abc_number_of(source_attrs),  source_attrs,  ABC_HTML_FLAG_OPEN  | ABC_HTML_FLAG_SHOW},
@@ -429,8 +470,13 @@ static html_label_t  html_labels[] =
        {script_keys,     ABC_HTML_SCRIPT,   abc_number_of(script_attrs),  script_attrs,  ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {style_keys,      ABC_HTML_STYLE,    0,                            NULL,          ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
 
        {script_keys,     ABC_HTML_SCRIPT,   abc_number_of(script_attrs),  script_attrs,  ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {style_keys,      ABC_HTML_STYLE,    0,                            NULL,          ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
 
-       {css_id_keys,     ABC_CSS_ID,        abc_number_of(css_id_attrs),  css_id_attrs,  ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
-       {css_class_keys,  ABC_CSS_CLASS,     abc_number_of(css_id_attrs),  css_id_attrs,  ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+       {css_id_keys,      ABC_CSS_ID,       abc_number_of(css_id_attrs),  css_id_attrs,  ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+       {css_class_keys,   ABC_CSS_CLASS,    abc_number_of(css_id_attrs),  css_id_attrs,  ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+
+       {css_link_keys,    ABC_CSS_LINK,     abc_number_of(css_id_attrs),  css_id_attrs,  ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+       {css_visited_keys, ABC_CSS_VISITED,  abc_number_of(css_id_attrs),  css_id_attrs,  ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+       {css_hover_keys,   ABC_CSS_HOVER,    abc_number_of(css_id_attrs),  css_id_attrs,  ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+       {css_active_keys,  ABC_CSS_ACTIVE,   abc_number_of(css_id_attrs),  css_id_attrs,  ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
 };
 
 static int __html_parse_obj(abc_html_t* html, abc_char_t* c);
 };
 
 static int __html_parse_obj(abc_html_t* html, abc_char_t* c);
index 49dda16461fef3d59a7875cdfcf082c23898ec7c..8f2733402ce3f0cecec244264c32c6692d3e99cc 100644 (file)
@@ -62,6 +62,10 @@ enum abc_objs
        ABC_HTML_B,
        ABC_HTML_I,
 
        ABC_HTML_B,
        ABC_HTML_I,
 
+       ABC_HTML_OL,
+       ABC_HTML_UL,
+       ABC_HTML_LI,
+
        ABC_HTML_NB, // total HTML objects
 
        ABC_HTML_ATTR_ID,
        ABC_HTML_NB, // total HTML objects
 
        ABC_HTML_ATTR_ID,
@@ -112,6 +116,19 @@ enum abc_objs
        ABC_HTML_ATTR_CONTROLS,
 
        // css objects
        ABC_HTML_ATTR_CONTROLS,
 
        // css objects
+       ABC_CSS_LINK,
+       ABC_CSS_VISITED,
+       ABC_CSS_HOVER,
+       ABC_CSS_ACTIVE,
+
+       ABC_CSS_LIST_STYLE,
+       ABC_CSS_LIST_STYLE_TYPE,
+       ABC_CSS_LIST_STYLE_IMAGE,
+       ABC_CSS_LIST_STYLE_POSITION,
+
+       // ... new css add here
+
+       // css enum 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,
 };
@@ -153,7 +170,8 @@ struct abc_obj_s
        int             text_pos;
        abc_io_t        io;
 
        int             text_pos;
        abc_io_t        io;
 
-       int             css_dot; // dot position for css class
+       int             css_dot;   // dot   position for css class
+       int             css_colon; // colon position for css status
 
        scf_string_t*   file; // file name
        int             line; // line
 
        scf_string_t*   file; // file name
        int             line; // line
@@ -165,6 +183,7 @@ struct abc_obj_s
        scf_string_t*   js_entry;
 
        uint32_t        clicked:1;
        scf_string_t*   js_entry;
 
        uint32_t        clicked:1;
+       uint32_t        visited:1;
 };
 
 abc_obj_t*     abc_obj_alloc(scf_string_t* file, int line, int pos, int type);
 };
 
 abc_obj_t*     abc_obj_alloc(scf_string_t* file, int line, int pos, int type);
@@ -172,6 +191,7 @@ void           abc_obj_free (abc_obj_t*    obj);
 abc_obj_t*     abc_obj_find (abc_obj_t*    root, int x, int y);
 void           abc_obj_print(abc_obj_t*    obj);
 
 abc_obj_t*     abc_obj_find (abc_obj_t*    root, int x, int y);
 void           abc_obj_print(abc_obj_t*    obj);
 
+void           abc_obj_set_css  (abc_obj_t* obj, abc_obj_t* css);
 int            abc_obj_set_attr (abc_obj_t* obj, int key, const char* value, size_t len);
 abc_obj_t*     abc_obj_get_attr (abc_obj_t* obj, int key);
 abc_obj_t*     abc_obj_find_attr(abc_obj_t* obj, int key);
 int            abc_obj_set_attr (abc_obj_t* obj, int key, const char* value, size_t len);
 abc_obj_t*     abc_obj_get_attr (abc_obj_t* obj, int key);
 abc_obj_t*     abc_obj_find_attr(abc_obj_t* obj, int key);
index c2d8c9dc66722e999f691528e57f165c326da5f1..86344a7b20c260f0c5e3795c9fb847ec801388bc 100644 (file)
@@ -39,6 +39,7 @@ CFILES += abc_render_input.c
 CFILES += abc_render_table.c
 CFILES += abc_render_tr.c
 CFILES += abc_render_td.c
 CFILES += abc_render_table.c
 CFILES += abc_render_tr.c
 CFILES += abc_render_td.c
+CFILES += abc_render_li.c
 
 CFILES += abc_render_video.c
 CFILES += abc_render_audio.c
 
 CFILES += abc_render_video.c
 CFILES += abc_render_audio.c
index 4ed637a4b67d0f27e31e8a557994711efe62acb5..6c85004d1ae607cf8ff3bf76e169067dcd44e8c8 100644 (file)
--- a/ui/abc.h
+++ b/ui/abc.h
@@ -76,4 +76,6 @@ int  __init_program(GLuint* pprog, const char* vert_shader, const char* frag_sha
 
 int  __init_buffers(GLuint* vao, GLuint buffers[2]);
 
 
 int  __init_buffers(GLuint* vao, GLuint buffers[2]);
 
+int __init_text(cairo_t* cr, abc_obj_t* obj, double dx);
+
 #endif
 #endif
index 2c0c4ee6b935942ffc1ccba92f9629c051c8f773..84882f40ea0051e5665dbf662a1c626507ccc618 100644 (file)
@@ -54,6 +54,10 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] =
        [ABC_HTML_TR]       = abc_layout_empty,
        [ABC_HTML_TD]       = abc_layout_td,
 
        [ABC_HTML_TR]       = abc_layout_empty,
        [ABC_HTML_TD]       = abc_layout_td,
 
+       [ABC_HTML_OL]       = abc_layout_empty,
+       [ABC_HTML_UL]       = abc_layout_empty,
+       [ABC_HTML_LI]       = abc_layout_h1,
+
        [ABC_HTML_VIDEO]    = abc_layout_video,
        [ABC_HTML_AUDIO]    = abc_layout_audio,
        [ABC_HTML_SOURCE]   = abc_layout_empty,
        [ABC_HTML_VIDEO]    = abc_layout_video,
        [ABC_HTML_AUDIO]    = abc_layout_audio,
        [ABC_HTML_SOURCE]   = abc_layout_empty,
@@ -176,6 +180,9 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                        case ABC_HTML_H4:
                        case ABC_HTML_H5:
                        case ABC_HTML_H6:
                        case ABC_HTML_H4:
                        case ABC_HTML_H5:
                        case ABC_HTML_H6:
+                       case ABC_HTML_OL:
+                       case ABC_HTML_UL:
+                       case ABC_HTML_LI:
                                child->x = root->x + 4;
                                child->y = y + h;
 
                                child->x = root->x + 4;
                                child->y = y + h;
 
@@ -183,6 +190,9 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                                if (ret < 0)
                                        return ret;
 
                                if (ret < 0)
                                        return ret;
 
+                               if (ABC_HTML_UL == root->type || ABC_HTML_OL == root->type)
+                                       child->w    += 16;
+
                                x = root->x  + 4;
                                y = child->y + child->h;
                                h = 0;
                                x = root->x  + 4;
                                y = child->y + child->h;
                                h = 0;
index c7caa07b6c7b5692ee48367d1eb5924eaeb5aaa5..a0f107abf705e69d2413459bc7456a494c8b28db 100644 (file)
@@ -57,7 +57,7 @@ static int __av_filter_init(abc_obj_t* obj)
        }
 
        if (avin->aopen) {
        }
 
        if (avin->aopen) {
-               ret = abc_avio_open(&aout, "ffmpeg_alsa", NULL, "hw:0");
+               ret = abc_avio_open(&aout, "ffmpeg_alsa", NULL, "");
                if (ret < 0)
                        goto error;
 
                if (ret < 0)
                        goto error;
 
index 6811585bdbd47097496c744444d08737d9c13944..50586a669583383e89eb7bbd20d32084e70ae162 100644 (file)
@@ -19,6 +19,7 @@ extern abc_render_t  abc_render_input;
 extern abc_render_t  abc_render_table;
 extern abc_render_t  abc_render_tr;
 extern abc_render_t  abc_render_td;
 extern abc_render_t  abc_render_table;
 extern abc_render_t  abc_render_tr;
 extern abc_render_t  abc_render_td;
+extern abc_render_t  abc_render_li;
 
 extern abc_render_t  abc_render_video;
 extern abc_render_t  abc_render_audio;
 
 extern abc_render_t  abc_render_video;
 extern abc_render_t  abc_render_audio;
@@ -56,6 +57,10 @@ static abc_render_t* abc_renders[ABC_HTML_NB] =
        [ABC_HTML_TR]       = &abc_render_tr,
        [ABC_HTML_TD]       = &abc_render_td,
 
        [ABC_HTML_TR]       = &abc_render_tr,
        [ABC_HTML_TD]       = &abc_render_td,
 
+       [ABC_HTML_OL]       = &abc_render_empty,
+       [ABC_HTML_UL]       = &abc_render_empty,
+       [ABC_HTML_LI]       = &abc_render_li,
+
        [ABC_HTML_VIDEO]    = &abc_render_video,
        [ABC_HTML_AUDIO]    = &abc_render_audio,
        [ABC_HTML_SOURCE]   = &abc_render_empty,
        [ABC_HTML_VIDEO]    = &abc_render_video,
        [ABC_HTML_AUDIO]    = &abc_render_audio,
        [ABC_HTML_SOURCE]   = &abc_render_empty,
index 1c3879c2fb64ac9eae0afce41c38524d96aa304b..a10d92755c008b6a0840232ac3b3ffe2becc5b4a 100644 (file)
@@ -40,6 +40,13 @@ static int _render_fini_a_href(abc_render_t* render)
 
 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_obj_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_HREF);
+
+       if (!attr || !attr->value || attr->value->len <= 0) {
+               scf_loge("hyper link '%s' not found a URL\n", obj->text->data);
+               return -EINVAL;
+       }
+
        if (0 == program)
                __init_program(&program, vert_shader, frag_shader);
 
        if (0 == program)
                __init_program(&program, vert_shader, frag_shader);
 
@@ -53,9 +60,6 @@ static int _render_draw_a_href(abc_render_t* render, abc_obj_t* obj, int width,
        cairo_surface_t*      surface;
        cairo_t*              cr;
 
        cairo_surface_t*      surface;
        cairo_t*              cr;
 
-       scf_list_t*           l;
-       abc_obj_t*            attr;
-
        uint8_t* bgra = malloc(width * 32 * 4);
        if (!bgra)
                return -ENOMEM;
        uint8_t* bgra = malloc(width * 32 * 4);
        if (!bgra)
                return -ENOMEM;
@@ -67,15 +71,7 @@ static int _render_draw_a_href(abc_render_t* render, abc_obj_t* obj, int width,
        cairo_set_font_size   (cr, 24);
        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
 
        cairo_set_font_size   (cr, 24);
        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
 
-       for (l   = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
-               attr = scf_list_data(l, abc_obj_t, list);
-
-               if (ABC_HTML_ATTR_HREF == attr->type) {
-
-                       cairo_text_extents(cr, attr->value->data, &extents);
-                       break;
-               }
-       }
+       cairo_text_extents(cr, attr->value->data, &extents);
 
        int w = extents.width + extents.x_bearing;
        int h = extents.height;
 
        int w = extents.width + extents.x_bearing;
        int h = extents.height;
@@ -88,14 +84,6 @@ static int _render_draw_a_href(abc_render_t* render, abc_obj_t* obj, int width,
        surface = NULL;
        cr = NULL;
 
        surface = NULL;
        cr = NULL;
 
-       if (l == scf_list_sentinel(&obj->attrs)) {
-               scf_loge("hyper link '%s' not found a URL\n", obj->text->data);
-
-               free(bgra);
-               bgra = NULL;
-               return -EINVAL;
-       }
-
        scf_logd("extents: x_bearing: %f, width: %f, y_bearing: %f, height: %f\n",
                        extents.x_bearing, extents.width, extents.y_bearing, extents.height);
 
        scf_logd("extents: x_bearing: %f, width: %f, y_bearing: %f, height: %f\n",
                        extents.x_bearing, extents.width, extents.y_bearing, extents.height);
 
index 267272df71e5fead42a06f5f5ffb806990d7e945..935319c247e2e2753d46b02d7161b940ace9a704 100644 (file)
@@ -75,7 +75,7 @@ static int _render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int width
        if (ret < 0)
                return ret;
 
        if (ret < 0)
                return ret;
 
-       scf_logi("background-image: %s\n", spath->data);
+       scf_logd("background-image: %s\n", spath->data);
 
        ret = abc_img_open(&img, spath->data);
 
 
        ret = abc_img_open(&img, spath->data);
 
@@ -155,7 +155,7 @@ static int _render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int width
        if (attr) {
                abc_css_position(&x, &y, w, h, obj, attr->value->data);
 
        if (attr) {
                abc_css_position(&x, &y, w, h, obj, attr->value->data);
 
-               scf_logi("background-position: %s, x: %f, y: %f, w: %f, h: %f\n", attr->value->data, x, y, w, h);
+               scf_logd("background-position: %s, x: %f, y: %f, w: %f, h: %f\n", attr->value->data, x, y, w, h);
 
                if (x + w > 1.0)
                        index_x = -1;
 
                if (x + w > 1.0)
                        index_x = -1;
@@ -178,7 +178,7 @@ static int _render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int width
                }
        }
 
                }
        }
 
-       scf_logi("repeat_x: %d, repeat_y: %d, index_x: %d, index_y: %d\n", repeat_x, repeat_y, index_x, index_y);
+       scf_logd("repeat_x: %d, repeat_y: %d, index_x: %d, index_y: %d\n", repeat_x, repeat_y, index_x, index_y);
 
        glUseProgram(program);
 
 
        glUseProgram(program);
 
index a3997546ca0376239c0641b0f73e648cb3e3e414..e6d90cd42fd6f07bdaa96196670d7be5643a998f 100644 (file)
@@ -38,7 +38,7 @@ static int _render_fini_h1(abc_render_t* render)
        return 0;
 }
 
        return 0;
 }
 
-static int __init_text(cairo_t* cr, abc_obj_t* obj)
+int __init_text(cairo_t* cr, abc_obj_t* obj, double dx)
 {
        abc_obj_t* attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
        if (attr) {
 {
        abc_obj_t* attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
        if (attr) {
@@ -76,8 +76,9 @@ static int __init_text(cairo_t* cr, abc_obj_t* obj)
        cairo_set_source_rgba(cr, r, g, b, 1.0);
        cairo_text_extents   (cr, obj->text->data, &extents);
 
        cairo_set_source_rgba(cr, r, g, b, 1.0);
        cairo_text_extents   (cr, obj->text->data, &extents);
 
-       cairo_move_to  (cr, extents.x_bearing, -extents.y_bearing);
+       cairo_move_to  (cr, extents.x_bearing + dx, -extents.y_bearing);
        cairo_show_text(cr, obj->text->data);
        cairo_show_text(cr, obj->text->data);
+       cairo_stroke(cr);
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_TEXT_DECORATION);
        if (attr) {
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_TEXT_DECORATION);
        if (attr) {
@@ -138,7 +139,7 @@ static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int
        cairo_stroke(cr);
 
        if (obj->text)
        cairo_stroke(cr);
 
        if (obj->text)
-               __init_text(cr, obj);
+               __init_text(cr, obj, 0.0);
 //     cairo_surface_write_to_png(surface, "tmp.png");
 
        cairo_destroy(cr);
 //     cairo_surface_write_to_png(surface, "tmp.png");
 
        cairo_destroy(cr);
diff --git a/ui/abc_render_li.c b/ui/abc_render_li.c
new file mode 100644 (file)
index 0000000..9349b6b
--- /dev/null
@@ -0,0 +1,249 @@
+#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 vec4 rect; \n"
+       "uniform sampler2D tex_rgba; \n"
+       "uniform sampler2D tex_img; \n"
+       "void main() { \n"
+       "    vec2 xy = v_texCoord; \n"
+       "    if (xy.x > rect.x && xy.x < rect.x + rect.z \n"
+       "     && xy.y > rect.y && xy.y < rect.y + rect.w) { \n"
+       "        xy.x = (xy.x - rect.x) / rect.z; \n"
+       "        xy.y = (xy.y - rect.y) / rect.w; \n"
+       "        vec4 v = texture2D(tex_img, xy).rgba; \n"
+       "        outputColor = vec4(v.b, v.g, v.r, 1.0); \n"
+       "    } else { \n"
+       "        vec4 v = texture2D(tex_rgba, xy).rgba; \n"
+       "        outputColor = vec4(v.b, v.g, v.r, 1.0); \n"
+       "    } \n"
+       "} \n";
+
+
+static GLuint program = 0;
+
+static GLuint vao = 0;
+static GLuint buffers[2]   = {0};
+static GLuint texture_rgba = 0;
+static GLuint texture_img  = 0;
+
+static GLuint uniform_mvp;
+static GLuint uniform_rgba;
+static GLuint uniform_img;
+static GLuint uniform_rect;
+
+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)
+{
+       abc_obj_t*        attr;
+       cairo_surface_t*  surface;
+       cairo_t*          cr;
+
+       uint8_t* bgra = calloc(1, obj->w * obj->h * 4);
+       if (!bgra)
+               return -ENOMEM;
+
+       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);
+
+       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, r, g, b);
+       cairo_rectangle(cr, 0, 0, obj->w, obj->h);
+       cairo_fill(cr);
+       cairo_stroke(cr);
+
+       if (obj->text)
+               __init_text(cr, obj, 16);
+
+       if (ABC_HTML_UL == obj->parent->type) {
+               r = 0.0;
+               g = 0.0;
+               b = 0.0;
+               attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
+               if (attr)
+                       abc_css_color(&r, &g, &b, attr->value->data);
+
+               cairo_set_source_rgb(cr, r, g, b);
+
+               attr = abc_obj_find_attr(obj, ABC_CSS_LIST_STYLE_TYPE);
+               if (attr) {
+                       if (!strcmp(attr->value->data, "circle"))
+                               cairo_arc (cr, 8, 8, 3, 0, 2 * M_PI);
+
+                       else if (!strcmp(attr->value->data, "square")) {
+                               cairo_rectangle(cr, 5, 5, 6, 6);
+                               cairo_fill(cr);
+
+                       } else if (!strcmp(attr->value->data, "disc")) {
+                               cairo_arc (cr, 8, 8, 3, 0, 2 * M_PI);
+                               cairo_fill(cr);
+                       }
+               } else {
+                       cairo_arc (cr, 8, 8, 3, 0, 2 * M_PI);
+                       cairo_fill(cr);
+               }
+
+               cairo_stroke(cr);
+       }
+//     cairo_surface_write_to_png(surface, "tmp.png");
+
+       cairo_destroy(cr);
+       cairo_surface_destroy(surface);
+       surface = NULL;
+       cr = NULL;
+
+       abc_img_t*  img   = NULL;
+       uint8_t*    bgra1 = NULL;
+
+       GLfloat  x = 0.0;
+       GLfloat  y = 0.0;
+       GLfloat  w = 0.0;
+       GLfloat  h = 0.0;
+
+       attr = abc_obj_find_attr(obj, ABC_CSS_LIST_STYLE_IMAGE);
+
+       if (attr && attr->value && attr->value->len > 0)
+       {
+               scf_string_t* spath = NULL;
+               abc_io_t*     io    = NULL;
+
+               int ret = __io_url_css(&io, &spath, obj->file->data, attr->value->data);
+               if (ret < 0) {
+                       free(bgra);
+                       return ret;
+               }
+
+               scf_logd("list-style-image: %s\n", spath->data);
+
+               ret = abc_img_open(&img, spath->data);
+
+               scf_string_free(spath);
+               spath = NULL;
+               if (ret < 0) {
+                       free(bgra);
+                       return ret;
+               }
+
+               bgra1 = calloc(1, img->width * img->height * 4);
+               if (!bgra1) {
+                       abc_img_close(img);
+                       free(bgra);
+                       return -ENOMEM;
+               }
+
+               ret = abc_img_read(img, bgra1, img->width * img->height * 4);
+               if (ret < 0) {
+                       abc_img_close(img);
+                       free(bgra1);
+                       free(bgra);
+                       return ret;
+               }
+
+               x = obj->h * 0.333 / (float)obj->w;
+               y = 0.333;
+               w = x;
+               h = y;
+
+               if (0 == texture_img)
+                       __init_texture(&texture_img, GL_RGBA, img->width, img->height, NULL);
+       }
+
+       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);
+
+       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);
+
+       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_mvp  = glGetUniformLocation(program, "mvp");
+       uniform_rgba = glGetUniformLocation(program, "tex_rgba");
+       uniform_img  = glGetUniformLocation(program, "tex_img");
+       uniform_rect = glGetUniformLocation(program, "rect");
+
+       glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
+
+       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);
+
+       if (img) {
+               glActiveTexture(GL_TEXTURE1);
+               glBindTexture  (GL_TEXTURE_2D, texture_img);
+               glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, img->width, img->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra1);
+               glUniform1i(uniform_img,  1);
+       }
+
+       glUniform4f(uniform_rect, x, y, w, h);
+
+       // 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);
+
+       abc_img_close(img);
+       free(bgra);
+       return 0;
+}
+
+abc_render_t  abc_render_li =
+{
+       .type = ABC_HTML_LI,
+
+       .draw = _render_draw_li,
+       .fini = _render_fini_li,
+};
index c3a890d9f2be4d4f398c630b9540ef96ed2e99cd..c931f2ce73bd648cc412e4ea5330ce6b5941dc46 100644 (file)
--- a/ui/main.c
+++ b/ui/main.c
@@ -64,9 +64,11 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
        if (!ctx->current->root)
                return 0;
 
        if (!ctx->current->root)
                return 0;
 
+       scf_list_t* l;
        abc_obj_t*  prev = ctx->current->current;
        abc_obj_t*  obj  = abc_obj_find(ctx->current->root, x, y);
        abc_obj_t*  attr;
        abc_obj_t*  prev = ctx->current->current;
        abc_obj_t*  obj  = abc_obj_find(ctx->current->root, x, y);
        abc_obj_t*  attr;
+       abc_obj_t*  css;
 
        int ret = 0;
 
 
        int ret = 0;
 
@@ -80,6 +82,13 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
                gdk_window_set_cursor(window, cursor);
                g_object_unref(cursor);
 
                gdk_window_set_cursor(window, cursor);
                g_object_unref(cursor);
 
+               if (prev->visited)
+                       css = abc_obj_get_attr(prev, ABC_CSS_VISITED);
+               else
+                       css = abc_obj_get_attr(prev, ABC_CSS_LINK);
+               if (css)
+                       abc_obj_set_css(prev, css);
+
                prev->clicked = 0;
                ret = 1;
        }
                prev->clicked = 0;
                ret = 1;
        }
@@ -88,8 +97,8 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
                scf_logd("obj: %s, type: %d, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
                                obj->keys[0], obj->type, obj->x, obj->y, obj->w, obj->h, x, y);
 
                scf_logd("obj: %s, type: %d, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
                                obj->keys[0], obj->type, obj->x, obj->y, obj->w, obj->h, x, y);
 
-               switch (obj->type) {
-
+               switch (obj->type)
+               {
                        case ABC_HTML_A:
                                display = gtk_widget_get_display(GTK_WIDGET(ctx->gl_area));
                                window  = gtk_widget_get_window (GTK_WIDGET(ctx->gl_area));
                        case ABC_HTML_A:
                                display = gtk_widget_get_display(GTK_WIDGET(ctx->gl_area));
                                window  = gtk_widget_get_window (GTK_WIDGET(ctx->gl_area));
@@ -120,6 +129,12 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
                                break;
                };
 
                                break;
                };
 
+               css = abc_obj_get_attr(obj, ABC_CSS_HOVER);
+               if (css) {
+                       abc_obj_set_css(obj, css);
+                       ret = 1;
+               }
+
                ctx->current->current = obj;
        }
 
                ctx->current->current = obj;
        }
 
@@ -164,16 +179,24 @@ static int __do_button_release_a(abc_ctx_t* ctx, abc_obj_t* obj, int x, int y)
 static int __do_button_release(abc_ctx_t* ctx, int x, int y)
 {
        abc_html_t* html;
 static int __do_button_release(abc_ctx_t* ctx, int x, int y)
 {
        abc_html_t* html;
-       abc_obj_t*  attr;
        abc_obj_t*  obj = abc_obj_find(ctx->current->root, x, y);
        abc_obj_t*  obj = abc_obj_find(ctx->current->root, x, y);
+       abc_obj_t*  css;
+       abc_obj_t*  attr;
+
        if (!obj)
        if (!obj)
-               return -ENOMEM;
+               return __do_button_move(ctx, x, y);
 
 
-       scf_logd("obj: %s, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
-                       obj->key->data, obj->x, obj->y, obj->w, obj->h, x, y);
+       obj->visited = 1;
+
+       css = abc_obj_get_attr(obj, ABC_CSS_VISITED);
+       if (css)
+               abc_obj_set_css(obj, css);
 
 
-       switch (obj->type) {
+       scf_logd("obj: %s, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
+                       obj->keys[0], obj->x, obj->y, obj->w, obj->h, x, y);
 
 
+       switch (obj->type)
+       {
                case ABC_HTML_A:
                        return __do_button_release_a(ctx, obj, x, y);
                        break;
                case ABC_HTML_A:
                        return __do_button_release_a(ctx, obj, x, y);
                        break;
@@ -200,6 +223,7 @@ static int __do_button_release(abc_ctx_t* ctx, int x, int y)
                        return __do_button_move(ctx, x, y);
                        break;
                default:
                        return __do_button_move(ctx, x, y);
                        break;
                default:
+                       return __do_button_move(ctx, x, y);
                        break;
        };
 
                        break;
        };
 
@@ -306,6 +330,32 @@ static gboolean button_release_event(GtkWidget* self, GdkEventButton* event, gpo
        return TRUE;
 }
 
        return TRUE;
 }
 
+static gboolean button_press_event(GtkWidget* self, GdkEventButton* event, gpointer user_data)
+{
+       abc_ctx_t* ctx = user_data;
+
+       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);
+
+               abc_html_t* html;
+               abc_obj_t*  obj = abc_obj_find(ctx->current->root, event->x, event->y);
+               abc_obj_t*  css;
+
+               if (obj) {
+                       css = abc_obj_get_attr(obj, ABC_CSS_ACTIVE);
+                       if (css) {
+                               abc_obj_set_css(obj, css);
+
+                               gtk_gl_area_queue_render(ctx->gl_area);
+                       }
+               }
+       }
+
+       return TRUE;
+}
+
 static void __utf8_delete(abc_ctx_t* ctx)
 {
        abc_obj_t* obj;
 static void __utf8_delete(abc_ctx_t* ctx)
 {
        abc_obj_t* obj;
@@ -396,11 +446,11 @@ static gboolean timer_handler(gpointer user_data)
                obj = ctx->current->current;
                if (obj) {
                        obj->jiffies++;
                obj = ctx->current->current;
                if (obj) {
                        obj->jiffies++;
-                       gtk_gl_area_queue_render(ctx->gl_area);
-               } else {
-                       if (ctx->current->has_video)
-                               gtk_gl_area_queue_render(ctx->gl_area);
+//                     gtk_gl_area_queue_render(ctx->gl_area);
                }
                }
+
+               if (ctx->current->has_video)
+                       gtk_gl_area_queue_render(ctx->gl_area);
        }
 
        return TRUE;
        }
 
        return TRUE;
@@ -536,6 +586,7 @@ int main(int argc, char *argv[])
        gtk_widget_add_events(GTK_WIDGET(gl_area), GDK_POINTER_MOTION_MASK);
 
        g_signal_connect(window,  "button-release-event", G_CALLBACK(button_release_event), &ctx);
        gtk_widget_add_events(GTK_WIDGET(gl_area), GDK_POINTER_MOTION_MASK);
 
        g_signal_connect(window,  "button-release-event", G_CALLBACK(button_release_event), &ctx);
+       g_signal_connect(window,  "button-press-event",   G_CALLBACK(button_press_event),   &ctx);
        g_signal_connect(window,  "key-press-event",      G_CALLBACK(key_press_event),      &ctx);
        g_signal_connect(gl_area, "motion-notify-event",  G_CALLBACK(button_move_event),    &ctx);
 
        g_signal_connect(window,  "key-press-event",      G_CALLBACK(key_press_event),      &ctx);
        g_signal_connect(gl_area, "motion-notify-event",  G_CALLBACK(button_move_event),    &ctx);