From: yu.dongliang <18588496441@163.com> Date: Tue, 21 Apr 2026 10:44:28 +0000 (+0800) Subject: html: support , ,
, X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=520b49377bca2888e587ea31b6216ca43075196f;p=abc.git html: support , ,
, --- diff --git a/examples/table.html b/examples/table.html new file mode 100644 index 0000000..326065b --- /dev/null +++ b/examples/table.html @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + +
DynastyTime
QinBC. 221-206
HanBC. 206-AD.220
+ + diff --git a/html/abc_css.c b/html/abc_css.c index 1cd5527..b00f26b 100644 --- a/html/abc_css.c +++ b/html/abc_css.c @@ -251,6 +251,7 @@ static int __css_parse_obj(abc_obj_t* css, abc_char_t* c) int ret; int dot = -1; int colon = -1; + int comma = -1; while (1) { c = __io_pop_char(&css->io); @@ -290,6 +291,9 @@ static int __css_parse_obj(abc_obj_t* css, abc_char_t* c) if (colon < 0 && ':' == c->c) colon = key->len; + if (comma < 0 && ',' == c->c) + comma = key->len; + scf_string_cat_cstr_len(key, c->utf8, c->len); } @@ -315,6 +319,8 @@ static int __css_parse_obj(abc_obj_t* css, abc_char_t* c) default: if (dot >= 0) label = __html_find_label2(ABC_CSS_CLASS); + else if (comma >= 0) + label = __html_find_label2(ABC_CSS_COMMA); else if (colon >= 0) label = __html_find_label(key->data + colon); else @@ -343,6 +349,7 @@ static int __css_parse_obj(abc_obj_t* css, abc_char_t* c) switch (obj->type) { case ABC_CSS_ID: case ABC_CSS_CLASS: + case ABC_CSS_COMMA: case ABC_CSS_LINK: case ABC_CSS_VISITED: diff --git a/html/abc_html.c b/html/abc_html.c index 60eaa47..c33a917 100644 --- a/html/abc_html.c +++ b/html/abc_html.c @@ -7,6 +7,9 @@ static char* href_keys[] = {"href", "地址", NULL}; static char* width_keys[] = {"width", "宽度", NULL}; static char* height_keys[] = {"height", "高度", NULL}; +static char* margin_keys[] = {"margin", "外边距", NULL}; +static char* border_keys[] = {"border", "边框", NULL}; +static char* padding_keys[] = {"padding", "内边距", NULL}; static char* font_keys[] = {"font", "字体", NULL}; static char* font_size_keys[] = {"font-size", "字号", NULL}; @@ -72,6 +75,7 @@ static char* audio_keys[] = {"audio", "音频", NULL}; static char* source_keys[] = {"source", "源", NULL}; static char* table_keys[] = {"table", "表格", NULL}; +static char* th_keys[] = {"th", "表头", NULL}; static char* tr_keys[] = {"tr", "行", NULL}; static char* td_keys[] = {"td", "列", NULL}; @@ -101,6 +105,7 @@ static char* style_keys[] = {"style", "样式", NULL}; static char* css_id_keys[] = {"#", NULL}; static char* css_class_keys[] = {".", NULL}; +static char* css_comma_keys[] = {",", NULL}; static char* css_link_keys[] = {":link", ":未访问", NULL}; static char* css_visited_keys[] = {":visited", ":已访问", NULL}; @@ -275,6 +280,8 @@ static html_attr_t css_id_attrs[] = {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, + {border_keys, "", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, + {text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW}, {text_decoration_keys, "", ABC_HTML_ATTR_TEXT_DECORATION, ABC_HTML_FLAG_SHOW}, {text_transform_keys, "", ABC_HTML_ATTR_TEXT_TRANSFORM, ABC_HTML_FLAG_SHOW}, @@ -415,6 +422,49 @@ static html_attr_t ol_attrs[] = {list_style_pos_keys, "", ABC_CSS_LIST_STYLE_POSITION, ABC_HTML_FLAG_SHOW}, }; +static html_attr_t table_attrs[] = +{ + {class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW}, + {style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW}, + {id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW}, + {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0}, + {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0}, + {font_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW}, + {font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0}, + + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, + + {margin_keys, "2", ABC_HTML_ATTR_MARGIN, ABC_HTML_FLAG_SHOW}, + {border_keys, "1", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, + {padding_keys, "4", ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW}, +}; + +static html_attr_t th_attrs[] = +{ + {class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW}, + {style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW}, + {id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW}, + {font_keys, "SimHei", ABC_HTML_ATTR_FONT, 0}, + {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0}, + {font_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW}, + {font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0}, + + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, +}; + +static html_attr_t td_attrs[] = +{ + {class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW}, + {style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW}, + {id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW}, + {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0}, + {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0}, + {font_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW}, + {font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0}, + + {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, +}; + static html_attr_t script_attrs[] = { {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0}, @@ -453,9 +503,10 @@ static html_label_t html_labels[] = {label_keys, ABC_HTML_LABEL, abc_number_of(label_attrs), label_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, {center_keys, ABC_HTML_CENTER, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, - {table_keys, ABC_HTML_TABLE, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, - {tr_keys, ABC_HTML_TR, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, - {td_keys, ABC_HTML_TD, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, + {table_keys, ABC_HTML_TABLE, abc_number_of(table_attrs), table_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, + {tr_keys, ABC_HTML_TR, abc_number_of(td_attrs), td_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, + {td_keys, ABC_HTML_TD, abc_number_of(td_attrs), td_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, + {th_keys, ABC_HTML_TH, abc_number_of(th_attrs), th_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, {ol_keys, ABC_HTML_OL, abc_number_of(ol_attrs), ol_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, {ul_keys, ABC_HTML_UL, abc_number_of(ol_attrs), ol_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, @@ -472,6 +523,7 @@ static html_label_t html_labels[] = {css_id_keys, ABC_CSS_ID, abc_number_of(css_id_attrs), css_id_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, {css_class_keys, ABC_CSS_CLASS, abc_number_of(css_id_attrs), css_id_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, + {css_comma_keys, ABC_CSS_COMMA, abc_number_of(css_id_attrs), css_id_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, {css_link_keys, ABC_CSS_LINK, abc_number_of(css_id_attrs), css_id_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, {css_visited_keys, ABC_CSS_VISITED, abc_number_of(css_id_attrs), css_id_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW}, diff --git a/html/abc_obj.h b/html/abc_obj.h index 523ba51..f157ec8 100644 --- a/html/abc_obj.h +++ b/html/abc_obj.h @@ -46,6 +46,7 @@ enum abc_objs ABC_HTML_TABLE, ABC_HTML_TR, + ABC_HTML_TH, ABC_HTML_TD, ABC_HTML_VIDEO, @@ -103,6 +104,10 @@ enum abc_objs ABC_HTML_ATTR_WIDTH, ABC_HTML_ATTR_HEIGHT, + ABC_HTML_ATTR_MARGIN, + ABC_HTML_ATTR_BORDER, + ABC_HTML_ATTR_PADDING, + ABC_HTML_ATTR_XMLNS, ABC_HTML_ATTR_XMLANG, ABC_HTML_ATTR_LANG, @@ -126,6 +131,8 @@ enum abc_objs ABC_CSS_LIST_STYLE_IMAGE, ABC_CSS_LIST_STYLE_POSITION, + ABC_CSS_COMMA, + // ... new css add here // css enum from html attrs above @@ -165,6 +172,9 @@ struct abc_obj_s int margin; int padding; + int td_width; // width of a table element + int td_height; // height of a table element + int progress; uint32_t jiffies; // timeout numbers of sys timer diff --git a/ui/Makefile b/ui/Makefile index 86344a7..7962f38 100644 --- a/ui/Makefile +++ b/ui/Makefile @@ -12,6 +12,7 @@ CFILES += abc_layout_img.c CFILES += abc_layout_form.c CFILES += abc_layout_label.c CFILES += abc_layout_input.c +CFILES += abc_layout_table.c CFILES += abc_layout_td.c CFILES += abc_layout_video.c @@ -37,7 +38,6 @@ CFILES += abc_render_label.c CFILES += abc_render_input.c CFILES += abc_render_table.c -CFILES += abc_render_tr.c CFILES += abc_render_td.c CFILES += abc_render_li.c diff --git a/ui/abc_layout.c b/ui/abc_layout.c index 818668c..a8b33c5 100644 --- a/ui/abc_layout.c +++ b/ui/abc_layout.c @@ -13,6 +13,7 @@ int abc_layout_form (abc_layout_t* layout, abc_obj_t* obj, int width, int height int abc_layout_label(abc_layout_t* layout, abc_obj_t* obj, int width, int height); int abc_layout_input(abc_layout_t* layout, abc_obj_t* obj, int width, int height); +int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height); int abc_layout_td (abc_layout_t* layout, abc_obj_t* obj, int width, int height); int abc_layout_video(abc_layout_t* layout, abc_obj_t* obj, int width, int height); @@ -50,9 +51,10 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] = [ABC_HTML_LABEL] = abc_layout_label, [ABC_HTML_INPUT] = abc_layout_input, - [ABC_HTML_TABLE] = abc_layout_empty, + [ABC_HTML_TABLE] = abc_layout_table, [ABC_HTML_TR] = abc_layout_empty, [ABC_HTML_TD] = abc_layout_td, + [ABC_HTML_TH] = abc_layout_td, [ABC_HTML_OL] = abc_layout_empty, [ABC_HTML_UL] = abc_layout_empty, diff --git a/ui/abc_layout_table.c b/ui/abc_layout_table.c new file mode 100644 index 0000000..41da221 --- /dev/null +++ b/ui/abc_layout_table.c @@ -0,0 +1,53 @@ +#include"abc.h" + +int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height) +{ + scf_list_t* l; + scf_list_t* l2; + abc_obj_t* tr; + abc_obj_t* td; + abc_obj_t* attr; + + int margin = 0; + int border = 1; + int padding = 4; + + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_MARGIN); + if (attr) + margin = atoi(attr->value->data); + + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BORDER); + if (attr) + border = atoi(attr->value->data); + + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_PADDING); + if (attr) + padding = atoi(attr->value->data); + + int d = margin + border + padding; + int x = obj->x + d; + int y = obj->y + d; + + for (l = scf_list_head(&obj->childs); l != scf_list_sentinel(&obj->childs); l = scf_list_next(l)) { + tr = scf_list_data(l, abc_obj_t, list); + + for (l2 = scf_list_head(&tr->childs); l2 != scf_list_sentinel(&tr->childs); l2 = scf_list_next(l2)) { + td = scf_list_data(l2, abc_obj_t, list); + + td->x = x; + td->y = y; + td->w = obj->td_width + d * 2; + td->h = obj->td_height + d * 2; + + x += td->w; + } + + obj->w = x + d - obj->x; + + x = obj->x + d; + y += obj->td_height + d * 2; + } + + obj->h = y + d - obj->y; + return 0; +} diff --git a/ui/abc_layout_td.c b/ui/abc_layout_td.c index 73d9410..fac5fff 100644 --- a/ui/abc_layout_td.c +++ b/ui/abc_layout_td.c @@ -2,6 +2,7 @@ int abc_layout_td(abc_layout_t* layout, abc_obj_t* obj, int width, int height) { + abc_obj_t* table; abc_obj_t* attr; cairo_text_extents_t extents; cairo_surface_t* surface; @@ -32,6 +33,21 @@ int abc_layout_td(abc_layout_t* layout, abc_obj_t* obj, int width, int height) obj->w = (obj->w + 3) & ~0x3; obj->h = (obj->h + 3) & ~0x3; + table = obj->parent; + while (table && ABC_HTML_TABLE != table->type) + table = table->parent; + + // width of event table element is width of the max one + if (obj->w < table->td_width) + obj->w = table->td_width; + else + table->td_width = obj->w; + + if (obj->h < table->td_height) + obj->h = table->td_height; + else + table->td_height = 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\n", obj->text->data, obj->w, obj->h, extents.x_bearing, extents.y_bearing, extents.width, extents.height, diff --git a/ui/abc_render.c b/ui/abc_render.c index 50586a6..bf23041 100644 --- a/ui/abc_render.c +++ b/ui/abc_render.c @@ -17,7 +17,6 @@ extern abc_render_t abc_render_label; extern abc_render_t abc_render_input; extern abc_render_t abc_render_table; -extern abc_render_t abc_render_tr; extern abc_render_t abc_render_td; extern abc_render_t abc_render_li; @@ -54,8 +53,9 @@ static abc_render_t* abc_renders[ABC_HTML_NB] = [ABC_HTML_INPUT] = &abc_render_input, [ABC_HTML_TABLE] = &abc_render_table, - [ABC_HTML_TR] = &abc_render_tr, + [ABC_HTML_TR] = &abc_render_empty, [ABC_HTML_TD] = &abc_render_td, + [ABC_HTML_TH] = &abc_render_td, [ABC_HTML_OL] = &abc_render_empty, [ABC_HTML_UL] = &abc_render_empty, diff --git a/ui/abc_render_table.c b/ui/abc_render_table.c index 592865e..295ddf0 100644 --- a/ui/abc_render_table.c +++ b/ui/abc_render_table.c @@ -5,7 +5,7 @@ static const char* vert_shader = "layout(location = 0) in vec4 position; \n" "layout(location = 1) in vec2 a_texCoord; \n" "out vec2 v_texCoord; \n" - "unitable mat4 mvp; \n" + "uniform mat4 mvp; \n" "void main() { \n" "gl_Position = mvp * position; \n" "v_texCoord = a_texCoord; \n" @@ -15,22 +15,39 @@ static const char* frag_shader = "#version 330 core\n" "in vec2 v_texCoord; \n" "out vec4 outputColor; \n" - "unitable sampler2D tex_rgba; \n" + "uniform float x_margin; \n" + "uniform float y_margin; \n" + "uniform float x_border; \n" + "uniform float y_border; \n" + "uniform vec4 color; \n" + "uniform vec4 bgColor; \n" "void main() { \n" - " vec2 xy = v_texCoord; \n" - " vec4 v = texture2D(tex_rgba, xy).rgba; \n" - " outputColor = vec4(v.b, v.g, v.r, 1.0); \n" + " float x = v_texCoord.x; \n" + " float y = v_texCoord.y; \n" + " if (((x > x_margin && x < x_margin + x_border) || (x > 1.0 - x_margin - x_border && x < 1.0 - x_margin)) \n" + " && (y > y_margin && y < 1.0 - y_margin)) { \n" + " outputColor = color; \n" + " } else if (((y > y_margin && y < y_margin + y_border) || (y > 1.0 - y_margin - y_border && y < 1.0 - y_margin)) \n" + " && (x > x_margin && x < 1.0 - x_margin)) { \n" + " outputColor = color; \n" + " } else { \n" + " outputColor = bgColor; \n" + " } \n" "} \n"; static GLuint program = 0; static GLuint vao = 0; -static GLuint buffers[2] = {0}; -static GLuint texture_rgba = 0; +static GLuint buffers[2] = {0}; static GLuint uniform_mvp; -static GLuint uniform_rgba; +static GLuint uniform_x_margin; +static GLuint uniform_y_margin; +static GLuint uniform_x_border; +static GLuint uniform_y_border; +static GLuint uniform_color; +static GLuint uniform_bgColor; static int _render_fini_table(abc_render_t* render) @@ -40,62 +57,42 @@ static int _render_fini_table(abc_render_t* render) static int _render_draw_table(abc_render_t* render, abc_obj_t* obj, int width, int height) { - if (!obj->text) - return 0; - if (0 == program) __init_program(&program, vert_shader, frag_shader); if (0 == vao) __init_buffers(&vao, buffers); - if (0 == texture_rgba) - __init_texture(&texture_rgba, GL_RGBA, obj->w, obj->h, NULL); - - abc_obj_t* attr; - cairo_text_extents_t extents; - cairo_surface_t* surface; - cairo_t* cr; - - uint8_t* bgra = calloc(1, obj->w * obj->h * 4); - if (!bgra) - return -ENOMEM; + double margin = 0.0; + double border = 1.0; - surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4); - cr = cairo_create(surface); + double r0 = 0.0; + double g0 = 0.0; + double b0 = 0.0; - cairo_set_line_width(cr, 1); - cairo_set_source_rgb(cr, 1, 1, 1); - cairo_rectangle(cr, 0, 0, obj->w, obj->h); - cairo_fill(cr); - cairo_stroke(cr); + double r1 = 0.0; + double g1 = 0.0; + double b1 = 0.0; - attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT); + abc_obj_t* attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR); if (attr) - cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + abc_css_color(&r0, &g0, &b0, attr->value->data); - attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE); + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR); if (attr) - cairo_set_font_size(cr, atoi(attr->value->data)); + abc_css_color(&r1, &g1, &b1, attr->value->data); - cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); - cairo_text_extents(cr, obj->text->data, &extents); - - 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"); + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_MARGIN); + if (attr) + margin = atof(attr->value->data); - cairo_destroy(cr); - cairo_surface_destroy(surface); - surface = NULL; - cr = NULL; + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BORDER); + if (attr) + border = atof(attr->value->data); float mvp[16]; __compute_mvp(mvp, 0, 0, 0); - scf_logi("%s, x: %d, y: %d, w: %d, h: %d\n", obj->text->data, obj->x, obj->y, obj->w, obj->h); - GLfloat vert_update[] = { 2.0 * obj->x / (float)width - 1.0, @@ -111,17 +108,29 @@ static int _render_draw_table(abc_render_t* render, abc_obj_t* obj, int width, i -2.0 * obj->y / (float)height + 1.0, }; + GLfloat x_margin = margin / (float)obj->w; + GLfloat y_margin = margin / (float)obj->h; + + GLfloat x_border = border / (float)obj->w; + GLfloat y_border = border / (float)obj->h; + glUseProgram(program); - uniform_rgba = glGetUniformLocation(program, "tex_rgba"); - uniform_mvp = glGetUniformLocation(program, "mvp"); + uniform_mvp = glGetUniformLocation(program, "mvp"); + uniform_x_margin = glGetUniformLocation(program, "x_margin"); + uniform_y_margin = glGetUniformLocation(program, "y_margin"); + uniform_x_border = glGetUniformLocation(program, "x_border"); + uniform_y_border = glGetUniformLocation(program, "y_border"); + uniform_color = glGetUniformLocation(program, "color"); + uniform_bgColor = glGetUniformLocation(program, "bgColor"); glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp); - // board - glActiveTexture(GL_TEXTURE0); - glBindTexture (GL_TEXTURE_2D, texture_rgba); - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, obj->w, obj->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra); - glUniform1i(uniform_rgba, 0); + glUniform1f(uniform_x_margin, x_margin); + glUniform1f(uniform_y_margin, y_margin); + 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, 1.0); // draw glBindBuffer (GL_ARRAY_BUFFER, buffers[0]); @@ -133,8 +142,6 @@ static int _render_draw_table(abc_render_t* render, abc_obj_t* obj, int width, i glBindVertexArray(0); glUseProgram(0); - - free(bgra); return 0; } diff --git a/ui/abc_render_td.c b/ui/abc_render_td.c index 1f96e32..08670ee 100644 --- a/ui/abc_render_td.c +++ b/ui/abc_render_td.c @@ -1,5 +1,7 @@ #include"abc.h" +extern abc_render_t abc_render_table; + static const char* vert_shader = "#version 330 core\n" "layout(location = 0) in vec4 position; \n" @@ -40,9 +42,34 @@ static int _render_fini_td(abc_render_t* render) static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int height) { + abc_render_table.draw(&abc_render_table, obj, width, height); + if (!obj->text) return 0; + abc_obj_t* attr; + + int margin = 0; + int border = 1; + int padding = 4; + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_MARGIN); + if (attr) + margin = atoi(attr->value->data); + + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BORDER); + if (attr) + border = atoi(attr->value->data); + + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_PADDING); + if (attr) + padding = atoi(attr->value->data); + + int d = margin + border + padding; + int x = obj->x + d; + int y = obj->y + d; + int w = obj->w - d * 2; + int h = obj->h - d * 2; + if (0 == program) __init_program(&program, vert_shader, frag_shader); @@ -50,26 +77,44 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int __init_buffers(&vao, buffers); if (0 == texture_rgba) - __init_texture(&texture_rgba, GL_RGBA, obj->w, obj->h, NULL); + __init_texture(&texture_rgba, GL_RGBA, w, h, NULL); + + uint8_t* bgra = calloc(1, w * h * 4); + if (!bgra) + return -ENOMEM; - abc_obj_t* attr; cairo_text_extents_t extents; cairo_surface_t* surface; cairo_t* cr; - uint8_t* bgra = calloc(1, obj->w * obj->h * 4); - if (!bgra) - return -ENOMEM; - - surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4); + surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w, h, w * 4); cr = cairo_create(surface); cairo_set_line_width(cr, 1); - cairo_set_source_rgb(cr, 1, 1, 1); - cairo_rectangle(cr, 0, 0, obj->w, obj->h); + + // clear table element's area with background-color + double r = 1.0; + double g = 1.0; + 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); + + cairo_set_source_rgb(cr, r, g, b); + cairo_rectangle(cr, 0, 0, w, h); cairo_fill(cr); cairo_stroke(cr); + // draw text + r = 0.0; + g = 0.0; + b = 0.0; + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR); + if (attr) + abc_css_color(&r, &g, &b, attr->value->data); + + cairo_set_source_rgb(cr, r, g, b); + attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT); if (attr) cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); @@ -78,11 +123,9 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int if (attr) cairo_set_font_size(cr, atoi(attr->value->data)); - cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); - cairo_text_extents(cr, obj->text->data, &extents); - - cairo_move_to (cr, extents.x_bearing, -extents.y_bearing); - cairo_show_text(cr, obj->text->data); + cairo_text_extents(cr, obj->text->data, &extents); + 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"); @@ -98,17 +141,17 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int GLfloat vert_update[] = { - 2.0 * obj->x / (float)width - 1.0, - -2.0 * (obj->y + obj->h) / (float)height + 1.0, + 2.0 * x / (float)width - 1.0, + -2.0 * (y + h) / (float)height + 1.0, - 2.0 * (obj->x + obj->w) / (float)width - 1.0, - -2.0 * (obj->y + obj->h) / (float)height + 1.0, + 2.0 * (x + w) / (float)width - 1.0, + -2.0 * (y + h) / (float)height + 1.0, - 2.0 * obj->x / (float)width - 1.0, - -2.0 * obj->y / (float)height + 1.0, + 2.0 * x / (float)width - 1.0, + -2.0 * y / (float)height + 1.0, - 2.0 * (obj->x + obj->w) / (float)width - 1.0, - -2.0 * obj->y / (float)height + 1.0, + 2.0 * (x + w) / (float)width - 1.0, + -2.0 * y / (float)height + 1.0, }; glUseProgram(program); @@ -117,10 +160,9 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp); - // board glActiveTexture(GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, texture_rgba); - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, obj->w, obj->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra); + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra); glUniform1i(uniform_rgba, 0); // draw