+#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;
+}