summaryrefslogtreecommitdiff
path: root/css
diff options
context:
space:
mode:
Diffstat (limited to 'css')
-rw-r--r--css/hints.c239
-rw-r--r--css/hints.h7
2 files changed, 191 insertions, 55 deletions
diff --git a/css/hints.c b/css/hints.c
index 066212e89..a3242c689 100644
--- a/css/hints.c
+++ b/css/hints.c
@@ -28,6 +28,9 @@
#include "css/hints.h"
#include "css/select.h"
+#define LOG_STATS
+#undef LOG_STATS
+
/******************************************************************************
* Utility functions *
******************************************************************************/
@@ -1711,77 +1714,209 @@ static css_error node_presentational_hint_background_image(
return CSS_PROPERTY_NOT_SET;
}
+struct css_hint_ctx {
+ struct css_hint *hints;
+ uint32_t alloc;
+ uint32_t len;
+};
+
+struct css_hint_ctx hint_ctx;
+
+static void css_hint_destroy(struct css_hint_ctx *hint)
+{
+ hint->alloc = 0;
+ hint->len = 0;
+ free(hint->hints);
+}
+
+static nserror css_hint_extend(struct css_hint_ctx *hint)
+{
+ uint32_t alloc = (hint->alloc == 0) ? 32 : hint->alloc * 2;
+ struct css_hint *temp;
+
+ temp = realloc(hint->hints, sizeof(struct css_hint) * alloc);
+ if (temp != NULL) {
+ hint->hints = temp;
+ hint->alloc = alloc;
+
+ return NSERROR_OK;
+ }
+
+ return NSERROR_NOMEM;
+}
+
+nserror css_hint_init(void)
+{
+ nserror err;
+
+ err = css_hint_extend(&hint_ctx);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
+ return NSERROR_OK;
+}
+
+void css_hint_fini(void)
+{
+ css_hint_destroy(&hint_ctx);
+}
+
+
/* Exported function, documeted in css/hints.h */
-css_error node_presentational_hint(void *pw, void *node,
- uint32_t property, css_hint *hint)
+static inline css_error node_presentational_hint_internal(
+ void *pw, void *node, struct css_hint_ctx *hints)
{
+ struct css_hint_ctx *ctx = hints;
+ uint32_t property;
+ nserror nserr;
+ css_error err;
- switch (property) {
- case CSS_PROP_BACKGROUND_IMAGE:
- return node_presentational_hint_background_image(pw, node, hint);
+ ctx->len = 0;
- case CSS_PROP_BACKGROUND_COLOR:
- return node_presentational_hint_background_color(pw, node, hint);
- case CSS_PROP_CAPTION_SIDE:
- return node_presentational_hint_caption_side(pw, node, hint);
+ for (property = 0; property < CSS_N_PROPERTIES; property++) {
+ css_hint *hint = &(ctx->hints[ctx->len]);
- case CSS_PROP_COLOR:
- return node_presentational_hint_color(pw, node, hint);
+ if (ctx->alloc == 0 || ctx->len == ctx->alloc - 1) {
+ nserr = css_hint_extend(ctx);
+ if (nserr != NSERROR_OK) {
+ return NSERROR_NOMEM;
+ }
+ }
- case CSS_PROP_FLOAT:
- return node_presentational_hint_float(pw, node, hint);
+ switch (property) {
+ case CSS_PROP_BACKGROUND_IMAGE:
+ err = node_presentational_hint_background_image(
+ pw, node, hint);
+ break;
- case CSS_PROP_FONT_SIZE:
- return node_presentational_hint_font_size(pw, node, hint);
+ case CSS_PROP_BACKGROUND_COLOR:
+ err = node_presentational_hint_background_color(
+ pw, node, hint);
+ break;
- case CSS_PROP_HEIGHT:
- return node_presentational_hint_height(pw, node, hint);
+ case CSS_PROP_CAPTION_SIDE:
+ err = node_presentational_hint_caption_side(
+ pw, node, hint);
+ break;
- case CSS_PROP_WIDTH:
- return node_presentational_hint_width(pw, node, hint);
+ case CSS_PROP_COLOR:
+ err = node_presentational_hint_color(
+ pw, node, hint);
+ break;
- case CSS_PROP_BORDER_SPACING:
- return node_presentational_hint_border_spacing(pw, node, hint);
+ case CSS_PROP_FLOAT:
+ err = node_presentational_hint_float(
+ pw, node, hint);
+ break;
- case CSS_PROP_BORDER_TOP_COLOR :
- case CSS_PROP_BORDER_RIGHT_COLOR :
- case CSS_PROP_BORDER_BOTTOM_COLOR :
- case CSS_PROP_BORDER_LEFT_COLOR :
- return node_presentational_hint_border_trbl_color(pw, node, hint);
+ case CSS_PROP_FONT_SIZE:
+ err = node_presentational_hint_font_size(
+ pw, node, hint);
+ break;
- case CSS_PROP_BORDER_TOP_STYLE :
- case CSS_PROP_BORDER_RIGHT_STYLE :
- case CSS_PROP_BORDER_BOTTOM_STYLE :
- case CSS_PROP_BORDER_LEFT_STYLE :
- return node_presentational_hint_border_trbl_style(pw, node, hint);
+ case CSS_PROP_HEIGHT:
+ err = node_presentational_hint_height(
+ pw, node, hint);
+ break;
- case CSS_PROP_BORDER_TOP_WIDTH :
- case CSS_PROP_BORDER_RIGHT_WIDTH :
- case CSS_PROP_BORDER_BOTTOM_WIDTH :
- case CSS_PROP_BORDER_LEFT_WIDTH :
- return node_presentational_hint_border_trbl_width(pw, node, hint);
+ case CSS_PROP_WIDTH:
+ err = node_presentational_hint_width(
+ pw, node, hint);
+ break;
- case CSS_PROP_MARGIN_TOP :
- case CSS_PROP_MARGIN_BOTTOM :
- return node_presentational_hint_margin_tb(pw, node, hint);
+ case CSS_PROP_BORDER_SPACING:
+ err = node_presentational_hint_border_spacing(
+ pw, node, hint);
+ break;
- case CSS_PROP_MARGIN_RIGHT:
- case CSS_PROP_MARGIN_LEFT:
- return node_presentational_hint_margin_rl(pw, node, hint, property);
+ case CSS_PROP_BORDER_TOP_COLOR:
+ case CSS_PROP_BORDER_RIGHT_COLOR:
+ case CSS_PROP_BORDER_BOTTOM_COLOR:
+ case CSS_PROP_BORDER_LEFT_COLOR:
+ err = node_presentational_hint_border_trbl_color(
+ pw, node, hint);
+ break;
- case CSS_PROP_PADDING_TOP:
- case CSS_PROP_PADDING_RIGHT :
- case CSS_PROP_PADDING_BOTTOM :
- case CSS_PROP_PADDING_LEFT:
- return node_presentational_hint_padding_trbl(pw, node, hint);
+ case CSS_PROP_BORDER_TOP_STYLE:
+ case CSS_PROP_BORDER_RIGHT_STYLE:
+ case CSS_PROP_BORDER_BOTTOM_STYLE:
+ case CSS_PROP_BORDER_LEFT_STYLE:
+ err = node_presentational_hint_border_trbl_style(
+ pw, node, hint);
+ break;
- case CSS_PROP_TEXT_ALIGN:
- return node_presentational_hint_text_align(pw, node, hint);
+ case CSS_PROP_BORDER_TOP_WIDTH:
+ case CSS_PROP_BORDER_RIGHT_WIDTH:
+ case CSS_PROP_BORDER_BOTTOM_WIDTH:
+ case CSS_PROP_BORDER_LEFT_WIDTH:
+ err = node_presentational_hint_border_trbl_width(
+ pw, node, hint);
+ break;
+
+ case CSS_PROP_MARGIN_TOP:
+ case CSS_PROP_MARGIN_BOTTOM:
+ err = node_presentational_hint_margin_tb(
+ pw, node, hint);
+ break;
+
+ case CSS_PROP_MARGIN_RIGHT:
+ case CSS_PROP_MARGIN_LEFT:
+ err = node_presentational_hint_margin_rl(
+ pw, node, hint, property);
+ break;
- case CSS_PROP_VERTICAL_ALIGN:
- return node_presentational_hint_vertical_align(pw, node, hint);
+ case CSS_PROP_PADDING_TOP:
+ case CSS_PROP_PADDING_RIGHT:
+ case CSS_PROP_PADDING_BOTTOM:
+ case CSS_PROP_PADDING_LEFT:
+ err = node_presentational_hint_padding_trbl(
+ pw, node, hint);
+ break;
+
+ case CSS_PROP_TEXT_ALIGN:
+ err = node_presentational_hint_text_align(
+ pw, node, hint);
+ break;
+
+ case CSS_PROP_VERTICAL_ALIGN:
+ err = node_presentational_hint_vertical_align(
+ pw, node, hint);
+ break;
+
+ default:
+ err = CSS_PROPERTY_NOT_SET;
+ break;
+ }
+
+ if (err == CSS_OK) {
+ hint->prop = property;
+ ctx->len++;
+ }
}
- return CSS_PROPERTY_NOT_SET;
+ return CSS_OK;
+}
+
+
+/* Exported function, documeted in css/hints.h */
+css_error node_presentational_hint(void *pw, void *node,
+ uint32_t *nhints, css_hint **hints)
+{
+ css_error err;
+
+ err = node_presentational_hint_internal(pw, node, &hint_ctx);
+ if (err != CSS_OK) {
+ return err;
+ }
+
+#ifdef LOG_STATS
+ LOG("Properties with hints: %i", hint_ctx.len);
+#endif
+
+ *nhints = hint_ctx.len;
+ *hints = hint_ctx.hints;
+
+ return CSS_OK;
}
diff --git a/css/hints.h b/css/hints.h
index 68d4c1063..d2b07b578 100644
--- a/css/hints.h
+++ b/css/hints.h
@@ -23,7 +23,8 @@
#include "css/css.h"
-
+nserror css_hint_init(void);
+void css_hint_fini(void);
/**
@@ -40,8 +41,8 @@
css_error node_presentational_hint(
void *pw,
void *node,
- uint32_t property,
- css_hint *hint);
+ uint32_t *nhints,
+ css_hint **hints);
bool nscss_parse_colour(const char *data, css_color *result);