--- /dev/null
+<!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>
--- /dev/null
+<!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>
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);
-
- 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;
}
- 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)
{
+ 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);
-
- 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;
}
- 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;
}
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}, \
{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}, \
{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}, \
{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)
static html_attr_t div_attrs[] =
{
ABC_CSS_BOX(2px, , 2px)
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t h1_attrs[] =
{
ABC_CSS_BOX(2px, , 2px)
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t h2_attrs[] =
{
ABC_CSS_BOX(2px, , 2px)
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t h3_attrs[] =
{
ABC_CSS_BOX(2px, , 2px)
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t h4_attrs[] =
{
ABC_CSS_BOX(2px, , 2px)
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t h5_attrs[] =
{
ABC_CSS_BOX(2px, , 2px)
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t h6_attrs[] =
{
ABC_CSS_BOX(2px, , 2px)
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t p_attrs[] =
{
ABC_CSS_BOX(2px, , 2px)
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
{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()
static html_attr_t b_attrs[] =
{
ABC_CSS_BOX( , , )
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t i_attrs[] =
{
ABC_CSS_BOX( , , )
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t a_attrs[] =
{
ABC_CSS_BOX( , , )
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t img_attrs[] =
{
ABC_CSS_BOX( , , )
+ ABC_CSS_SCROLL( , , )
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( , , )
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
{control_keys, "", ABC_HTML_ATTR_CONTROLS, 0},
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, )
- {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)
+ ABC_CSS_SCROLL( , , )
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)
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t ol_attrs[] =
{
ABC_CSS_BOX(2px, , 2px)
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t table_attrs[] =
{
ABC_CSS_BOX(2px, 2px, 4px)
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t th_attrs[] =
{
ABC_CSS_BOX(2px, 2px, 4px)
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t td_attrs[] =
{
ABC_CSS_BOX(2px, 2px, 4px)
+ ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
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)
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* 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);
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_CSS_CLASS = ABC_HTML_ATTR_CLASS,
};
-enum abc_border_style
+enum abc_border_type
{
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_THROUGH,
};
-enum abc_position_style
+enum abc_position_type
{
ABC_POSITION_STATIC,
ABC_POSITION_RELATIVE,
ABC_POSITION_ABSOLUTE,
- ABC_POSITION_FIXED,
ABC_POSITION_STICKY,
+ ABC_POSITION_FIXED,
};
-enum abc_overflow_style
+enum abc_overflow_type
{
ABC_OVERFLOW_VISIBLE,
ABC_OVERFLOW_HIDDEN,
int padding_left;
int padding_right;
+ // the sum of margin + border + padding for top, bottom, left, right
int top;
int bottom;
int left;
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;
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);
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] =
{
- [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,
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 { \
- 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)
-#define LAYOUT_POS_RELATIVE(X, L, R) \
+#define LAYOUT_POS_RELATIVE(X, L_SET, R_SET, L, R) \
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)
-#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) { \
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)
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;
- 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);
- 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);
- 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);
- 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);
- 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;
- switch (pos_type)
+ switch (obj->position_type)
{
case ABC_POSITION_FIXED:
- LAYOUT_POS_FIXED(x, w, w_set, left, right);
- 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:
- 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:
- LAYOUT_POS_ABSOLUTE(x, w, left, right);
- 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;
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)
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_w = root->w;
- }
- if (root->h_set) {
+ if (root->h_set)
root->h0 = root->h;
- root_h = root->h;
- } else {
+ else {
if (ABC_HTML_BODY != root->type)
root->h = 0;
}
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;
+ 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;
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);
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;
}
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);
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,
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)
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;
+ 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);
- 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)
- 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)
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,
}
break;
+ case ABC_HTML:
+ case ABC_HTML_BODY:
case ABC_HTML_DIV:
ret = 1;
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,
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,