css: support 'position sticky, fixed, absolute, relative, static' master
authoryu.dongliang <18588496441@163.com>
Mon, 25 May 2026 13:42:51 +0000 (21:42 +0800)
committeryu.dongliang <18588496441@163.com>
Mon, 25 May 2026 13:42:51 +0000 (21:42 +0800)
examples/padding.html [new file with mode: 0644]
examples/position_sticky.html [new file with mode: 0644]
html/abc_css_length.c
html/abc_html.c
html/abc_obj.c
html/abc_obj.h
ui/abc_layout.c
ui/abc_layout_div.c
ui/abc_render.c
ui/main.c

diff --git a/examples/padding.html b/examples/padding.html
new file mode 100644 (file)
index 0000000..0d84985
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"> 
+<title>菜鸟教程(runoob.com)</title>
+<style>
+p
+{
+       background-color:yellow;
+}
+p.padding
+{
+       padding-top:25px;
+       padding-bottom:25px;
+       padding-right:50px;
+       padding-left:50px;
+}
+</style>
+</head>
+
+<body>
+<p>这是一个没有指定填充边距的段落。</p>
+<p class="padding">这是一个指定填充边距的段落。</p>
+</body>
+
+</html>
diff --git a/examples/position_sticky.html b/examples/position_sticky.html
new file mode 100644 (file)
index 0000000..ecc9df2
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"> 
+<style>
+div.sticky {
+  position: sticky;
+  top: 0;
+  padding: 5px;
+  background-color: #cae8ca;
+  border: 2px solid #4CAF50;
+}
+</style>
+</head>
+<body>
+
+<p>尝试滚动页面。</p>
+<p>注意: IE/Edge 15 及更早 IE 版本不支持 sticky 属性。</p>
+
+<div class="sticky">我是粘性定位!</div>
+
+<div style="padding-bottom:2000px">
+  <p>滚动我</p>
+  <p>来回滚动我</p>
+  <p>滚动我</p>
+  <p>来回滚动我</p>
+  <p>滚动我</p>
+  <p>来回滚动我</p>
+</div>
+
+</body>
+</html>
index 9b1fa6a781fd559c2c4b792322df71bf383d1fce..59b5f5742a56900d0bddb8d020b01e16218aa081 100644 (file)
@@ -71,46 +71,48 @@ next:
 
 int abc_css_width(abc_obj_t* obj, int width)
 {
 
 int abc_css_width(abc_obj_t* obj, int width)
 {
+       obj->left  = obj->margin_left  + obj->border_left  + obj->padding_left;
+       obj->right = obj->margin_right + obj->border_right + obj->padding_right;
+
        abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_WIDTH);
 
        if (attr && attr->value && attr->value->len > 0) {
 
                obj->w  = abc_css_length(obj, width, attr->value->data);
        abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_WIDTH);
 
        if (attr && attr->value && attr->value->len > 0) {
 
                obj->w  = abc_css_length(obj, width, attr->value->data);
-
-               obj->w += obj->margin_left + obj->border_left
-                                              + obj->padding_left
-                                              + obj->padding_right
-                                              + obj->border_right
-                                              + obj->margin_right;
-
-               if (obj->w > width - obj->x)
-                       obj->w = width - obj->x;
+               obj->w += obj->left + obj->right;
                return 1;
        }
 
                return 1;
        }
 
-       obj->w = width - obj->x;
+       if (obj->x + obj->left + obj->right < width)
+               obj->w = width     - obj->x;
+
+       else if (obj->left + obj->right < width)
+               obj->w = width - obj->left - obj->right;
+       else
+               obj->w = width + obj->left + obj->right;
        return 0;
 }
 
 int abc_css_height(abc_obj_t* obj, int height)
 {
        return 0;
 }
 
 int abc_css_height(abc_obj_t* obj, int height)
 {
+       obj->top    = obj->margin_top    + obj->border_top    + obj->padding_top;
+       obj->bottom = obj->margin_bottom + obj->border_bottom + obj->padding_bottom;
+
        abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_HEIGHT);
 
        if (attr && attr->value && attr->value->len > 0) {
 
                obj->h  = abc_css_length(obj, height, attr->value->data);
        abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_HEIGHT);
 
        if (attr && attr->value && attr->value->len > 0) {
 
                obj->h  = abc_css_length(obj, height, attr->value->data);
-
-               obj->h += obj->margin_top + obj->border_top
-                                             + obj->padding_top
-                                             + obj->padding_bottom
-                                             + obj->border_bottom
-                                             + obj->margin_bottom;
-
-               if (obj->h > height - obj->y)
-                       obj->h = height - obj->y;
+               obj->h += obj->top + obj->bottom;
                return 1;
        }
 
                return 1;
        }
 
-       obj->h = height - obj->y;
+       if (obj->y + obj->top + obj->bottom < height)
+               obj->h = height   - obj->y;
+
+       else if (obj->bottom + obj->top < height)
+               obj->h = height  - obj->top - obj->bottom;
+       else
+               obj->h = height + obj->top + obj->bottom;
        return 0;
 }
        return 0;
 }
