<body>
<p>Hello World!</p>
-<p>这个段落采用CSS样式化。</p>
+<p>这个段落<b>采用</b>CSS样式化。</p>
</body>
</html>
for (l = scf_list_head(&label->attrs); l != scf_list_sentinel(&label->attrs); l = scf_list_next(l)) {
attr = scf_list_data(l, abc_obj_t, list);
- abc_obj_set_attr(obj, attr->type, attr->value->data);
+ abc_recursive_set_attr(obj, attr->type, attr->value->data);
}
}
static char* font_size_keys[] = {"font-size", "字号", NULL};
static char* font_color_keys[] = {"font-color", "字体颜色", "color", "颜色", NULL};
+static char* font_bold_keys[] = {"bold", "加粗", NULL};
+static char* font_italic_keys[] = {"italic", "斜体", NULL};
+
static char* text_align_keys[] = {"text-align", "对齐", NULL};
static char* type_keys[] = {"type", "类型", NULL};
static char* h6_keys[] = {"h6", "标题6", NULL};
static char* p_keys[] = {"p", "段落", NULL};
static char* a_keys[] = {"a", "超链接", NULL};
+static char* b_keys[] = {"b", "加粗", NULL};
+static char* i_keys[] = {"i", "斜体", NULL};
static char* play_keys[] = {"play", "播放", NULL};
static char* progress_keys[] = {"progress", "进度条", NULL};
{text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
};
+static html_attr_t b_attrs[] =
+{
+ {font_keys, "SimHei", ABC_HTML_ATTR_FONT, 0},
+ {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0},
+ {font_bold_keys, "true", ABC_HTML_ATTR_FONT_BOLD, 0},
+ {font_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
+ {text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
+};
+
+static html_attr_t i_attrs[] =
+{
+ {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0},
+ {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0},
+ {font_italic_keys, "true", ABC_HTML_ATTR_FONT_ITALIC, 0},
+ {font_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
+ {text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
+};
+
static html_attr_t a_attrs[] =
{
{href_keys, "", ABC_HTML_ATTR_HREF, ABC_HTML_FLAG_SHOW},
{script_keys, ABC_HTML_SCRIPT, abc_number_of(script_attrs), script_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
{style_keys, ABC_HTML_STYLE, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+
+ {b_keys, ABC_HTML_B, abc_number_of(b_attrs), b_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+ {i_keys, ABC_HTML_I, abc_number_of(i_attrs), i_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
};
static int __html_parse_obj(abc_html_t* html, abc_char_t* c);
return -EINVAL;
}
+int abc_recursive_set_attr(abc_obj_t* obj, int key, const char* value)
+{
+ scf_list_t* l;
+ abc_obj_t* child;
+
+ abc_obj_set_attr(obj, key, value);
+
+ for (l = scf_list_head(&obj->childs); l != scf_list_sentinel(&obj->childs); l = scf_list_next(l)) {
+ child = scf_list_data(l, abc_obj_t, list);
+
+ abc_recursive_set_attr(child, key, value);
+ }
+
+ return 0;
+}
+
abc_obj_t* abc_obj_get_attr(abc_obj_t* obj, int key)
{
scf_list_t* l;
ABC_HTML_PROGRESS,
ABC_HTML_SCRIPT,
-
ABC_HTML_STYLE,
+ ABC_HTML_B,
+ ABC_HTML_I,
+
ABC_HTML_NB, // total HTML objects
ABC_HTML_ATTR_ID,
ABC_HTML_ATTR_FONT,
ABC_HTML_ATTR_FONT_SIZE,
ABC_HTML_ATTR_FONT_COLOR,
+ ABC_HTML_ATTR_FONT_BOLD,
+ ABC_HTML_ATTR_FONT_ITALIC,
ABC_HTML_ATTR_TEXT_ALIGN,
scf_string_t* abc_obj_to_string(abc_obj_t* obj);
+int abc_recursive_set_attr(abc_obj_t* obj, int key, const char* value);
+
#endif
[ABC_HTML_SCRIPT] = abc_layout_empty,
[ABC_HTML_STYLE] = abc_layout_empty,
+
+ [ABC_HTML_B] = abc_layout_h1,
+ [ABC_HTML_I] = abc_layout_h1,
};
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);
+ }
+}
+
+int abc_layout_css(abc_obj_t* root)
+{
+ abc_obj_t* parent = root->parent;
+ abc_obj_t* attr;
+
+ attr = abc_obj_get_attr(root, ABC_HTML_ATTR_TEXT_ALIGN);
+ if (attr) {
+ if (!parent || parent->w <= 0 || parent->h <= 0)
+ return 0;
+
+ switch (parent->type)
+ {
+ case ABC_HTML_BODY:
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ int x = root->x;
+
+ if (!strcmp(attr->value->data, "center"))
+ root->x = parent->x + (parent->w - root->w) / 2 + 4;
+
+ else if (!strcmp(attr->value->data, "right"))
+ root->x = parent->x + parent->w - root->w - 4;
+
+ abc_css_update_xy(root, root->x - x, 0);
+ }
+
+ return 0;
+}
+
int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
{
scf_string_t* key;
if (width <= 0 || height <= 0)
return -EINVAL;
+ switch (root->type)
+ {
+ case ABC_HTML_BODY:
+ root->w = width;
+ root->h = height;
+ break;
+ default:
+ break;
+ };
+
int x = root->x + 4;
int y = root->y + 4;
int h = 0;
child = scf_list_data(l, abc_obj_t, list);
int ret;
- switch (child->type) {
-
+ switch (child->type)
+ {
case ABC_HTML_H1:
case ABC_HTML_H2:
case ABC_HTML_H3:
if (root->h < Y - root->y)
root->h = Y - root->y;
+ abc_layout_css(root);
+
if (root->keys)
scf_logd("key: %s, x: %d, y: %d, w: %d, h: %d\n", root->keys[0], root->x, root->y, root->w, root->h);
cr = cairo_create(surface);
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
- if (attr)
- cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+ if (attr) {
+ int bold = CAIRO_FONT_WEIGHT_NORMAL;
+ int italic = CAIRO_FONT_SLANT_NORMAL;
+
+ if (abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_BOLD))
+ bold = CAIRO_FONT_WEIGHT_BOLD;
+
+ if (abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_ITALIC))
+ italic = CAIRO_FONT_SLANT_OBLIQUE;
+
+ cairo_select_font_face(cr, attr->value->data, italic, bold);
+ }
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
if (attr)
cairo_set_font_size(cr, atoi(attr->value->data));
+ cairo_font_options_t *options = cairo_font_options_create();
+ cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_SUBPIXEL);
+ cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_FULL);
+ cairo_font_options_set_hint_metrics(options, CAIRO_HINT_METRICS_ON);
+ cairo_set_font_options(cr, options);
+ cairo_font_options_destroy(options);
+
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
cairo_text_extents(cr, obj->text->data, &extents);
[ABC_HTML_SCRIPT] = &abc_render_empty,
[ABC_HTML_STYLE] = &abc_render_empty,
+
+ [ABC_HTML_B] = &abc_render_h1,
+ [ABC_HTML_I] = &abc_render_h1,
};
int abc_renders_fini()
cairo_stroke(cr);
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
- if (attr)
- cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+ if (attr) {
+ int bold = CAIRO_FONT_WEIGHT_NORMAL;
+ int italic = CAIRO_FONT_SLANT_NORMAL;
+
+ if (abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_BOLD))
+ bold = CAIRO_FONT_WEIGHT_BOLD;
+
+ if (abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_ITALIC))
+ italic = CAIRO_FONT_SLANT_OBLIQUE;
+
+ cairo_select_font_face(cr, attr->value->data, italic, bold);
+ }
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
if (attr)
cairo_set_font_size(cr, atoi(attr->value->data));
+ cairo_font_options_t *options = cairo_font_options_create();
+ cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_SUBPIXEL);
+ cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_FULL);
+ cairo_font_options_set_hint_metrics(options, CAIRO_HINT_METRICS_ON);
+ cairo_set_font_options(cr, options);
+ cairo_font_options_destroy(options);
+
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
if (attr) {
cairo_move_to (cr, extents.x_bearing, -extents.y_bearing);
cairo_show_text(cr, obj->text->data);
-// cairo_surface_write_to_png(surface, "tmp.png");
+ cairo_surface_write_to_png(surface, "tmp.png");
cairo_destroy(cr);
cairo_surface_destroy(surface);