<meta charset="utf-8">
<style>
div {
- background-color:gray;
+ background-color:lightGray;
width: 200px;
height: 50px;
border: 1px dotted black;
+ padding: 25px;
overflow: visible;
+ scrollbar-width: 15px;
+ scrollbar-color: orangeRed lightGray;
+}
+
+p {
+ border: 1px dotted red;
}
</style>
</head>
} else if (p) {
if (i > 1)
- abc_css_color(r, g, b, p);
+ abc_css_color(r, g, b, p, -1);
else if (1 == i)
__css_border_type(type, p, (size_t)(str - p));
{css_YellowGreen, 0x9acd32},
};
-int abc_css_color(double* r, double* g, double* b, const uint8_t* str)
+int abc_css_color(double* r, double* g, double* b, const uint8_t* str, size_t len)
{
*r = 0.0;
*g = 0.0;
*b = 0.0;
+ if (!str || 0 == len)
+ return 0;
+
if ('#' == *str) {
uint64_t value = 0;
+ long i;
- while (*++str) {
- int c = *str;
+ for (i = 1; i < len && str[i]; i++) {
+ int c = str[i];
if ('0' <= c && '9' >= c) {
value <<= 4;
*b = ( value & 0xff) / 255.0;
} else if (!__html_strncmp(str, "rgb(", 4)) {
- const uint8_t* p = str + 4;
-
- str = p;
- while (*str && ',' != *str)
- str++;
- *r = atof(p) / 255.0;
-
- if (*str) {
- p = ++str;
- while (*str && ',' != *str)
- str++;
- *g = atof(p) / 255.0;
-
- if (*str) {
- p = ++str;
- while (*str && ')' != *str)
- str++;
- *b = atof(p) / 255.0;
+ long i;
+ long j = 4;
+ int k = 0;
+
+ for (i = 4; i < len && str[i]; i++) {
+ int c = str[i];
+
+ if (',' == c || ')' == c) {
+ switch (k) {
+ case 0:
+ *r = atof(str + j) / 255.0;
+ break;
+ case 1:
+ *g = atof(str + j) / 255.0;
+ break;
+ case 2:
+ *b = atof(str + j) / 255.0;
+ break;
+ };
+
+ if (++k > 2)
+ break;
+ j = i + 1;
}
}
} else {
int j;
for (j = 0; c->names[j]; j++) {
- if (!__html_strcmp(c->names[j], str)) {
+ if (!__html_strncmp(c->names[j], str, len)) {
*r = ((c->color >> 16) & 0xff) / 255.0;
*g = ((c->color >> 8) & 0xff) / 255.0;
*b = ( c->color & 0xff) / 255.0;
return 0;
}
+
+int abc_css_scrollbar_color(double thumb[3], double track[3], const uint8_t* str)
+{
+ thumb[0] = 0.0;
+ thumb[1] = 0.0;
+ thumb[2] = 0.0;
+
+ track[0] = 0.0;
+ track[1] = 0.0;
+ track[2] = 0.0;
+
+ if (!str)
+ return 0;
+
+ int c;
+ int c0 = ' ';
+ int k = 0;
+ long i = 0;
+ long j = 0;
+
+ do {
+ c = str[i++];
+
+ if (' ' == c0) {
+ if ('\0' == c || ' ' == c || '\t' == c || '\r' == c || '\n' == c)
+ continue;
+
+ c0 = c;
+ j = i - 1;
+
+ } else if ('\0' == c || ' ' == c || '\t' == c || '\r' == c || '\n' == c) {
+
+ if (0 == k) {
+ abc_css_color(thumb, thumb + 1, thumb + 2, str + j, i - 1 - j);
+ k = 1;
+ } else {
+ abc_css_color(track, track + 1, track + 2, str + j, i - 1 - j);
+ break;
+ }
+
+ c0 = ' ';
+ j = i;
+ }
+ } while (c);
+
+ return 0;
+}
return ABC_POSITION_STATIC;
}
+
+int abc_css_overflow(const uint8_t* str)
+{
+ if (!__html_strcmp(str, "hidden"))
+ return ABC_OVERFLOW_HIDDEN;
+
+ else if (!__html_strcmp(str, "scroll"))
+ return ABC_OVERFLOW_SCROLL;
+
+ else if (!__html_strcmp(str, "auto"))
+ return ABC_OVERFLOW_SCROLL;
+
+ return ABC_OVERFLOW_VISIBLE;
+}
+
+void abc_overflow_show(int* x, int* y, int* w, int* h, int mask_x, int mask_y, int mask_w, int mask_h)
+{
+#define CSS_OVERFLOW_SHOW(px, pw, x2, x3) \
+ do { \
+ int x1 = *px + *pw; \
+ \
+ if (*px > x3) \
+ *pw = 0; \
+ else if (x1 < x2) \
+ *pw = 0; \
+ else { \
+ if (*px < x2) \
+ *px = x2; \
+ \
+ if (x1 > x3) \
+ *pw = x3 - *px; \
+ else \
+ *pw = x1 - *px; \
+ } \
+ } while (0)
+
+ CSS_OVERFLOW_SHOW(x, w, mask_x, mask_x + mask_w);
+ CSS_OVERFLOW_SHOW(y, h, mask_y, mask_y + mask_h);
+}
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* bg_repeat_keys[] = {"background-repeat", "背景重复", NULL};
static char* bg_position_keys[] = {"background-position", "背景位置", NULL};
+static char* overflow_keys[] = {"overflow", "内容溢出", NULL};
+static char* scroll_width_keys[] = {"scrollbar-width", "滚动条宽度", NULL};
+static char* scroll_color_keys[] = {"scrollbar-color", "滚动条颜色", NULL};
+
static char* list_style_keys[] = {"list-style", "列表风格", NULL};
static char* list_style_type_keys[] = {"list-style-type", "列表标记", NULL};
static char* list_style_image_keys[] = {"list-style-image", "列表标记图片", NULL};
static html_attr_t body_attrs[] =
{
#define ABC_CSS_BOX(margin, border, padding) \
- {margin_keys, #margin, ABC_HTML_ATTR_MARGIN, ABC_HTML_FLAG_SHOW}, \
- {border_keys, #border, ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, \
- {padding_keys, #padding, ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW}, \
+ {margin_keys, #margin, ABC_HTML_ATTR_MARGIN, ABC_HTML_FLAG_SHOW}, \
+ {border_keys, #border, ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, \
+ {padding_keys, #padding, ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW}, \
\
- {overflow_keys, "", ABC_HTML_ATTR_OVERFLOW, ABC_HTML_FLAG_SHOW}, \
+ {overflow_keys, "", ABC_CSS_OVERFLOW, ABC_HTML_FLAG_SHOW}, \
+ {scroll_width_keys, "", ABC_CSS_SCROLLBAR_WIDTH, ABC_HTML_FLAG_SHOW}, \
+ {scroll_color_keys, "", ABC_CSS_SCROLLBAR_COLOR, 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}, \
+ {position_keys, "", ABC_CSS_POSITION, ABC_HTML_FLAG_SHOW}, \
+ {top_keys, "", ABC_CSS_TOP, ABC_HTML_FLAG_SHOW}, \
+ {bottom_keys, "", ABC_CSS_BOTTOM, ABC_HTML_FLAG_SHOW}, \
+ {left_keys, "", ABC_CSS_LEFT, ABC_HTML_FLAG_SHOW}, \
+ {right_keys, "", ABC_CSS_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},
+ {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}, \
- {class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW}, \
- {id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW},
+ {style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW}, \
+ {class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW}, \
+ {id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW},
#define ABC_CSS_BACK_GROUND(color) \
- {bg_keys, "", ABC_HTML_ATTR_BG, ABC_HTML_FLAG_SHOW}, \
- {bg_color_keys, #color, ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, \
- {bg_image_keys, "", ABC_HTML_ATTR_BG_IMAGE, ABC_HTML_FLAG_SHOW}, \
- {bg_repeat_keys, "", ABC_HTML_ATTR_BG_REPEAT, ABC_HTML_FLAG_SHOW}, \
- {bg_position_keys, "", ABC_HTML_ATTR_BG_POSITION, ABC_HTML_FLAG_SHOW},
+ {bg_keys, "", ABC_HTML_ATTR_BG, ABC_HTML_FLAG_SHOW}, \
+ {bg_color_keys, #color, ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, \
+ {bg_image_keys, "", ABC_HTML_ATTR_BG_IMAGE, ABC_HTML_FLAG_SHOW}, \
+ {bg_repeat_keys, "", ABC_HTML_ATTR_BG_REPEAT, ABC_HTML_FLAG_SHOW}, \
+ {bg_position_keys, "", ABC_HTML_ATTR_BG_POSITION, ABC_HTML_FLAG_SHOW},
#define ABC_CSS_FONT(font, size, color, style) \
- {font_keys, #font, ABC_HTML_ATTR_FONT, 0}, \
- {font_size_keys, #size, ABC_HTML_ATTR_FONT_SIZE, 0}, \
- {font_color_keys, #color, ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW}, \
- {font_style_keys, #style, ABC_HTML_ATTR_FONT_STYLE, 0},
+ {font_keys, #font, ABC_HTML_ATTR_FONT, 0}, \
+ {font_size_keys, #size, ABC_HTML_ATTR_FONT_SIZE, 0}, \
+ {font_color_keys, #color, ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW}, \
+ {font_style_keys, #style, ABC_HTML_ATTR_FONT_STYLE, 0},
#define ABC_CSS_TEXT(align, underline) \
{text_align_keys, #align, ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW}, \
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_color (double* r, double* g, double* b, const uint8_t* str, size_t len);
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_height(abc_obj_t* obj, int height, int margin);
int abc_css_position(const uint8_t* str);
+int abc_css_overflow(const uint8_t* str);
+
+void abc_overflow_show(int* x, int* y, int* w, int* h, int mask_x, int mask_y, int mask_w, int mask_h);
#endif
}
}
+void abc_dfs_update_xy(abc_obj_t* root, int dx, int dy)
+{
+ scf_list_t* l;
+ abc_obj_t* obj;
+
+ for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) {
+ obj = scf_list_data(l, abc_obj_t, list);
+
+ obj->x += dx;
+ obj->y += dy;
+
+ abc_dfs_update_xy(obj, dx, dy);
+ }
+}
+
abc_obj_t* abc_obj_find(abc_obj_t* root, int x, int y)
{
scf_list_t* l;
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_CSS_BORDER_COLLAPSE,
+ ABC_CSS_POSITION,
+ ABC_CSS_TOP,
+ ABC_CSS_BOTTOM,
+ ABC_CSS_LEFT,
+ ABC_CSS_RIGHT,
+
+ ABC_CSS_OVERFLOW,
+ ABC_CSS_SCROLLBAR_WIDTH,
+ ABC_CSS_SCROLLBAR_COLOR,
+
// css pse class (element)
ABC_CSS_FIRST_CHILD,
// css selectors from html attrs above
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_line_style
+{
+ ABC_LINE_NONE,
+ ABC_LINE_UNDER,
+ ABC_LINE_OVER,
+ ABC_LINE_THROUGH,
+};
+
enum abc_position_style
{
ABC_POSITION_STATIC,
ABC_POSITION_STICKY,
};
-enum abc_line_style
+enum abc_overflow_style
{
- ABC_LINE_NONE,
- ABC_LINE_UNDER,
- ABC_LINE_OVER,
- ABC_LINE_THROUGH,
+ ABC_OVERFLOW_VISIBLE,
+ ABC_OVERFLOW_HIDDEN,
+ ABC_OVERFLOW_SCROLL,
+ ABC_OVERFLOW_AUTO,
};
struct abc_text_s
int w;
int h;
+ int overflow_type;
+ // view area that object can see
+ int view_x;
+ int view_y;
+ int view_w;
+ int view_h;
+
+ int mouse_down_x;
+ int mouse_down_y;
+ int mouse_move_x;
+ int mouse_move_y;
+
+ int scroll_x;
+ int scroll_y;
+ int content_w;
+ int content_h;
+
double y_bearing;
int margin;
int padding;
abc_obj_t* abc_obj_find_type(abc_obj_t* root, int type);
+void abc_dfs_update_xy(abc_obj_t* root, int dx, int dy);
+
scf_string_t* abc_obj_to_string(abc_obj_t* obj);
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)
CFILES += main.c
CFILES += abc_layout.c
-CFILES += abc_layout_html.c
-CFILES += abc_layout_title.c
-CFILES += abc_layout_head.c
CFILES += abc_layout_body.c
CFILES += abc_layout_div.c
CFILES += abc_layout_audio.c
CFILES += abc_render.c
-CFILES += abc_render_html.c
-CFILES += abc_render_title.c
-CFILES += abc_render_head.c
CFILES += abc_render_body.c
CFILES += __render_border.c
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);
+ abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
if (0 == program)
__init_program(&program, vert_shader, frag_shader);
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);
"uniform float y_border; \n"
"uniform vec4 color; \n"
"uniform vec4 bgColor; \n"
+ "\n"
+ "uniform vec4 thumbColor; \n"
+ "uniform vec4 trackColor; \n"
+ "uniform vec2 wh; \n"
+ "uniform float w_scroll; \n"
+ "uniform float scroll_y; \n"
+ "uniform float scroll_h; \n"
+ "vec4 yScrollColor(float center, float L, float R, float dR, float y, float dx) { \n"
+ " if (y < center - L + R) { \n"
+ " float dy = center - L + R - y; \n"
+ " float r = sqrt(dx * dx + dy * dy); \n"
+ " float beta = smoothstep(R - dR, R + dR, r); \n"
+ " return mix(thumbColor, trackColor, beta); \n"
+ " } else if (y > center + L - R) { \n"
+ " float dy = center + L - R - y; \n"
+ " float r = sqrt(dx * dx + dy * dy); \n"
+ " float beta = smoothstep(R - dR, R + dR, r); \n"
+ " return mix(thumbColor, trackColor, beta); \n"
+ " } else { \n"
+ " return thumbColor; \n"
+ " } \n"
+ " return trackColor; \n"
+ "} \n"
"void main() { \n"
" float x = v_texCoord.x; \n"
" float y = v_texCoord.y; \n"
+ " float aspect = wh.x / wh.y; \n"
" if ((x >= 0.0 && x <= x_border) || (x >= 1.0 - x_border && x <= 1.0)) { \n"
" outputColor = color; \n"
" } else if ((y >= 0.0 && y <= y_border) || (y >= 1.0 - y_border && y <= 1.0)) { \n"
" outputColor = color; \n"
+ " } else if (x > 1.0 - x_border - w_scroll && x < 1.0 - x_border) { \n"
+ " float R = w_scroll / 2.0; \n"
+ " float L = scroll_h / 2.0; \n"
+ " float dx = 1.0 - x_border - x - R; \n"
+ " float dR = 1.0 / wh.y; \n"
+ " outputColor = yScrollColor(scroll_y, L, R * aspect, dR, y, dx * aspect); \n"
" } else { \n"
" outputColor = bgColor; \n"
" } \n"
static GLuint uniform_color;
static GLuint uniform_bgColor;
+static GLuint uniform_thumbColor;
+static GLuint uniform_trackColor;
+
+static GLuint uniform_wh;
+static GLuint uniform_w_scroll;
+static GLuint uniform_scroll_y;
+static GLuint uniform_scroll_h;
static int __render_fini_border(abc_render_t* render)
{
int border = 0;
int border_type = ABC_BORDER_SOLID;
- double r0 = 0.0;
- double g0 = 0.0;
- double b0 = 0.0;
-
- double r1 = 0.0;
- double g1 = 0.0;
- double b1 = 0.0;
- double a1 = 0.0;
+ double fgColor[3] = {0.0, 0.0, 0.0};
+ double bgColor[4] = {0.0, 0.0, 0.0, 0.0};
abc_obj_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_COLOR);
if (attr && attr->value->len > 0) {
- a1 = 1.0;
- abc_css_color(&r1, &g1, &b1, attr->value->data);
+ bgColor[4] = 1.0;
+ abc_css_color(bgColor, bgColor + 1, bgColor + 2, attr->value->data, attr->value->len);
}
- attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_MARGIN);
+ 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(&r0, &g0, &b0, &border, &border_type, obj, attr->value->data);
+ abc_css_border(fgColor, fgColor + 1, fgColor + 2, &border, &border_type, obj, attr->value->data);
else {
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
if (attr)
- abc_css_color(&r0, &g0, &b0, attr->value->data);
+ abc_css_color(fgColor, fgColor + 1, fgColor + 2, attr->value->data, attr->value->len);
}
int x = obj->x + margin;
int w = obj->w - margin * 2;
int h = obj->h - margin * 2;
+ obj->view_x = x;
+ obj->view_y = y;
+ obj->view_w = w;
+ obj->view_h = h;
+
+ abc_obj_t* parent = obj->parent;
+
+ if (parent && (x < parent->view_x
+ || y < parent->view_y
+ || x + w > parent->view_x + parent->view_w
+ || y + h > parent->view_y + parent->view_h)) {
+
+ attr = abc_obj_find_attr(obj, ABC_CSS_OVERFLOW);
+ if (attr)
+ obj->overflow_type = abc_css_overflow(attr->value->data);
+
+ switch (obj->overflow_type)
+ {
+ case ABC_OVERFLOW_HIDDEN:
+ abc_overflow_show(&obj->view_x, &obj->view_y, &obj->view_w, &obj->view_h,
+ parent->view_x,
+ parent->view_y, parent->view_w, parent->view_h);
+
+ scf_logw("x: %d, y: %d, w: %d, h: %d, obj: x: %d, y: %d, w: %d, h: %d, parent: x: %d, y: %d, w: %d, h: %d\n",
+ x, y, w, h,
+ obj->view_x, obj->view_y, obj->view_w, obj->view_h,
+ parent->view_x, parent->view_y, parent->view_w, parent->view_h);
+ break;
+ case ABC_OVERFLOW_SCROLL:
+ break;
+ default:
+ break;
+ };
+ }
+
float mvp[16];
__compute_mvp(mvp, 0, 0, 0);
GLfloat vert_update[] =
{
- 2.0 * x / (float)width - 1.0,
- -2.0 * (y + h) / (float)height + 1.0,
+ 2.0 * obj->view_x / (float)width - 1.0,
+ -2.0 * (obj->view_y + obj->view_h) / (float)height + 1.0,
- 2.0 * (x + w) / (float)width - 1.0,
- -2.0 * (y + h) / (float)height + 1.0,
+ 2.0 * (obj->view_x + obj->view_w) / (float)width - 1.0,
+ -2.0 * (obj->view_y + obj->view_h) / (float)height + 1.0,
- 2.0 * x / (float)width - 1.0,
- -2.0 * y / (float)height + 1.0,
+ 2.0 * obj->view_x / (float)width - 1.0,
+ -2.0 * obj->view_y / (float)height + 1.0,
- 2.0 * (x + w) / (float)width - 1.0,
- -2.0 * y / (float)height + 1.0,
+ 2.0 * (obj->view_x + obj->view_w) / (float)width - 1.0,
+ -2.0 * obj->view_y / (float)height + 1.0,
+ };
+
+ GLfloat texture_update[] =
+ {
+ (obj->view_x - x) / (float)w,
+ (obj->view_y + obj->view_h - y) / (float)h,
+
+ (obj->view_x + obj->view_w - x) / (float)w,
+ (obj->view_y + obj->view_h - y) / (float)h,
+
+ (obj->view_x - x) / (float)w,
+ (obj->view_y - y) / (float)h,
+
+ (obj->view_x + obj->view_w - x) / (float)w,
+ (obj->view_y - y) / (float)h,
};
GLfloat x_border = border / (float)w;
GLfloat y_border = border / (float)h;
+ if (ABC_OVERFLOW_HIDDEN == obj->overflow_type) {
+ for (int i = 0; i < sizeof(texture_update) / sizeof(texture_update[0]) / 2; i++)
+ scf_logi("%lg, %lg\n", texture_update[2 * i], texture_update[2 * i + 1]);
+
+ printf(" x_border: %lg, y_border: %lg\n\n", x_border, y_border);
+ }
+
+ GLfloat aspect = w / (float)h;
+ GLfloat w_scroll = 0.0;
+ GLfloat scroll_y = 0.0;
+ GLfloat scroll_h = 0.0;
+
+ double thumbColor[4] = {bgColor[0], bgColor[1], bgColor[2], bgColor[3]};
+ double trackColor[4] = {bgColor[0], bgColor[1], bgColor[2], bgColor[3]};
+
+ if (obj->content_h > obj->h)
+ {
+ float percent = h / (float)obj->content_h;
+ int len = h * percent;
+ int range = h - len;
+ int min = len / 2;
+ int max = h - min;
+
+ if (obj->scroll_y < min)
+ obj->scroll_y = min;
+ if (obj->scroll_y > max)
+ obj->scroll_y = max;
+
+ w_scroll = 25.0;
+
+ attr = abc_obj_get_attr(obj, ABC_CSS_SCROLLBAR_WIDTH);
+ if (attr && attr->value->len > 0)
+ w_scroll = atof(attr->value->data);
+
+ attr = abc_obj_get_attr(obj, ABC_CSS_SCROLLBAR_COLOR);
+ if (attr && attr->value->len > 0) {
+ thumbColor[3] = 1.0;
+ trackColor[3] = 1.0;
+ abc_css_scrollbar_color(thumbColor, trackColor, attr->value->data);
+ } else {
+ thumbColor[0] = 1.0;
+ thumbColor[1] = 0.27;
+ thumbColor[2] = 0.0;
+ thumbColor[3] = 1.0;
+ }
+
+ scf_logi("obj mouse_down_x: %d, mouse_down_y: %d, mouse_move_x: %d, mouse_move_y: %d, x: %d, y: %d, x+w: %d, y+h: %d\n",
+ obj->mouse_down_x,
+ obj->mouse_down_x, obj->mouse_move_x, obj->mouse_move_y,
+ x, y, x + w, y + h);
+
+ int dy = 0;
+ if (obj->mouse_move_x > x + w - w_scroll
+ && obj->mouse_move_x < x + w
+ && obj->mouse_move_y > y
+ && obj->mouse_move_y < y + h) {
+
+ if (obj->mouse_down_x > x + w - w_scroll
+ && obj->mouse_down_x < x + w
+ && obj->mouse_down_y > y
+ && obj->mouse_down_y < y + h) {
+
+ dy = obj->mouse_move_y - obj->mouse_down_y;
+ if (dy < min - obj->scroll_y)
+ dy = min - obj->scroll_y;
+ if (dy > max - obj->scroll_y)
+ dy = max - obj->scroll_y;
+
+ assert(dy >= -range && dy <= range);
+
+ obj->scroll_y += dy;
+ }
+ }
+
+ dy = -(obj->scroll_y - min) * (obj->content_h - obj->h) / range;
+
+ abc_dfs_update_xy(obj, 0, dy);
+
+ scroll_h = percent;
+ scroll_y = obj->scroll_y / (float)h;
+
+ w_scroll /= (float)w;
+ if (w_scroll > scroll_h / aspect)
+ w_scroll = scroll_h / aspect;
+
+ scf_logi("aspect: %lg, w_scroll: %lg, scroll_y: %lg, scroll_h: %lg\n\n", aspect, w_scroll, scroll_y, scroll_h);
+ }
+
glUseProgram(program);
uniform_mvp = glGetUniformLocation(program, "mvp");
uniform_x_border = glGetUniformLocation(program, "x_border");
uniform_color = glGetUniformLocation(program, "color");
uniform_bgColor = glGetUniformLocation(program, "bgColor");
+ uniform_thumbColor = glGetUniformLocation(program, "thumbColor");
+ uniform_trackColor = glGetUniformLocation(program, "trackColor");
+
+ uniform_wh = glGetUniformLocation(program, "wh");
+ uniform_scroll_y = glGetUniformLocation(program, "scroll_y");
+ uniform_scroll_h = glGetUniformLocation(program, "scroll_h");
+ uniform_w_scroll = glGetUniformLocation(program, "w_scroll");
+
glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
glUniform1f(uniform_x_border, x_border);
glUniform1f(uniform_y_border, y_border);
- glUniform4f(uniform_color, r0, g0, b0, 1.0);
- glUniform4f(uniform_bgColor, r1, g1, b1, a1);
+ glUniform4f(uniform_color, fgColor[0], fgColor[1], fgColor[2], 1.0);
+ glUniform4f(uniform_bgColor, bgColor[0], bgColor[1], bgColor[2], bgColor[3]);
+
+ glUniform4f(uniform_thumbColor, thumbColor[0], thumbColor[1], thumbColor[2], thumbColor[3]);
+ glUniform4f(uniform_trackColor, trackColor[0], trackColor[1], trackColor[2], trackColor[3]);
+
+ glUniform2f(uniform_wh, (GLfloat)w, (GLfloat)h);
+ glUniform1f(uniform_scroll_y, scroll_y);
+ glUniform1f(uniform_scroll_h, scroll_h);
+ glUniform1f(uniform_w_scroll, w_scroll);
// 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);
glEnable(GL_BLEND);
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
if (attr)
- abc_css_color(&r, &g, &b, attr->value->data);
+ abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
cairo_set_font_size (cr, size);
cairo_set_source_rgba(cr, r, g, b, 1.0);
if (obj->w <= 0 || obj->h <= 0)
return 0;
- int d = abc_css_margin(obj);
+ int d = obj->d;
int x = obj->x + d;
int y = obj->y + d;
int w = obj->w - d * 2;
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);
+ 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);
cr = cairo_create(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:
+ 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 * x / (float)width - 1.0,
- -2.0 * (y + 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 * (x + w) / (float)width - 1.0,
- -2.0 * (y + 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 * x / (float)width - 1.0,
- -2.0 * y / (float)height + 1.0,
+ 2.0 * view_x / (float)width - 1.0,
+ -2.0 * view_y / (float)height + 1.0,
- 2.0 * (x + w) / (float)width - 1.0,
- -2.0 * 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,
+
+ (view_x + view_w - x) / (float)w,
+ (view_y + view_h - y) / (float)h,
+
+ (view_x - x) / (float)w,
+ (view_y - y) / (float)h,
+
+ (view_x + view_w - x) / (float)w,
+ (view_y - y) / (float)h,
};
glUseProgram(program);
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);
glEnable(GL_BLEND);
#include"abc.h"
-int abc_layout_html (abc_layout_t* layout, abc_obj_t* obj, int width, int height);
-int abc_layout_title(abc_layout_t* layout, abc_obj_t* obj, int width, int height);
-int abc_layout_head (abc_layout_t* layout, abc_obj_t* obj, int width, int height);
int abc_layout_body (abc_layout_t* layout, abc_obj_t* obj, int width, int height);
int abc_layout_text(abc_layout_t* layout, abc_obj_t* obj, int width, int height);
static abc_layout_pt abc_layouts[ABC_HTML_NB] =
{
- [ABC_HTML] = abc_layout_html,
- [ABC_HTML_TITLE] = abc_layout_title,
+ [ABC_HTML] = abc_layout_empty,
+ [ABC_HTML_TITLE] = abc_layout_empty,
[ABC_HTML_META] = abc_layout_empty,
- [ABC_HTML_HEAD] = abc_layout_head,
+ [ABC_HTML_HEAD] = abc_layout_empty,
[ABC_HTML_BODY] = abc_layout_body,
[ABC_HTML_DIV] = abc_layout_div,
return f(layout, obj, width, height);
}
-void abc_css_update_xy(abc_obj_t* root, int dx, int dy)
-{
- scf_list_t* l;
- abc_obj_t* obj;
-
- for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) {
- obj = scf_list_data(l, abc_obj_t, list);
-
- obj->x += dx;
- obj->y += dy;
-
- abc_css_update_xy(obj, dx, dy);
- }
-}
-
#define LAYOUT_POS_FIXED(X, W, SET, L, R) \
do { \
if (!obj->SET) { \
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); \
+ abc_obj_t* attr = abc_obj_get_attr(tmp, ABC_CSS_POSITION); \
\
if (attr && attr->value->len > 0 \
&& __html_strcmp(attr->value->data, "static")) \
else if (!__html_strcmp(attr->value->data, "right"))
obj->x = parent->x + parent->w - obj->w - 8;
- abc_css_update_xy(obj, obj->x - x, 0);
+ abc_dfs_update_xy(obj, obj->x - x, 0);
}
- attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_POSITION);
+ attr = abc_obj_get_attr(obj, ABC_CSS_POSITION);
if (!attr || 0 == attr->value->len)
return 0;
int left = 0;
int right = 0;
- attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TOP);
+ attr = abc_obj_get_attr(obj, ABC_CSS_TOP);
if (attr)
top = abc_css_length(obj, attr->value->data, obj->h);
- attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BOTTOM);
+ attr = abc_obj_get_attr(obj, ABC_CSS_BOTTOM);
if (attr)
bottom = abc_css_length(obj, attr->value->data, obj->h);
- attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_LEFT);
+ attr = abc_obj_get_attr(obj, ABC_CSS_LEFT);
if (attr)
left = abc_css_length(obj, attr->value->data, obj->w);
- attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_RIGHT);
+ attr = abc_obj_get_attr(obj, ABC_CSS_RIGHT);
if (attr)
right = abc_css_length(obj, attr->value->data, obj->w);
break;
};
- abc_css_update_xy(obj, obj->x - x, obj->y - y);
+ abc_dfs_update_xy(obj, obj->x - x, obj->y - y);
return pos_type;
}
break;
};
+ root->overflow_type = ABC_OVERFLOW_VISIBLE;
+
scf_list_t* l;
abc_obj_t* child;
if (root->h < Y - root->y)
root->h = Y - root->y;
+ root->content_w = root->w;
+ root->content_h = root->h;
+
int ret = abc_layout_obj(NULL, root, width, height);
if (ret < 0)
return ret;
#if 0
if (root->keys)
scf_logw("key: %s, ", root->keys[0]);
- if (root->text)
- printf("%s, ", root->text->data);
- printf("x: %d, y: %d, w: %d, h: %d\n", root->x, root->y, root->w, root->h);
+// if (root->text)
+// printf("%s, ", root->text->data);
+ printf("x: %d, y: %d, w: %d, h: %d, content_w: %d, content_h: %d: %d\n",
+ root->x, root->y, root->w, root->h, root->content_w, root->content_h, root->content_h - root->d * 2);
#endif
return 0;
}
+++ /dev/null
-#include"abc.h"
-
-int abc_layout_head(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
-{
- return 0;
-}
+++ /dev/null
-#include"abc.h"
-
-int abc_layout_html(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
-{
- return 0;
-}
int collapse = 0;
- attr = abc_obj_find_attr(obj, ABC_CSS_BORDER_COLLAPSE);
+ attr = abc_obj_get_attr(obj, ABC_CSS_BORDER_COLLAPSE);
if (attr) {
if (!__html_strcmp(attr->value->data, "collapse")) {
collapse = 1;
}
}
- int d = abc_css_margin(obj);
+ int d = obj->d;
int w_set = abc_css_width (obj, width, d);
int h_set = abc_css_height(obj, height, d);
+++ /dev/null
-#include"abc.h"
-
-int abc_layout_title(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
-{
- return 0;
-}
#include"abc.h"
-extern abc_render_t abc_render_html;
-extern abc_render_t abc_render_title;
-extern abc_render_t abc_render_head;
extern abc_render_t abc_render_body;
extern abc_render_t abc_render_text;
[ABC_HTML] = &abc_render_empty,
[ABC_HTML_HEAD] = &abc_render_empty,
[ABC_HTML_META] = &abc_render_empty,
- [ABC_HTML_TITLE] = &abc_render_title,
+ [ABC_HTML_TITLE] = &abc_render_empty,
[ABC_HTML_BODY] = &abc_render_body,
[ABC_HTML_DIV] = &abc_render_body,
+++ /dev/null
-#include"abc.h"
-
-static int _render_fini_div(abc_render_t* render)
-{
- return 0;
-}
-
-static int _render_draw_div(abc_render_t* render, abc_obj_t* obj, int width, int height)
-{
- return 0;
-}
-
-abc_render_t abc_render_div =
-{
- .type = ABC_HTML_H1,
-
- .draw = _render_draw_div,
- .fini = _render_fini_div,
-};
+++ /dev/null
-#include"abc.h"
-
-static int _render_fini_head(abc_render_t* render)
-{
- return 0;
-}
-
-static int _render_draw_head(abc_render_t* render, abc_obj_t* obj, int width, int height)
-{
- return 0;
-}
-
-abc_render_t abc_render_head =
-{
- .type = ABC_HTML_H1,
-
- .draw = _render_draw_head,
- .fini = _render_fini_head,
-};
+++ /dev/null
-#include"abc.h"
-
-static int _render_fini_html(abc_render_t* render)
-{
- return 0;
-}
-
-static int _render_draw_html(abc_render_t* render, abc_obj_t* obj, int width, int height)
-{
- return 0;
-}
-
-abc_render_t abc_render_html =
-{
- .type = ABC_HTML_H1,
-
- .draw = _render_draw_html,
- .fini = _render_fini_html,
-};
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
if (attr)
- abc_css_color(&r, &g, &b, attr->value->data);
+ 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);
cr = cairo_create(surface);
b = 0.0;
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
if (attr)
- abc_css_color(&r, &g, &b, attr->value->data);
+ abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
cairo_set_source_rgb(cr, r, g, b);
double b = 1.0;
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
if (attr)
- abc_css_color(&r, &g, &b, attr->value->data);
+ 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);
b = 0.0;
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
if (attr)
- abc_css_color(&r, &g, &b, attr->value->data);
+ abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
cairo_set_source_rgb(cr, r, g, b);
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);
glEnable(GL_BLEND);
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
if (attr)
- abc_css_color(bcolor, bcolor + 1, bcolor + 2, attr->value->data);
+ abc_css_color(bcolor, bcolor + 1, bcolor + 2, attr->value->data, attr->value->len);
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
if (attr)
- abc_css_color(fcolor, fcolor + 1, fcolor + 2, attr->value->data);
+ abc_css_color(fcolor, fcolor + 1, fcolor + 2, attr->value->data, attr->value->len);
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
if (attr)
+++ /dev/null
-#include"abc.h"
-
-static int _render_fini_title(abc_render_t* render)
-{
- return 0;
-}
-
-static int _render_draw_title(abc_render_t* render, abc_obj_t* obj, int width, int height)
-{
- return 0;
-}
-
-abc_render_t abc_render_title =
-{
- .type = ABC_HTML_H1,
-
- .draw = _render_draw_title,
- .fini = _render_fini_title,
-};
abc_css_active(prev);
+ prev->mouse_down_x = -1;
+ prev->mouse_down_y = -1;
+ prev->mouse_move_x = -1;
+ prev->mouse_move_y = -1;
+
+ if (ABC_HTML_DIV == prev->type)
+ scf_logw("prev: %p mouse down_x: %d, down_y: %d, move_x: %d, move_y: %d\n", prev,
+ prev->mouse_down_x,
+ prev->mouse_down_y,
+ prev->mouse_move_x,
+ prev->mouse_move_y);
+
prev->clicked = 0;
ret = 1;
}
scf_logd("obj: %s, type: %d, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
obj->keys[0], obj->type, obj->x, obj->y, obj->w, obj->h, x, y);
+ int scroll_width = 25;
+
switch (obj->type)
{
case ABC_HTML_A:
}
}
break;
+
+ case ABC_HTML_DIV:
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TYPE);
+
+ if (attr && attr->value->len > 0)
+ scroll_width = atoi(attr->value->data);
+
+ if (obj->x + obj->w > scroll_width
+ && obj->mouse_move_x > obj->x + obj->w - scroll_width
+ && obj->mouse_move_x < obj->x + obj->w
+ && obj->mouse_move_y > obj->y
+ && obj->mouse_move_y < obj->y + obj->h)
+ ret = 1;
+ break;
default:
break;
};
+ if (ABC_HTML_DIV == obj->type)
+ scf_logw("obj: %p, mouse down_x: %d, down_y: %d, move_x: %d, move_y: %d\n", obj,
+ obj->mouse_down_x,
+ obj->mouse_down_y,
+ obj->mouse_move_x,
+ obj->mouse_move_y);
+
obj->css_pse_type = ABC_CSS_HOVER;
ret |= abc_css_active(obj);
if (!obj)
return __do_button_move(ctx, x, y);
+ obj->mouse_down_x = -1;
+ obj->mouse_down_y = -1;
+ obj->mouse_move_x = -1;
+ obj->mouse_move_y = -1;
+
obj->visited = 1;
obj->css_pse_type = ABC_CSS_VISITED;
abc_obj_t* css;
if (obj) {
+ obj->mouse_down_x = event->x;
+ obj->mouse_down_y = event->y;
+
+ if (ABC_HTML_DIV == obj->type)
+ scf_logw("obj: %p mouse down_x: %d, down_y: %d, move_x: %d, move_y: %d\n", obj,
+ obj->mouse_down_x,
+ obj->mouse_down_y,
+ obj->mouse_move_x,
+ obj->mouse_move_y);
+
obj->css_pse_type = ABC_CSS_ACTIVE;
if (abc_css_active(obj) > 0)
static gboolean button_move_event(GtkWidget* self, GdkEventMotion* event, gpointer user_data)
{
- abc_ctx_t* ctx = user_data;
+ abc_ctx_t* ctx = user_data;
+ abc_obj_t* obj;
+
+ if (ctx->current->io.download && ctx->current->root)
+ {
+ obj = abc_obj_find(ctx->current->root, event->x, event->y);
+ if (obj) {
+ obj->mouse_move_x = event->x;
+ obj->mouse_move_y = event->y;
+ }
+ }
int ret = __do_button_move(ctx, event->x, event->y);
if (ret > 0)
g_signal_connect(window, "button-release-event", G_CALLBACK(button_release_event), &ctx);
g_signal_connect(window, "button-press-event", G_CALLBACK(button_press_event), &ctx);
- g_signal_connect(window, "key-press-event", G_CALLBACK(key_press_event), &ctx);
- g_signal_connect(gl_area, "motion-notify-event", G_CALLBACK(button_move_event), &ctx);
+ g_signal_connect(gl_area, "key-press-event", G_CALLBACK(key_press_event), &ctx);
+ g_signal_connect(window, "motion-notify-event", G_CALLBACK(button_move_event), &ctx);
g_timeout_add(1, timer_handler, &ctx);