<style>
[title]
{
- color:blue;
+color:red;
}
</style>
</head>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>菜鸟教程(runoob.com)</title>
+<style>
+input[type="text"]
+{
+ width:150px;
+ margin-bottom:10px;
+ background-color:yellow;
+ border: 1px solid red;
+ display: block;
+}
+input[type="button"]
+{
+ width:120px;
+ margin-left:35px;
+ border: 1px solid red;
+ display: block;
+}
+</style>
+</head>
+<body>
+
+<form name="input" action="demo-form.php" method="get">
+Firstname:<input type="text" name="fname" value="Peter" size="20">
+Lastname:<input type="text" name="lname" value="Griffin" size="20">
+<input type="button" value="Example Button">
+
+</form>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>菜鸟教程(runoob.com)</title>
+<style>
+h1.hidden {display:none;}
+</style>
+</head>
+
+<body>
+
+<h1>这是一个可见标题</h1>
+<h1 class="hidden">这是一个隐藏标题</h1>
+<p>注意, 实例中的隐藏标题不占用空间。</p>
+
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>菜鸟教程(runoob.com)</title>
+<style>
+h1.hidden {visibility:hidden;}
+</style>
+</head>
+
+<body>
+<h1>这是一个可见标题</h1>
+<h1 class="hidden">这是一个隐藏标题</h1>
+<p>注意, 实例中的隐藏标题仍然占用空间。</p>
+</body>
+</html>
CFILES += abc_css_position.c
CFILES += abc_css_border.c
CFILES += abc_css_length.c
+CFILES += abc_css_display.c
CFILES += abc_io_util.c
CFILES += abc_io_file.c
case ',':
case ':':
case '.':
- case '[':
- case ']':
case '(':
case ')':
+// case '[':
+ case ']':
// case '#':
if (s->len > 0 && ' ' == s->data[s->len - 1]) {
s->data[s->len - 1] = c->c;
assert(next >= 0 && next < vec->size);
+ if (len >= 2
+ && '\"' == key[0]
+ && '\"' == key[len - 1]) {
+ key++;
+ len -= 2;
+ }
+
+ char* value = NULL;
+ int vlen = 0;
+
int j = (intptr_t)vec->data[next];
- int k;
+ int k = css->text->len;
+ int m = k;
+ int n;
+ int eq = 0;
+
+ if (j < css->text->len)
+ eq = css->text->data[j];
+
+ switch (eq) {
+ case '~':
+ case '|':
+ case '^':
+ case '$':
+ case '*':
+ if ('=' != css->text->data[++j])
+ return NULL;
+
+ case '=':
+ next--;
+ assert(next >= 0 && next < vec->size);
+
+ k = (intptr_t) vec->data[next];
+ if (k <= j)
+ return NULL;
+
+ if (']' != css->text->data[k])
+ return NULL;
+
+ value = css->text->data + j + 1;
+ vlen = k - j - 1;
+
+ if (vlen >= 2
+ && '\"' == value[0]
+ && '\"' == value[vlen - 1]) {
+ value++;
+ vlen -= 2;
+ }
+
+ scf_logd("current: %s, key: %.*s, value: %.*s, next: %d\n",
+ current->keys[0], len, key, vlen, value, next);
+ break;
+
+ case ']':
+ k = j;
+ break;
+ default:
+ return NULL;
+ break;
+ };
+
+ scf_logd("current: %s, key: %.*s, next: %d\n", current->keys[0], len, key, next);
+
+ if (next - 1 >= 0 && next - 1 < vec->size)
+ {
+ m = (intptr_t) vec->data[--next];
+ if (m <= k)
+ return NULL;
+ }
+
int c = 0;
- if (j < css->text->len)
- c = css->text->data[j];
+ if (m < css->text->len)
+ c = css->text->data[m];
switch (c) {
case ' ':
{
attr = abc_obj_get_attr2(current, key, len);
- if (attr && attr->value && attr->value->len > 0)
+ if (!attr || !attr->value || 0 == attr->value->len)
+ continue;
+
+ if (!value)
+ break;
+ if (vlen == attr->value->len && !__html_strncmp(attr->value->data, value, vlen))
break;
}
break;
if (!attr || !attr->value || 0 == attr->value->len)
return NULL;
+
+ if (value) {
+ if (vlen != attr->value->len || __html_strncmp(attr->value->data, value, vlen))
+ return NULL;
+ }
}
break;
if (!attr || !attr->value || 0 == attr->value->len)
return NULL;
+
+ if (value) {
+ if (vlen != attr->value->len || __html_strncmp(attr->value->data, value, vlen))
+ return NULL;
+ }
break;
case '~':
attr = abc_obj_get_attr2(tmp, key, len);
- if (attr && attr->value && attr->value->len > 0)
+ if (!attr || !attr->value || 0 == attr->value->len)
+ continue;
+
+ if (!value)
+ break;
+ if (vlen == attr->value->len && !__html_strncmp(attr->value->data, value, vlen))
break;
}
scf_logd("current: %s, key: %.*s, j: %d, next: %s\n", current->keys[0], len, key, j, css->text->data + j);
- k = (intptr_t) vec->data[next - 1];
- if (k <= j)
+ n = (intptr_t) vec->data[next - 1];
+ if (n <= m)
return NULL;
current = __css_select_by_attr(css, current, vec, next - 1, key, len);
if (!current)
return NULL;
- pse = abc_obj_get_attr2(current, css->text->data + j, k - j);
+ pse = abc_obj_get_attr2(current, css->text->data + m, k - n);
if (!pse)
return NULL;
css->css_pse_chain = pseLink;
pseLink = NULL;
- scf_logd("current: %s, key: %.*s, j: %d, k: %d, next: %.*s\n", current->keys[0], len, key, j, k,
- k - j, css->text->data + j);
+ scf_logd("current: %s, key: %.*s, m: %d, n: %d, next: %.*s\n", current->keys[0], len, key, m, n,
+ n - m, css->text->data + m);
break;
default:
attr = abc_obj_get_attr2(current, key, len);
if (!attr || !attr->value || 0 == attr->value->len)
return NULL;
+
+ if (value) {
+ if (vlen != attr->value->len || __html_strncmp(attr->value->data, value, vlen))
+ return NULL;
+ }
break;
};
ret = 0;
switch (c) {
case '#':
- current = __css_select_by_id_class(css, current, vec, vec->size - 1, ABC_CSS_ID, key, len);
- j = i;
+ if (n_sqares <= 0) {
+ current = __css_select_by_id_class(css, current, vec, vec->size - 1, ABC_CSS_ID, key, len);
+ j = i;
+ }
break;
case '.':
- current = __css_select_by_id_class(css, current, vec, vec->size - 1, ABC_CSS_CLASS, key, len);
- j = i;
+ if (n_sqares <= 0) {
+ current = __css_select_by_id_class(css, current, vec, vec->size - 1, ABC_CSS_CLASS, key, len);
+ j = i;
+ }
break;
case ']':
goto end;
}
- scf_logw("i: %d, %.*s\n", i, len, key);
+ scf_logd("i: %d, %.*s\n", i, len, key);
current = __css_select_by_attr(css, current, vec, vec->size - 1, key, len);
j = i;
break;
case ':':
- if (i > 0 && ':' == css->text->data[i - 1])
- {
- if (j < css->text->len) {
- scf_loge("pse element must be the last for combinators '%s', file: %s, line: %d\n",
- css->text->data, css->file->data, css->text_line);
- ret = 0;
- goto end;
- }
- } else
- j = i;
+ if (n_sqares <= 0) {
+ if (i > 0 && ':' == css->text->data[i - 1])
+ {
+ if (j < css->text->len) {
+ scf_loge("pse element must be the last for combinators '%s', file: %s, line: %d\n",
+ css->text->data, css->file->data, css->text_line);
+ ret = 0;
+ goto end;
+ }
+ } else
+ j = i;
+ }
break;
case ' ':
case '>':
case '+':
- current = __css_select_by_key(css, current, vec, vec->size - 1, key, len);
- j = i;
+ if (n_sqares <= 0) {
+ current = __css_select_by_key(css, current, vec, vec->size - 1, key, len);
+ j = i;
+ }
break;
default:
if (0 == i)
--- /dev/null
+#include"abc_html.h"
+
+int abc_css_display(const uint8_t* str)
+{
+ if (!__html_strcmp(str, "block"))
+ return ABC_DISPLAY_BLOCK;
+
+ if (!__html_strcmp(str, "inline"))
+ return ABC_DISPLAY_INLINE;
+
+ else if (!__html_strcmp(str, "inline-block"))
+ return ABC_DISPLAY_INLINE_BLOCK;
+
+ else if (!__html_strcmp(str, "none"))
+ return ABC_DISPLAY_NONE;
+
+ return ABC_DISPLAY_INLINE;
+}
+
+static int __css_visible(abc_obj_t* obj)
+{
+ abc_attr_t* attr = abc_obj_get_attr(obj, ABC_CSS_VISIBILITY);
+
+ if (attr && attr->value && attr->value->len > 0)
+ {
+ if (!__html_strcmp(attr->value->data, "visible"))
+ return ABC_VISIBLE_VISIBLE;
+
+ else if (!__html_strcmp(attr->value->data, "hidden"))
+ return ABC_VISIBLE_HIDDEN;
+
+ else if (!__html_strcmp(attr->value->data, "collapse"))
+ return ABC_VISIBLE_COLLAPSE;
+ }
+
+ return ABC_VISIBLE_INHERIT;
+}
+
+int abc_css_visible(abc_obj_t* obj)
+{
+ while (obj) {
+ int ret = __css_visible(obj);
+
+ if (ABC_VISIBLE_INHERIT != ret)
+ return ret;
+
+ obj = obj->parent;
+ }
+
+ return ABC_VISIBLE_VISIBLE;
+}
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) {
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) {
static char* width_keys[] = {"width", "宽度", NULL};
static char* height_keys[] = {"height", "高度", NULL};
+static char* display_keys[] = {"display", "显示模式", NULL};
+static char* visible_keys[] = {"visibility", "可见性", NULL};
+
static char* margin_keys[] = {"margin", "外边距", NULL};
static char* margin_top_keys[] = {"margin-top", "上边缘", NULL};
static char* margin_bottom_keys[] = {"margin-bottom", "下边缘", NULL};
static char* for_keys[] = {"for", "关于", NULL};
static char* id_keys[] = {"id", "编号", NULL};
+static char* size_keys[] = {"size", NULL};
static char* value_keys[] = {"value", "值", NULL};
static char* action_keys[] = {"action", "动作", NULL};
static char* method_keys[] = {"method", "方法", NULL};
static html_attr_t html_attrs[] =
{
-#define ABC_CSS_BOX(margin, border, padding) \
+#define ABC_CSS_BOX(display, margin, border, padding) \
+ {display_keys, #display, ABC_CSS_DISPLAY, ABC_HTML_FLAG_SHOW}, \
+ {visible_keys, "", ABC_CSS_VISIBILITY, ABC_HTML_FLAG_SHOW}, \
{border_keys, #border, ABC_CSS_BORDER, ABC_HTML_FLAG_SHOW}, \
{border_top_keys, #border, ABC_CSS_BORDER_TOP, ABC_HTML_FLAG_SHOW}, \
{border_bottom_keys, #border, ABC_CSS_BORDER_BOTTOM, 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() \
+#define ABC_CSS_SELECTOR(type) \
{style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW}, \
{class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW}, \
{title_keys, "", ABC_HTML_ATTR_TITLE, ABC_HTML_FLAG_SHOW}, \
+ {type_keys, #type, ABC_HTML_ATTR_TYPE, ABC_HTML_FLAG_SHOW}, \
+ {name_keys, "", ABC_HTML_ATTR_NAME, ABC_HTML_FLAG_SHOW}, \
{id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW},
#define ABC_CSS_BACK_GROUND(color) \
{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( , , 12px)
+ ABC_CSS_BOX(block, , , 12px)
ABC_CSS_SCROLL(scroll, 12px, orangeRed white)
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND(white)
static html_attr_t body_attrs[] =
{
- ABC_CSS_BOX( , , 8px)
+ ABC_CSS_BOX(block, , , 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_BOX(block, 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_BOX(block, 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_BOX(block, 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_BOX(block, 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_BOX(block, 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_BOX(block, 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_BOX(block, 2px, , 2px)
ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t hr_attrs[] =
{
- ABC_CSS_BOX( , , )
+ ABC_CSS_BOX(, , , )
ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t p_attrs[] =
{
- ABC_CSS_BOX(2px, , 2px)
+ ABC_CSS_BOX(block, 2px, , 2px)
ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
{list_style_image_keys, "", ABC_CSS_LIST_STYLE_IMAGE, ABC_HTML_FLAG_SHOW}, \
{list_style_pos_keys, "", ABC_CSS_LIST_STYLE_POSITION, ABC_HTML_FLAG_SHOW},
- ABC_CSS_BOX(2px, , 2px)
+ 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_BOX(inline, , , )
ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t i_attrs[] =
{
- ABC_CSS_BOX( , , )
+ ABC_CSS_BOX(inline, , , )
ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t a_attrs[] =
{
- ABC_CSS_BOX( , , )
+ ABC_CSS_BOX(inline, , , )
ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t img_attrs[] =
{
- ABC_CSS_BOX( , , )
+ ABC_CSS_BOX(inline-block, , , )
ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
static html_attr_t video_attrs[] =
{
- ABC_CSS_BOX( , , )
+ ABC_CSS_BOX(block, , , )
ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
static html_attr_t input_attrs[] =
{
- ABC_CSS_BOX(1px, 1px, 1px)
+ ABC_CSS_BOX(inline-block, 1px, 2px, 1px)
ABC_CSS_SCROLL( , , )
- ABC_CSS_SELECTOR()
- ABC_CSS_BACK_GROUND()
+ ABC_CSS_SELECTOR(text)
+ ABC_CSS_BACK_GROUND(lightGray)
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},
+ {size_keys, "", ABC_HTML_ATTR_SIZE, 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_BOX(inline, 1px, , 1px)
ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t form_attrs[] =
{
- ABC_CSS_BOX(1px, 1px, 1px)
+ ABC_CSS_BOX(block, 2px, , 2px)
ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
static html_attr_t ol_attrs[] =
{
- ABC_CSS_BOX(2px, , 2px)
+ ABC_CSS_BOX(block, 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_BOX(block, 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_BOX(block, 2px, 2px, 4px)
ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
{vertical_align_keys, "", ABC_HTML_ATTR_VERTICAL_ALIGN, ABC_HTML_FLAG_SHOW},
};
+static html_attr_t tr_attrs[] =
+{
+ ABC_CSS_BOX(block, , , )
+ ABC_CSS_SCROLL( , , )
+ ABC_CSS_SELECTOR()
+ ABC_CSS_BACK_GROUND()
+
+ ABC_CSS_FONT(SimSong, 16, black, )
+ ABC_CSS_TEXT( , )
+
+ {vertical_align_keys, "", ABC_HTML_ATTR_VERTICAL_ALIGN, ABC_HTML_FLAG_SHOW},
+};
+
static html_attr_t td_attrs[] =
{
- ABC_CSS_BOX(2px, 2px, 4px)
+ ABC_CSS_BOX(inline-block, 2px, 2px, 4px)
ABC_CSS_SCROLL( , , )
ABC_CSS_SELECTOR()
ABC_CSS_BACK_GROUND()
{center_keys, ABC_HTML_CENTER, 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},
+ {tr_keys, ABC_HTML_TR, abc_number_of(tr_attrs), tr_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},
static int __html_parse_text(abc_html_t* html, abc_obj_t* obj)
{
+ if (ABC_HTML_FLAG_OPEN == (obj->flags & 0x1)) // single labels
+ return 0;
+
scf_string_t* text = scf_string_alloc();
if (!text)
return -ENOMEM;
}
}
- if ('\n' == c->c) {
- html->n_lines++;
- html->pos = 0;
- } else {
- html->pos += c->len;
- scf_string_cat_cstr_len(text, c->utf8, c->len);
- }
+ html->pos += c->len;
+
+ switch (c->c)
+ {
+ case '\n':
+ html->n_lines++;
+ html->pos = 0;
+ case '\t':
+ case '\r':
+ c->utf8[0] = ' ';
+ break;
+ default:
+ break;
+ };
+
+ scf_string_cat_cstr_len(text, c->utf8, c->len);
free(c);
c = NULL;
}
+ while (text->len > 0 && ' ' == text->data[text->len - 1])
+ text->data[--text->len] = '\0';
+
if (text->len > 0)
obj->text = text;
else
scf_string_free(text);
text = NULL;
- if (ABC_HTML_FLAG_OPEN == (obj->flags & 0x1)) { // single labels
- __io_push_char(&html->io, c);
- c = NULL;
- return 0;
- };
-
html->pos++;
free(c);
c = NULL;
obj->text = NULL; \
mov->parent = obj; \
mov->flags = obj->flags; \
- mov->index = obj->n_childs++; \
scf_list_add_tail(&obj->childs, &mov->list); \
+ obj->n_texts++; \
scf_logd("--- %s, %s\n", obj->keys[0], mov->text->data); \
} while (0)
scf_list_add_tail(&html->current->childs, &obj->list);
- obj ->index = html->current->n_childs++;
- html->current = obj;
+ obj ->list_order = html->current->n_childs++;
+ html->current = obj;
}
if ('/' == ret) {
void abc_css_margin (abc_obj_t* obj, int width);
void abc_css_border (abc_obj_t* obj, int width);
void abc_css_padding(abc_obj_t* obj, int width);
+int abc_css_visible(abc_obj_t* obj);
int abc_css_width (abc_obj_t* obj, int width);
int abc_css_height (abc_obj_t* obj, int height);
int abc_css_position(const uint8_t* str);
int abc_css_overflow(const uint8_t* str);
+int abc_css_display (const uint8_t* str);
int abc_css_scrollbar_width(const uint8_t* str);
int abc_css_scrollbar_color(double thumb[3], double track[3], const uint8_t* str);
if (obj->keys)
printf("<%s", obj->keys[0]);
+ int n = 0;
int i;
for (i = 0; i < sizeof(obj->attrs) / sizeof(obj->attrs[0]); i++) {
attr = obj->attrs[i];
if (!attr)
continue;
- if (ABC_HTML_FLAG_SHOW & attr->flags)
+ if (attr && attr->value && attr->value->len > 0 && (ABC_HTML_FLAG_SHOW & attr->flags)) {
+ n++;
abc_attr_print(attr);
+
+ if (0 == (n & 0x3))
+ printf("\n");
+ }
}
if (obj->flags & ABC_HTML_FLAG_SINGLE)
ABC_HTML_ATTR_ACTION,
ABC_HTML_ATTR_METHOD,
+ ABC_HTML_ATTR_SIZE,
+
ABC_HTML_ATTR_FONT,
ABC_HTML_ATTR_FONT_SIZE,
ABC_HTML_ATTR_FONT_COLOR,
ABC_HTML_ATTR_CONTROLS,
// css attrs
+ ABC_CSS_DISPLAY,
+ ABC_CSS_VISIBILITY,
+
ABC_CSS_MARGIN,
ABC_CSS_MARGIN_TOP,
ABC_CSS_MARGIN_BOTTOM,
ABC_CSS_COMBINATOR,
// css selectors from html attrs above
- ABC_CSS_ID = ABC_HTML_ATTR_ID,
- ABC_CSS_CLASS = ABC_HTML_ATTR_CLASS,
+ ABC_CSS_ID = ABC_HTML_ATTR_ID,
+ ABC_CSS_CLASS = ABC_HTML_ATTR_CLASS,
+};
+
+enum abc_display_type
+{
+ ABC_DISPLAY_NONE,
+ ABC_DISPLAY_BLOCK,
+ ABC_DISPLAY_INLINE,
+ ABC_DISPLAY_INLINE_BLOCK,
+};
+
+enum abc_visible_type
+{
+ ABC_VISIBLE_VISIBLE,
+ ABC_VISIBLE_HIDDEN,
+ ABC_VISIBLE_COLLAPSE,
+ ABC_VISIBLE_INHERIT,
};
enum abc_border_type
scf_list_t list;
scf_list_t childs;
int n_childs;
- int index;
+ int n_texts;
abc_attr_t* attrs[ABC_HTML_CSS_NB - ABC_HTML_ATTR_ID];
int w;
int h;
+ int display_type;
int overflow_type;
int position_type;
int content_w;
int content_h;
+ int list_order;
int list_order_width;
double y_bearing;
CFILES += abc_render_hr.c
CFILES += abc_render_a_href.c
CFILES += abc_render_img.c
-CFILES += abc_render_form.c
CFILES += abc_render_label.c
CFILES += abc_render_input.c
CFILES += ../html/abc_css_position.c
CFILES += ../html/abc_css_border.c
CFILES += ../html/abc_css_length.c
+CFILES += ../html/abc_css_display.c
CFILES += ../html/abc_io_util.c
CFILES += ../html/abc_io_file.c
return 0;
}
-static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_IMAGE);
if (!attr)
obj->mouse_move_x, y0, y1, x0, x1, scroll_width, scroll_tri);
}
-static int __render_draw_border(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int __render_draw_border(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
abc_obj_t* parent = obj->parent;
+ if (ABC_HTML_TD == obj->type || ABC_HTML_TH == obj->type)
+ {
+ while (parent && ABC_HTML_TABLE != parent->type)
+ parent = parent->parent;
+
+ if (!parent)
+ return 0;
+ }
+
if (0 == program)
__init_program(&program, vert_shader, frag_shader);
return 0;
}
-void __draw_text(cairo_text_extents_t* extents, cairo_t* cr, const char* text, double x, double y, double y_bearing, int line_type, int line_width)
+void __draw_text(cairo_text_extents_t* extents, cairo_t* cr, const char* text,
+ double x,
+ double y, double y_bearing, int line_type, double line_width)
{
cairo_text_extents(cr, text, extents);
double w = extents->width;
x += extents->x_bearing;
y -= extents->y_bearing;
- cairo_set_line_width(cr, 1);
+ cairo_set_line_width(cr, 1.0);
cairo_move_to(cr, x, y);
cairo_show_text(cr, text);
cairo_stroke(cr);
cairo_stroke(cr);
}
-int __init_text(cairo_t* cr, abc_obj_t* obj, int num_flag)
+int __init_text(cairo_t* cr, abc_obj_t* obj, int num_flag, double scale)
{
abc_attr_t* attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
if (attr) {
if (attr)
abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
- cairo_set_font_size (cr, size);
+ cairo_set_font_size (cr, size * scale);
cairo_set_source_rgba(cr, r, g, b, 1.0);
if (ABC_HTML_OL == obj->parent->type && num_flag)
{
cairo_text_extents(cr, obj->text->data, &extents);
- cairo_move_to (cr, obj->parent->list_order_width - (extents.x_bearing + extents.width + size / 2), -obj->y_bearing);
+ double x_bearing = obj->parent->list_order_width * scale - (extents.x_bearing + extents.width + size * scale / 2);
+ double y_bearing = obj->y_bearing * scale;
+
+ cairo_move_to (cr, x_bearing, -y_bearing);
cairo_show_text(cr, obj->text->data);
cairo_stroke(cr);
return 0;
line_type = ABC_LINE_THROUGH;
}
+ double x = obj->parent->list_order_width;
+ double y = 0.0;
+
if (!obj->text_splits) {
- __draw_text(&extents, cr, obj->text->data, obj->parent->list_order_width, 0.0, obj->y_bearing, line_type, line_width);
+ __draw_text(&extents, cr, obj->text->data, x * scale, 0.0, obj->y_bearing * scale, line_type, line_width * scale);
return 0;
}
scf_string_t* s;
abc_text_t* t;
- double x = obj->parent->list_order_width;
- double y = 0.0;
-
while (obj->text_splits) {
t = obj->text_splits;
return -ENOMEM;
}
- __draw_text(&extents, cr, s->data, x, y, obj->y_bearing, line_type, line_width);
+ __draw_text(&extents, cr, s->data, x * scale, y, obj->y_bearing * scale, line_type, line_width * scale);
y += extents.height;
obj->text_splits = t->next;
return 0;
}
-static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
if (obj->w <= 0 || obj->h <= 0)
return 0;
int w = obj->w - obj->left - obj->right;
int h = obj->h - obj->top - obj->bottom;
+ int w_text = w * ctx->gl_scale;
+ int h_text = h * ctx->gl_scale;
+
scf_logd("obj->type: %d, obj->w: %d, obj->h: %d, w: %d, h: %d\n", obj->type, obj->w, obj->h, w, h);
if (0 == program)
__init_buffers(&vao, buffers);
if (0 == texture_rgba)
- __init_texture(&texture_rgba, GL_RGBA, w, h, NULL);
+ __init_texture(&texture_rgba, GL_RGBA, w_text, h_text, NULL);
abc_attr_t* attr;
cairo_surface_t* surface;
cairo_t* cr;
- uint8_t* bgra = calloc(1, w * h * 4);
+ uint8_t* bgra = calloc(1, w_text * h_text * 4);
if (!bgra)
return -ENOMEM;
if (attr)
abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
- surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w, h, w * 4);
+ surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4);
cr = cairo_create(surface);
cairo_set_line_width(cr, 1);
cairo_set_source_rgba(cr, r, g, b, 0.0);
- cairo_rectangle(cr, 0, 0, w, h);
+ cairo_rectangle(cr, 0, 0, w_text, h_text);
cairo_fill(cr);
cairo_stroke(cr);
if (obj->text)
- __init_text(cr, obj, 0);
+ __init_text(cr, obj, 0, ctx->gl_scale);
// cairo_surface_write_to_png(surface, "tmp.png");
cairo_destroy(cr);
// board
glActiveTexture(GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, texture_rgba);
- glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
+ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
glUniform1i(uniform_rgba, 0);
// draw
{
int type;
- int (*draw)(abc_render_t* render, abc_obj_t* obj, int width, int height);
+ int (*draw)(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx);
int (*fini)(abc_render_t* render);
void *priv;
GtkBuilder* builder;
GtkGLArea* gl_area;
+ double gl_scale;
+ int gl_width;
+ int gl_height;
GtkButton* back;
GtkButton* forward;
GtkIMContext* im;
};
-#define ABC_CTX_INIT(__ctx) {SCF_LIST_INIT((__ctx).html_list), NULL, NULL, NULL, NULL, NULL, NULL}
+#define ABC_CTX_INIT(__ctx) {SCF_LIST_INIT((__ctx).html_list), NULL, NULL, NULL, 1.0, 0, 0, NULL, NULL, NULL}
static const GLfloat vert_array[] = {
-1.0f, -1.0f,
};
int abc_renders_fini();
-int abc_render_draw(abc_obj_t* obj, int width, int height);
-
+int abc_render_draw(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
int abc_render_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height);
int abc_layout_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height);
int __init_buffers(GLuint* vao, GLuint buffers[2]);
-void __draw_text(cairo_text_extents_t* extents, cairo_t* cr, const char* text, double x, double y, double y_bearing, int line_type, int line_width);
+void __draw_text(cairo_text_extents_t* extents, cairo_t* cr, const char* text, double x, double y, double y_bearing, int line_type, double line_width);
-int __init_text (cairo_t* cr, abc_obj_t* obj, int num_flag);
+int __init_text (cairo_t* cr, abc_obj_t* obj, int num_flag, double scale);
int __layout_text(cairo_t* cr, abc_obj_t* obj, int x, int width, cairo_text_extents_t* extents);
extern abc_render_t __render_border;
[ABC_HTML_HEAD] = abc_layout_empty,
[ABC_HTML_BODY] = abc_layout_body,
[ABC_HTML_DIV] = abc_layout_div,
+ [ABC_HTML_FORM] = abc_layout_div,
[ABC_CORE_TEXT] = abc_layout_text,
[ABC_HTML_B] = abc_layout_text,
[ABC_HTML_IMG] = abc_layout_img,
- [ABC_HTML_FORM] = abc_layout_form,
[ABC_HTML_LABEL] = abc_layout_label,
[ABC_HTML_INPUT] = abc_layout_input,
if (width <= 0 || height <= 0)
return -EINVAL;
+ if (ABC_HTML_SCRIPT == root->type
+ || ABC_HTML_STYLE == root->type
+ || ABC_HTML_LINK == root->type)
+ return 0;
+
+ abc_attr_t* attr;
+
int root_w = width;
int root_h = height;
- switch (root->type)
+ abc_css_margin (root, width);
+ abc_css_border (root, width);
+ abc_css_padding(root, width);
+
+ if (ABC_HTML == root->type)
+ root->display_type = ABC_DISPLAY_BLOCK;
+
+ switch (root->display_type)
{
- case ABC_HTML_SCRIPT:
- case ABC_HTML_STYLE:
- case ABC_HTML_LINK:
+ case ABC_DISPLAY_BLOCK:
+ case ABC_DISPLAY_INLINE_BLOCK:
+ root->top = root->margin_top + root->border_top + root->padding_top;
+ root->bottom = root->margin_bottom + root->border_bottom + root->padding_bottom;
+ root->left = root->margin_left + root->border_left + root->padding_left;
+ root->right = root->margin_right + root->border_right + root->padding_right;
+ break;
+
+ case ABC_DISPLAY_INLINE:
+ root->margin_top = 0;
+ root->margin_bottom = 0;
+
+ root->top = root->margin_top + root->border_top + root->padding_top;
+ root->bottom = root->margin_bottom + root->border_bottom + root->padding_bottom;
+ root->left = root->margin_left + root->border_left + root->padding_left;
+ root->right = root->margin_right + root->border_right + root->padding_right;
+ break;
+
+ default: // display: none
+ root->margin_top = 0;
+ root->margin_bottom = 0;
+ root->margin_left = 0;
+ root->margin_right = 0;
+
+ root->border_top = 0;
+ root->border_bottom = 0;
+ root->border_left = 0;
+ root->border_right = 0;
+
+ root->padding_top = 0;
+ root->padding_bottom = 0;
+ root->padding_left = 0;
+ root->padding_right = 0;
+
+ root->top = 0;
+ root->bottom = 0;
+ root->left = 0;
+ root->right = 0;
+
+ root->w = 0;
+ root->h = 0;
return 0;
break;
+ };
+ switch (root->type)
+ {
case ABC_HTML:
- abc_css_margin (root, width);
- abc_css_border (root, width);
- abc_css_padding(root, width);
-
root->w = width;
root->h = height;
case ABC_HTML_BODY:
case ABC_HTML_DIV:
- abc_css_margin (root, width);
- abc_css_border (root, width);
- abc_css_padding(root, width);
-
root->w_set = abc_css_width (root, width);
root->h_set = abc_css_height(root, height);
}
break;
default:
- abc_css_margin (root, width);
- abc_css_border (root, width);
- abc_css_padding(root, width);
break;
};
- root->top = root->margin_top + root->border_top + root->padding_top;
- root->bottom = root->margin_bottom + root->border_bottom + root->padding_bottom;
- root->left = root->margin_left + root->border_left + root->padding_left;
- 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);
+ 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);
}
+ scf_list_t* l;
+ abc_obj_t* child;
+
int x = root->x + root->left;
int y = root->y + root->top;
int h = 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);
+ attr = abc_obj_get_attr(child, ABC_CSS_DISPLAY);
+ if (attr)
+ child->display_type = abc_css_display(attr->value->data);
+ else
+ child->display_type = ABC_DISPLAY_INLINE;
+
int ret;
- switch (child->type)
+ switch (child->display_type)
{
- case ABC_HTML_H1:
- case ABC_HTML_H2:
- case ABC_HTML_H3:
- case ABC_HTML_H4:
- case ABC_HTML_H5:
- case ABC_HTML_H6:
- case ABC_HTML_DIV:
- case ABC_HTML_OL:
- case ABC_HTML_UL:
- case ABC_HTML_LI:
+ case ABC_DISPLAY_BLOCK:
child->x = root->x + root->left;
child->y = y + h;
h = 0;
break;
- case ABC_HTML_BR:
- case ABC_HTML_HR:
- case ABC_HTML_TR:
- x = root->x + root->left;
- y += h;
- h = 0;
+ case ABC_DISPLAY_INLINE_BLOCK:
+ case ABC_DISPLAY_INLINE:
default:
+ if (ABC_HTML_BR == child->type) {
+ y += h;
+ h = 0;
+ x = root->x + root->left;
+ }
+
child->x = x;
child->y = y;
h = child->h;
x = child->x + child->w;
}
-
- if (ABC_HTML_P == child->type) {
- x = root->x + root->left;
- y += h;
- h = 0;
- }
break;
};
int abc_layout_form(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
{
abc_attr_t* attr;
+ abc_attr_t* style;
cairo_text_extents_t extents;
cairo_surface_t* surface;
cairo_t* cr;
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;
+
+ style = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_STYLE);
+ if (style) {
+ if (!__html_strcmp(style->value->data, "bold"))
+ bold = CAIRO_FONT_WEIGHT_BOLD;
+
+ else if (!__html_strcmp(style->value->data, "italic") || !__html_strcmp(style->value->data, "oblique"))
+ italic = CAIRO_FONT_SLANT_OBLIQUE;
+ }
+
+ cairo_select_font_face(cr, attr->value->data, italic, bold);
+ }
+ int size = 16;
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
if (attr)
- cairo_set_font_size(cr, atoi(attr->value->data));
+ size = atoi(attr->value->data);
+
+ cairo_set_font_size(cr, size);
+
+ int w_set = abc_css_width (obj, width);
+ int h_set = abc_css_height(obj, height);
+
+ int w = (width - obj->left - obj->right) / size * size;
- cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
- cairo_text_extents(cr, obj->text->data, &extents);
+ int ret = __layout_text(cr, obj, 0, w, &extents);
+ if (ret < 0)
+ scf_loge("ret: %d\n", ret);
-// obj->x = 4;
-// obj->y = 4;
- obj->w = extents.width + extents.x_bearing;
- obj->h = extents.height + extents.height / 2;
+ obj->y_bearing = extents.y_bearing;
- obj->w = (obj->w + 3) & ~0x3;
- obj->h = (obj->h + 3) & ~0x3;
+ obj->w = extents.width + obj->left + obj->right;
+ obj->h = extents.height + extents.height / 2 + obj->top + obj->bottom;
- scf_logi("%s, w: %d, h: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg\n",
+ 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,
- extents.x_advance, extents.y_advance);
+ extents.x_advance, extents.y_advance, width, height);
cairo_destroy(cr);
cairo_surface_destroy(surface);
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, text, &extents);
-// obj->x = 4;
-// obj->y = 4;
- obj->w = extents.width + extents.x_bearing;
+ obj->w = extents.x_advance + extents.x_bearing;
obj->h = extents.height;
- obj->w = ((obj->w + 3) & ~0x3) + 8;
- obj->h = ((obj->h + 3) & ~0x3) + 8;
+ obj->w = ((obj->w + 3) & ~0x3) + obj->left + obj->right;
+ obj->h = ((obj->h + 3) & ~0x3) + obj->top + obj->bottom;
scf_logd("%s, w: %d, h: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg\n",
text, obj->w, obj->h,
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);
-// obj->x = 4;
-// obj->y = 4;
- obj->w = extents.width + extents.x_bearing;
+ obj->w = extents.x_advance + extents.x_bearing;
obj->h = extents.height;
- obj->w = ((obj->w + 3) & ~0x3) + 4;
- obj->h = ((obj->h + 3) & ~0x3) + 4;
+ obj->w = obj->w + obj->left + obj->right;
+ obj->h = obj->h + obj->top + obj->bottom;
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,
+ text, obj->w, obj->h,
extents.x_bearing, extents.y_bearing, extents.width, extents.height,
extents.x_advance, extents.y_advance);
abc_obj_set_attr(obj, ABC_CSS_PADDING_LEFT, "0", 1);
abc_obj_set_attr(obj, ABC_CSS_PADDING_RIGHT, "0", 1);
- abc_css_margin (obj, width);
- abc_css_border (obj, width);
- abc_css_padding(obj, width);
+ obj->padding_top = 0;
+ obj->padding_bottom = 0;
+ obj->padding_left = 0;
+ obj->padding_right = 0;
obj->top = obj->margin_top + obj->border_top;
obj->bottom = obj->margin_bottom + obj->border_bottom;
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);
+ if (ABC_VISIBLE_COLLAPSE == abc_css_visible(tr))
+ continue;
+
int left = obj->left;
int right = obj->right;
int top = obj->top;
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);
+ if (ABC_VISIBLE_COLLAPSE == abc_css_visible(td))
+ continue;
+
if (collapse) {
abc_obj_set_attr(td, ABC_CSS_MARGIN_TOP, "0", 1);
abc_obj_set_attr(td, ABC_CSS_MARGIN_BOTTOM, "0", 1);
abc_obj_set_attr(td, ABC_CSS_MARGIN_LEFT, "0", 1);
abc_obj_set_attr(td, ABC_CSS_MARGIN_RIGHT, "0", 1);
+ td->margin_top = 0;
+ td->margin_bottom = 0;
+ td->margin_left = 0;
+ td->margin_right = 0;
+
td->top = td->border_top + td->padding_top;
td->bottom = td->border_bottom + td->padding_bottom;
td->left = td->border_left + td->padding_left;
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);
-// obj->x = 4;
-// obj->y = 4;
- obj->w = extents.width + extents.x_bearing;
- obj->h = extents.height + extents.height / 2;
+ obj->w = extents.x_advance + extents.x_bearing;
+ obj->h = extents.height + extents.height / 2;
obj->w = (obj->w + 3) & ~0x3;
obj->h = (obj->h + 3) & ~0x3;
extern abc_render_t abc_render_a_href;
extern abc_render_t abc_render_img;
-extern abc_render_t abc_render_form;
extern abc_render_t abc_render_label;
extern abc_render_t abc_render_input;
[ABC_HTML_HEAD] = &abc_render_empty,
[ABC_HTML_META] = &abc_render_empty,
[ABC_HTML_TITLE] = &abc_render_empty,
+
[ABC_HTML_BODY] = &abc_render_body,
[ABC_HTML_DIV] = &abc_render_body,
+ [ABC_HTML_FORM] = &abc_render_body,
[ABC_CORE_TEXT] = &abc_render_text,
[ABC_HTML_B] = &abc_render_text,
[ABC_HTML_A_HREF] = &abc_render_a_href,
[ABC_HTML_IMG] = &abc_render_img,
- [ABC_HTML_FORM] = &abc_render_form,
[ABC_HTML_LABEL] = &abc_render_label,
[ABC_HTML_INPUT] = &abc_render_input,
return 0;
}
-int abc_render_draw(abc_obj_t* obj, int width, int height)
+int abc_render_draw(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
{
if (obj->type >= ABC_HTML_NB)
return 0;
if (!render)
return -EINVAL;
- return render->draw(render, obj, width, height);
+ return render->draw(render, obj, width, height, ctx);
}
static int __obj_render_cmp(const void* v0, const void* v1)
abc_obj_t* child;
abc_obj_t** childs;
- int ret = abc_render_draw(root, width, height);
- if (ret < 0)
- return ret;
+ int ret = 0;
+
+ if (ABC_VISIBLE_VISIBLE == abc_css_visible(root)) {
+
+ ret = abc_render_draw(ctx, root, width, height);
+ if (ret < 0)
+ return ret;
+ }
- childs = calloc(root->n_childs + 1, sizeof(abc_obj_t*));
+ childs = calloc(root->n_childs + root->n_texts + 1, sizeof(abc_obj_t*));
if (!childs)
return -ENOMEM;
childs[n++] = child;
- assert(n <= root->n_childs);
+ assert(n <= root->n_childs + root->n_texts);
}
qsort(childs, n, sizeof(abc_obj_t*), __obj_render_cmp);
if (!render)
return -EINVAL;
- ret = render->draw(render, ctx->current->current, width, height);
+ ret = render->draw(render, ctx->current->current, width, height, ctx);
if (ret < 0)
return ret;
}
return 0;
}
-static int _render_draw_a_href(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int _render_draw_a_href(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_HREF);
return 0;
}
-static int _render_draw_audio(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int _render_draw_audio(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_SRC);
if (!attr) {
return 0;
}
-static int _render_draw_body(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int _render_draw_body(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
- __render_border.draw(&__render_border, obj, width, height);
+ __render_border.draw(&__render_border, obj, width, height, ctx);
abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_IMAGE);
if (attr && attr->value && attr->value->len > 0)
{
- __render_bg_image.draw(&__render_bg_image, obj, width, height);
+ __render_bg_image.draw(&__render_bg_image, obj, width, height, ctx);
}
if (obj->text)
- __render_text.draw(&__render_text, obj, width, height);
+ __render_text.draw(&__render_text, obj, width, height, ctx);
return 0;
}
return 0;
}
-static int _render_draw_empty(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int _render_draw_empty(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
return 0;
}
+++ /dev/null
-#include"abc.h"
-
-static const char* vert_shader =
- "#version 330 core\n"
- "layout(location = 0) in vec4 position; \n"
- "layout(location = 1) in vec2 a_texCoord; \n"
- "out vec2 v_texCoord; \n"
- "uniform mat4 mvp; \n"
- "void main() { \n"
- "gl_Position = mvp * position; \n"
- "v_texCoord = a_texCoord; \n"
- "} \n";
-
-static const char* frag_shader =
- "#version 330 core\n"
- "in vec2 v_texCoord; \n"
- "out vec4 outputColor; \n"
- "uniform sampler2D tex_rgba; \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"
- "} \n";
-
-
-static GLuint program = 0;
-
-static GLuint vao = 0;
-static GLuint buffers[2] = {0};
-static GLuint texture_rgba = 0;
-
-static GLuint uniform_mvp;
-static GLuint uniform_rgba;
-
-
-static int _render_fini_form(abc_render_t* render)
-{
- return 0;
-}
-
-static int _render_draw_form(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_attr_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);
- 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);
- cairo_fill(cr);
- 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);
-
- attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
- 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_surface_write_to_png(surface, "tmp.png");
-
- cairo_destroy(cr);
- cairo_surface_destroy(surface);
- surface = NULL;
- cr = NULL;
-
- 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,
- -2.0 * (obj->y + obj->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 * obj->x / (float)width - 1.0,
- -2.0 * obj->y / (float)height + 1.0,
-
- 2.0 * (obj->x + obj->w) / (float)width - 1.0,
- -2.0 * obj->y / (float)height + 1.0,
- };
-
- glUseProgram(program);
- uniform_rgba = glGetUniformLocation(program, "tex_rgba");
- uniform_mvp = glGetUniformLocation(program, "mvp");
-
- 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);
-
- // draw
- glBindBuffer (GL_ARRAY_BUFFER, buffers[0]);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
-
- glBindVertexArray(vao);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- glBindVertexArray(0);
- glUseProgram(0);
-
- free(bgra);
- return 0;
-}
-
-abc_render_t abc_render_form =
-{
- .type = ABC_HTML_FORM,
-
- .draw = _render_draw_form,
- .fini = _render_fini_form,
-};
return 0;
}
-static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
if (obj->w <= 0 || obj->h <= 0)
return 0;
- __render_border.draw(&__render_border, obj, width, height);
+ __render_border.draw(&__render_border, obj, width, height, ctx);
if (obj->text)
- __render_text.draw(&__render_text, obj, width, height);
+ __render_text.draw(&__render_text, obj, width, height, ctx);
return 0;
}
return 0;
}
-static int __render_draw_hr(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int __render_draw_hr(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
abc_obj_t* parent = obj->parent;
return 0;
}
-static int _render_draw_img(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int _render_draw_img(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
abc_attr_t* attr;
abc_img_t* img = NULL;
return 0;
}
-static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
+ __render_border.draw(&__render_border, obj, width, height, ctx);
+
+ int x = obj->x + obj->left;
+ int y = obj->y + obj->top;
+ int w = obj->w - obj->left - obj->right;
+ int h = obj->h - obj->top - obj->bottom;
+
+ int w_text = w * ctx->gl_scale;
+ int h_text = h * ctx->gl_scale;
+
if (0 == program)
__init_program(&program, vert_shader, frag_shader);
__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_text, h_text, NULL);
abc_attr_t* type;
abc_attr_t* attr;
cairo_surface_t* surface;
cairo_t* cr;
- uint8_t* bgra = calloc(1, obj->w * obj->h * 4);
+ uint8_t* bgra = calloc(1, w_text * h_text * 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_text, h_text, w_text * 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);
+ double r = 0.0;
+ double g = 0.0;
+ double b = 0.0;
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
+ if (attr)
+ abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+
+ cairo_set_line_width (cr, 1);
+ cairo_set_source_rgba(cr, r, g, b, 1.0);
+ cairo_rectangle(cr, 0, 0, w_text, h_text);
cairo_fill(cr);
cairo_stroke(cr);
- cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
- cairo_set_line_width (cr, 2);
- cairo_rectangle(cr, 2, 2, obj->w - 4, obj->h - 4);
- 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);
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
+ if (attr)
+ abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+
+ int size = 16;
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
if (attr)
- cairo_set_font_size(cr, atoi(attr->value->data));
+ size = atoi(attr->value->data);
- int x_cursor = 6;
+ cairo_set_font_size (cr, size * ctx->gl_scale);
+ cairo_set_source_rgba(cr, r, g, b, 1.0);
+
+ int x_cursor = 2;
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_VALUE);
type = abc_obj_find_attr(obj, ABC_HTML_ATTR_TYPE);
memset(passwd, '*', attr->value->len);
cairo_text_extents(cr, passwd, &extents);
- cairo_move_to (cr, extents.x_bearing + 4, -extents.y_bearing + (obj->h - extents.height) / 2);
+ cairo_move_to (cr, extents.x_bearing, -extents.y_bearing + (h_text - extents.height) / 2);
cairo_show_text(cr, passwd);
free(passwd);
passwd = NULL;
} else {
cairo_text_extents(cr, attr->value->data, &extents);
- cairo_move_to (cr, extents.x_bearing + 4, -extents.y_bearing + (obj->h - extents.height) / 2);
+ cairo_move_to (cr, extents.x_bearing, -extents.y_bearing + (h_text - extents.height) / 2);
cairo_show_text(cr, attr->value->data);
}
cairo_stroke(cr);
- x_cursor = 6 + extents.x_bearing + extents.width;
+ x_cursor = 2 * ctx->gl_scale + extents.x_bearing + extents.x_advance;
}
- if (obj->clicked && obj->jiffies % 72 < 36) {
+ if (obj->clicked && obj->jiffies % 1024 < 512) {
cairo_set_line_width (cr, 1);
- cairo_move_to(cr, x_cursor, 4);
- cairo_line_to(cr, x_cursor, obj->h - 4);
+ cairo_move_to(cr, x_cursor, 0);
+ cairo_line_to(cr, x_cursor, h_text);
cairo_stroke (cr);
}
- cairo_surface_write_to_png(surface, "tmp.png");
+// cairo_surface_write_to_png(surface, "tmp.png");
cairo_destroy(cr);
cairo_surface_destroy(surface);
surface = NULL;
cr = NULL;
+ int view_x = x;
+ int view_y = y;
+ int view_w = w;
+ int view_h = h;
+
+ switch (obj->overflow_type)
+ {
+ case ABC_OVERFLOW_HIDDEN:
+ case ABC_OVERFLOW_SCROLL:
+ case ABC_OVERFLOW_AUTO:
+ abc_overflow_show(&view_x, &view_y, &view_w, &view_h,
+ obj->view_x,
+ obj->view_y, obj->view_w, obj->view_h);
+ break;
+ default:
+ break;
+ };
+
float mvp[16];
__compute_mvp(mvp, 0, 0, 0);
GLfloat vert_update[] =
{
- 2.0 * obj->x / (float)width - 1.0,
- -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+ 2.0 * view_x / (float)width - 1.0,
+ -2.0 * (view_y + view_h) / (float)height + 1.0,
+
+ 2.0 * (view_x + view_w) / (float)width - 1.0,
+ -2.0 * (view_y + view_h) / (float)height + 1.0,
+
+ 2.0 * view_x / (float)width - 1.0,
+ -2.0 * view_y / (float)height + 1.0,
+
+ 2.0 * (view_x + view_w) / (float)width - 1.0,
+ -2.0 * view_y / (float)height + 1.0,
+ };
+
+ GLfloat texture_update[] =
+ {
+ (view_x - x) / (float)w,
+ (view_y + view_h - y) / (float)h,
- 2.0 * (obj->x + obj->w) / (float)width - 1.0,
- -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+ (view_x + view_w - x) / (float)w,
+ (view_y + view_h - y) / (float)h,
- 2.0 * obj->x / (float)width - 1.0,
- -2.0 * obj->y / (float)height + 1.0,
+ (view_x - x) / (float)w,
+ (view_y - y) / (float)h,
- 2.0 * (obj->x + obj->w) / (float)width - 1.0,
- -2.0 * obj->y / (float)height + 1.0,
+ (view_x + view_w - x) / (float)w,
+ (view_y - y) / (float)h,
};
glUseProgram(program);
// 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_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
glUniform1i(uniform_rgba, 0);
// draw
glBindBuffer (GL_ARRAY_BUFFER, buffers[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
+ glBindBuffer (GL_ARRAY_BUFFER, buffers[1]);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_update), texture_update);
+
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
return 0;
}
-static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
+ __render_border.draw(&__render_border, obj, width, height, ctx);
+
if (!obj->text)
return 0;
+ int x = obj->x + obj->left;
+ int y = obj->y + obj->top;
+ int w = obj->w - obj->left - obj->right;
+ int h = obj->h - obj->top - obj->bottom;
+
+ int w_text = w * ctx->gl_scale;
+ int h_text = h * ctx->gl_scale;
+
if (0 == program)
__init_program(&program, vert_shader, frag_shader);
__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_text, h_text, NULL);
+ abc_attr_t* type;
abc_attr_t* attr;
cairo_text_extents_t extents;
cairo_surface_t* surface;
cairo_t* cr;
- uint8_t* bgra = calloc(1, obj->w * obj->h * 4);
+ uint8_t* bgra = calloc(1, w_text * h_text * 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_text, h_text, w_text * 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);
+ double r = 0.0;
+ double g = 0.0;
+ double b = 0.0;
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
+ if (attr)
+ abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+
+ cairo_set_line_width (cr, 1);
+ cairo_set_source_rgba(cr, r, g, b, 1.0);
+ cairo_rectangle(cr, 0, 0, w_text, h_text);
cairo_fill(cr);
cairo_stroke(cr);
if (attr)
cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+ attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
+ if (attr)
+ abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+
+ int size = 16;
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
if (attr)
- cairo_set_font_size(cr, atoi(attr->value->data));
+ size = 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_set_font_size (cr, size * ctx->gl_scale);
+ cairo_set_source_rgba(cr, r, g, b, 1.0);
- cairo_move_to (cr, extents.x_bearing + 2, -extents.y_bearing + 2);
+ cairo_text_extents(cr, obj->text->data, &extents);
+ cairo_move_to (cr, extents.x_bearing, -extents.y_bearing + (h_text - extents.height) / 2);
cairo_show_text(cr, obj->text->data);
+ cairo_stroke(cr);
// cairo_surface_write_to_png(surface, "tmp.png");
surface = NULL;
cr = NULL;
+ int view_x = x;
+ int view_y = y;
+ int view_w = w;
+ int view_h = h;
+
+ switch (obj->overflow_type)
+ {
+ case ABC_OVERFLOW_HIDDEN:
+ case ABC_OVERFLOW_SCROLL:
+ case ABC_OVERFLOW_AUTO:
+ abc_overflow_show(&view_x, &view_y, &view_w, &view_h,
+ obj->view_x,
+ obj->view_y, obj->view_w, obj->view_h);
+ break;
+ default:
+ break;
+ };
+
float mvp[16];
__compute_mvp(mvp, 0, 0, 0);
- scf_logd("%s, x: %d, y: %d, w: %d, h: %d\n", obj->text->data, obj->x, obj->y, obj->w, obj->h);
+ scf_logd("x: %d, y: %d, w: %d, h: %d\n", obj->x, obj->y, obj->w, obj->h);
GLfloat vert_update[] =
{
- 2.0 * obj->x / (float)width - 1.0,
- -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+ 2.0 * view_x / (float)width - 1.0,
+ -2.0 * (view_y + view_h) / (float)height + 1.0,
+
+ 2.0 * (view_x + view_w) / (float)width - 1.0,
+ -2.0 * (view_y + view_h) / (float)height + 1.0,
+
+ 2.0 * view_x / (float)width - 1.0,
+ -2.0 * view_y / (float)height + 1.0,
+
+ 2.0 * (view_x + view_w) / (float)width - 1.0,
+ -2.0 * view_y / (float)height + 1.0,
+ };
+
+ GLfloat texture_update[] =
+ {
+ (view_x - x) / (float)w,
+ (view_y + view_h - y) / (float)h,
- 2.0 * (obj->x + obj->w) / (float)width - 1.0,
- -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+ (view_x + view_w - x) / (float)w,
+ (view_y + view_h - y) / (float)h,
- 2.0 * obj->x / (float)width - 1.0,
- -2.0 * obj->y / (float)height + 1.0,
+ (view_x - x) / (float)w,
+ (view_y - y) / (float)h,
- 2.0 * (obj->x + obj->w) / (float)width - 1.0,
- -2.0 * obj->y / (float)height + 1.0,
+ (view_x + view_w - x) / (float)w,
+ (view_y - y) / (float)h,
};
glUseProgram(program);
// 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_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
glUniform1i(uniform_rgba, 0);
// draw
glBindBuffer (GL_ARRAY_BUFFER, buffers[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
+ glBindBuffer (GL_ARRAY_BUFFER, buffers[1]);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_update), texture_update);
+
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
return 0;
}
-static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
abc_attr_t* attr;
cairo_surface_t* surface;
cairo_t* cr;
- uint8_t* bgra = calloc(1, obj->w * obj->h * 4);
+ int w_text = obj->w * ctx->gl_scale;
+ int h_text = obj->h * ctx->gl_scale;
+
+ uint8_t* bgra = calloc(1, w_text * h_text * 4);
if (!bgra)
return -ENOMEM;
if (attr)
abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
- 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_text, h_text, w_text * 4);
cr = cairo_create(surface);
cairo_set_line_width(cr, 1);
cairo_set_source_rgb(cr, r, g, b);
- cairo_rectangle(cr, 0, 0, obj->w, obj->h);
+ cairo_rectangle(cr, 0, 0, w_text, h_text);
cairo_fill(cr);
cairo_stroke(cr);
int offset = obj->parent->list_order_width;
if (obj->text)
- __init_text(cr, obj, 0);
+ __init_text(cr, obj, 0, ctx->gl_scale);
cairo_destroy(cr);
cairo_surface_destroy(surface);
attr = abc_obj_find_attr(obj, ABC_CSS_LIST_STYLE_IMAGE);
+ int w_order = offset * ctx->gl_scale;
+ int h_order = size * ctx->gl_scale;
+
if (ABC_HTML_OL == obj->parent->type || !attr || !attr->value || attr->value->len <= 0)
{
- bgra1 = calloc(1, offset * size * 4);
+ bgra1 = calloc(1, w_order * h_order * 4);
if (!bgra1) {
free(bgra);
return -ENOMEM;
}
- surface = cairo_image_surface_create_for_data(bgra1, CAIRO_FORMAT_ARGB32, offset, size, offset * 4);
+ surface = cairo_image_surface_create_for_data(bgra1, CAIRO_FORMAT_ARGB32, w_order, h_order, w_order * 4);
cr = cairo_create(surface);
- cairo_set_line_width(cr, 1);
+ cairo_set_line_width(cr, 1.0 * ctx->gl_scale);
cairo_set_source_rgb(cr, r, g, b);
- cairo_rectangle(cr, 0, 0, offset, size);
+ cairo_rectangle(cr, 0, 0, w_order, h_order);
cairo_fill(cr);
cairo_stroke(cr);
if (ABC_HTML_OL == obj->parent->type)
{
- scf_string_t* s = abc_ol_list_style(obj, obj->index);
+ scf_string_t* s = abc_ol_list_style(obj, obj->list_order);
if (!s) {
free(bgra1);
free(bgra);
}
SCF_XCHG(obj->text, s);
- __init_text(cr, obj, 1);
+ __init_text(cr, obj, 1, ctx->gl_scale);
SCF_XCHG(obj->text, s);
scf_string_free(s);
attr = abc_obj_find_attr(obj, ABC_CSS_LIST_STYLE_TYPE);
if (attr) {
if (!strcmp(attr->value->data, "circle"))
- cairo_arc (cr, offset / 2, size / 2, size / 4, 0, 2 * M_PI);
+ cairo_arc (cr, w_order / 2, h_order / 2, h_order / 4, 0, 2 * M_PI);
else if (!strcmp(attr->value->data, "square")) {
- cairo_rectangle(cr, offset / 4, size / 4, size / 2, size / 2);
+ cairo_rectangle(cr, w_order / 4, h_order / 4, h_order / 2, h_order / 2);
cairo_fill(cr);
} else if (!strcmp(attr->value->data, "disc")) {
- cairo_arc (cr, offset / 2, size / 2, size / 4, 0, 2 * M_PI);
+ cairo_arc (cr, w_order / 2, h_order / 2, h_order / 4, 0, 2 * M_PI);
cairo_fill(cr);
}
} else {
- cairo_arc (cr, offset / 2, size / 2, size / 4, 0, 2 * M_PI);
+ cairo_arc (cr, w_order / 2, h_order / 2, h_order / 4, 0, 2 * M_PI);
cairo_fill(cr);
}
__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_text, h_text, NULL);
if (0 == texture_img)
- __init_texture(&texture_img, GL_RGBA, offset, size, NULL);
+ __init_texture(&texture_img, GL_RGBA, w_order, h_order, NULL);
float mvp[16];
__compute_mvp(mvp, 0, 0, 0);
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_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
glUniform1i(uniform_rgba, 0);
glActiveTexture(GL_TEXTURE1);
if (img)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img->width, img->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra1);
else
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, offset, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra1);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w_order, h_order, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra1);
glUniform1i(uniform_img, 1);
glUniform4f(uniform_rect, x, y, w, h);
glBindBuffer (GL_ARRAY_BUFFER, buffers[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
+ glBindBuffer (GL_ARRAY_BUFFER, buffers[1]);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_array), texture_array);
+
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
return 0;
}
-static int _render_draw_table(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int _render_draw_table(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
- __render_border.draw(&__render_border, obj, width, height);
+ __render_border.draw(&__render_border, obj, width, height, ctx);
return 0;
}
return 0;
}
-static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
- __render_border.draw(&__render_border, obj, width, height);
+ __render_border.draw(&__render_border, obj, width, height, ctx);
if (!obj->text)
return 0;
int w = obj->w - obj->left - obj->right;
int h = obj->h - obj->top - obj->bottom;
+ int w_text = w * ctx->gl_scale;
+ int h_text = h * ctx->gl_scale;
+
if (0 == program)
__init_program(&program, vert_shader, frag_shader);
__init_buffers(&vao, buffers);
if (0 == texture_rgba)
- __init_texture(&texture_rgba, GL_RGBA, w, h, NULL);
+ __init_texture(&texture_rgba, GL_RGBA, w_text, h_text, NULL);
- uint8_t* bgra = calloc(1, w * h * 4);
+ uint8_t* bgra = calloc(1, w_text * h_text * 4);
if (!bgra)
return -ENOMEM;
cairo_surface_t* surface;
cairo_t* cr;
- surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w, h, w * 4);
+ surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4);
cr = cairo_create(surface);
cairo_set_line_width(cr, 1);
abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
cairo_set_source_rgb(cr, r, g, b);
- cairo_rectangle(cr, 0, 0, w, h);
+ cairo_rectangle(cr, 0, 0, w_text, h_text);
cairo_fill(cr);
cairo_stroke(cr);
if (attr)
cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+ int size = 16;
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
if (attr)
- cairo_set_font_size(cr, atoi(attr->value->data));
+ size = atoi(attr->value->data);
+
+ cairo_set_font_size(cr, size * ctx->gl_scale);
+ cairo_text_extents (cr, obj->text->data, &extents);
- 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;
+ x_bearing = w_text - extents.width - x_bearing;
else if (!__html_strcmp(attr->value->data, "center"))
- x_bearing = (w - extents.width) / 2 - x_bearing;
+ x_bearing = (w_text - 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;
+ y_bearing += h_text - extents.height;
else if (!__html_strcmp(attr->value->data, "center"))
- y_bearing += (h - extents.height) / 2;
+ y_bearing += (h_text - extents.height) / 2;
}
cairo_move_to (cr, x_bearing, y_bearing);
glActiveTexture(GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, texture_rgba);
- glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
+ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
glUniform1i(uniform_rgba, 0);
// draw
static int _draw_text_line(abc_obj_t* obj, const char* text,
int x, int y, int w, int h, int width, int height,
float mvp[16],
- double bcolor[3], double fcolor[3], int font_size, int bold, int italic, int line_type, int line_width)
+ double bcolor[3], double fcolor[3], int font_size, int bold, int italic, int line_type, double line_width, double scale)
{
- uint8_t* bgra = calloc(1, w * h * 4);
+ int w_text = w * scale;
+ int h_text = h * scale;
+
+ uint8_t* bgra = calloc(1, w_text * h_text * 4);
if (!bgra)
return -ENOMEM;
cairo_surface_t* surface;
cairo_t* cr;
- surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w, h, w * 4);
+ surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4);
cr = cairo_create(surface);
cairo_set_line_width(cr, 1);
cairo_set_source_rgba(cr, bcolor[0], bcolor[1], bcolor[2], 0.0);
- cairo_rectangle(cr, 0, 0, w, h);
+ cairo_rectangle(cr, 0, 0, w_text, h_text);
cairo_fill(cr);
cairo_stroke(cr);
if (attr)
cairo_select_font_face(cr, attr->value->data, italic, bold);
- cairo_set_font_size (cr, font_size);
+ cairo_set_font_size (cr, font_size * scale);
cairo_set_source_rgba(cr, fcolor[0], fcolor[1], fcolor[2], 1.0);
- __draw_text(&extents, cr, text, 0, 0, obj->y_bearing, line_type, line_width);
+ __draw_text(&extents, cr, text, 0, 0, obj->y_bearing * scale, line_type, line_width * scale);
// cairo_surface_write_to_png(surface, "tmp.png");
// board
glActiveTexture(GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, texture_rgba);
- glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
+ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
glUniform1i(uniform_rgba, 0);
// draw
return 0;
}
-static int _render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int _render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
if (obj->w <= 0 || obj->h <= 0)
return 0;
if (!obj->text_splits)
return _draw_text_line(obj, obj->text->data,
x, y, w, h, width, height, mvp,
- bcolor, fcolor, size, bold, italic, line_type, line_width);
+ bcolor, fcolor, size, bold, italic, line_type, line_width, ctx->gl_scale);
while (obj->text_splits) {
t = obj->text_splits;
_draw_text_line(obj, s->data,
x, y, w, h, width, height, mvp,
- bcolor, fcolor, size, bold, italic, line_type, line_width);
+ bcolor, fcolor, size, bold, italic, line_type, line_width, ctx->gl_scale);
scf_string_free(s);
s = NULL;
return 0;
}
-static int _render_draw_video(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int _render_draw_video(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
{
scf_list_t* l;
abc_frame_t* f;
static void resize(GtkGLArea* self, gint width, gint height, gpointer user_data)
{
- GdkGLContext *context;
+ GdkGLContext* context;
+ abc_ctx_t* ctx = user_data;
gtk_gl_area_make_current(self);
scf_logi("width: %d, height: %d\n", width, height);
+ ctx->gl_width = width;
+ ctx->gl_height = height;
+
context = gtk_gl_area_get_context(self);
if (gdk_gl_context_get_use_es(context))
int width = gtk_widget_get_allocated_width (GTK_WIDGET(self));
int height = gtk_widget_get_allocated_height(GTK_WIDGET(self));
- scf_logd("root: %p, width: %d, height: %d\n\n", root, width, height);
+ ctx->gl_scale = ctx->gl_width / (double)width;
+
+ scf_logi("root: %p, width: %d, height: %d, scale: %lg\n\n", root, width, height, ctx->gl_scale);
- glViewport(0, 0, width, height);
+ glViewport(0, 0, width * ctx->gl_scale, height * ctx->gl_scale);
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
if (gtk_widget_get_window(GTK_WIDGET(ctx->gl_area)) == event->window) {
- scf_logw("event x_root: %f, y_root: %f, x: %f, y: %f\n",
- event->x_root, event->y_root, event->x, event->y);
+ int scale = gtk_widget_get_scale_factor(self);
+
+ scf_logw("event x_root: %f, y_root: %f, x: %f, y: %f, scale: %d\n",
+ event->x_root, event->y_root, event->x, event->y, scale);
int ret = __do_button_release(ctx, event->x, event->y);
if (ret > 0)
if (gtk_widget_get_window(GTK_WIDGET(ctx->gl_area)) == event->window) {
- scf_logw("event x_root: %f, y_root: %f, x: %f, y: %f\n",
- event->x_root, event->y_root, event->x, event->y);
+ scf_logw("event x_root: %f, y_root: %f, x: %f, y: %f, ctx->gl_scale: %lg\n",
+ event->x_root, event->y_root, event->x, event->y, ctx->gl_scale);
abc_html_t* html;
abc_obj_t* obj = abc_obj_find(ctx->current->root, event->x, event->y);
obj = ctx->current->current;
if (obj) {
obj->jiffies++;
-// gtk_gl_area_queue_render(ctx->gl_area);
+
+ if (ABC_HTML_INPUT == obj->type && 0 == obj->jiffies % 64)
+ gtk_gl_area_queue_render(ctx->gl_area);
}
if (ctx->current->has_video)
forward = gtk_builder_get_object(builder, "button_forward");
refresh = gtk_builder_get_object(builder, "button_refresh");
- ctx.current = html;
- ctx.builder = builder;
- ctx.gl_area = GTK_GL_AREA(gl_area);
+ ctx.current = html;
+ ctx.builder = builder;
+ ctx.gl_area = GTK_GL_AREA(gl_area);
+ ctx.gl_scale = 1.0;
ctx.back = GTK_BUTTON(back);
ctx.forward = GTK_BUTTON(forward);
g_signal_connect(forward, "clicked", G_CALLBACK(forward_clicked), &ctx);
g_signal_connect(refresh, "clicked", G_CALLBACK(refresh_clicked), &ctx);
- g_signal_connect(gl_area, "resize", G_CALLBACK(resize), NULL);
+ g_signal_connect(gl_area, "resize", G_CALLBACK(resize), &ctx);
g_signal_connect(gl_area, "unrealize", G_CALLBACK(unrealize), NULL);
g_signal_connect(gl_area, "render", G_CALLBACK(render), &ctx);