css: support a simple scroll-bar with 'scrollbar-width' & 'scrollbar-color' as CSS...
authoryu.dongliang <18588496441@163.com>
Tue, 19 May 2026 11:19:22 +0000 (19:19 +0800)
committeryu.dongliang <18588496441@163.com>
Tue, 19 May 2026 11:19:22 +0000 (19:19 +0800)
26 files changed:
examples/overflow.html
html/abc_css_border.c
html/abc_css_color.c
html/abc_css_position.c
html/abc_html.c
html/abc_html.h
html/abc_obj.c
html/abc_obj.h
ui/Makefile
ui/__render_bg_image.c
ui/__render_border.c
ui/__render_text.c
ui/abc_layout.c
ui/abc_layout_head.c [deleted file]
ui/abc_layout_html.c [deleted file]
ui/abc_layout_table.c
ui/abc_layout_title.c [deleted file]
ui/abc_render.c
ui/abc_render_div.c [deleted file]
ui/abc_render_head.c [deleted file]
ui/abc_render_html.c [deleted file]
ui/abc_render_li.c
ui/abc_render_td.c
ui/abc_render_text.c
ui/abc_render_title.c [deleted file]
ui/main.c

index 89fb8f77018ad581bda08be02bfcb44abd86eaa0..55fcd84605772b090d53f4dd5988053a75084e78 100644 (file)
@@ -4,11 +4,18 @@
 <meta charset="utf-8">
 <style>
 div {
-       background-color:gray;
+       background-color:lightGray;
        width: 200px;
        height: 50px;
        border: 1px dotted black;
+       padding: 25px;
        overflow: visible;
+       scrollbar-width: 15px;
+       scrollbar-color: orangeRed lightGray;
+}
+
+p {
+       border: 1px dotted red;
 }
 </style>
 </head>
index 47b8f9a41dd7b2b9d040b4f0296e794ce86a6c5a..ab68fb420b9d7503e348b854dc70760a81e59608 100644 (file)
@@ -100,7 +100,7 @@ int abc_css_border(double* r, double* g, double* b, int* width, int* type, abc_o
                        } else if (p) {
 
                                if (i > 1)
-                                       abc_css_color(r, g, b, p);
+                                       abc_css_color(r, g, b, p, -1);
                                else if (1 == i)
                                        __css_border_type(type, p, (size_t)(str - p));
 
index 330474faa38c3f1922d8d0f619154bfe7b211cbd..3783bc345afb697c336f75d44b578facc51a3036 100644 (file)
@@ -319,17 +319,21 @@ static css_color_t  css_colors[] =
        {css_YellowGreen,     0x9acd32},
 };
 
