css : support complex pse class (element) chain for HTML object.
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<style>
+div {
+ background-color:gray;
+ width: 200px;
+ height: 50px;
+ border: 1px dotted black;
+ overflow: visible;
+}
+</style>
+</head>
+
+<body>
+
+<div id="overflowTest">
+<p>这里的文本内容会溢出元素框。</p>
+<p>这里的文本内容会溢出元素框。</p>
+<p>这里的文本内容会溢出元素框。</p>
+</div>
+
+</body>
+</html>
{
color:red;
}
+
+.violet:first-child b
+{
+ color:violet;
+}
</style>
</head>
<body>
+<p class="violet">I am a <b>strong</b> man. I am a <b>strong</b> man.</p>
+
<p>I am a <b>strong</b> man. I am a <b>strong</b> man.</p>
<p>I am a <b>strong</b> man. I am a <b>strong</b> man.</p>
+
<p><b>注意:</b> 当 :first-child 作用于 IE8 以及更早版本的浏览器, !DOCTYPE 必须已经定义.</p>
</body>
</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<style>
+h2.pos_left
+{
+ position:relative;
+ left:-10px;
+}
+
+h2.pos_right
+{
+ position:relative;
+ left:10px;
+}
+</style>
+</head>
+
+<body>
+<h2>这是位于正常位置的标题</h2>
+<h2 class="pos_left">这个标题相对于其正常位置向左移动</h2>
+<h2 class="pos_right">这个标题相对于其正常位置向右移动</h2>
+<p>相对定位会按照元素的原始位置对该元素进行移动。</p>
+<p>样式 "left:-20px" 从元素的原始左侧位置减去 20 像素。</p>
+<p>样式 "left:20px" 向元素的原始左侧位置增加 20 像素。</p>
+</body>
+</html>
int i;
int j;
+ int k;
if (attrs && n_attrs > 0) {
for (i = 0; i < n_attrs; i++) {
return -EINVAL;
found:
- for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
-
- for (j = 0; attr->keys[j]; j++) {
- if (!__html_strcmp(attr->keys[j], key->data))
- break;
- }
- }
+ k = attrs[i].type;
+ assert(k >= ABC_HTML_ATTR_ID && k < ABC_HTML_CSS_NB);
- if (l == scf_list_sentinel(&obj->attrs)) {
+ attr = obj->attrs[k - ABC_HTML_ATTR_ID];
+ if (!attr) {
int ret = __html_add_attr(obj, attrs[i].type, attrs[i].names, attrs[i].value, attrs[i].flags);
if (ret < 0)
return ret;
- l = scf_list_tail(&obj->attrs);
- attr = scf_list_data(l, abc_obj_t, list);
+ attr = obj->attrs[k - ABC_HTML_ATTR_ID];
}
scf_string_free(key);
};
}
-static void __css_set_pse(abc_obj_t* obj, abc_obj_t* pse, int colon)
+static int __css_set_pse_dynamic(abc_obj_t* obj, abc_obj_t* pse)
{
- scf_string_t* s;
- scf_list_t* l;
- abc_obj_t* attr;
- abc_obj_t* attr2;
- abc_obj_t* pse2;
-
- if (scf_list_empty(&pse->attrs))
- return;
+ scf_list_t* l;
+ abc_obj_t* pse2;
- if (colon > 0 && ':' == pse->text->data[colon - 1])
- colon--;
+ for (l = scf_list_head(&obj->css_pse_rules); l != scf_list_sentinel(&obj->css_pse_rules); l = scf_list_next(l)) {
+ pse2 = scf_list_data(l, abc_obj_t, list);
- char* key = pse->text->data + colon;
- int len = pse->text->len - colon;
+ if (pse2->type == pse->type
+ && pse2->text->len == pse->text->len
+ && !__html_strcmp(pse2->text->data, pse->text->data))
+ break;
+ }
- pse2 = abc_obj_get_attr2(obj, key, len);
- if (!pse2) {
+ if (l == scf_list_sentinel(&obj->css_pse_rules))
+ {
pse2 = abc_obj_alloc(pse->file, pse->line, pse->pos, pse->type);
if (!pse2)
- return;
+ return -ENOMEM;
+
+ pse2->text = scf_string_clone(pse->text);
+ if (!pse2->text) {
+ abc_obj_free(pse2);
+ return -ENOMEM;
+ }
pse2->flags = pse->flags;
pse2->keys = pse->keys;
- }
-
- s = scf_string_clone(pse->text);
- if (!s)
- return;
-
- if (pse2->text)
- scf_string_free(pse2->text);
-
- pse2->text = s;
-
- for (l = scf_list_head(&pse->attrs); l != scf_list_sentinel(&pse->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
-
- if (!attr->value || 0 == attr->value->len)
- continue;
- attr2 = abc_obj_alloc(attr->file, attr->line, attr->pos, attr->type);
- if (!attr2)
- return;
+ scf_list_add_tail(&obj->css_pse_rules, &pse2->list);
+ }
- attr2->value = scf_string_clone(attr->value);
- if (!attr2->value) {
- abc_obj_free(attr2);
- return;
- }
+ int ret = abc_obj_copy_attrs(pse2, pse);
+ if (ret < 0)
+ return ret;
- attr2->keys = attr->keys;
- attr2->flags = attr->flags;
+ switch (pse->css_pse_type) {
+ case ABC_CSS_LINK:
+ abc_obj_set_css(obj, pse);
+ break;
+ default:
+ break;
+ };
- scf_list_add_tail(&pse2->attrs, &attr2->list);
+ scf_slist_clear(pse2->css_pse_chain, pse_link_t, next, free);
- switch (pse->css_pse_type)
- {
- case ABC_CSS_FIRST_CHILD:
- case ABC_CSS_LINK:
- __css_set_attr(obj, attr);
- break;
- default:
- break;
- };
- }
+ pse2->css_pse_chain = pse->css_pse_chain;
+ pse ->css_pse_chain = NULL;
}
static void __css_merge(abc_obj_t* dst, abc_obj_t* src)
{
- scf_list_t* l;
- abc_obj_t* s;
- abc_obj_t* d;
+ abc_obj_t* s;
+ abc_obj_t* d;
+ int i;
- for (l = scf_list_head(&src->attrs); l != scf_list_sentinel(&src->attrs); ) {
- s = scf_list_data(l, abc_obj_t, list);
- l = scf_list_next(l);
+ for (i = 0; i < sizeof(src->attrs) / sizeof(src->attrs[0]); i++) {
+ s = src->attrs[i];
- d = abc_obj_get_attr(dst, s->type);
+ if (!s || !s->value || 0 == s->value->len)
+ continue;
+
+ d = dst->attrs[i];
if (d)
SCF_XCHG(d->value, s->value);
else {
- scf_list_del(&s->list);
- scf_list_add_tail(&dst->attrs, &s->list);
+ dst->attrs[i] = s;
+ src->attrs[i] = NULL;
}
}
}
scf_list_t* l;
abc_obj_t* tmp;
abc_obj_t* pse;
+ pse_link_t* pseLink;
assert(next >= 0 && next < vec->size);
if (!current)
return NULL;
+ pseLink = calloc(1, sizeof(pse_link_t));
+ if (!pseLink)
+ return NULL;
+
+ pseLink->obj = current;
+ pseLink->pse_type = pse->type;
+ pseLink->next = css->css_pse_chain;
+
+ 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);
break;
scf_list_t* l;
abc_obj_t* tmp;
abc_obj_t* attr;
+ abc_obj_t* pse;
+ pse_link_t* pseLink;
assert(next >= 0 && next < vec->size);
current = tmp;
break;
+
+ case ':':
+ assert(next - 1 >= 0 && next - 1 < vec->size);
+
+ 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)
+ return NULL;
+
+ current = __css_select_by_attr(css, current, vec, next - 1, type, key, len);
+ if (!current)
+ return NULL;
+
+ pse = abc_obj_get_attr2(current, css->text->data + j, k - j);
+ if (!pse)
+ return NULL;
+
+ if (css->css_pse_type < pse->type)
+ css->css_pse_type = pse->type;
+
+ current = __css_filter_pse(current, pse);
+ if (!current)
+ return NULL;
+
+ pseLink = calloc(1, sizeof(pse_link_t));
+ if (!pseLink)
+ return NULL;
+
+ pseLink->obj = current;
+ pseLink->pse_type = pse->type;
+ pseLink->next = css->css_pse_chain;
+
+ 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);
+ break;
default:
attr = abc_obj_get_attr(current, type);
scf_vector_t* vec;
abc_obj_t* current = obj;
- int colon = -1;
int c;
int i;
int j = css->text->len;
goto end;
css->css_pse_type = 0;
+ scf_slist_clear(css->css_pse_chain, pse_link_t, next, free);
for (i = css->text->len - 1; i >= 0; i--) {
c = css->text->data[i];
break;
case ':':
- if (colon < 0)
- colon = i;
-
if (i > 0 && ':' == css->text->data[i - 1])
{
if (j < css->text->len) {
}
}
- if (colon < 0)
+ if (css->css_pse_type < ABC_CSS_PSE_STATIC)
abc_obj_set_css(obj, css);
else
- __css_set_pse(obj, css, colon);
+ __css_set_pse_dynamic(obj, css);
ret = 0;
end:
+ scf_slist_clear(css->css_pse_chain, pse_link_t, next, free);
scf_vector_free(vec);
return ret;
}
if (ret < 0 && EOF != ret)
return ret;
- for (l = scf_list_head(&css->attrs); l != scf_list_sentinel(&css->attrs); ) {
- attr = scf_list_data(l, abc_obj_t, list);
- l = scf_list_next(l);
+ int i;
+ for (i = 0; i < sizeof(css->attrs) / sizeof(css->attrs[0]); i++) {
+ attr = css->attrs[i];
+ if (!attr)
+ continue;
__css_set_attr(obj, attr);
- scf_list_del(&attr->list);
abc_obj_free(attr);
- attr = NULL;
+ css->attrs[i] = NULL;
}
}
}
void abc_obj_set_css(abc_obj_t* obj, abc_obj_t* css)
+{
+ abc_obj_t* attr;
+ int i;
+
+ for (i = 0; i < sizeof(css->attrs) / sizeof(css->attrs[0]); i++) {
+ attr = css->attrs[i];
+
+ if (attr)
+ __css_set_attr(obj, attr);
+ }
+}
+
+int abc_css_active(abc_obj_t* obj)
{
scf_list_t* l;
- abc_obj_t* attr;
+ abc_obj_t* css;
+ pse_link_t* pseLink;
- for (l = scf_list_head(&css->attrs); l != scf_list_sentinel(&css->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
+ int n = 0;
+ for (l = scf_list_head(&obj->css_pse_rules); l != scf_list_sentinel(&obj->css_pse_rules); l = scf_list_next(l)) {
+ css = scf_list_data(l, abc_obj_t, list);
- __css_set_attr(obj, attr);
+ pseLink = css->css_pse_chain;
+ while (pseLink) {
+ if (pseLink->obj->css_pse_type != pseLink->pse_type)
+ break;
+
+ pseLink = pseLink->next;
+ }
+
+ if (!pseLink) {
+ abc_obj_set_css(obj, css);
+ n++;
+ }
}
+
+ return n;
}
*r = 0.0;
*g = 0.0;
*b = 0.0;
- *width = 1;
+ *width = 0;
*type = ABC_BORDER_SOLID;
const uint8_t* p = NULL;
double g = 0.0;
double b = 0.0;
- abc_obj_t* attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_MARGIN);
+ abc_obj_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_MARGIN);
if (attr)
margin = atoi(attr->value->data);
- attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BORDER);
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BORDER);
if (attr)
abc_css_border(&r, &g, &b, &border, &type, obj, attr->value->data);
- attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_PADDING);
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_PADDING);
if (attr)
padding = atoi(attr->value->data);
int x = 0;
double value = 0.0;
+ double decimal = 0.1;
+ int neg = 0;
int dot = 0;
int percent = 0;
int prev = 0;
do {
c = *str;
- if ('.' == c)
- dot = 10;
+ if ('-' == c)
+ neg++;
+ else if ('.' == c)
+ dot++;
else if ('%' == c)
percent++;
} else if ('0' <= c && '9' >= c) {
- if (dot > 0) {
- value += (c - '0') / (double)dot;
- dot *= 10;
+ if (dot) {
+ value += (c - '0') * decimal;
+ decimal *= 0.1;
} else {
value *= 10.0;
value += c - '0';
if (' ' == prev || '\t' == prev || '\r' == prev || '\n' == prev)
goto next;
+ if (neg)
+ value = -value;
+
if (percent)
x = value * 0.01 * len;
else if (unit) {
// for other css units, ignore
x = value;
- }
+ } else
+ x = value;
unit = NULL;
value = 0.0;
}
}
-int abc_css_position(float* x, float* y, float w, float h, abc_obj_t* obj, const uint8_t* str)
+int abc_css_bg_position(float* x, float* y, float w, float h, abc_obj_t* obj, const uint8_t* str)
{
*x = 0.5 - w / 2;
*y = 0.5 - h / 2;
return 0;
}
+
+int abc_css_position(const uint8_t* str)
+{
+ if (!__html_strcmp(str, "relative"))
+ return ABC_POSITION_RELATIVE;
+
+ else if (!__html_strcmp(str, "absolute"))
+ return ABC_POSITION_ABSOLUTE;
+
+ else if (!__html_strcmp(str, "fixed"))
+ return ABC_POSITION_FIXED;
+
+ else if (!__html_strcmp(str, "sticky"))
+ return ABC_POSITION_STICKY;
+
+ return ABC_POSITION_STATIC;
+}
static char* border_keys[] = {"border", "边框", NULL};
static char* padding_keys[] = {"padding", "内边距", NULL};
+static char* overflow_keys[] = {"overflow", NULL};
+
+static char* position_keys[] = {"position", "定位", NULL};
+static char* top_keys[] = {"top", "上", NULL};
+static char* bottom_keys[] = {"bottom", "下", NULL};
+static char* left_keys[] = {"left", "左", NULL};
+static char* right_keys[] = {"right", "右", NULL};
+
static char* font_keys[] = {"font", "字体", NULL};
static char* font_size_keys[] = {"font-size", "字号", NULL};
static char* font_color_keys[] = {"font-color", "字体颜色", "color", "颜色", NULL};
{border_keys, #border, ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, \
{padding_keys, #padding, 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},
+ {overflow_keys, "", ABC_HTML_ATTR_OVERFLOW, ABC_HTML_FLAG_SHOW}, \
+ \
+ {position_keys, "", ABC_HTML_ATTR_POSITION, ABC_HTML_FLAG_SHOW}, \
+ {top_keys, "", ABC_HTML_ATTR_TOP, ABC_HTML_FLAG_SHOW}, \
+ {bottom_keys, "", ABC_HTML_ATTR_BOTTOM, ABC_HTML_FLAG_SHOW}, \
+ {left_keys, "", ABC_HTML_ATTR_LEFT, ABC_HTML_FLAG_SHOW}, \
+ {right_keys, "", ABC_HTML_ATTR_RIGHT, ABC_HTML_FLAG_SHOW}, \
+ \
+ {width_keys, "", ABC_HTML_ATTR_WIDTH, ABC_HTML_FLAG_SHOW}, \
+ {height_keys, "", ABC_HTML_ATTR_HEIGHT, ABC_HTML_FLAG_SHOW},
#define ABC_CSS_SELECTOR() \
{style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW}, \
ABC_CSS_TEXT(left, )
};
+static html_attr_t div_attrs[] =
+{
+ ABC_CSS_BOX(2px, , 2px)
+ ABC_CSS_SELECTOR()
+ ABC_CSS_BACK_GROUND()
+
+ ABC_CSS_FONT(SimSong, 16, black, )
+ ABC_CSS_TEXT(left, )
+};
+
static html_attr_t h1_attrs[] =
{
ABC_CSS_BOX(2px, , 2px)
{head_keys, ABC_HTML_HEAD, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
{title_keys, ABC_HTML_TITLE, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
{body_keys, ABC_HTML_BODY, abc_number_of(body_attrs), body_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
- {div_keys, ABC_HTML_DIV, abc_number_of(body_attrs), body_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+ {div_keys, ABC_HTML_DIV, abc_number_of(div_attrs), div_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
{h1_keys, ABC_HTML_H1, abc_number_of(h1_attrs), h1_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
{h2_keys, ABC_HTML_H2, abc_number_of(h2_attrs), h2_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
int __html_add_attr(abc_obj_t* obj, int type, char** names, const char* value, int flags)
{
+ if (type < ABC_HTML_ATTR_ID || type >= ABC_HTML_CSS_NB)
+ return -EINVAL;
+
abc_obj_t* attr = abc_obj_alloc(NULL, 0, 0, type);
if (!attr)
return -ENOMEM;
attr->flags = flags;
- scf_list_add_tail(&obj->attrs, &attr->list);
+ int i = type - ABC_HTML_ATTR_ID;
+ if (obj->attrs[i])
+ abc_obj_free(obj->attrs[i]);
+
+ obj->attrs[i] = attr;
return 0;
}
} else if (obj->parent) {
- for (l = scf_list_head(&obj->parent->attrs); l != scf_list_sentinel(&obj->parent->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
+ for (i = 0; i < sizeof(obj->parent->attrs) / sizeof(obj->parent->attrs[0]); i++) {
+ attr = obj->parent->attrs[i];
+ if (!attr)
+ continue;
ret = __html_add_attr(obj, attr->type, attr->keys, attr->value->data, 0);
if (ret < 0)
free(c);
c = NULL;
- scf_list_t* l;
abc_obj_t* attr;
+ int i;
+ int j;
- for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
-
- int j;
- for (j = 0; attr->keys[j]; j++) {
+ for (i = 0; i < sizeof(obj->attrs) / sizeof(obj->attrs[0]); i++) {
+ attr = obj->attrs[i];
+ if (!attr)
+ continue;
+ for (j = 0; attr->keys[j]; j++)
+ {
if (!__html_strcmp(attr->keys[j], key->data))
goto found;
}
}
- if (l == scf_list_sentinel(&obj->attrs)) {
-
+ if (i >= sizeof(obj->attrs) / sizeof(obj->attrs[0])) {
scf_loge("invalid HTML attribute '%s' in file: %s, line: %d\n", key->data, html->file->data, html->n_lines);
scf_string_free(key);
return -1;
int abc_css_parse (abc_obj_t* css);
int abc_css_merge (abc_html_t* html, abc_obj_t* css);
int abc_css_use (abc_html_t* html, abc_obj_t* obj);
+int abc_css_active(abc_obj_t* obj);
-int abc_css_color (double* r, double* g, double* b, const uint8_t* str);
-int abc_css_position(float* x, float* y, float w, float h, abc_obj_t* obj, const uint8_t* str);
+int abc_css_bg_position(float* x, float* y, float w, float h, abc_obj_t* obj, const uint8_t* str);
+int abc_css_color (double* r, double* g, double* b, const uint8_t* str);
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);
int abc_css_width (abc_obj_t* obj, int width, int margin);
int abc_css_height(abc_obj_t* obj, int height, int margin);
+int abc_css_position(const uint8_t* str);
+
#endif
}
scf_list_init(&obj->list);
- scf_list_init(&obj->attrs);
scf_list_init(&obj->childs);
+ scf_list_init(&obj->css_pse_rules);
obj->type = type;
abc_filter_close(obj->av_filter, 0);
#endif
- scf_list_clear(&obj->attrs, abc_obj_t, list, abc_obj_free);
- scf_list_clear(&obj->childs, abc_obj_t, list, abc_obj_free);
+ scf_list_clear(&obj->childs, abc_obj_t, list, abc_obj_free);
+ scf_list_clear(&obj->css_pse_rules, abc_obj_t, list, abc_obj_free);
+ scf_slist_clear(obj->css_pse_chain, pse_link_t, next, free);
free(obj);
}
int abc_obj_copy_attrs(abc_obj_t* dst, abc_obj_t* src)
{
- scf_list_t* l;
- abc_obj_t* attr;
- abc_obj_t* copy;
+ abc_obj_t* attr;
+ abc_obj_t* copy;
+ int i;
- for (l = scf_list_head(&src->attrs); l != scf_list_sentinel(&src->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
+ for (i = 0; i < sizeof(src->attrs) / sizeof(src->attrs[0]); i++) {
+ attr = src->attrs[i];
+ if (!attr)
+ continue;
copy = abc_obj_alloc(attr->file, attr->line, attr->pos, attr->type);
if (!copy)
copy->keys = attr->keys;
copy->flags = attr->flags;
- scf_list_add_tail(&dst->attrs, ©->list);
+ if (dst->attrs[i])
+ abc_obj_free(dst->attrs[i]);
+
+ dst->attrs[i] = copy;
}
return 0;
int abc_obj_set_attr(abc_obj_t* obj, int key, const char* value, size_t len)
{
scf_string_t* s;
- scf_list_t* l;
abc_obj_t* attr;
- for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
+ if (key < ABC_HTML_ATTR_ID || key >= ABC_HTML_CSS_NB)
+ return -EINVAL;
- if (attr->type == key) {
- s = scf_string_cstr_len(value, len);
- if (s) {
- scf_string_free(attr->value);
- attr->value = s;
- return 0;
- }
- return -ENOMEM;
- }
- }
+ attr = obj->attrs[key - ABC_HTML_ATTR_ID];
+ if (!attr)
+ return -EINVAL;
+
+ s = scf_string_cstr_len(value, len);
+ if (!s)
+ return -ENOMEM;
- return -EINVAL;
+ scf_string_free(attr->value);
+ attr->value = s;
+ return 0;
}
abc_obj_t* abc_obj_get_attr2(abc_obj_t* obj, const char* key, int len)
{
- scf_list_t* l;
- abc_obj_t* attr;
+ abc_obj_t* attr;
+ int i;
- for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
+ for (i = 0; i < sizeof(obj->attrs) / sizeof(obj->attrs[0]); i++) {
+ attr = obj->attrs[i];
- if (!abc_obj_cmp_keys(attr, key, len))
+ if (attr && !abc_obj_cmp_keys(attr, key, len))
return attr;
}
return NULL;
}
-abc_obj_t* abc_obj_get_attr(abc_obj_t* obj, int key)
+abc_obj_t* abc_obj_find_attr(abc_obj_t* obj, int key)
{
- scf_list_t* l;
- abc_obj_t* attr;
+ abc_obj_t* attr;
- for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
+ while (obj) {
+ attr = abc_obj_get_attr(obj, key);
- if (attr->type == key)
+ if (attr && attr->value && attr->value->len > 0)
return attr;
+
+ obj = obj->parent;
}
return NULL;
}
-abc_obj_t* abc_obj_find_attr(abc_obj_t* obj, int key)
+void abc_css_print(abc_obj_t* obj)
{
- abc_obj_t* attr;
+ if (!obj)
+ return;
- while (obj) {
- attr = abc_obj_get_attr(obj, key);
+ if (!(ABC_HTML_FLAG_SHOW & obj->flags))
+ return;
- if (attr && attr->value && attr->value->len > 0)
- return attr;
+ if (obj->text)
+ printf("%s ", obj->text->data);
+ else if (obj->keys)
+ printf("%s ", obj->keys[0]);
- obj = obj->parent;
+ pse_link_t* pseLink;
+ abc_obj_t* attr;
+ int i;
+
+ printf("{\n");
+
+ for (i = 0; i < sizeof(obj->attrs) / sizeof(obj->attrs[0]); i++) {
+ attr = obj->attrs[i];
+
+ if (!attr || !attr->value || 0 == attr->value->len)
+ continue;
+
+ if (ABC_HTML_FLAG_SHOW & attr->flags)
+ printf(" %s: %s;\n", attr->keys[0], attr->value->data);
}
- return NULL;
+ pseLink = obj->css_pse_chain;
+ while (pseLink) {
+ attr = abc_obj_get_attr(pseLink->obj, pseLink->pse_type);
+
+ printf("%s%s ", pseLink->obj->keys[0], attr->keys[0]);
+
+ pseLink = pseLink->next;
+ }
+
+ printf("}\n");
}
void abc_obj_print(abc_obj_t* obj)
} else if (obj->keys)
printf("<%s", obj->keys[0]);
- for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
+ 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)
abc_obj_print(attr);
for (l = scf_list_head(&obj->childs); l != scf_list_sentinel(&obj->childs); l = scf_list_next(l)) {
child = scf_list_data(l, abc_obj_t, list);
- abc_obj_print(child);
+ switch (obj->type)
+ {
+ case ABC_HTML_LINK:
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TYPE);
+
+ if (!attr || __html_strcmp(attr->value->data, "text/css"))
+ break;
+ case ABC_HTML_STYLE:
+ abc_css_print(child);
+ break;
+
+ default:
+ abc_obj_print(child);
+ break;
+ };
+ }
+
+ for (l = scf_list_head(&obj->css_pse_rules); l != scf_list_sentinel(&obj->css_pse_rules); l = scf_list_next(l)) {
+ child = scf_list_data(l, abc_obj_t, list);
+
+ abc_css_print(child);
}
if (ABC_HTML_FLAG_CLOSE == (obj->flags & (ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SINGLE))) {
return ret;
}
- for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
+ 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) {
ret = __abc_obj_to_string(attr, s);
#include"abc_ffmpeg.h"
#include"abc_io.h"
-typedef struct abc_obj_s abc_obj_t;
-typedef struct abc_text_s abc_text_t;
+typedef struct abc_obj_s abc_obj_t;
+typedef struct abc_text_s abc_text_t;
+typedef struct pse_link_s pse_link_t;
enum abc_objs
{
ABC_HTML_ATTR_BORDER,
ABC_HTML_ATTR_PADDING,
+ ABC_HTML_ATTR_POSITION,
+ ABC_HTML_ATTR_TOP,
+ ABC_HTML_ATTR_BOTTOM,
+ ABC_HTML_ATTR_LEFT,
+ ABC_HTML_ATTR_RIGHT,
+
+ ABC_HTML_ATTR_OVERFLOW,
+
ABC_HTML_ATTR_XMLNS,
ABC_HTML_ATTR_XMLANG,
ABC_HTML_ATTR_LANG,
ABC_HTML_ATTR_CONTROLS,
- // css objects
+ // css attrs
ABC_CSS_LIST_STYLE,
ABC_CSS_LIST_STYLE_TYPE,
ABC_CSS_LIST_STYLE_IMAGE,
ABC_CSS_BORDER_COLLAPSE,
- // css pse class or pse element, first status onload
+ // css pse class (element)
ABC_CSS_FIRST_CHILD,
- ABC_CSS_LINK,
- // status after user operations
+ ABC_CSS_PSE_STATIC, // css pse static barrier, all pse classes (elements) above only based on HTML topology
+
+ ABC_CSS_LINK,
ABC_CSS_VISITED,
ABC_CSS_HOVER,
ABC_CSS_ACTIVE,
- // ... new css add here
+ ABC_CSS_PSE_DYNAMIC, // css pse dynamic barrier, pse classes (elements) above based on user operations
+
+ ABC_HTML_CSS_NB = ABC_CSS_PSE_DYNAMIC, // total HTML & CSS attrs
// css selectors
ABC_CSS_PSE_CLASS,
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,
+ ABC_CSS_POSITION = ABC_HTML_ATTR_POSITION,
+ ABC_CSS_OVERFLOW = ABC_HTML_ATTR_OVERFLOW,
};
enum abc_border_style
ABC_BORDER_DASHED,
};
+enum abc_position_style
+{
+ ABC_POSITION_STATIC,
+ ABC_POSITION_RELATIVE,
+ ABC_POSITION_ABSOLUTE,
+ ABC_POSITION_FIXED,
+ ABC_POSITION_STICKY,
+};
+
enum abc_line_style
{
ABC_LINE_NONE,
int h;
};
+struct pse_link_s
+{
+ pse_link_t* next;
+
+ abc_obj_t* obj;
+ int pse_type;
+};
+
+#define ABC_HTML_FLAG_OPEN 0
+#define ABC_HTML_FLAG_CLOSE 1
+#define ABC_HTML_FLAG_SINGLE 2
+#define ABC_HTML_FLAG_SHOW 4
+
struct abc_obj_s
{
- scf_list_t list;
+ int type;
+ uint32_t flags;
- scf_list_t attrs;
+ char** keys;
+ scf_string_t* value;
+
+ abc_obj_t* parent;
+
+ scf_list_t list;
scf_list_t childs;
int n_childs;
int index;
- abc_obj_t* parent;
+ abc_obj_t* attrs[ABC_HTML_CSS_NB - ABC_HTML_ATTR_ID];
void* gtk_builder;
abc_filter_t* av_filter;
abc_avio_t* vout;
- int type;
+ scf_string_t* text;
+ abc_text_t* text_splits; // for layout, split a long text to multi-lines and save every-line here
+ int text_line;
+ int text_pos;
+ abc_io_t io;
-#define ABC_HTML_FLAG_OPEN 0
-#define ABC_HTML_FLAG_CLOSE 1
-#define ABC_HTML_FLAG_SINGLE 2
-#define ABC_HTML_FLAG_SHOW 4
- uint32_t flags;
+ pse_link_t* css_pse_chain;
+ scf_list_t css_pse_rules;
+ int css_pse_type;
int d; // margin + border + padding
int w0;
int progress;
uint32_t jiffies; // timeout numbers of sys timer
- char** keys;
- scf_string_t* value;
- scf_string_t* text;
- abc_text_t* text_splits; // for layout, split a long text to multi-lines and save every-line here
-
- int text_line;
- int text_pos;
- abc_io_t io;
-
- int css_pse_type;
scf_string_t* file; // file name
int line; // line
int abc_obj_set_attr (abc_obj_t* obj, int key, const char* value, size_t len);
abc_obj_t* abc_obj_get_attr2(abc_obj_t* obj, const char* key, int len);
-abc_obj_t* abc_obj_get_attr (abc_obj_t* obj, int key);
abc_obj_t* abc_obj_find_attr(abc_obj_t* obj, int key);
abc_obj_t* abc_obj_find_type(abc_obj_t* root, int type);
scf_string_t* abc_ol_list_style(abc_obj_t* obj, int num);
+
+static inline abc_obj_t* abc_obj_get_attr(abc_obj_t* obj, int key)
+{
+ if (key < ABC_HTML_ATTR_ID || key >= ABC_HTML_CSS_NB)
+ return NULL;
+
+ return obj->attrs[key - ABC_HTML_ATTR_ID];
+}
+
#endif
CFILES += ../js/parse/scf_dfa_async.c
CFILES += ../js/parse/scf_dfa_block.c
-CFLAGS += -g -O3 -D_GNU_SOURCE
+CFLAGS += -g -D_GNU_SOURCE
CFLAGS += -I./
CFLAGS += -I../html
CFLAGS += -I../ffmpeg
attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_POSITION);
if (attr) {
- abc_css_position(&x, &y, w, h, obj, attr->value->data);
+ abc_css_bg_position(&x, &y, w, h, obj, attr->value->data);
scf_logd("background-position: %s, x: %f, y: %f, w: %f, h: %f\n", attr->value->data, x, y, w, h);
[ABC_HTML_DIV] = abc_layout_div,
[ABC_CORE_TEXT] = abc_layout_text,
+ [ABC_HTML_B] = abc_layout_text,
+ [ABC_HTML_I] = abc_layout_text,
+ [ABC_HTML_A] = abc_layout_text,
[ABC_HTML_H1] = abc_layout_h1,
[ABC_HTML_H2] = abc_layout_h1,
[ABC_HTML_P] = abc_layout_h1,
[ABC_HTML_BR] = abc_layout_h1,
- [ABC_HTML_A] = abc_layout_h1,
[ABC_HTML_IMG] = abc_layout_img,
[ABC_HTML_FORM] = abc_layout_form,
[ABC_HTML_SCRIPT] = abc_layout_empty,
[ABC_HTML_STYLE] = abc_layout_empty,
[ABC_HTML_LINK] = abc_layout_empty,
-
- [ABC_HTML_B] = abc_layout_text,
- [ABC_HTML_I] = abc_layout_text,
};
int abc_layout_obj(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
}
}
-int abc_layout_css(abc_obj_t* root)
+#define LAYOUT_POS_FIXED(X, W, SET, L, R) \
+ do { \
+ if (!obj->SET) { \
+ if (L && R) { \
+ obj->X = parent->X + L; \
+ obj->W = parent->W - L - R; \
+ } else if (L) \
+ obj->X = parent->X + L; \
+ else if (R) \
+ obj->X = parent->X + parent->W - R - obj->W; \
+ } else if (L) \
+ obj->X = parent->X + L; \
+ else if (R) \
+ obj->X = parent->X + parent->W - R - obj->W; \
+ } while (0)
+
+#define LAYOUT_POS_RELATIVE(X, L, R) \
+ do { \
+ if (L) \
+ obj->X += L; \
+ else if (R) \
+ obj->X += R; \
+ } while (0)
+
+#define LAYOUT_POS_ABSOLUTE(X, W, L, R) \
+ do { \
+ abc_obj_t* tmp = parent; \
+ while (tmp && ABC_HTML != tmp->type) { \
+ abc_obj_t* attr = abc_obj_get_attr(tmp, ABC_HTML_ATTR_POSITION); \
+ \
+ if (attr && attr->value->len > 0 \
+ && __html_strcmp(attr->value->data, "static")) \
+ break; \
+ tmp = tmp->parent; \
+ } \
+ if (tmp) { \
+ if (L) \
+ obj->X = tmp->X + L; \
+ else if (R) \
+ obj->X = tmp->X + tmp->W - R - obj->W; \
+ } \
+ } while (0)
+
+int abc_layout_css(abc_obj_t* obj)
{
- abc_obj_t* parent = root->parent;
+ abc_obj_t* parent = obj->parent;
abc_obj_t* attr;
if (!parent || parent->w <= 0)
break;
};
- attr = abc_obj_get_attr(root, ABC_HTML_ATTR_TEXT_ALIGN);
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TEXT_ALIGN);
if (attr) {
- int x = root->x;
+ int x = obj->x;
if (!__html_strcmp(attr->value->data, "center"))
- root->x = parent->x + (parent->w - root->w) / 2 + 4;
+ obj->x = parent->x + (parent->w - obj->w) / 2 + 4;
else if (!__html_strcmp(attr->value->data, "right"))
- root->x = parent->x + parent->w - root->w - 8;
+ obj->x = parent->x + parent->w - obj->w - 8;
- abc_css_update_xy(root, root->x - x, 0);
+ abc_css_update_xy(obj, obj->x - x, 0);
}
- return 0;
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_POSITION);
+ if (!attr || 0 == attr->value->len)
+ return 0;
+
+ int pos_type = abc_css_position(attr->value->data);
+ if (ABC_POSITION_STATIC == pos_type)
+ return 0;
+
+ int top = 0;
+ int bottom = 0;
+ int left = 0;
+ int right = 0;
+
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TOP);
+ if (attr)
+ top = abc_css_length(obj, attr->value->data, obj->h);
+
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BOTTOM);
+ if (attr)
+ bottom = abc_css_length(obj, attr->value->data, obj->h);
+
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_LEFT);
+ if (attr)
+ left = abc_css_length(obj, attr->value->data, obj->w);
+
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_RIGHT);
+ if (attr)
+ right = abc_css_length(obj, attr->value->data, obj->w);
+
+ int x = obj->x;
+ int y = obj->y;
+
+ switch (pos_type)
+ {
+ case ABC_POSITION_FIXED:
+ LAYOUT_POS_FIXED(x, w, w_set, left, right);
+ LAYOUT_POS_FIXED(y, h, h_set, top, bottom);
+ break;
+
+ case ABC_POSITION_RELATIVE:
+ scf_logd("top: %d, bottom: %d, left: %d, right: %d, obj->w: %d, parent->w: %d\n", top, bottom, left, right, obj->w, parent->w);
+ LAYOUT_POS_RELATIVE(x, left, right);
+ LAYOUT_POS_RELATIVE(y, top, bottom);
+ break;
+
+ case ABC_POSITION_ABSOLUTE:
+ LAYOUT_POS_ABSOLUTE(x, w, left, right);
+ LAYOUT_POS_ABSOLUTE(y, h, top, bottom);
+ break;
+ default:
+ break;
+ };
+
+ abc_css_update_xy(obj, obj->x - x, obj->y - y);
+
+ return pos_type;
}
int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
return 0;
break;
+ case ABC_HTML:
+ root->d = abc_css_margin(root);
+ root->w = width;
+ root->h = height;
+
+ root->w0 = width;
+ root->h0 = height;
+
+ root->w_set = 1;
+ root->h_set = 1;
+ break;
+
case ABC_HTML_BODY:
case ABC_HTML_DIV:
root->d = abc_css_margin(root);
if (root->w_set) {
root->w0 = root->w;
root_w = root->w;
- } else {
-// if (ABC_HTML_BODY != root->type)
-// root->w = 0;
}
if (root->h_set) {
}
break;
default:
+ root->d = abc_css_margin(root);
break;
};
int X = 0;
int Y = 0;
+ root_w -= root->d * 2;
+ root_h -= root->d * 2;
+
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);
if (ret < 0)
return ret;
+ ret = abc_layout_css(child);
+ if (ABC_POSITION_FIXED == ret || ABC_POSITION_ABSOLUTE == ret)
+ break;
+
x = root->x + root->d;
y = child->y + child->h;
h = 0;
if (ret < 0)
return ret;
+ ret = abc_layout_css(child);
+ if (ABC_POSITION_FIXED == ret || ABC_POSITION_ABSOLUTE == ret)
+ break;
+
if (ABC_CORE_TEXT == child->type && child->text_splits) {
abc_text_t* t = child->text_splits;
x += t->w;
}
- scf_logd("--- x: %d, y: %d, h: %d ---\n\n", x, y, h);
-
- } else if (x + child->w < root_w) {
+ } else if (x + child->w < root->x + root->d + root_w) {
if (h < child->h)
h = child->h;
if (ret < 0)
return ret;
+ abc_layout_css(child);
+
h = child->h;
x = child->x + child->w;
}
int ret = abc_layout_obj(NULL, root, width, height);
if (ret < 0)
return ret;
-
- abc_layout_css(root);
#if 0
if (root->keys)
scf_logw("key: %s, ", root->keys[0]);
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, height);
cr = cairo_create(surface);
- w = w / size * size;
-
- int ret = __layout_text(cr, obj, 0, w, &extents);
+ int ret = __layout_text(cr, obj, 0, w / size * size, &extents);
if (ret < 0)
scf_loge("ret: %d\n", ret);
- w = extents.width + extents.x_bearing + obj->d * 2;
h = extents.height + extents.height / 2 + obj->d * 2;
obj->w = obj->w_set ? obj->w0 : w;
obj->h = obj->h_set ? obj->h0 : h + obj->h;
-// obj->w = (obj->w + 3) & ~0x3;
-// obj->h = (obj->h + 3) & ~0x3;
scf_logd("%s, w: %d, h: %d, d: %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, d,
if (attr)
size = atoi(attr->value->data);
- cairo_set_font_size (cr, size);
- cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
+ cairo_set_font_size(cr, size);
int d = abc_css_margin(obj);
int w_set = abc_css_width (obj, width, d);
obj->y_bearing = extents.y_bearing;
- w = extents.x_advance + extents.x_bearing + d * 2 + dw;
-
- obj->w = w;
+ obj->w = extents.width + d * 2 + dw;
obj->h = extents.height + extents.height / 2 + d * 2;
-// obj->w = (obj->w + 3) & ~0x3;
-// obj->h = (obj->h + 3) & ~0x3;
scf_logd("%s, w: %d, h: %d, d: %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, d,
int abc_layout_img(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
{
- scf_list_t* l;
- abc_obj_t* attr;
+ obj->w_set = abc_css_width (obj, width, obj->d);
+ obj->h_set = abc_css_height(obj, height, obj->d);
- for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
-
- switch (attr->type) {
-
- case ABC_HTML_ATTR_WIDTH:
- obj->w = atoi(attr->value->data);
- break;
-
- case ABC_HTML_ATTR_HEIGHT:
- obj->h = atoi(attr->value->data);
- break;
- default:
- break;
- };
- }
-
-// obj->x = 4;
-// obj->y = 4;
-
- obj->w = (obj->w + 3) & ~0x3;
- obj->h = (obj->h + 3) & ~0x3;
-
- scf_logd("%s, w: %d, h: %d\n", obj->text->data, obj->w, obj->h);
+ scf_logi("w: %d, h: %d, d: %d\n", obj->w, obj->h, obj->d);
return 0;
}
cairo_text_extents (cr, obj->text->data, extents);
int w = extents->x_bearing + extents->x_advance;
- if (x + w <= width)
+ if (x + w <= width) {
+ extents->width = w;
return 0;
+ }
extents->width = width;
extents->height = 0;
if (n < 0)
return n;
- w = (tmp.x_bearing + tmp.x_advance + size - 1) / size * size;
+ w = tmp.x_bearing + tmp.x_advance;
if (x + w <= width) {
x = 0;
{
abc_obj_t* parent = obj->parent;
abc_obj_t* attr;
- abc_obj_t* style;
cairo_text_extents_t extents;
- cairo_text_extents_t extents2;
cairo_surface_t* surface;
cairo_t* cr;
if (!obj->text)
return 0;
- int x = obj->x - parent->x;
- int w = parent->w_set ? parent->w0 : width;
int d = parent->d;
- int h;
+ int x = obj->x - (parent->x + d);
+ int w = width;
scf_logd("obj->x: %d, parent->x: %d, w: %d, d: %d\n", obj->x, parent->x, w, d);
- x -= d;
- w -= d * 2;
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, height);
cr = cairo_create(surface);
if (attr)
size = atoi(attr->value->data);
- w = w / size * size;
-
- scf_logd("text: %s, w: %d\n", obj->text->data, w);
-
- int ret = __layout_text(cr, obj, x, w, &extents);
+ int ret = __layout_text(cr, obj, x, w / size * size, &extents);
if (ret < 0)
scf_loge("ret: %d\n", ret);
if (parent->y_bearing > obj->y_bearing)
parent->y_bearing = obj->y_bearing;
- obj->w = extents.x_bearing + extents.x_advance;
- obj->h = extents.height + extents.height / 2;
-// obj->w = (obj->w + 3) & ~0x3;
-// obj->h = (obj->h + 3) & ~0x3;
+ obj->w = extents.width;
+ obj->h = extents.height + extents.height / 2;
scf_logd("%s, w: %d, h: %d, d: %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, d,
[ABC_CORE_TEXT] = &abc_render_text,
[ABC_HTML_B] = &abc_render_text,
[ABC_HTML_I] = &abc_render_text,
+ [ABC_HTML_A] = &abc_render_text,
[ABC_HTML_H1] = &abc_render_h1,
[ABC_HTML_H2] = &abc_render_h1,
[ABC_HTML_P] = &abc_render_h1,
[ABC_HTML_BR] = &abc_render_h1,
- [ABC_HTML_A] = &abc_render_h1,
[ABC_HTML_A_HREF] = &abc_render_a_href,
[ABC_HTML_IMG] = &abc_render_img,
static int _render_draw_audio(abc_render_t* render, abc_obj_t* obj, int width, int height)
{
- scf_list_t* l;
- abc_obj_t* attr;
-
- for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
-
- if (ABC_HTML_ATTR_SRC == attr->type)
- break;
- }
-
- if (l == scf_list_sentinel(&obj->attrs)) {
- scf_loge("src image of '%s' not found\n", obj->keys[0]);
- return -1;
+ abc_obj_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_SRC);
+ if (!attr) {
+ scf_loge("src audio of '%s' not found\n", obj->keys[0]);
+ return -EINVAL;
}
if (0 == program)
scf_logi("%s, x: %d, y: %d, w: %d, h: %d\n", obj->keys[0], obj->x, obj->y, obj->w, obj->h);
+ int x = obj->x + obj->d;
+ int y = obj->y + obj->d;
+ int w = obj->w - obj->d * 2;
+ int h = obj->h - obj->d * 2;
+
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);
g_object_unref(cursor);
if (prev->visited)
- css = abc_obj_get_attr(prev, ABC_CSS_VISITED);
+ prev->css_pse_type = ABC_CSS_VISITED;
else
- css = abc_obj_get_attr(prev, ABC_CSS_LINK);
- if (css)
- abc_obj_set_css(prev, css);
+ prev->css_pse_type = ABC_CSS_LINK;
+
+ abc_css_active(prev);
prev->clicked = 0;
ret = 1;
break;
};
- css = abc_obj_get_attr(obj, ABC_CSS_HOVER);
- if (css) {
- abc_obj_set_css(obj, css);
- ret = 1;
- }
+ obj->css_pse_type = ABC_CSS_HOVER;
+
+ ret |= abc_css_active(obj);
ctx->current->current = obj;
}
if (!obj)
return __do_button_move(ctx, x, y);
- obj->visited = 1;
+ obj->visited = 1;
+ obj->css_pse_type = ABC_CSS_VISITED;
- css = abc_obj_get_attr(obj, ABC_CSS_VISITED);
- if (css)
- abc_obj_set_css(obj, css);
+ abc_css_active(obj);
scf_logd("obj: %s, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
obj->keys[0], obj->x, obj->y, obj->w, obj->h, x, y);
abc_obj_t* css;
if (obj) {
- css = abc_obj_get_attr(obj, ABC_CSS_ACTIVE);
- if (css) {
- abc_obj_set_css(obj, css);
+ obj->css_pse_type = ABC_CSS_ACTIVE;
+ if (abc_css_active(obj) > 0)
gtk_gl_area_queue_render(ctx->gl_area);
- }
}
}