{
background-color:#b0c4de;
background-image:url('img.png');
+ background-position:right top;
+ background-repeat:no-repeat;
}
h1 {background-color:#6495ed;}
CFILES += abc_html.c
CFILES += abc_css.c
CFILES += abc_css_color.c
+CFILES += abc_css_position.c
CFILES += abc_io_util.c
CFILES += abc_io_file.c
--- /dev/null
+#include"abc_html.h"
+
+typedef struct css_pos_s
+{
+ char** names;
+ float value;
+} css_pos_t;
+
+static char* css_left[] = {"left", "左", NULL};
+static char* css_right[] = {"right", "右", NULL};
+static char* css_top[] = {"top", "上", NULL};
+static char* css_bottom[] = {"bottom", "下", NULL};
+
+static css_pos_t css_poss[] =
+{
+ {css_left, 0.0},
+ {css_right, 1.0},
+ {css_top, 0.0},
+ {css_bottom, 1.0},
+};
+
+static void __css_pos_value(float* value, const char* name, size_t name_len)
+{
+ int i;
+ for (i = 0; i < sizeof(css_poss) / sizeof(css_poss[0]); i++) {
+ css_pos_t* c = &css_poss[i];
+
+ int j;
+ for (j = 0; c->names[j]; j++) {
+ if (!strncmp(c->names[j], name, name_len)) {
+ *value = c->value;
+ return;
+ }
+ }
+ }
+}
+
+int abc_css_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;
+
+ const uint8_t* p = str;
+ const uint8_t* unit = NULL;
+
+ double value = 0.0;
+ int dot = 0;
+ int percent = 0;
+ int prev = 0;
+ int n = 0;
+ int c = 0;
+
+ do {
+ c = *str;
+
+ if ('.' == c)
+ dot = 10;
+ else if ('%' == c)
+ percent++;
+
+ else if ('a' <= c && 'z' >= c) {
+
+ if (' ' == prev || '\t' == prev || '\r' == prev || '\n' == prev)
+ p = str;
+ else if (!unit)
+ unit = str;
+
+ } else if ('0' <= c && '9' >= c) {
+
+ if (dot > 0) {
+ value += (c - '0') / (double)dot;
+ dot *= 10;
+ } else {
+ value *= 10.0;
+ value += c - '0';
+ }
+
+ } else if ('\0' == c || ' ' == c || '\t' == c || '\r' == c || '\n' == c) {
+
+ if (c) {
+ if (' ' == prev || '\t' == prev || '\r' == prev || '\n' == prev) {
+ prev = c;
+ str++;
+ continue;
+ }
+ }
+
+ if (percent) {
+ value *= 0.01;
+
+ if (n > 0)
+ *y = value;
+ else
+ *x = value;
+
+ } else if ('a' <= *p && *p <= 'z') {
+ if (n > 0)
+ __css_pos_value(y, p, (size_t)(str - p));
+ else
+ __css_pos_value(x, p, (size_t)(str - p));
+
+ } else if (unit) {
+ // for other css units, ignore
+ }
+
+ p = str;
+ unit = NULL;
+ value = 0.0;
+ dot = 0;
+ percent = 0;
+ n++;
+ }
+
+ prev = c;
+ str++;
+ } while (c);
+
+ return 0;
+}
static char* font_bold_keys[] = {"bold", "加粗", NULL};
static char* font_italic_keys[] = {"italic", "斜体", NULL};
-static char* text_align_keys[] = {"text-align", "对齐", NULL};
+static char* text_align_keys[] = {"text-align", "对齐", NULL};
-static char* bg_color_keys[] = {"background-color", "背景颜色", NULL};
-static char* bg_image_keys[] = {"background-image", "背景图片", NULL};
+static char* bg_keys[] = {"background", "背景", NULL};
+static char* bg_color_keys[] = {"background-color", "背景颜色", NULL};
+static char* bg_image_keys[] = {"background-image", "背景图片", NULL};
+static char* bg_repeat_keys[] = {"background-repeat", "背景重复", NULL};
+static char* bg_position_keys[] = {"background-position", "背景位置", NULL};
static char* class_keys[] = {"class", "类名", NULL};
static char* type_keys[] = {"type", "类型", NULL};
static html_attr_t body_attrs[] =
{
- {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0},
- {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0},
- {bg_color_keys, "white", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW},
- {bg_image_keys, "", ABC_HTML_ATTR_BG_IMAGE, ABC_HTML_FLAG_SHOW},
+ {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0},
+ {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0},
+
+ {bg_keys, "", ABC_HTML_ATTR_BG, ABC_HTML_FLAG_SHOW},
+ {bg_color_keys, "white", 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},
};
static html_attr_t h1_attrs[] =
int abc_css_parse (abc_obj_t* css);
int abc_css_use (abc_html_t* html, abc_obj_t* obj);
-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);
+int abc_css_position(float* x, float* y, float w, float h, abc_obj_t* obj, const uint8_t* str);
#endif
ABC_HTML_ATTR_TEXT_ALIGN,
+ ABC_HTML_ATTR_BG,
ABC_HTML_ATTR_BG_COLOR,
ABC_HTML_ATTR_BG_IMAGE,
+ ABC_HTML_ATTR_BG_REPEAT,
+ ABC_HTML_ATTR_BG_POSITION,
ABC_HTML_ATTR_WIDTH,
ABC_HTML_ATTR_HEIGHT,
CFILES += ../html/abc_obj.c
CFILES += ../html/abc_css.c
CFILES += ../html/abc_css_color.c
+CFILES += ../html/abc_css_position.c
CFILES += ../html/abc_io_util.c
CFILES += ../html/abc_io_file.c
"out vec4 outputColor; \n"
"uniform vec4 bgColor; \n"
"uniform vec4 rect; \n"
+ "uniform int repeat_x; \n"
+ "uniform int repeat_y; \n"
+ "uniform int index_x; \n"
+ "uniform int index_y; \n"
"uniform sampler2D tex_rgba; \n"
"void main() { \n"
" vec2 xy = v_texCoord; \n"
- " if (rect.x < xy.x && xy.x < rect.x + rect.z \n"
- " && rect.y < xy.y && xy.y < rect.y + rect.w) { \n"
- " xy.x = (xy.x - rect.x) / rect.z; \n"
- " xy.y = (xy.y - rect.y) / rect.w; \n"
+ " float i = floor((xy.x - rect.x) / rect.z); \n"
+ " float j = floor((xy.y - rect.y) / rect.w); \n"
+ " if ((repeat_x > 0 || int(round(i)) == index_x) && (repeat_y > 0 || int(round(j)) == index_y)) { \n"
+ " float x = rect.x + i * rect.z; \n"
+ " float y = rect.y + j * rect.w; \n"
+ " xy.x = (xy.x - x) / rect.z; \n"
+ " xy.y = (xy.y - y) / rect.w; \n"
" vec4 v = texture2D(tex_rgba, xy).rgba; \n"
" outputColor = vec4(v.b, v.g, v.r, 1.0); \n"
" } else { \n"
static GLuint uniform_rgba;
static GLuint uniform_rect;
static GLuint uniform_color;
+static GLuint uniform_repeat_x;
+static GLuint uniform_repeat_y;
+static GLuint uniform_index_x;
+static GLuint uniform_index_y;
static int _render_fini_bg_image(abc_render_t* render)
{
h /= max;
}
+ GLint repeat_x = 1;
+ GLint repeat_y = 1;
+ GLint index_x = 0;
+ GLint index_y = 0;
+
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_POSITION);
+ if (attr) {
+ abc_css_position(&x, &y, w, h, obj, attr->value->data);
+
+ scf_logi("background-position: %s, x: %f, y: %f, w: %f, h: %f\n", attr->value->data, x, y, w, h);
+
+ if (x + w > 1.0)
+ index_x = -1;
+
+ if (y + h > 1.0)
+ index_y = -1;
+ }
+
+ attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_REPEAT);
+ if (attr) {
+ if (!strcmp(attr->value->data, "repeat-x"))
+ repeat_y = 0;
+
+ else if (!strcmp(attr->value->data, "repeat-y"))
+ repeat_x = 0;
+
+ else if (!strcmp(attr->value->data, "no-repeat")) {
+ repeat_x = 0;
+ repeat_y = 0;
+ }
+ }
+
+ scf_logi("repeat_x: %d, repeat_y: %d, index_x: %d, index_y: %d\n", repeat_x, repeat_y, index_x, index_y);
+
glUseProgram(program);
- uniform_color = glGetUniformLocation(program, "bgColor");
- uniform_rgba = glGetUniformLocation(program, "tex_rgba");
- uniform_rect = glGetUniformLocation(program, "rect");
- uniform_mvp = glGetUniformLocation(program, "mvp");
+
+ uniform_mvp = glGetUniformLocation(program, "mvp");
+ uniform_rgba = glGetUniformLocation(program, "tex_rgba");
+ uniform_rect = glGetUniformLocation(program, "rect");
+ uniform_color = glGetUniformLocation(program, "bgColor");
+ uniform_repeat_x = glGetUniformLocation(program, "repeat_x");
+ uniform_repeat_y = glGetUniformLocation(program, "repeat_y");
+ uniform_index_x = glGetUniformLocation(program, "index_x");
+ uniform_index_y = glGetUniformLocation(program, "index_y");
glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
glBindTexture (GL_TEXTURE_2D, texture_rgba);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, img->width, img->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
glUniform1i(uniform_rgba, 0);
+
glUniform4f(uniform_rect, x, y, w, h);
glUniform4f(uniform_color, r, g, b, 1.0);
+ glUniform1i(uniform_repeat_x, repeat_x);
+ glUniform1i(uniform_repeat_y, repeat_y);
+ glUniform1i(uniform_index_x, index_x);
+ glUniform1i(uniform_index_y, index_y);
+
// draw
glBindBuffer (GL_ARRAY_BUFFER, buffers[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);