-int abc_css_color(double* r, double* g, double* b, const uint8_t* str)
+int abc_css_color(double* r, double* g, double* b, const uint8_t* str, size_t len)
 {
        *r = 0.0;
        *g = 0.0;
        *b = 0.0;
 
+       if (!str || 0 == len)
+               return 0;
+
        if ('#' == *str) {
                uint64_t value = 0;
+               long     i;
 
-               while (*++str) {
-                       int c = *str;
+               for (i = 1; i < len && str[i]; i++) {
+                       int c = str[i];
 
                        if ('0' <= c && '9' >= c) {
                                value <<= 4;
@@ -349,24 +353,29 @@ int abc_css_color(double* r, double* g, double* b, const uint8_t* str)
                *b = ( value        & 0xff) / 255.0;
 
        } else if (!__html_strncmp(str, "rgb(", 4)) {
-               const uint8_t* p = str + 4;
-
-               str = p;
-               while (*str && ',' != *str)
-                       str++;
-               *r = atof(p) / 255.0;
-
-               if (*str) {
-                       p = ++str;
-                       while (*str && ',' != *str)
-                               str++;
-                       *g = atof(p) / 255.0;
-
-                       if (*str) {
-                               p = ++str;
-                               while (*str && ')' != *str)
-                                       str++;
-                               *b = atof(p) / 255.0;
+               long i;
+               long j = 4;
+               int  k = 0;
+
+               for (i = 4; i < len && str[i]; i++) {
+                       int c = str[i];
+
+                       if (',' == c || ')' == c) {
+                               switch (k) {
+                                       case 0:
+                                               *r = atof(str + j) / 255.0;
+                                               break;
+                                       case 1:
+                                               *g = atof(str + j) / 255.0;
+                                               break;
+                                       case 2:
+                                               *b = atof(str + j) / 255.0;
+                                               break;
+                               };
+
+                               if (++k > 2)
+                                       break;
+                               j = i + 1;
                        }
                }
        } else {
@@ -376,7 +385,7 @@ int abc_css_color(double* r, double* g, double* b, const uint8_t* str)
 
                        int j;
                        for (j = 0; c->names[j]; j++) {
-                               if (!__html_strcmp(c->names[j], str)) {
+                               if (!__html_strncmp(c->names[j], str, len)) {
                                        *r = ((c->color >> 16) & 0xff) / 255.0;
                                        *g = ((c->color >>  8) & 0xff) / 255.0;
                                        *b = ( c->color        & 0xff) / 255.0;
@@ -390,3 +399,50 @@ int abc_css_color(double* r, double* g, double* b, const uint8_t* str)
 
        return 0;
 }
+
+int abc_css_scrollbar_color(double thumb[3], double track[3], const uint8_t* str)
+{
+       thumb[0] = 0.0;
+       thumb[1] = 0.0;
+       thumb[2] = 0.0;
+
+       track[0] = 0.0;
+       track[1] = 0.0;
+       track[2] = 0.0;
+
+       if (!str)
+               return 0;
+
+       int  c;
+       int  c0 = ' ';
+       int  k  = 0;
+       long i  = 0;
+       long j  = 0;
+
+       do {
+               c = str[i++];
+
+               if (' ' == c0) {
+                       if ('\0' == c || ' ' == c || '\t' == c || '\r' == c || '\n' == c)
+                               continue;
+
+                       c0 = c;
+                       j  = i - 1;
+
+               } else if ('\0' == c || ' ' == c || '\t' == c || '\r' == c || '\n' == c) {
+
+                       if (0 == k) {
+                               abc_css_color(thumb, thumb + 1, thumb + 2, str + j, i - 1 - j);
+                               k = 1;
+                       } else {
+                               abc_css_color(track, track + 1, track + 2, str + j, i - 1 - j);
+                               break;
+                       }
+
+                       c0 = ' ';
+                       j  = i;
+               }
+       } while (c);
+
+       return 0;
+}
index bd82a81f0f4d255caad43e36ec56d431cd15c76e..0c06da7c0b67d403b2b367e02150005c6bc674ff 100644 (file)
@@ -135,3 +135,42 @@ int abc_css_position(const uint8_t* str)
 
        return ABC_POSITION_STATIC;
 }
+
+int abc_css_overflow(const uint8_t* str)
+{
+       if (!__html_strcmp(str, "hidden"))
+               return ABC_OVERFLOW_HIDDEN;
+
+       else if (!__html_strcmp(str, "scroll"))
+               return ABC_OVERFLOW_SCROLL;
+
+       else if (!__html_strcmp(str, "auto"))
+               return ABC_OVERFLOW_SCROLL;
+
+       return ABC_OVERFLOW_VISIBLE;
+}
+
+void abc_overflow_show(int* x, int* y, int* w, int* h, int mask_x, int mask_y, int mask_w, int mask_h)
+{
+#define CSS_OVERFLOW_SHOW(px, pw, x2, x3) \
+       do { \
+               int x1 = *px + *pw; \
+               \
+               if (*px > x3) \
+                       *pw = 0; \
+               else if (x1 < x2) \
+                       *pw = 0; \
+               else { \
+                       if (*px < x2) \
+                               *px = x2; \
+                       \
+                       if (x1 > x3) \
+                               *pw = x3 - *px; \
+                       else \
+                               *pw = x1 - *px; \
+               } \
+       } while (0)
+
+       CSS_OVERFLOW_SHOW(x, w, mask_x, mask_x + mask_w);
+       CSS_OVERFLOW_SHOW(y, h, mask_y, mask_y + mask_h);
+}
index bd87a4f74cb6521aa64d1a320362b3fc54e8bfae..f10fb090c4d2985c76cedfab461aaf99916a8ead 100644 (file)
@@ -11,8 +11,6 @@ static char* margin_keys[]     = {"margin",     "外边距",   NULL};
 static char* border_keys[]     = {"border",     "边框",     NULL};
 static char* padding_keys[]    = {"padding",    "内边距",   NULL};
 
-static char* overflow_keys[]   = {"overflow",   NULL};
-
 static char* position_keys[]   = {"position",   "定位",     NULL};
 static char* top_keys[]        = {"top",        "上",       NULL};
 static char* bottom_keys[]     = {"bottom",     "下",       NULL};
@@ -37,6 +35,10 @@ static char* bg_image_keys[]         = {"background-image",    "背景图片",
 static char* bg_repeat_keys[]        = {"background-repeat",   "背景重复",     NULL};
 static char* bg_position_keys[]      = {"background-position", "背景位置",     NULL};
 
+static char* overflow_keys[]         = {"overflow",            "内容溢出",     NULL};
+static char* scroll_width_keys[]     = {"scrollbar-width",     "滚动条宽度",   NULL};
+static char* scroll_color_keys[]     = {"scrollbar-color",     "滚动条颜色",   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};
@@ -145,38 +147,40 @@ static html_attr_t  meta_attrs[] =
 static html_attr_t  body_attrs[] =
 {
 #define ABC_CSS_BOX(margin, border, padding) \
-       {margin_keys,     #margin,     ABC_HTML_ATTR_MARGIN,          ABC_HTML_FLAG_SHOW}, \
-       {border_keys,     #border,     ABC_HTML_ATTR_BORDER,          ABC_HTML_FLAG_SHOW}, \
-       {padding_keys,    #padding,    ABC_HTML_ATTR_PADDING,         ABC_HTML_FLAG_SHOW}, \
+       {margin_keys,      #margin,     ABC_HTML_ATTR_MARGIN,         ABC_HTML_FLAG_SHOW}, \
+       {border_keys,      #border,     ABC_HTML_ATTR_BORDER,         ABC_HTML_FLAG_SHOW}, \
+       {padding_keys,     #padding,    ABC_HTML_ATTR_PADDING,        ABC_HTML_FLAG_SHOW}, \
        \
-       {overflow_keys,   "",          ABC_HTML_ATTR_OVERFLOW,        ABC_HTML_FLAG_SHOW}, \
+       {overflow_keys,     "",         ABC_CSS_OVERFLOW,             ABC_HTML_FLAG_SHOW}, \
+       {scroll_width_keys, "",         ABC_CSS_SCROLLBAR_WIDTH,      ABC_HTML_FLAG_SHOW}, \
+       {scroll_color_keys, "",         ABC_CSS_SCROLLBAR_COLOR,      ABC_HTML_FLAG_SHOW}, \
        \
-       {position_keys,   "",          ABC_HTML_ATTR_POSITION,        ABC_HTML_FLAG_SHOW}, \
-       {top_keys,        "",          ABC_HTML_ATTR_TOP,             ABC_HTML_FLAG_SHOW}, \
-       {bottom_keys,     "",          ABC_HTML_ATTR_BOTTOM,          ABC_HTML_FLAG_SHOW}, \
-       {left_keys,       "",          ABC_HTML_ATTR_LEFT,            ABC_HTML_FLAG_SHOW}, \
-       {right_keys,      "",          ABC_HTML_ATTR_RIGHT,           ABC_HTML_FLAG_SHOW}, \
+       {position_keys,     "",         ABC_CSS_POSITION,             ABC_HTML_FLAG_SHOW}, \
+       {top_keys,          "",         ABC_CSS_TOP,                  ABC_HTML_FLAG_SHOW}, \
+       {bottom_keys,       "",         ABC_CSS_BOTTOM,               ABC_HTML_FLAG_SHOW}, \
+       {left_keys,         "",         ABC_CSS_LEFT,                 ABC_HTML_FLAG_SHOW}, \
+       {right_keys,        "",         ABC_CSS_RIGHT,                ABC_HTML_FLAG_SHOW}, \
        \
-       {width_keys,      "",          ABC_HTML_ATTR_WIDTH,           ABC_HTML_FLAG_SHOW}, \
-       {height_keys,     "",          ABC_HTML_ATTR_HEIGHT,          ABC_HTML_FLAG_SHOW},
+       {width_keys,        "",         ABC_HTML_ATTR_WIDTH,          ABC_HTML_FLAG_SHOW}, \
+       {height_keys,       "",         ABC_HTML_ATTR_HEIGHT,         ABC_HTML_FLAG_SHOW},
 
 #define ABC_CSS_SELECTOR() \
-       {style_keys,       "",         ABC_HTML_ATTR_STYLE,           ABC_HTML_FLAG_SHOW}, \
-       {class_keys,       "",         ABC_HTML_ATTR_CLASS,           ABC_HTML_FLAG_SHOW}, \
-       {id_keys,          "",         ABC_HTML_ATTR_ID,              ABC_HTML_FLAG_SHOW},
+       {style_keys,        "",         ABC_HTML_ATTR_STYLE,          ABC_HTML_FLAG_SHOW}, \
+       {class_keys,        "",         ABC_HTML_ATTR_CLASS,          ABC_HTML_FLAG_SHOW}, \
+       {id_keys,           "",         ABC_HTML_ATTR_ID,             ABC_HTML_FLAG_SHOW},
 
 #define ABC_CSS_BACK_GROUND(color) \
-       {bg_keys,          "",         ABC_HTML_ATTR_BG,              ABC_HTML_FLAG_SHOW}, \
-       {bg_color_keys,   #color,      ABC_HTML_ATTR_BG_COLOR,        ABC_HTML_FLAG_SHOW}, \
-       {bg_image_keys,    "",         ABC_HTML_ATTR_BG_IMAGE,        ABC_HTML_FLAG_SHOW}, \
-       {bg_repeat_keys,   "",         ABC_HTML_ATTR_BG_REPEAT,       ABC_HTML_FLAG_SHOW}, \
-       {bg_position_keys, "",         ABC_HTML_ATTR_BG_POSITION,     ABC_HTML_FLAG_SHOW},
+       {bg_keys,           "",         ABC_HTML_ATTR_BG,             ABC_HTML_FLAG_SHOW}, \
+       {bg_color_keys,    #color,      ABC_HTML_ATTR_BG_COLOR,       ABC_HTML_FLAG_SHOW}, \
+       {bg_image_keys,     "",         ABC_HTML_ATTR_BG_IMAGE,       ABC_HTML_FLAG_SHOW}, \
+       {bg_repeat_keys,    "",         ABC_HTML_ATTR_BG_REPEAT,      ABC_HTML_FLAG_SHOW}, \
+       {bg_position_keys,  "",         ABC_HTML_ATTR_BG_POSITION,    ABC_HTML_FLAG_SHOW},
 
 #define ABC_CSS_FONT(font, size, color, style) \
-       {font_keys,        #font,      ABC_HTML_ATTR_FONT,            0}, \
-       {font_size_keys,   #size,      ABC_HTML_ATTR_FONT_SIZE,       0}, \
-       {font_color_keys,  #color,     ABC_HTML_ATTR_FONT_COLOR,      ABC_HTML_FLAG_SHOW}, \
-       {font_style_keys,  #style,     ABC_HTML_ATTR_FONT_STYLE,      0},
+       {font_keys,        #font,       ABC_HTML_ATTR_FONT,           0}, \
+       {font_size_keys,   #size,       ABC_HTML_ATTR_FONT_SIZE,      0}, \
+       {font_color_keys,  #color,      ABC_HTML_ATTR_FONT_COLOR,     ABC_HTML_FLAG_SHOW}, \
+       {font_style_keys,  #style,      ABC_HTML_ATTR_FONT_STYLE,     0},
 
 #define ABC_CSS_TEXT(align, underline) \
        {text_align_keys,      #align,      ABC_HTML_ATTR_TEXT_ALIGN,      ABC_HTML_FLAG_SHOW}, \
index 617cff4db1a9e0135cc3ac4a7c81711fb863a5cb..4180674294efac3a8fa3a5d2027571deb8a4da3d 100644 (file)
@@ -57,7 +57,7 @@ int  abc_css_active(abc_obj_t*  obj);
 
 int  abc_css_bg_position(float*  x, float*  y, float   w, float h, abc_obj_t* obj, const uint8_t* str);
 
-int  abc_css_color (double* r, double* g, double* b, const uint8_t* str);
+int  abc_css_color (double* r, double* g, double* b, const uint8_t* str, size_t len);
 int  abc_css_border(double* r, double* g, double* b, int* width, int* type, abc_obj_t* obj, const uint8_t* str);
 int  abc_css_margin(abc_obj_t* obj);
 int  abc_css_length(abc_obj_t* obj, const uint8_t* str, int len);
@@ -66,5 +66,8 @@ int  abc_css_width (abc_obj_t* obj, int width,  int margin);
 int  abc_css_height(abc_obj_t* obj, int height, int margin);
 
 int  abc_css_position(const uint8_t* str);
+int  abc_css_overflow(const uint8_t* str);
+
+void abc_overflow_show(int* x, int* y, int* w, int* h, int mask_x, int mask_y, int mask_w, int mask_h);
 
 #endif
index b4553575097f0ea587e7ab06fbc848cf90d16d47..ea0c89a61c323b110ebaaf98b522b93827e46600 100644 (file)
@@ -64,6 +64,21 @@ void abc_obj_free(abc_obj_t* obj)
        }
 }
 
+void abc_dfs_update_xy(abc_obj_t* root, int dx, int dy)
+{
+       scf_list_t*  l;
+       abc_obj_t*   obj;
+
+       for (l  = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) {
+               obj = scf_list_data(l, abc_obj_t, list);
+
+               obj->x += dx;
+               obj->y += dy;
+
+               abc_dfs_update_xy(obj, dx, dy);
+       }
+}
+
 abc_obj_t* abc_obj_find(abc_obj_t* root, int x, int y)
 {
        scf_list_t* l;
index c63fb660fd62b7fcfcf8bc942132195432f05844..f2d57150036e861d5be5d948bb954cc9bdea4a5a 100644 (file)
@@ -113,14 +113,6 @@ enum abc_objs
        ABC_HTML_ATTR_BORDER,
        ABC_HTML_ATTR_PADDING,
 
-       ABC_HTML_ATTR_POSITION,
-       ABC_HTML_ATTR_TOP,
-       ABC_HTML_ATTR_BOTTOM,
-       ABC_HTML_ATTR_LEFT,
-       ABC_HTML_ATTR_RIGHT,
-
-       ABC_HTML_ATTR_OVERFLOW,
-
        ABC_HTML_ATTR_XMLNS,
        ABC_HTML_ATTR_XMLANG,
        ABC_HTML_ATTR_LANG,
@@ -141,6 +133,16 @@ enum abc_objs
 
        ABC_CSS_BORDER_COLLAPSE,
 
+       ABC_CSS_POSITION,
+       ABC_CSS_TOP,
+       ABC_CSS_BOTTOM,
+       ABC_CSS_LEFT,
+       ABC_CSS_RIGHT,
+
+       ABC_CSS_OVERFLOW,
+       ABC_CSS_SCROLLBAR_WIDTH,
+       ABC_CSS_SCROLLBAR_COLOR,
+
        // css pse class (element)
        ABC_CSS_FIRST_CHILD,
 
@@ -163,8 +165,6 @@ enum abc_objs
        // css selectors from html attrs above
        ABC_CSS_ID       = ABC_HTML_ATTR_ID,
        ABC_CSS_CLASS    = ABC_HTML_ATTR_CLASS,
-       ABC_CSS_POSITION = ABC_HTML_ATTR_POSITION,
-       ABC_CSS_OVERFLOW = ABC_HTML_ATTR_OVERFLOW,
 };
 
 enum abc_border_style
@@ -174,6 +174,14 @@ enum abc_border_style
        ABC_BORDER_DASHED,
 };
 
+enum abc_line_style
+{
+       ABC_LINE_NONE,
+       ABC_LINE_UNDER,
+       ABC_LINE_OVER,
+       ABC_LINE_THROUGH,
+};
+
 enum abc_position_style
 {
        ABC_POSITION_STATIC,
@@ -183,12 +191,12 @@ enum abc_position_style
        ABC_POSITION_STICKY,
 };
 
-enum abc_line_style
+enum abc_overflow_style
 {
-       ABC_LINE_NONE,
-       ABC_LINE_UNDER,
-       ABC_LINE_OVER,
-       ABC_LINE_THROUGH,
+       ABC_OVERFLOW_VISIBLE,
+       ABC_OVERFLOW_HIDDEN,
+       ABC_OVERFLOW_SCROLL,
+       ABC_OVERFLOW_AUTO,
 };
 
 struct abc_text_s
@@ -255,6 +263,23 @@ struct abc_obj_s
        int             w;
        int             h;
 
+       int             overflow_type;
+       // view area that object can see
+       int             view_x;
+       int             view_y;
+       int             view_w;
+       int             view_h;
+
+       int             mouse_down_x;
+       int             mouse_down_y;
+       int             mouse_move_x;
+       int             mouse_move_y;
+
+       int             scroll_x;
+       int             scroll_y;
+       int             content_w;
+       int             content_h;
+
        double          y_bearing;
        int             margin;
        int             padding;
@@ -298,11 +323,12 @@ abc_obj_t*     abc_obj_find_attr(abc_obj_t* obj, int key);
 
 abc_obj_t*     abc_obj_find_type(abc_obj_t* root, int type);
 
+void           abc_dfs_update_xy(abc_obj_t* root, int dx, int dy);
+
 scf_string_t*  abc_obj_to_string(abc_obj_t* obj);
 
 scf_string_t*  abc_ol_list_style(abc_obj_t* obj, int num);
 
-
 static inline abc_obj_t* abc_obj_get_attr(abc_obj_t* obj, int key)
 {
        if (key < ABC_HTML_ATTR_ID || key >= ABC_HTML_CSS_NB)
index 78042e23d3f817ca5df4e467f2809fc6d1463df5..e7567f98b39d8969bb48e5210281cd34d6b5b843 100644 (file)
@@ -1,9 +1,6 @@
 CFILES += main.c
 
 CFILES += abc_layout.c
-CFILES += abc_layout_html.c
-CFILES += abc_layout_title.c
-CFILES += abc_layout_head.c
 CFILES += abc_layout_body.c
 CFILES += abc_layout_div.c
 
@@ -21,9 +18,6 @@ CFILES += abc_layout_video.c
 CFILES += abc_layout_audio.c
 
 CFILES += abc_render.c
-CFILES += abc_render_html.c
-CFILES += abc_render_title.c
-CFILES += abc_render_head.c
 CFILES += abc_render_body.c
 
 CFILES += __render_border.c
index 84375cea54bd539830668eb4e4ed7b76771489cb..eab0589e7921d0635ecc34215715d3c37fa5bdcb 100644 (file)
@@ -102,7 +102,7 @@ static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int widt
        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);
+               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
 
        if (0 == program)
                __init_program(&program, vert_shader, frag_shader);
@@ -210,6 +210,9 @@ static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int widt
        glBindBuffer   (GL_ARRAY_BUFFER, buffers[0]);
        glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
 
+       glBindBuffer   (GL_ARRAY_BUFFER, buffers[1]);
+       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_array), texture_array);
+
        glBindVertexArray(vao);
 
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
index e52787af76edb88034b154aa37d5c1ff93227818..125d9d852424c4b15a9dfa323f337a7d027cd4e0 100644 (file)
@@ -19,13 +19,43 @@ static const char* frag_shader =
        "uniform float y_border; \n"
        "uniform vec4  color; \n"
        "uniform vec4  bgColor; \n"
+       "\n"
+       "uniform vec4  thumbColor; \n"
+       "uniform vec4  trackColor; \n"
+       "uniform vec2  wh; \n"
+       "uniform float w_scroll; \n"
+       "uniform float scroll_y; \n"
+       "uniform float scroll_h; \n"
+       "vec4 yScrollColor(float center, float L, float R, float dR, float y, float dx) { \n"
+       "    if (y < center - L + R) { \n"
+       "        float dy = center - L + R - y; \n"
+       "        float r  = sqrt(dx * dx + dy * dy); \n"
+       "        float beta = smoothstep(R - dR, R + dR, r); \n"
+       "        return mix(thumbColor, trackColor, beta); \n"
+       "    } else if (y > center + L - R) { \n"
+       "        float dy = center + L - R - y; \n"
+       "        float r  = sqrt(dx * dx + dy * dy); \n"
+       "        float beta = smoothstep(R - dR, R + dR, r); \n"
+       "        return mix(thumbColor, trackColor, beta); \n"
+       "    } else { \n"
+       "        return thumbColor; \n"
+       "    } \n"
+       "    return trackColor; \n"
+       "} \n"
        "void main() { \n"
        "    float x = v_texCoord.x; \n"
        "    float y = v_texCoord.y; \n"
+       "    float aspect = wh.x / wh.y; \n"
        "    if ((x >= 0.0 && x <= x_border) || (x >= 1.0 - x_border && x <= 1.0)) { \n"
        "        outputColor = color; \n"
        "    } else if ((y >= 0.0 && y <= y_border) || (y >= 1.0 - y_border && y <= 1.0)) { \n"
        "        outputColor = color; \n"
+       "    } else if (x > 1.0 - x_border - w_scroll && x < 1.0 - x_border) { \n"
+       "        float R  = w_scroll / 2.0; \n"
+       "        float L  = scroll_h / 2.0; \n"
+       "        float dx = 1.0 - x_border - x - R; \n"
+       "        float dR = 1.0 / wh.y; \n"
+       "        outputColor = yScrollColor(scroll_y, L, R * aspect, dR, y, dx * aspect); \n"
        "    } else { \n"
        "        outputColor = bgColor; \n"
        "    } \n"
@@ -43,6 +73,13 @@ static GLuint uniform_y_border;
 static GLuint uniform_color;
 static GLuint uniform_bgColor;
 
+static GLuint uniform_thumbColor;
+static GLuint uniform_trackColor;
+
+static GLuint uniform_wh;
+static GLuint uniform_w_scroll;
+static GLuint uniform_scroll_y;
+static GLuint uniform_scroll_h;
 
 static int __render_fini_border(abc_render_t* render)
 {
@@ -61,32 +98,26 @@ static int __render_draw_border(abc_render_t* render, abc_obj_t* obj, int width,
        int border = 0;
        int border_type = ABC_BORDER_SOLID;
 
-       double r0 = 0.0;
-       double g0 = 0.0;
-       double b0 = 0.0;
-
-       double r1 = 0.0;
-       double g1 = 0.0;
-       double b1 = 0.0;
-       double a1 = 0.0;
+       double fgColor[3] = {0.0, 0.0, 0.0};
+       double bgColor[4] = {0.0, 0.0, 0.0, 0.0};
 
        abc_obj_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_COLOR);
        if (attr && attr->value->len > 0) {
-               a1 = 1.0;
-               abc_css_color(&r1, &g1, &b1, attr->value->data);
+               bgColor[4] = 1.0;
+               abc_css_color(bgColor, bgColor + 1, bgColor + 2, attr->value->data, attr->value->len);
        }
 
-       attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_MARGIN);
+       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_MARGIN);
        if (attr)
                margin = atoi(attr->value->data);
 
-       attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BORDER);
+       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BORDER);
        if (attr)
-               abc_css_border(&r0, &g0, &b0, &border, &border_type, obj, attr->value->data);
+               abc_css_border(fgColor, fgColor + 1, fgColor + 2, &border, &border_type, obj, attr->value->data);
        else {
                attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
                if (attr)
-                       abc_css_color(&r0, &g0, &b0, attr->value->data);
+                       abc_css_color(fgColor, fgColor + 1, fgColor + 2, attr->value->data, attr->value->len);
        }
 
        int x = obj->x + margin;
@@ -94,27 +125,165 @@ static int __render_draw_border(abc_render_t* render, abc_obj_t* obj, int width,
        int w = obj->w - margin * 2;
        int h = obj->h - margin * 2;
 
+       obj->view_x = x;
+       obj->view_y = y;
+       obj->view_w = w;
+       obj->view_h = h;
+
+       abc_obj_t* parent = obj->parent;
+
+       if (parent && (x < parent->view_x
+                               || y < parent->view_y
+                               || x + w > parent->view_x + parent->view_w
+                               || y + h > parent->view_y + parent->view_h)) {
+
+               attr = abc_obj_find_attr(obj, ABC_CSS_OVERFLOW);
+               if (attr)
+                       obj->overflow_type = abc_css_overflow(attr->value->data);
+
+               switch (obj->overflow_type)
+               {
+                       case ABC_OVERFLOW_HIDDEN:
+                               abc_overflow_show(&obj->view_x, &obj->view_y, &obj->view_w, &obj->view_h,
+                                               parent->view_x,
+                                               parent->view_y, parent->view_w, parent->view_h);
+
+                               scf_logw("x: %d, y: %d, w: %d, h: %d, obj: x: %d, y: %d, w: %d, h: %d, parent: x: %d, y: %d, w: %d, h: %d\n",
+                                               x, y, w, h,
+                                               obj->view_x,    obj->view_y,    obj->view_w,    obj->view_h,
+                                               parent->view_x, parent->view_y, parent->view_w, parent->view_h);
+                               break;
+                       case ABC_OVERFLOW_SCROLL:
+                               break;
+                       default:
+                               break;
+               };
+       }
+
        float mvp[16];
        __compute_mvp(mvp, 0, 0, 0);
 
        GLfloat vert_update[] =
        {
-                2.0 *  x      / (float)width  - 1.0,
-               -2.0 * (y + h) / (float)height + 1.0,
+                2.0 *  obj->view_x                / (float)width  - 1.0,
+               -2.0 * (obj->view_y + obj->view_h) / (float)height + 1.0,
 
-                2.0 * (x + w) / (float)width  - 1.0,
-               -2.0 * (y + h) / (float)height + 1.0,
+                2.0 * (obj->view_x + obj->view_w) / (float)width  - 1.0,
+               -2.0 * (obj->view_y + obj->view_h) / (float)height + 1.0,
 
-                2.0 *  x      / (float)width  - 1.0,
-               -2.0 *  y      / (float)height + 1.0,
+                2.0 *  obj->view_x                / (float)width  - 1.0,
+               -2.0 *  obj->view_y                / (float)height + 1.0,
 
-                2.0 * (x + w) / (float)width  - 1.0,
-               -2.0 *  y      / (float)height + 1.0,
+                2.0 * (obj->view_x + obj->view_w) / (float)width  - 1.0,
+               -2.0 *  obj->view_y                / (float)height + 1.0,
+       };
+
+       GLfloat texture_update[] =
+       {
+               (obj->view_x - x)               / (float)w,
+               (obj->view_y + obj->view_h - y) / (float)h,
+
+               (obj->view_x + obj->view_w - x) / (float)w,
+               (obj->view_y + obj->view_h - y) / (float)h,
+
+               (obj->view_x - x)               / (float)w,
+               (obj->view_y - y)               / (float)h,
+
+               (obj->view_x + obj->view_w - x) / (float)w,
+               (obj->view_y - y)               / (float)h,
        };
 
        GLfloat x_border = border / (float)w;
        GLfloat y_border = border / (float)h;
 
+       if (ABC_OVERFLOW_HIDDEN == obj->overflow_type) {
+               for (int i = 0; i < sizeof(texture_update) / sizeof(texture_update[0]) / 2; i++)
+                       scf_logi("%lg, %lg\n", texture_update[2 * i], texture_update[2 * i + 1]);
+
+               printf(" x_border: %lg, y_border: %lg\n\n", x_border, y_border);
+       }
+
+       GLfloat aspect   = w / (float)h;
+       GLfloat w_scroll = 0.0;
+       GLfloat scroll_y = 0.0;
+       GLfloat scroll_h = 0.0;
+
+       double thumbColor[4] = {bgColor[0], bgColor[1], bgColor[2], bgColor[3]};
+       double trackColor[4] = {bgColor[0], bgColor[1], bgColor[2], bgColor[3]};
+
+       if (obj->content_h > obj->h)
+       {
+               float percent = h / (float)obj->content_h;
+               int   len     = h * percent;
+               int   range   = h - len;
+               int   min     = len / 2;
+               int   max     = h - min;
+
+               if (obj->scroll_y < min)
+                       obj->scroll_y = min;
+               if (obj->scroll_y > max)
+                       obj->scroll_y = max;
+
+               w_scroll = 25.0;
+
+               attr = abc_obj_get_attr(obj, ABC_CSS_SCROLLBAR_WIDTH);
+               if (attr && attr->value->len > 0)
+                       w_scroll = atof(attr->value->data);
+
+               attr = abc_obj_get_attr(obj, ABC_CSS_SCROLLBAR_COLOR);
+               if (attr && attr->value->len > 0) {
+                       thumbColor[3] = 1.0;
+                       trackColor[3] = 1.0;
+                       abc_css_scrollbar_color(thumbColor, trackColor, attr->value->data);
+               } else {
+                       thumbColor[0] = 1.0;
+                       thumbColor[1] = 0.27;
+                       thumbColor[2] = 0.0;
+                       thumbColor[3] = 1.0;
+               }
+
+               scf_logi("obj mouse_down_x: %d, mouse_down_y: %d, mouse_move_x: %d, mouse_move_y: %d, x: %d, y: %d, x+w: %d, y+h: %d\n",
+                               obj->mouse_down_x,
+                               obj->mouse_down_x, obj->mouse_move_x, obj->mouse_move_y,
+                               x, y, x + w, y + h);
+
+               int dy = 0;
+               if (obj->mouse_move_x > x + w - w_scroll
+                               && obj->mouse_move_x < x + w
+                               && obj->mouse_move_y > y
+                               && obj->mouse_move_y < y + h) {
+
+                       if (obj->mouse_down_x > x + w - w_scroll
+                                       && obj->mouse_down_x < x + w
+                                       && obj->mouse_down_y > y
+                                       && obj->mouse_down_y < y + h) {
+
+                               dy = obj->mouse_move_y - obj->mouse_down_y;
+                               if (dy < min - obj->scroll_y)
+                                       dy = min - obj->scroll_y;
+                               if (dy > max - obj->scroll_y)
+                                       dy = max - obj->scroll_y;
+
+                               assert(dy >= -range && dy <= range);
+
+                               obj->scroll_y += dy;
+                       }
+               }
+
+               dy = -(obj->scroll_y - min) * (obj->content_h - obj->h) / range;
+
+               abc_dfs_update_xy(obj, 0, dy);
+
+               scroll_h = percent;
+               scroll_y = obj->scroll_y / (float)h;
+
+               w_scroll /= (float)w;
+               if (w_scroll > scroll_h / aspect)
+                       w_scroll = scroll_h / aspect;
+
+               scf_logi("aspect: %lg, w_scroll: %lg, scroll_y: %lg, scroll_h: %lg\n\n", aspect, w_scroll, scroll_y, scroll_h);
+       }
+
        glUseProgram(program);
        uniform_mvp      = glGetUniformLocation(program, "mvp");
        uniform_x_border = glGetUniformLocation(program, "x_border");
@@ -122,17 +291,36 @@ static int __render_draw_border(abc_render_t* render, abc_obj_t* obj, int width,
        uniform_color    = glGetUniformLocation(program, "color");
        uniform_bgColor  = glGetUniformLocation(program, "bgColor");
 
+       uniform_thumbColor = glGetUniformLocation(program, "thumbColor");
+       uniform_trackColor = glGetUniformLocation(program, "trackColor");
+
+       uniform_wh         = glGetUniformLocation(program, "wh");
+       uniform_scroll_y   = glGetUniformLocation(program, "scroll_y");
+       uniform_scroll_h   = glGetUniformLocation(program, "scroll_h");
+       uniform_w_scroll   = glGetUniformLocation(program, "w_scroll");
+
        glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
 
        glUniform1f(uniform_x_border, x_border);
        glUniform1f(uniform_y_border, y_border);
-       glUniform4f(uniform_color,    r0, g0, b0, 1.0);
-       glUniform4f(uniform_bgColor,  r1, g1, b1, a1);
+       glUniform4f(uniform_color,    fgColor[0], fgColor[1], fgColor[2], 1.0);
+       glUniform4f(uniform_bgColor,  bgColor[0], bgColor[1], bgColor[2], bgColor[3]);
+
+       glUniform4f(uniform_thumbColor, thumbColor[0], thumbColor[1], thumbColor[2], thumbColor[3]);
+       glUniform4f(uniform_trackColor, trackColor[0], trackColor[1], trackColor[2], trackColor[3]);
+
+       glUniform2f(uniform_wh,       (GLfloat)w, (GLfloat)h);
+       glUniform1f(uniform_scroll_y, scroll_y);
+       glUniform1f(uniform_scroll_h, scroll_h);
+       glUniform1f(uniform_w_scroll, w_scroll);
 
        // draw
        glBindBuffer   (GL_ARRAY_BUFFER, buffers[0]);
        glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
 
+       glBindBuffer   (GL_ARRAY_BUFFER, buffers[1]);
+       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_update), texture_update);
+
        glBindVertexArray(vao);
 
        glEnable(GL_BLEND);
index 609e4bc09f5719e45d52253436895bbcdf745597..ee2514a8b8eda77970c8375b8c37d351aa237a54 100644 (file)
@@ -108,7 +108,7 @@ int __init_text(cairo_t* cr, abc_obj_t* obj, int num_flag)
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
-               abc_css_color(&r, &g, &b, attr->value->data);
+               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
 
        cairo_set_font_size  (cr, size);
        cairo_set_source_rgba(cr, r, g, b, 1.0);
@@ -175,7 +175,7 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i
        if (obj->w <= 0 || obj->h <= 0)
                return 0;
 
-       int d = abc_css_margin(obj);
+       int d = obj->d;
        int x = obj->x + d;
        int y = obj->y + d;
        int w = obj->w - d * 2;
@@ -205,7 +205,7 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i
        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);
+               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
 
        surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w, h, w * 4);
        cr      = cairo_create(surface);
@@ -225,6 +225,22 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i
        surface = NULL;
        cr = NULL;
 
+       int view_x = x;
+       int view_y = y;
+       int view_w = w;
+       int view_h = h;
+
+       switch (obj->overflow_type)
+       {
+               case ABC_OVERFLOW_HIDDEN:
+                       abc_overflow_show(&view_x, &view_y, &view_w, &view_h,
+                                       obj->view_x,
+                                       obj->view_y, obj->view_w, obj->view_h);
+                       break;
+               default:
+                       break;
+       };
+
        float mvp[16];
        __compute_mvp(mvp, 0, 0, 0);
 
@@ -232,17 +248,32 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i
 
        GLfloat vert_update[] =
        {
-                2.0 *  x      / (float)width  - 1.0,
-               -2.0 * (y + h) / (float)height + 1.0,
+                2.0 *  view_x           / (float)width  - 1.0,
+               -2.0 * (view_y + view_h) / (float)height + 1.0,
 
-                2.0 * (x + w) / (float)width  - 1.0,
-               -2.0 * (y + h) / (float)height + 1.0,
+                2.0 * (view_x + view_w) / (float)width  - 1.0,
+               -2.0 * (view_y + view_h) / (float)height + 1.0,
 
-                2.0 *  x      / (float)width  - 1.0,
-               -2.0 *  y      / (float)height + 1.0,
+                2.0 *  view_x           / (float)width  - 1.0,
+               -2.0 *  view_y           / (float)height + 1.0,
 
-                2.0 * (x + w) / (float)width  - 1.0,
-               -2.0 *  y      / (float)height + 1.0,
+                2.0 * (view_x + view_w) / (float)width  - 1.0,
+               -2.0 *  view_y           / (float)height + 1.0,
+       };
+
+       GLfloat texture_update[] =
+       {
+               (view_x - x)          / (float)w,
+               (view_y + view_h - y) / (float)h,
+
+               (view_x + view_w - x) / (float)w,
+               (view_y + view_h - y) / (float)h,
+
+               (view_x - x)          / (float)w,
+               (view_y - y)          / (float)h,
+
+               (view_x + view_w - x) / (float)w,
+               (view_y - y)          / (float)h,
        };
 
        glUseProgram(program);
@@ -261,6 +292,9 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i
        glBindBuffer   (GL_ARRAY_BUFFER, buffers[0]);
        glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
 
+       glBindBuffer   (GL_ARRAY_BUFFER, buffers[1]);
+       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_update), texture_update);
+
        glBindVertexArray(vao);
 
        glEnable(GL_BLEND);
index 3528b7822b7903686f31608c5fb57964d037a818..de78ad1ddc43f6778724443726bf9f16e455f449 100644 (file)
@@ -1,8 +1,5 @@
 #include"abc.h"
 
-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_text(abc_layout_t* layout, abc_obj_t* obj, int width, int height);
@@ -28,10 +25,10 @@ int abc_layout_empty(abc_layout_t* layout, abc_obj_t* obj, int width, int height
 
 static abc_layout_pt abc_layouts[ABC_HTML_NB] =
 {
-       [ABC_HTML]          = abc_layout_html,
-       [ABC_HTML_TITLE]    = abc_layout_title,
+       [ABC_HTML]          = abc_layout_empty,
+       [ABC_HTML_TITLE]    = abc_layout_empty,
        [ABC_HTML_META]     = abc_layout_empty,
-       [ABC_HTML_HEAD]     = abc_layout_head,
+       [ABC_HTML_HEAD]     = abc_layout_empty,
        [ABC_HTML_BODY]     = abc_layout_body,
        [ABC_HTML_DIV]      = abc_layout_div,
 
@@ -89,21 +86,6 @@ int abc_layout_obj(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
        return f(layout, obj, width, height);
 }
 
-void abc_css_update_xy(abc_obj_t* root, int dx, int dy)
-{
-       scf_list_t*  l;
-       abc_obj_t*   obj;
-
-       for (l  = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) {
-               obj = scf_list_data(l, abc_obj_t, list);
-
-               obj->x += dx;
-               obj->y += dy;
-
-               abc_css_update_xy(obj, dx, dy);
-       }
-}
-
 #define LAYOUT_POS_FIXED(X, W, SET, L, R) \
        do { \
                if (!obj->SET) { \
@@ -132,7 +114,7 @@ void abc_css_update_xy(abc_obj_t* root, int dx, int dy)
        do { \
                abc_obj_t* tmp = parent; \
                while (tmp && ABC_HTML != tmp->type) { \
-                       abc_obj_t* attr = abc_obj_get_attr(tmp, ABC_HTML_ATTR_POSITION); \
+                       abc_obj_t* attr = abc_obj_get_attr(tmp, ABC_CSS_POSITION); \
                        \
                        if (attr && attr->value->len > 0 \
                                        && __html_strcmp(attr->value->data, "static")) \
@@ -175,10 +157,10 @@ int abc_layout_css(abc_obj_t* obj)
                else if (!__html_strcmp(attr->value->data, "right"))
                        obj->x = parent->x + parent->w - obj->w - 8;
 
-               abc_css_update_xy(obj, obj->x - x, 0);
+               abc_dfs_update_xy(obj, obj->x - x, 0);
        }
 
-       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_POSITION);
+       attr = abc_obj_get_attr(obj, ABC_CSS_POSITION);
        if (!attr || 0 == attr->value->len)
                return 0;
 
@@ -191,19 +173,19 @@ int abc_layout_css(abc_obj_t* obj)
        int left   = 0;
        int right  = 0;
 
-       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TOP);
+       attr = abc_obj_get_attr(obj, ABC_CSS_TOP);
        if (attr)
                top = abc_css_length(obj, attr->value->data, obj->h);
 
-       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BOTTOM);
+       attr = abc_obj_get_attr(obj, ABC_CSS_BOTTOM);
        if (attr)
                bottom = abc_css_length(obj, attr->value->data, obj->h);
 
-       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_LEFT);
+       attr = abc_obj_get_attr(obj, ABC_CSS_LEFT);
        if (attr)
                left = abc_css_length(obj, attr->value->data, obj->w);
 
-       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_RIGHT);
+       attr = abc_obj_get_attr(obj, ABC_CSS_RIGHT);
        if (attr)
                right = abc_css_length(obj, attr->value->data, obj->w);
 
@@ -231,7 +213,7 @@ int abc_layout_css(abc_obj_t* obj)
                        break;
        };
 
-       abc_css_update_xy(obj, obj->x - x, obj->y - y);
+       abc_dfs_update_xy(obj, obj->x - x, obj->y - y);
 
        return pos_type;
 }
@@ -291,6 +273,8 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                        break;
        };
 
+       root->overflow_type = ABC_OVERFLOW_VISIBLE;
+
        scf_list_t*  l;
        abc_obj_t*   child;
 
@@ -419,15 +403,19 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
        if (root->h < Y - root->y)
                root->h = Y - root->y;
 
+       root->content_w = root->w;
+       root->content_h = root->h;
+
        int ret = abc_layout_obj(NULL, root, width, height);
        if (ret < 0)
                return ret;
 #if 0
        if (root->keys)
                scf_logw("key: %s, ", root->keys[0]);
-       if (root->text)
-               printf("%s, ", root->text->data);
-       printf("x: %d, y: %d, w: %d, h: %d\n", root->x, root->y, root->w, root->h);
+//     if (root->text)
+//             printf("%s, ", root->text->data);
+       printf("x: %d, y: %d, w: %d, h: %d, content_w: %d, content_h: %d: %d\n",
+                       root->x, root->y, root->w, root->h, root->content_w, root->content_h, root->content_h - root->d * 2);
 #endif
        return 0;
 }
diff --git a/ui/abc_layout_head.c b/ui/abc_layout_head.c
deleted file mode 100644 (file)
index cb4d6c2..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#include"abc.h"
-
-int abc_layout_head(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
-{
-       return 0;
-}
diff --git a/ui/abc_layout_html.c b/ui/abc_layout_html.c
deleted file mode 100644 (file)
index 4615d4a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#include"abc.h"
-
-int abc_layout_html(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
-{
-       return 0;
-}
index e240c6b72ff7a1143583abb4f2729380c239e3a8..23a727e3586ea00b42237c650b5c193dc82a7081 100644 (file)
@@ -10,7 +10,7 @@ int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height
 
        int collapse = 0;
 
-       attr = abc_obj_find_attr(obj, ABC_CSS_BORDER_COLLAPSE);
+       attr = abc_obj_get_attr(obj, ABC_CSS_BORDER_COLLAPSE);
        if (attr) {
                if (!__html_strcmp(attr->value->data, "collapse")) {
                        collapse = 1;
@@ -18,7 +18,7 @@ int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height
                }
        }
 
-       int d     = abc_css_margin(obj);
+       int d     = obj->d;
        int w_set = abc_css_width (obj, width,  d);
        int h_set = abc_css_height(obj, height, d);
 
diff --git a/ui/abc_layout_title.c b/ui/abc_layout_title.c
deleted file mode 100644 (file)
index 35e1965..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#include"abc.h"
-
-int abc_layout_title(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
-{
-       return 0;
-}
index 961f059b0cf2a8857ed807a7e344ae4a68876574..a8e375c1f7e175776ed67f1f79a5801e1b1c5700 100644 (file)
@@ -1,8 +1,5 @@
 #include"abc.h"
 
-extern abc_render_t  abc_render_html;
-extern abc_render_t  abc_render_title;
-extern abc_render_t  abc_render_head;
 extern abc_render_t  abc_render_body;
 extern abc_render_t  abc_render_text;
 
@@ -30,7 +27,7 @@ static abc_render_t* abc_renders[ABC_HTML_NB] =
        [ABC_HTML]          = &abc_render_empty,
        [ABC_HTML_HEAD]     = &abc_render_empty,
        [ABC_HTML_META]     = &abc_render_empty,
-       [ABC_HTML_TITLE]    = &abc_render_title,
+       [ABC_HTML_TITLE]    = &abc_render_empty,
        [ABC_HTML_BODY]     = &abc_render_body,
        [ABC_HTML_DIV]      = &abc_render_body,
 
diff --git a/ui/abc_render_div.c b/ui/abc_render_div.c
deleted file mode 100644 (file)
index 5768b28..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#include"abc.h"
-
-static int _render_fini_div(abc_render_t* render)
-{
-       return 0;
-}
-
-static int _render_draw_div(abc_render_t* render, abc_obj_t* obj, int width, int height)
-{
-       return 0;
-}
-
-abc_render_t  abc_render_div =
-{
-       .type = ABC_HTML_H1,
-
-       .draw = _render_draw_div,
-       .fini = _render_fini_div,
-};
diff --git a/ui/abc_render_head.c b/ui/abc_render_head.c
deleted file mode 100644 (file)
index cef9af5..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#include"abc.h"
-
-static int _render_fini_head(abc_render_t* render)
-{
-       return 0;
-}
-
-static int _render_draw_head(abc_render_t* render, abc_obj_t* obj, int width, int height)
-{
-       return 0;
-}
-
-abc_render_t  abc_render_head =
-{
-       .type = ABC_HTML_H1,
-
-       .draw = _render_draw_head,
-       .fini = _render_fini_head,
-};
diff --git a/ui/abc_render_html.c b/ui/abc_render_html.c
deleted file mode 100644 (file)
index 37f13ec..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#include"abc.h"
-
-static int _render_fini_html(abc_render_t* render)
-{
-       return 0;
-}
-
-static int _render_draw_html(abc_render_t* render, abc_obj_t* obj, int width, int height)
-{
-       return 0;
-}
-
-abc_render_t  abc_render_html =
-{
-       .type = ABC_HTML_H1,
-
-       .draw = _render_draw_html,
-       .fini = _render_fini_html,
-};
index 138f4af11fa444a7b58417ef47026fbef449c225..ae56b27d45797f219f7e59fa660270547bee209c 100644 (file)
@@ -71,7 +71,7 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
        if (attr)
-               abc_css_color(&r, &g, &b, attr->value->data);
+               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
 
        surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4);
        cr      = cairo_create(surface);
@@ -139,7 +139,7 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int
                        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);
+                               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
 
                        cairo_set_source_rgb(cr, r, g, b);
 
index c9a884092bbe71d54702a4083193401adaf46595..07d91369ea8549bfa48723c7e58b69e55087723c 100644 (file)
@@ -96,7 +96,7 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int
        double b = 1.0;
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
        if (attr)
-               abc_css_color(&r, &g, &b, attr->value->data);
+               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
 
        cairo_set_source_rgb(cr, r, g, b);
        cairo_rectangle(cr, 0, 0, w, h);
@@ -109,7 +109,7 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int
        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);
+               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
 
        cairo_set_source_rgb(cr, r, g, b);
 
index 5c77f91120c382d51162fffabc675e246c35c4c7..dae5e774a4cde3c10413cb8d2035e17200630ce0 100644 (file)
@@ -109,6 +109,9 @@ static int _draw_text_line(abc_obj_t* obj, const char* text,
        glBindBuffer   (GL_ARRAY_BUFFER, buffers[0]);
        glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
 
+       glBindBuffer   (GL_ARRAY_BUFFER, buffers[1]);
+       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_array), texture_array);
+
        glBindVertexArray(vao);
 
        glEnable(GL_BLEND);
@@ -150,11 +153,11 @@ static int _render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, in
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
        if (attr)
-               abc_css_color(bcolor, bcolor + 1, bcolor + 2, attr->value->data);
+               abc_css_color(bcolor, bcolor + 1, bcolor + 2, attr->value->data, attr->value->len);
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
-               abc_css_color(fcolor, fcolor + 1, fcolor + 2, attr->value->data);
+               abc_css_color(fcolor, fcolor + 1, fcolor + 2, attr->value->data, attr->value->len);
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
        if (attr)
diff --git a/ui/abc_render_title.c b/ui/abc_render_title.c
deleted file mode 100644 (file)
index 3c53e7a..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#include"abc.h"
-
-static int _render_fini_title(abc_render_t* render)
-{
-       return 0;
-}
-
-static int _render_draw_title(abc_render_t* render, abc_obj_t* obj, int width, int height)
-{
-       return 0;
-}
-
-abc_render_t  abc_render_title =
-{
-       .type = ABC_HTML_H1,
-
-       .draw = _render_draw_title,
-       .fini = _render_fini_title,
-};
index 2c2f4d3386df2ea94992c21654cf6f4301a27944..104eecae2c6d0e6452debda8561747993266d841 100644 (file)
--- a/ui/main.c
+++ b/ui/main.c
@@ -89,6 +89,18 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
 
                abc_css_active(prev);
 
+               prev->mouse_down_x = -1;
+               prev->mouse_down_y = -1;
+               prev->mouse_move_x = -1;
+               prev->mouse_move_y = -1;
+
+               if (ABC_HTML_DIV == prev->type)
+                       scf_logw("prev: %p mouse down_x: %d, down_y: %d, move_x: %d, move_y: %d\n", prev,
+                                       prev->mouse_down_x,
+                                       prev->mouse_down_y,
+                                       prev->mouse_move_x,
+                                       prev->mouse_move_y);
+
                prev->clicked = 0;
                ret = 1;
        }
@@ -97,6 +109,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);
 
+               int scroll_width = 25;
+
                switch (obj->type)
                {
                        case ABC_HTML_A:
@@ -125,10 +139,31 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
                                        }
                                }
                                break;
+
+                       case ABC_HTML_DIV:
+                               attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TYPE);
+
+                               if (attr && attr->value->len > 0)
+                                       scroll_width = atoi(attr->value->data);
+
+                               if (obj->x + obj->w > scroll_width
+                                               && obj->mouse_move_x > obj->x + obj->w - scroll_width
+                                               && obj->mouse_move_x < obj->x + obj->w
+                                               && obj->mouse_move_y > obj->y
+                                               && obj->mouse_move_y < obj->y + obj->h)
+                                       ret = 1;
+                               break;
                        default:
                                break;
                };
 
+               if (ABC_HTML_DIV == obj->type)
+                       scf_logw("obj: %p, mouse down_x: %d, down_y: %d, move_x: %d, move_y: %d\n", obj,
+                                       obj->mouse_down_x,
+                                       obj->mouse_down_y,
+                                       obj->mouse_move_x,
+                                       obj->mouse_move_y);
+
                obj->css_pse_type = ABC_CSS_HOVER;
 
                ret |= abc_css_active(obj);
@@ -184,6 +219,11 @@ static int __do_button_release(abc_ctx_t* ctx, int x, int y)
        if (!obj)
                return __do_button_move(ctx, x, y);
 
+       obj->mouse_down_x = -1;
+       obj->mouse_down_y = -1;
+       obj->mouse_move_x = -1;
+       obj->mouse_move_y = -1;
+
        obj->visited      = 1;
        obj->css_pse_type = ABC_CSS_VISITED;
 
@@ -341,6 +381,16 @@ static gboolean button_press_event(GtkWidget* self, GdkEventButton* event, gpoin
                abc_obj_t*  css;
 
                if (obj) {
+                       obj->mouse_down_x = event->x;
+                       obj->mouse_down_y = event->y;
+
+                       if (ABC_HTML_DIV == obj->type)
+                               scf_logw("obj: %p mouse down_x: %d, down_y: %d, move_x: %d, move_y: %d\n", obj,
+                                               obj->mouse_down_x,
+                                               obj->mouse_down_y,
+                                               obj->mouse_move_x,
+                                               obj->mouse_move_y);
+
                        obj->css_pse_type = ABC_CSS_ACTIVE;
 
                        if (abc_css_active(obj) > 0)
@@ -405,7 +455,17 @@ static gboolean key_press_event(GtkWidget* self, GdkEventKey* event, gpointer us
 
 static gboolean button_move_event(GtkWidget* self, GdkEventMotion* event, gpointer user_data)
 {
-       abc_ctx_t* ctx  = user_data;
+       abc_ctx_t* ctx = user_data;
+       abc_obj_t* obj;
+
+       if (ctx->current->io.download && ctx->current->root)
+       {
+               obj = abc_obj_find(ctx->current->root, event->x, event->y);
+               if (obj) {
+                       obj->mouse_move_x = event->x;
+                       obj->mouse_move_y = event->y;
+               }
+       }
 
        int ret = __do_button_move(ctx, event->x, event->y);
        if (ret > 0)
@@ -582,8 +642,8 @@ int main(int argc, char *argv[])
 
        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(gl_area,  "key-press-event",      G_CALLBACK(key_press_event),      &ctx);
+       g_signal_connect(window,  "motion-notify-event",  G_CALLBACK(button_move_event),    &ctx);
 
        g_timeout_add(1, timer_handler, &ctx);