index beecad4fc6a4db25105ca73ad9b4687a70f8c75b..20bedb21571ccc8df53e30e12fd3b00930b0ba1f 100644 (file)
@@ -148,20 +148,6 @@ static char* css_active_keys[]  = {":active",  "正在点击",  NULL};
 static char* css_first_child_keys[] = {":first-child",  "第1个子元素", "第一个子元素", NULL};
 
 static html_attr_t  html_attrs[] =
 static char* css_first_child_keys[] = {":first-child",  "第1个子元素", "第一个子元素", NULL};
 
 static html_attr_t  html_attrs[] =
-{
-       {xmlns_keys,       "",           ABC_HTML_ATTR_XMLNS,     0},
-       {xmlang_keys,      "",           ABC_HTML_ATTR_XMLANG,    0},
-       {lang_keys,        "",           ABC_HTML_ATTR_LANG,      0},
-};
-
-static html_attr_t  meta_attrs[] =
-{
-       {http_equiv_keys,  "",           ABC_HTML_ATTR_HTTP_EQUIV, ABC_HTML_FLAG_SHOW},
-       {content_keys,     "",           ABC_HTML_ATTR_CONTENT,    ABC_HTML_FLAG_SHOW},
-       {charset_keys,     "",           ABC_HTML_ATTR_CHARSET,    ABC_HTML_FLAG_SHOW},
-};
-
-static html_attr_t  body_attrs[] =
 {
 #define ABC_CSS_BOX(margin, border, padding) \
        {border_keys,         #border,   ABC_CSS_BORDER,              ABC_HTML_FLAG_SHOW}, \
 {
 #define ABC_CSS_BOX(margin, border, padding) \
        {border_keys,         #border,   ABC_CSS_BORDER,              ABC_HTML_FLAG_SHOW}, \
@@ -182,10 +168,6 @@ static html_attr_t  body_attrs[] =
        {padding_left_keys,   #padding,  ABC_CSS_PADDING_LEFT,        ABC_HTML_FLAG_SHOW}, \
        {padding_right_keys,  #padding,  ABC_CSS_PADDING_RIGHT,       ABC_HTML_FLAG_SHOW}, \
        \
        {padding_left_keys,   #padding,  ABC_CSS_PADDING_LEFT,        ABC_HTML_FLAG_SHOW}, \
        {padding_right_keys,  #padding,  ABC_CSS_PADDING_RIGHT,       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_CSS_POSITION,            ABC_HTML_FLAG_SHOW}, \
        {top_keys,            "",        ABC_CSS_TOP,                 ABC_HTML_FLAG_SHOW}, \
        {bottom_keys,         "",        ABC_CSS_BOTTOM,              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}, \
@@ -195,6 +177,11 @@ static html_attr_t  body_attrs[] =
        {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_SCROLL(overflow, scroll_width, scroll_color) \
+       {overflow_keys,      #overflow,      ABC_CSS_OVERFLOW,            ABC_HTML_FLAG_SHOW}, \
+       {scroll_width_keys,  #scroll_width,  ABC_CSS_SCROLLBAR_WIDTH,     ABC_HTML_FLAG_SHOW}, \
+       {scroll_color_keys,  #scroll_color,  ABC_CSS_SCROLLBAR_COLOR,     ABC_HTML_FLAG_SHOW},
+
 #define ABC_CSS_SELECTOR() \
        {style_keys,          "",        ABC_HTML_ATTR_STYLE,         ABC_HTML_FLAG_SHOW}, \
        {class_keys,          "",        ABC_HTML_ATTR_CLASS,         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}, \
@@ -219,7 +206,30 @@ static html_attr_t  body_attrs[] =
        {text_transform_keys,  "",          ABC_HTML_ATTR_TEXT_TRANSFORM,  ABC_HTML_FLAG_SHOW}, \
        {text_indent_keys,     "",          ABC_HTML_ATTR_TEXT_INDENT,     ABC_HTML_FLAG_SHOW},
 
        {text_transform_keys,  "",          ABC_HTML_ATTR_TEXT_TRANSFORM,  ABC_HTML_FLAG_SHOW}, \
        {text_indent_keys,     "",          ABC_HTML_ATTR_TEXT_INDENT,     ABC_HTML_FLAG_SHOW},
 
-       ABC_CSS_BOX(4px, , 4px)
+       ABC_CSS_BOX( , , 12px)
+       ABC_CSS_SCROLL(scroll, 12px, orangeRed white)
+       ABC_CSS_SELECTOR()
+       ABC_CSS_BACK_GROUND(white)
+
+       ABC_CSS_FONT(SimSong, 16, black, )
+       ABC_CSS_TEXT(left, )
+
+       {xmlns_keys,       "",           ABC_HTML_ATTR_XMLNS,     0},
+       {xmlang_keys,      "",           ABC_HTML_ATTR_XMLANG,    0},
+       {lang_keys,        "",           ABC_HTML_ATTR_LANG,      0},
+};
+
+static html_attr_t  meta_attrs[] =
+{
+       {http_equiv_keys,  "",           ABC_HTML_ATTR_HTTP_EQUIV, ABC_HTML_FLAG_SHOW},
+       {content_keys,     "",           ABC_HTML_ATTR_CONTENT,    ABC_HTML_FLAG_SHOW},
+       {charset_keys,     "",           ABC_HTML_ATTR_CHARSET,    ABC_HTML_FLAG_SHOW},
+};
+
+static html_attr_t  body_attrs[] =
+{
+       ABC_CSS_BOX( , , 8px)
+       ABC_CSS_SCROLL( , 8px, orangeRed white)
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND(white)
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND(white)
 
@@ -230,6 +240,7 @@ static html_attr_t  body_attrs[] =
 static html_attr_t  div_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
 static html_attr_t  div_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -240,6 +251,7 @@ static html_attr_t  div_attrs[] =
 static html_attr_t  h1_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
 static html_attr_t  h1_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -250,6 +262,7 @@ static html_attr_t  h1_attrs[] =
 static html_attr_t  h2_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
 static html_attr_t  h2_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -260,6 +273,7 @@ static html_attr_t  h2_attrs[] =
 static html_attr_t  h3_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
 static html_attr_t  h3_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -270,6 +284,7 @@ static html_attr_t  h3_attrs[] =
 static html_attr_t  h4_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
 static html_attr_t  h4_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -280,6 +295,7 @@ static html_attr_t  h4_attrs[] =
 static html_attr_t  h5_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
 static html_attr_t  h5_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -290,6 +306,7 @@ static html_attr_t  h5_attrs[] =
 static html_attr_t  h6_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
 static html_attr_t  h6_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -300,6 +317,7 @@ static html_attr_t  h6_attrs[] =
 static html_attr_t  p_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
 static html_attr_t  p_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -318,6 +336,7 @@ static html_attr_t  css_id_attrs[] =
        {list_style_pos_keys,   "",     ABC_CSS_LIST_STYLE_POSITION,   ABC_HTML_FLAG_SHOW},
 
        ABC_CSS_BOX(2px, , 2px)
        {list_style_pos_keys,   "",     ABC_CSS_LIST_STYLE_POSITION,   ABC_HTML_FLAG_SHOW},
 
        ABC_CSS_BOX(2px, , 2px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -331,6 +350,7 @@ static html_attr_t  css_id_attrs[] =
 static html_attr_t  b_attrs[] =
 {
        ABC_CSS_BOX( , , )
 static html_attr_t  b_attrs[] =
 {
        ABC_CSS_BOX( , , )
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -343,6 +363,7 @@ static html_attr_t  b_attrs[] =
 static html_attr_t  i_attrs[] =
 {
        ABC_CSS_BOX( , , )
 static html_attr_t  i_attrs[] =
 {
        ABC_CSS_BOX( , , )
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -355,6 +376,7 @@ static html_attr_t  i_attrs[] =
 static html_attr_t  a_attrs[] =
 {
        ABC_CSS_BOX( , , )
 static html_attr_t  a_attrs[] =
 {
        ABC_CSS_BOX( , , )
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -378,14 +400,16 @@ static html_attr_t  link_attrs[] =
 static html_attr_t  img_attrs[] =
 {
        ABC_CSS_BOX( , , )
 static html_attr_t  img_attrs[] =
 {
        ABC_CSS_BOX( , , )
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
 
        ABC_CSS_SELECTOR()
 
-       {src_keys,  "",  ABC_HTML_ATTR_SRC,  ABC_HTML_FLAG_SHOW},
+       {src_keys,       "",  ABC_HTML_ATTR_SRC,  ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  video_attrs[] =
 {
        ABC_CSS_BOX( , , )
 };
 
 static html_attr_t  video_attrs[] =
 {
        ABC_CSS_BOX( , , )
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
 
        {control_keys,  "",  ABC_HTML_ATTR_CONTROLS,  0},
        ABC_CSS_SELECTOR()
 
        {control_keys,  "",  ABC_HTML_ATTR_CONTROLS,  0},
@@ -405,32 +429,35 @@ static html_attr_t  source_attrs[] =
 static html_attr_t  input_attrs[] =
 {
        ABC_CSS_BOX(1px, 1px, 1px)
 static html_attr_t  input_attrs[] =
 {
        ABC_CSS_BOX(1px, 1px, 1px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_FONT(SimSong, 16, black, )
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_FONT(SimSong, 16, black, )
        ABC_CSS_TEXT(left, )
 
-       {type_keys,   "text",  ABC_HTML_ATTR_TYPE,   ABC_HTML_FLAG_SHOW},
-       {name_keys,   "",      ABC_HTML_ATTR_NAME,   ABC_HTML_FLAG_SHOW},
-       {value_keys,  "",      ABC_HTML_ATTR_VALUE,  ABC_HTML_FLAG_SHOW},
+       {type_keys,     "text",  ABC_HTML_ATTR_TYPE,   ABC_HTML_FLAG_SHOW},
+       {name_keys,     "",      ABC_HTML_ATTR_NAME,   ABC_HTML_FLAG_SHOW},
+       {value_keys,    "",      ABC_HTML_ATTR_VALUE,  ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  label_attrs[] =
 {
        ABC_CSS_BOX(1px, 1px, 1px)
 };
 
 static html_attr_t  label_attrs[] =
 {
        ABC_CSS_BOX(1px, 1px, 1px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_FONT(SimSong, 16, black, )
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_FONT(SimSong, 16, black, )
        ABC_CSS_TEXT(left, )
 
-       {for_keys,  "",  ABC_HTML_ATTR_FOR,  ABC_HTML_FLAG_SHOW},
+       {for_keys,      "",  ABC_HTML_ATTR_FOR,  ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  form_attrs[] =
 {
        ABC_CSS_BOX(1px, 1px, 1px)
 };
 
 static html_attr_t  form_attrs[] =
 {
        ABC_CSS_BOX(1px, 1px, 1px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -445,6 +472,7 @@ static html_attr_t  form_attrs[] =
 static html_attr_t  ol_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
 static html_attr_t  ol_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -456,6 +484,7 @@ static html_attr_t  ol_attrs[] =
 static html_attr_t  table_attrs[] =
 {
        ABC_CSS_BOX(2px, 2px, 4px)
 static html_attr_t  table_attrs[] =
 {
        ABC_CSS_BOX(2px, 2px, 4px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -468,6 +497,7 @@ static html_attr_t  table_attrs[] =
 static html_attr_t  th_attrs[] =
 {
        ABC_CSS_BOX(2px, 2px, 4px)
 static html_attr_t  th_attrs[] =
 {
        ABC_CSS_BOX(2px, 2px, 4px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -480,6 +510,7 @@ static html_attr_t  th_attrs[] =
 static html_attr_t  td_attrs[] =
 {
        ABC_CSS_BOX(2px, 2px, 4px)
 static html_attr_t  td_attrs[] =
 {
        ABC_CSS_BOX(2px, 2px, 4px)
+       ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
        ABC_CSS_SELECTOR()
        ABC_CSS_BACK_GROUND()
 
@@ -971,6 +1002,7 @@ static int __html_parse_text(abc_html_t* html, abc_obj_t* obj)
                                obj->text   = NULL; \
                                mov->parent = obj; \
                                mov->flags  = obj->flags; \
                                obj->text   = NULL; \
                                mov->parent = obj; \
                                mov->flags  = obj->flags; \
+                               mov->index  = obj->n_childs++; \
                                scf_list_add_tail(&obj->childs, &mov->list); \
                                scf_logd("--- %s, %s\n", obj->keys[0], mov->text->data); \
                        } while (0)
                                scf_list_add_tail(&obj->childs, &mov->list); \
                                scf_logd("--- %s, %s\n", obj->keys[0], mov->text->data); \
                        } while (0)
index 411572f2e3ed991adcb37006fdcadd25077d3c21..c6a661b4286fe8dbe1715f51e700eb014d0f0877 100644 (file)
@@ -82,7 +82,18 @@ void abc_attr_free(abc_attr_t* attr)
 void abc_dfs_update_xy(abc_obj_t* root, int dx, int dy)
 {
        scf_list_t*  l;
 void abc_dfs_update_xy(abc_obj_t* root, int dx, int dy)
 {
        scf_list_t*  l;
+       abc_attr_t*  attr;
        abc_obj_t*   obj;
        abc_obj_t*   obj;
+       abc_obj_t*   html = root;
+
+       while (html && ABC_HTML != html->type)
+               html = html->parent;
+
+       int X0 = html->x + html->left;
+       int X1 = html->x + html->w - html->right;
+
+       int Y0 = html->y + html->top;
+       int Y1 = html->y + html->h - html->bottom;
 
        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);
 
        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);
@@ -90,6 +101,43 @@ void abc_dfs_update_xy(abc_obj_t* root, int dx, int dy)
                obj->x += dx;
                obj->y += dy;
 
                obj->x += dx;
                obj->y += dy;
 
+               switch (obj->position_type)
+               {
+                       case ABC_POSITION_FIXED:
+                               if (obj->css_left)
+                                       obj->x = X0 + obj->css_left;
+                               else if (obj->right_set)
+                                       obj->x = X1 - obj->css_right - obj->w;
+
+                               if (obj->top_set)
+                                       obj->y = Y0 + obj->css_top;
+                               else if (obj->bottom_set)
+                                       obj->y = Y1 - obj->css_bottom - obj->h;
+                               break;
+
+                       case ABC_POSITION_STICKY:
+                               if (obj->left_set) {
+                                       if (obj->x < X0 + obj->css_left)
+                                               obj->x = X0 + obj->css_left;
+
+                               } else if (obj->right_set) {
+                                       if (obj->x > X1 - obj->css_right - obj->w)
+                                               obj->x = X1 - obj->css_right - obj->w;
+                               }
+
+                               if (obj->top_set) {
+                                       if (obj->y < Y0 + obj->css_top)
+                                               obj->y = Y0 + obj->css_top;
+
+                               } else if (obj->bottom_set) {
+                                       if (obj->y > Y1 - obj->css_bottom - obj->h)
+                                               obj->y = Y1 - obj->css_bottom - obj->h;
+                               }
+                               break;
+                       default:
+                               break;
+               };
+
                abc_dfs_update_xy(obj, dx, dy);
        }
 }
                abc_dfs_update_xy(obj, dx, dy);
        }
 }
index d775695b2d8c605dba8809362e3dd73d2bc59e7b..ff49d6a15bc267baf423489f6342dc89125bd719 100644 (file)
@@ -182,14 +182,14 @@ enum abc_objs
        ABC_CSS_CLASS    = ABC_HTML_ATTR_CLASS,
 };
 
        ABC_CSS_CLASS    = ABC_HTML_ATTR_CLASS,
 };
 
-enum abc_border_style
+enum abc_border_type
 {
        ABC_BORDER_SOLID,
        ABC_BORDER_DOTTED,
        ABC_BORDER_DASHED,
 };
 
 {
        ABC_BORDER_SOLID,
        ABC_BORDER_DOTTED,
        ABC_BORDER_DASHED,
 };
 
-enum abc_line_style
+enum abc_line_type
 {
        ABC_LINE_NONE,
        ABC_LINE_UNDER,
 {
        ABC_LINE_NONE,
        ABC_LINE_UNDER,
@@ -197,16 +197,16 @@ enum abc_line_style
        ABC_LINE_THROUGH,
 };
 
        ABC_LINE_THROUGH,
 };
 
-enum abc_position_style
+enum abc_position_type
 {
        ABC_POSITION_STATIC,
        ABC_POSITION_RELATIVE,
        ABC_POSITION_ABSOLUTE,
 {
        ABC_POSITION_STATIC,
        ABC_POSITION_RELATIVE,
        ABC_POSITION_ABSOLUTE,
-       ABC_POSITION_FIXED,
        ABC_POSITION_STICKY,
        ABC_POSITION_STICKY,
+       ABC_POSITION_FIXED,
 };
 
 };
 
-enum abc_overflow_style
+enum abc_overflow_type
 {
        ABC_OVERFLOW_VISIBLE,
        ABC_OVERFLOW_HIDDEN,
 {
        ABC_OVERFLOW_VISIBLE,
        ABC_OVERFLOW_HIDDEN,
@@ -295,6 +295,7 @@ struct abc_obj_s
        int             padding_left;
        int             padding_right;
 
        int             padding_left;
        int             padding_right;
 
+       // the sum of margin + border + padding for top, bottom, left, right
        int             top;
        int             bottom;
        int             left;
        int             top;
        int             bottom;
        int             left;
@@ -309,6 +310,13 @@ struct abc_obj_s
        int             h;
 
        int             overflow_type;
        int             h;
 
        int             overflow_type;
+       int             position_type;
+
+       int             css_top;
+       int             css_bottom;
+       int             css_left;
+       int             css_right;
+
        // view area that object can see
        int             view_x;
        int             view_y;
        // view area that object can see
        int             view_x;
        int             view_y;
@@ -349,6 +357,11 @@ struct abc_obj_s
 
        uint32_t        w_set:1;
        uint32_t        h_set:1;
 
        uint32_t        w_set:1;
        uint32_t        h_set:1;
+
+       uint32_t        top_set:1;
+       uint32_t        bottom_set:1;
+       uint32_t        left_set:1;
+       uint32_t        right_set: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);
index a1555f17a4297eadd4cf7d377f1eea15917720c0..c03ef1acd77467696594c18af82daf201047d8d7 100644 (file)
@@ -23,9 +23,16 @@ int abc_layout_empty(abc_layout_t* layout, abc_obj_t* obj, int width, int height
        return 0;
 }
 
        return 0;
 }
 
+int abc_layout_html(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+{
+       obj->w = obj->w0;
+       obj->h = obj->h0;
+       return 0;
+}
+
 static abc_layout_pt abc_layouts[ABC_HTML_NB] =
 {
 static abc_layout_pt abc_layouts[ABC_HTML_NB] =
 {
-       [ABC_HTML]          = abc_layout_empty,
+       [ABC_HTML]          = abc_layout_html,
        [ABC_HTML_TITLE]    = abc_layout_empty,
        [ABC_HTML_META]     = abc_layout_empty,
        [ABC_HTML_HEAD]     = abc_layout_empty,
        [ABC_HTML_TITLE]    = abc_layout_empty,
        [ABC_HTML_META]     = abc_layout_empty,
        [ABC_HTML_HEAD]     = abc_layout_empty,
@@ -86,31 +93,32 @@ int abc_layout_obj(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
        return f(layout, obj, width, height);
 }
 
        return f(layout, obj, width, height);
 }
 
-#define LAYOUT_POS_FIXED(X, W, SET, L, R) \
+#define LAYOUT_POS_FIXED(X, W, W_SET, L_SET, R_SET, L, R) \
        do { \
        do { \
-               if (!obj->SET) { \
-                       if (L && R) { \
-                               obj->X = parent->X + L; \
-                               obj->W = parent->W - L - R; \
-                       } else if (L) \
-                               obj->X = parent->X + L; \
-                       else if (R) \
-                               obj->X = parent->X + parent->W - R - obj->W; \
-               } else if (L) \
-                       obj->X = parent->X + L; \
-               else if (R) \
-                       obj->X = parent->X + parent->W - R - obj->W; \
+               abc_obj_t* tmp = parent; \
+               while (tmp && ABC_HTML != tmp->type) \
+                       tmp = tmp->parent; \
+               \
+               if (tmp) { \
+                       if (!obj->W_SET && obj->L && obj->R) \
+                               obj->W = tmp->W - obj->L - obj->R; \
+                       \
+                       if (obj->L_SET) \
+                               obj->X = tmp->X + obj->L; \
+                       else if (obj->R_SET) \
+                               obj->X = tmp->X + tmp->W - obj->R - obj->W; \
+               } \
        } while (0)
 
        } while (0)
 
-#define LAYOUT_POS_RELATIVE(X, L, R) \
+#define LAYOUT_POS_RELATIVE(X, L_SET, R_SET, L, R) \
        do { \
        do { \
-               if (L) \
-                       obj->X += L; \
-               else if (R) \
-                       obj->X += R; \
+               if (obj->L_SET) \
+                       obj->X += obj->L; \
+               else if (obj->R_SET) \
+                       obj->X += obj->R; \
        } while (0)
 
        } while (0)
 
-#define LAYOUT_POS_ABSOLUTE(X, W, L, R) \
+#define LAYOUT_POS_ABSOLUTE(X, W, L_SET, R_SET, L, R) \
        do { \
                abc_obj_t* tmp = parent; \
                while (tmp && ABC_HTML != tmp->type) { \
        do { \
                abc_obj_t* tmp = parent; \
                while (tmp && ABC_HTML != tmp->type) { \
@@ -122,10 +130,10 @@ int abc_layout_obj(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
                        tmp = tmp->parent; \
                } \
                if (tmp) { \
                        tmp = tmp->parent; \
                } \
                if (tmp) { \
-                       if (L) \
-                               obj->X = tmp->X + L; \
-                       else if (R) \
-                               obj->X = tmp->X + tmp->W - R - obj->W; \
+                       if (obj->L_SET) \
+                               obj->X = tmp->X + obj->L; \
+                       else if (obj->R_SET) \
+                               obj->X = tmp->X + tmp->W - obj->R - obj->W; \
                } \
        } while (0)
 
                } \
        } while (0)
 
@@ -160,54 +168,61 @@ int abc_layout_css(abc_obj_t* obj)
                abc_dfs_update_xy(obj, obj->x - x, 0);
        }
 
                abc_dfs_update_xy(obj, obj->x - x, 0);
        }
 
-       attr = abc_obj_get_attr(obj, ABC_CSS_POSITION);
-       if (!attr || 0 == attr->value->len)
+       if (ABC_POSITION_STATIC == obj->position_type)
                return 0;
 
                return 0;
 
-       int pos_type = abc_css_position(attr->value->data);
-       if (ABC_POSITION_STATIC == pos_type)
-               return 0;
+       obj->css_top    = 0;
+       obj->css_bottom = 0;
+       obj->css_left   = 0;
+       obj->css_right  = 0;
 
 
-       int top    = 0;
-       int bottom = 0;
-       int left   = 0;
-       int right  = 0;
+       obj->top_set    = 0;
+       obj->bottom_set = 0;
+       obj->left_set   = 0;
+       obj->right_set  = 0;
 
        attr = abc_obj_get_attr(obj, ABC_CSS_TOP);
 
        attr = abc_obj_get_attr(obj, ABC_CSS_TOP);
-       if (attr)
-               top = abc_css_length(obj, obj->h, attr->value->data);
+       if (attr && attr->value && attr->value->len > 0) {
+               obj->top_set = 1;
+               obj->css_top = abc_css_length(obj, obj->h, attr->value->data);
+       }
 
        attr = abc_obj_get_attr(obj, ABC_CSS_BOTTOM);
 
        attr = abc_obj_get_attr(obj, ABC_CSS_BOTTOM);
-       if (attr)
-               bottom = abc_css_length(obj, obj->h, attr->value->data);
+       if (attr && attr->value && attr->value->len > 0) {
+               obj->bottom_set = 1;
+               obj->css_bottom = abc_css_length(obj, obj->h, attr->value->data);
+       }
 
        attr = abc_obj_get_attr(obj, ABC_CSS_LEFT);
 
        attr = abc_obj_get_attr(obj, ABC_CSS_LEFT);
-       if (attr)
-               left = abc_css_length(obj, obj->w, attr->value->data);
+       if (attr && attr->value && attr->value->len > 0) {
+               obj->left_set = 1;
+               obj->css_left = abc_css_length(obj, obj->w, attr->value->data);
+       }
 
        attr = abc_obj_get_attr(obj, ABC_CSS_RIGHT);
 
        attr = abc_obj_get_attr(obj, ABC_CSS_RIGHT);
-       if (attr)
-               right = abc_css_length(obj, obj->w, attr->value->data);
+       if (attr && attr->value && attr->value->len > 0) {
+               obj->right_set = 1;
+               obj->css_right = abc_css_length(obj, obj->w, attr->value->data);
+       }
 
        int x = obj->x;
        int y = obj->y;
 
 
        int x = obj->x;
        int y = obj->y;
 
-       switch (pos_type)
+       switch (obj->position_type)
        {
                case ABC_POSITION_FIXED:
        {
                case ABC_POSITION_FIXED:
-                       LAYOUT_POS_FIXED(x, w, w_set, leftright);
-                       LAYOUT_POS_FIXED(y, h, h_set, top,  bottom);
+                       LAYOUT_POS_FIXED(x, w, w_set, left_set, right_set,  css_left, css_right);
+                       LAYOUT_POS_FIXED(y, h, h_set, top_set,  bottom_set, css_top,  css_bottom);
                        break;
 
                case ABC_POSITION_RELATIVE:
                        break;
 
                case ABC_POSITION_RELATIVE:
-                       scf_logd("top: %d, bottom: %d, left: %d, right: %d, obj->w: %d, parent->w: %d\n", top, bottom, left, right, obj->w, parent->w);
-                       LAYOUT_POS_RELATIVE(x, left, right);
-                       LAYOUT_POS_RELATIVE(y, top,  bottom);
+                       LAYOUT_POS_RELATIVE(x, left_set, right_set,  css_left, css_right);
+                       LAYOUT_POS_RELATIVE(y, top_set,  bottom_set, css_top,  css_bottom);
                        break;
 
                case ABC_POSITION_ABSOLUTE:
                        break;
 
                case ABC_POSITION_ABSOLUTE:
-                       LAYOUT_POS_ABSOLUTE(x, w, leftright);
-                       LAYOUT_POS_ABSOLUTE(y, h, top,  bottom);
+                       LAYOUT_POS_ABSOLUTE(x, w, left_set, right_set,  css_left, css_right);
+                       LAYOUT_POS_ABSOLUTE(y, h, top_set,  bottom_set, css_top,  css_bottom);
                        break;
                default:
                        break;
                        break;
                default:
                        break;
@@ -215,7 +230,7 @@ int abc_layout_css(abc_obj_t* obj)
 
        abc_dfs_update_xy(obj, obj->x - x, obj->y - y);
 
 
        abc_dfs_update_xy(obj, obj->x - x, obj->y - y);
 
-       return pos_type;
+       return obj->position_type;
 }
 
 int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
 }
 
 int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
@@ -261,15 +276,15 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                        root->w_set = abc_css_width (root, width);
                        root->h_set = abc_css_height(root, height);
 
                        root->w_set = abc_css_width (root, width);
                        root->h_set = abc_css_height(root, height);
 
-                       if (root->w_set) {
+                       root_w = root->w;
+                       root_h = root->h;
+
+                       if (root->w_set)
                                root->w0 = root->w;
                                root->w0 = root->w;
-                               root_w   = root->w;
-                       }
 
 
-                       if (root->h_set) {
+                       if (root->h_set)
                                root->h0 = root->h;
                                root->h0 = root->h;
-                               root_h   = root->h;
-                       } else {
+                       else {
                                if (ABC_HTML_BODY != root->type)
                                        root->h = 0;
                        }
                                if (ABC_HTML_BODY != root->type)
                                        root->h = 0;
                        }
@@ -287,9 +302,16 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
        root->right  = root->margin_right  + root->border_right  + root->padding_right;
 
        root->overflow_type = ABC_OVERFLOW_VISIBLE;
        root->right  = root->margin_right  + root->border_right  + root->padding_right;
 
        root->overflow_type = ABC_OVERFLOW_VISIBLE;
+       root->position_type = ABC_POSITION_STATIC;
 
        scf_list_t*  l;
        abc_obj_t*   child;
 
        scf_list_t*  l;
        abc_obj_t*   child;
+       abc_attr_t*  attr = abc_obj_get_attr(root, ABC_CSS_POSITION);
+
+       if (attr && attr->value && attr->value->len > 0)
+       {
+               root->position_type = abc_css_position(attr->value->data);
+       }
 
        int x = root->x + root->left;
        int y = root->y + root->top;
 
        int x = root->x + root->left;
        int y = root->y + root->top;
@@ -301,6 +323,9 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
        root_w -= root->left + root->right;
        root_h -= root->top  + root->bottom;
 
        root_w -= root->left + root->right;
        root_h -= root->top  + root->bottom;
 
+       scf_logd("w: %d, h: %d, top: %d, bottom: %d, left: %d, right: %d, root_w: %d, root_h: %d\n",
+                       root->w, root->h, root->top, root->bottom, root->left, root->right, root_w, root_h);
+
        for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) {
                child = scf_list_data(l, abc_obj_t, list);
 
        for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) {
                child = scf_list_data(l, abc_obj_t, list);
 
@@ -427,8 +452,8 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                scf_logw("key: %s, ", root->keys[0]);
 //     if (root->text)
 //             printf("%s, ", root->text->data);
                scf_logw("key: %s, ", root->keys[0]);
 //     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);
+       printf("x: %d, y: %d, w: %d, h: %d, bottom: %d, content_w: %d, content_h: %d\n",
+                       root->x, root->y, root->w, root->h, root->bottom, root->content_w, root->content_h);
 #endif
        return 0;
 }
 #endif
        return 0;
 }
index f1c0fe299853da6e03681da293f20c4e5b4bbb96..ea423e49dc9e0a72077829825504c492104d35aa 100644 (file)
@@ -47,9 +47,9 @@ int abc_layout_div(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
        obj->w = obj->w_set ? obj->w0 : w;
        obj->h = obj->h_set ? obj->h0 : h + obj->h;
 
        obj->w = obj->w_set ? obj->w0 : w;
        obj->h = obj->h_set ? obj->h0 : h + obj->h;
 
-       scf_logd("%s, w: %d, h: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg, width: %d, height: %d\n",
-                       obj->text->data, obj->w, obj->h,
-                       extents.x_bearing, extents.y_bearing, extents.width, extents.height,
+       scf_logd("%s, w: %d, h: %d, top: %d, bottom: %d, left: %d, right: %d, x_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg, width: %d, height: %d\n",
+                       obj->text->data, obj->w, obj->h, obj->top, obj->bottom, obj->left, obj->right,
+                       extents.x_bearing, extents.width, extents.height,
                        extents.x_advance, extents.y_advance, width, height);
 
        cairo_destroy(cr);
                        extents.x_advance, extents.y_advance, width, height);
 
        cairo_destroy(cr);
index a8e375c1f7e175776ed67f1f79a5801e1b1c5700..43a3d5096bc6011fa3d45e12a03e18698a72e457 100644 (file)
@@ -24,7 +24,7 @@ extern abc_render_t  abc_render_empty;
 
 static abc_render_t* abc_renders[ABC_HTML_NB] =
 {
 
 static abc_render_t* abc_renders[ABC_HTML_NB] =
 {
-       [ABC_HTML]          = &abc_render_empty,
+       [ABC_HTML]          = &abc_render_body,
        [ABC_HTML_HEAD]     = &abc_render_empty,
        [ABC_HTML_META]     = &abc_render_empty,
        [ABC_HTML_TITLE]    = &abc_render_empty,
        [ABC_HTML_HEAD]     = &abc_render_empty,
        [ABC_HTML_META]     = &abc_render_empty,
        [ABC_HTML_TITLE]    = &abc_render_empty,
@@ -104,6 +104,18 @@ int abc_render_draw(abc_obj_t* obj, int width, int height)
        return render->draw(render, obj, width, height);
 }
 
        return render->draw(render, obj, width, height);
 }
 
+static int __obj_render_cmp(const void* v0, const void* v1)
+{
+       const abc_obj_t* obj0 = *(const abc_obj_t**)v0;
+       const abc_obj_t* obj1 = *(const abc_obj_t**)v1;
+
+       if (obj0->position_type < obj1->position_type)
+               return -1;
+       else if (obj0->position_type > obj1->position_type)
+               return 1;
+       return 0;
+}
+
 static int __render_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height)
 {
        switch (root->type)
 static int __render_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height)
 {
        switch (root->type)
@@ -119,20 +131,38 @@ static int __render_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height)
 
        scf_list_t* l;
        abc_obj_t*  child;
 
        scf_list_t* l;
        abc_obj_t*  child;
+       abc_obj_t** childs;
 
        int ret = abc_render_draw(root, width, height);
        if (ret < 0)
                return ret;
 
 
        int ret = abc_render_draw(root, width, height);
        if (ret < 0)
                return ret;
 
+       childs = calloc(root->n_childs + 1, sizeof(abc_obj_t*));
+       if (!childs)
+               return -ENOMEM;
+
+       int i;
+       int n = 0;
        for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) {
                child = scf_list_data(l, abc_obj_t, list);
 
        for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) {
                child = scf_list_data(l, abc_obj_t, list);
 
-               ret = __render_root(ctx, child, width, height);
+               childs[n++] = child;
+
+               assert(n <= root->n_childs);
+       }
+
+       qsort(childs, n, sizeof(abc_obj_t*), __obj_render_cmp);
+
+       for (i = 0; i < n; i++) {
+               ret = __render_root(ctx, childs[i], width, height);
                if (ret < 0)
                if (ret < 0)
-                       return ret;
+                       goto error;
        }
 
        }
 
-       return 0;
+       ret = 0;
+error:
+       free(childs);
+       return ret;
 }
 
 int abc_render_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height)
 }
 
 int abc_render_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height)
index b232f491c06d0d07b92f88c10f1a5d6da10eb655..a5a2e997289a37e0d70161e5f62f708911e4a704 100644 (file)
--- a/ui/main.c
+++ b/ui/main.c
@@ -94,7 +94,7 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
                prev->mouse_move_x = -1;
                prev->mouse_move_y = -1;
 
                prev->mouse_move_x = -1;
                prev->mouse_move_y = -1;
 
-               if (ABC_HTML_DIV == prev->type)
+               if (ABC_HTML == 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,
                        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,
@@ -138,6 +138,8 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
                                }
                                break;
 
                                }
                                break;
 
+                       case ABC_HTML:
+                       case ABC_HTML_BODY:
                        case ABC_HTML_DIV:
                                ret = 1;
                                break;
                        case ABC_HTML_DIV:
                                ret = 1;
                                break;
@@ -145,7 +147,7 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
                                break;
                };
 
                                break;
                };
 
-               if (ABC_HTML_DIV == obj->type)
+               if (ABC_HTML == 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,
                        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,
@@ -374,7 +376,7 @@ static gboolean button_press_event(GtkWidget* self, GdkEventButton* event, gpoin
                        obj->mouse_move_x = -1;
                        obj->mouse_move_y = -1;
 
                        obj->mouse_move_x = -1;
                        obj->mouse_move_y = -1;
 
-                       if (ABC_HTML_DIV == obj->type)
+                       if (ABC_HTML == 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,
                                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,