From: yu.dongliang <18588496441@163.com>
Date: Mon, 27 Apr 2026 10:53:38 +0000 (+0800)
Subject: css: text-align & vertical-align ok for
, | , |
X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=3ee9002b2615a5fd50236cbde76282646b9dc147;p=abc.git
css: text-align & vertical-align ok for , | , |
---
diff --git a/examples/table.html b/examples/table.html
index 5c73bda..15b3ba1 100644
--- a/examples/table.html
+++ b/examples/table.html
@@ -2,13 +2,28 @@
diff --git a/html/Makefile b/html/Makefile
index 88b0972..276d458 100644
--- a/html/Makefile
+++ b/html/Makefile
@@ -5,6 +5,7 @@ CFILES += abc_css.c
CFILES += abc_css_color.c
CFILES += abc_css_position.c
CFILES += abc_css_border.c
+CFILES += abc_css_length.c
CFILES += abc_io_util.c
CFILES += abc_io_file.c
diff --git a/html/abc_css_length.c b/html/abc_css_length.c
new file mode 100644
index 0000000..f51c989
--- /dev/null
+++ b/html/abc_css_length.c
@@ -0,0 +1,62 @@
+#include"abc_html.h"
+
+int abc_css_length(abc_obj_t* obj, const uint8_t* str, int len)
+{
+ const uint8_t* p = str;
+ const uint8_t* unit = NULL;
+
+ int x = 0;
+ double value = 0.0;
+ int dot = 0;
+ int percent = 0;
+ int prev = 0;
+ int c = 0;
+
+ do {
+ c = *str;
+
+ if ('.' == c)
+ dot = 10;
+ else if ('%' == c)
+ percent++;
+
+ else if ('a' <= c && 'z' >= c) {
+ if (!unit)
+ unit = str;
+
+ } else if ('0' <= c && '9' >= c) {
+
+ if (dot > 0) {
+ value += (c - '0') / (double)dot;
+ dot *= 10;
+ } else {
+ value *= 10.0;
+ value += c - '0';
+ }
+
+ } else if ('\0' == c || ' ' == c || '\t' == c || '\r' == c || '\n' == c) {
+
+ if (' ' == prev || '\t' == prev || '\r' == prev || '\n' == prev)
+ goto next;
+
+ if (percent)
+ x = value * 0.01 * len;
+ else if (unit) {
+ // for other css units, ignore
+ x = value;
+ }
+
+ unit = NULL;
+ value = 0.0;
+ dot = 0;
+ percent = 0;
+ break;
+ }
+
+next:
+ prev = c;
+ str++;
+ } while (c);
+
+ return x;
+}
diff --git a/html/abc_html.c b/html/abc_html.c
index 1fc771a..af65462 100644
--- a/html/abc_html.c
+++ b/html/abc_html.c
@@ -21,6 +21,8 @@ static char* text_decoration_keys[] = {"text-decoration", "ä¸å线",
static char* text_transform_keys[] = {"text-transform", "大å°å", NULL};
static char* text_indent_keys[] = {"text-transform", "缩è¿", NULL};
+static char* vertical_align_keys[] = {"vertical-align", "åç´å¯¹é½", NULL};
+
static char* bg_keys[] = {"background", "èæ¯", NULL};
static char* bg_color_keys[] = {"background-color", "èæ¯é¢è²", NULL};
static char* bg_image_keys[] = {"background-image", "èæ¯å¾ç", NULL};
@@ -295,6 +297,8 @@ static html_attr_t css_id_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},
+ {vertical_align_keys, "", ABC_HTML_ATTR_VERTICAL_ALIGN, ABC_HTML_FLAG_SHOW},
+
{list_style_keys, "", ABC_CSS_LIST_STYLE, ABC_HTML_FLAG_SHOW},
{list_style_type_keys, "", ABC_CSS_LIST_STYLE_TYPE, ABC_HTML_FLAG_SHOW},
{list_style_image_keys, "", ABC_CSS_LIST_STYLE_IMAGE, ABC_HTML_FLAG_SHOW},
@@ -444,6 +448,9 @@ static html_attr_t table_attrs[] =
{border_keys, "1", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW},
{padding_keys, "4", ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW},
+ {width_keys, "", ABC_HTML_ATTR_WIDTH, ABC_HTML_FLAG_SHOW},
+ {height_keys, "", ABC_HTML_ATTR_HEIGHT, ABC_HTML_FLAG_SHOW},
+
{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},
@@ -463,6 +470,9 @@ static html_attr_t th_attrs[] =
{border_keys, "1", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW},
{padding_keys, "4", ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW},
+ {width_keys, "", ABC_HTML_ATTR_WIDTH, ABC_HTML_FLAG_SHOW},
+ {height_keys, "", ABC_HTML_ATTR_HEIGHT, ABC_HTML_FLAG_SHOW},
+
{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},
@@ -472,6 +482,9 @@ static html_attr_t th_attrs[] =
{font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0},
{bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW},
+
+ {text_align_keys, "", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
+ {vertical_align_keys, "", ABC_HTML_ATTR_VERTICAL_ALIGN, ABC_HTML_FLAG_SHOW},
};
static html_attr_t td_attrs[] =
@@ -480,6 +493,9 @@ static html_attr_t td_attrs[] =
{border_keys, "1", ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW},
{padding_keys, "4", ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW},
+ {width_keys, "", ABC_HTML_ATTR_WIDTH, ABC_HTML_FLAG_SHOW},
+ {height_keys, "", ABC_HTML_ATTR_HEIGHT, ABC_HTML_FLAG_SHOW},
+
{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},
@@ -489,6 +505,9 @@ static html_attr_t td_attrs[] =
{font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0},
{bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW},
+
+ {text_align_keys, "", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
+ {vertical_align_keys, "", ABC_HTML_ATTR_VERTICAL_ALIGN, ABC_HTML_FLAG_SHOW},
};
static html_attr_t script_attrs[] =
diff --git a/html/abc_html.h b/html/abc_html.h
index 2058468..8d5ea23 100644
--- a/html/abc_html.h
+++ b/html/abc_html.h
@@ -59,5 +59,6 @@ int abc_css_position(float* x, float* y, float w, float h, abc_obj_t* obj,
int abc_css_border(double* r, double* g, double* b, int* width, int* type, abc_obj_t* obj, const uint8_t* str);
int abc_css_margin(abc_obj_t* obj);
+int abc_css_length(abc_obj_t* obj, const uint8_t* str, int len);
#endif
diff --git a/html/abc_obj.h b/html/abc_obj.h
index 816fa7b..ee84845 100644
--- a/html/abc_obj.h
+++ b/html/abc_obj.h
@@ -95,6 +95,8 @@ enum abc_objs
ABC_HTML_ATTR_TEXT_TRANSFORM,
ABC_HTML_ATTR_TEXT_INDENT,
+ ABC_HTML_ATTR_VERTICAL_ALIGN,
+
ABC_HTML_ATTR_BG,
ABC_HTML_ATTR_BG_COLOR,
ABC_HTML_ATTR_BG_IMAGE,
diff --git a/ui/Makefile b/ui/Makefile
index 7ca2bea..91bc65c 100644
--- a/ui/Makefile
+++ b/ui/Makefile
@@ -50,6 +50,7 @@ CFILES += ../html/abc_css.c
CFILES += ../html/abc_css_color.c
CFILES += ../html/abc_css_position.c
CFILES += ../html/abc_css_border.c
+CFILES += ../html/abc_css_length.c
CFILES += ../html/abc_io_util.c
CFILES += ../html/abc_io_file.c
diff --git a/ui/abc_layout_table.c b/ui/abc_layout_table.c
index 8c4124d..b877475 100644
--- a/ui/abc_layout_table.c
+++ b/ui/abc_layout_table.c
@@ -18,13 +18,42 @@ int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height
}
}
- int d = abc_css_margin(obj);
+ int w_set = 0;
+ int h_set = 0;
+ int d = abc_css_margin(obj);
+
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_WIDTH);
+ if (attr && attr->value && attr->value->len > 0)
+ {
+ obj->w = abc_css_length(obj, attr->value->data, width);
+ obj->w += d * 2;
+
+ if (obj->w > width - obj->x)
+ obj->w = width - obj->x;
+
+ w_set = 1;
+ }
+
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_HEIGHT);
+ if (attr && attr->value && attr->value->len > 0)
+ {
+ obj->h = abc_css_length(obj, attr->value->data, height);
+ obj->h += d * 2;
+
+ if (obj->h > height - obj->y)
+ obj->h = height - obj->y;
+
+ h_set = 1;
+ }
+
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);
+ int w = obj->td_width;
+ int h = obj->td_height;
int d2 = d;
for (l2 = scf_list_head(&tr->childs); l2 != scf_list_sentinel(&tr->childs); l2 = scf_list_next(l2)) {
@@ -35,18 +64,39 @@ int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height
d2 = abc_css_margin(td);
+ if (w_set) {
+ w_set = 0;
+ obj->td_width = (obj->w - d * 2) / tr->n_childs - d2 * 2;
+ }
+
+ if (h_set) {
+ h_set = 0;
+ obj->td_height = (obj->h - d * 2) / obj->n_childs - d2 * 2;
+ }
+
+ w = obj->td_width;
+ h = obj->td_height;
+
+ attr = abc_obj_get_attr(td, ABC_HTML_ATTR_WIDTH);
+ if (attr && attr->value && attr->value->len > 0)
+ w = abc_css_length(td, attr->value->data, obj->w);
+
+ attr = abc_obj_get_attr(td, ABC_HTML_ATTR_HEIGHT);
+ if (attr && attr->value && attr->value->len > 0)
+ h = abc_css_length(td, attr->value->data, obj->h);
+
td->x = x;
td->y = y;
- td->w = obj->td_width + d2 * 2;
- td->h = obj->td_height + d2 * 2;
+ td->w = w + d2 * 2;
+ td->h = h + d2 * 2;
x += td->w;
}
obj->w = x + d - obj->x;
- x = obj->x + d;
- y += obj->td_height + d2 * 2;
+ x = obj->x + d;
+ y += h + d2 * 2;
}
obj->h = y + d - obj->y;
diff --git a/ui/abc_render_td.c b/ui/abc_render_td.c
index 08670ee..558e87e 100644
--- a/ui/abc_render_td.c
+++ b/ui/abc_render_td.c
@@ -123,9 +123,30 @@ 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_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);
+ double x_bearing = extents.x_bearing;
+ double y_bearing = -extents.y_bearing;
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_TEXT_ALIGN);
+ if (attr) {
+ if (!__html_strcmp(attr->value->data, "right"))
+ x_bearing = w - extents.width - x_bearing;
+
+ else if (!__html_strcmp(attr->value->data, "center"))
+ x_bearing = (w - extents.width) / 2 - x_bearing;
+ }
+
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_VERTICAL_ALIGN);
+ if (attr) {
+ if (!__html_strcmp(attr->value->data, "bottom"))
+ y_bearing += h - extents.height;
+
+ else if (!__html_strcmp(attr->value->data, "center"))
+ y_bearing += (h - extents.height) / 2;
+ }
+
+ cairo_move_to (cr, x_bearing, y_bearing);
+ cairo_show_text(cr, obj->text->data);
// cairo_surface_write_to_png(surface, "tmp.png");
| |