diff options
Diffstat (limited to 'css/hints.c')
-rw-r--r-- | css/hints.c | 1611 |
1 files changed, 0 insertions, 1611 deletions
diff --git a/css/hints.c b/css/hints.c deleted file mode 100644 index 356153983..000000000 --- a/css/hints.c +++ /dev/null @@ -1,1611 +0,0 @@ -/* - * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <string.h> -#include <strings.h> - -#include "utils/nsoption.h" -#include "utils/corestrings.h" -#include "utils/log.h" -#include "utils/nsurl.h" -#include "utils/utils.h" - -#include "css/hints.h" -#include "css/select.h" - -#define LOG_STATS -#undef LOG_STATS - -/****************************************************************************** - * Utility functions * - ******************************************************************************/ - -/** - * Determine if a given character is whitespace - * - * \param c Character to consider - * \return true if character is whitespace, false otherwise - */ -static bool isWhitespace(char c) -{ - return c == ' ' || c == '\t' || c == '\f' || c == '\r' || c == '\n'; -} - -/** - * Determine if a given character is a valid hex digit - * - * \param c Character to consider - * \return true if character is a valid hex digit, false otherwise - */ -static bool isHex(char c) -{ - return ('0' <= c && c <= '9') || - ('A' <= (c & ~0x20) && (c & ~0x20) <= 'F'); -} - -/** - * Convert a character representing a hex digit to the corresponding hex value - * - * \param c Character to convert - * \return Hex value represented by character - * - * \note This function assumes an ASCII-compatible character set - */ -static uint8_t charToHex(char c) -{ - /* 0-9 */ - c -= '0'; - - /* A-F */ - if (c > 9) - c -= 'A' - '9' - 1; - - /* a-f */ - if (c > 15) - c -= 'a' - 'A'; - - return c; -} - - -/****************************************************************************** - * Common parsing functions * - ******************************************************************************/ - -/** - * Parse a number string - * - * \param data Data to parse (NUL-terminated) - * \param maybe_negative Negative numbers permitted - * \param real Floating point numbers permitted - * \param value Pointer to location to receive numeric value - * \param consumed Pointer to location to receive number of input - * bytes consumed - * \return true on success, false on invalid input - */ -static bool parse_number(const char *data, bool maybe_negative, bool real, - css_fixed *value, size_t *consumed) -{ - size_t len; - const uint8_t *ptr; - int32_t intpart = 0; - int32_t fracpart = 0; - int32_t pwr = 1; - int sign = 1; - - *consumed = 0; - - len = strlen(data); - ptr = (const uint8_t *) data; - - if (len == 0) - return false; - - /* Skip leading whitespace */ - while (len > 0 && isWhitespace(ptr[0])) { - len--; - ptr++; - } - - if (len == 0) - return false; - - /* Extract sign, if any */ - if (ptr[0] == '+') { - len--; - ptr++; - } else if (ptr[0] == '-' && maybe_negative) { - sign = -1; - len--; - ptr++; - } - - if (len == 0) - return false; - - /* Must have a digit [0,9] */ - if ('0' > ptr[0] || ptr[0] > '9') - return false; - - /* Now extract intpart, assuming base 10 */ - while (len > 0) { - /* Stop on first non-digit */ - if (ptr[0] < '0' || '9' < ptr[0]) - break; - - /* Prevent overflow of 'intpart'; proper clamping below */ - if (intpart < (1 << 22)) { - intpart *= 10; - intpart += ptr[0] - '0'; - } - ptr++; - len--; - } - - /* And fracpart, again, assuming base 10 */ - if (real && len > 1 && ptr[0] == '.' && - ('0' <= ptr[1] && ptr[1] <= '9')) { - ptr++; - len--; - - while (len > 0) { - if (ptr[0] < '0' || '9' < ptr[0]) - break; - - if (pwr < 1000000) { - pwr *= 10; - fracpart *= 10; - fracpart += ptr[0] - '0'; - } - ptr++; - len--; - } - - fracpart = ((1 << 10) * fracpart + pwr/2) / pwr; - if (fracpart >= (1 << 10)) { - intpart++; - fracpart &= (1 << 10) - 1; - } - } - - if (sign > 0) { - /* If the result is larger than we can represent, - * then clamp to the maximum value we can store. */ - if (intpart >= (1 << 21)) { - intpart = (1 << 21) - 1; - fracpart = (1 << 10) - 1; - } - } else { - /* If the negated result is smaller than we can represent - * then clamp to the minimum value we can store. */ - if (intpart >= (1 << 21)) { - intpart = -(1 << 21); - fracpart = 0; - } else { - intpart = -intpart; - if (fracpart) { - fracpart = (1 << 10) - fracpart; - intpart--; - } - } - } - - *value = (intpart << 10) | fracpart; - - *consumed = ptr - (const uint8_t *) data; - - return true; -} - -/** - * Parse a dimension string - * - * \param data Data to parse (NUL-terminated) - * \param strict Whether to enforce strict parsing rules - * \param length Pointer to location to receive dimension's length - * \param unit Pointer to location to receive dimension's unit - * \return true on success, false on invalid input - */ -static bool parse_dimension(const char *data, bool strict, css_fixed *length, - css_unit *unit) -{ - size_t len; - size_t read; - css_fixed value; - - len = strlen(data); - - if (parse_number(data, false, true, &value, &read) == false) - return false; - - if (strict && value < INTTOFIX(1)) - return false; - - *length = value; - - if (len > read && data[read] == '%') - *unit = CSS_UNIT_PCT; - else - *unit = CSS_UNIT_PX; - - return true; -} - -/** - * Mapping of colour name to CSS color - */ -struct colour_map { - const char *name; - css_color color; -}; - -/** - * Name comparator for named colour matching - * - * \param a Name to match - * \param b Colour map entry to consider - * \return 0 on match, - * < 0 if a < b, - * > 0 if b > a. - */ -static int cmp_colour_name(const void *a, const void *b) -{ - const char *aa = a; - const struct colour_map *bb = b; - - return strcasecmp(aa, bb->name); -} - -/** - * Parse a named colour - * - * \param name Name to parse - * \param result Pointer to location to receive css_color - * \return true on success, false on invalid input - */ -static bool parse_named_colour(const char *name, css_color *result) -{ - static const struct colour_map named_colours[] = { - { "aliceblue", 0xfff0f8ff }, - { "antiquewhite", 0xfffaebd7 }, - { "aqua", 0xff00ffff }, - { "aquamarine", 0xff7fffd4 }, - { "azure", 0xfff0ffff }, - { "beige", 0xfff5f5dc }, - { "bisque", 0xffffe4c4 }, - { "black", 0xff000000 }, - { "blanchedalmond", 0xffffebcd }, - { "blue", 0xff0000ff }, - { "blueviolet", 0xff8a2be2 }, - { "brown", 0xffa52a2a }, - { "burlywood", 0xffdeb887 }, - { "cadetblue", 0xff5f9ea0 }, - { "chartreuse", 0xff7fff00 }, - { "chocolate", 0xffd2691e }, - { "coral", 0xffff7f50 }, - { "cornflowerblue", 0xff6495ed }, - { "cornsilk", 0xfffff8dc }, - { "crimson", 0xffdc143c }, - { "cyan", 0xff00ffff }, - { "darkblue", 0xff00008b }, - { "darkcyan", 0xff008b8b }, - { "darkgoldenrod", 0xffb8860b }, - { "darkgray", 0xffa9a9a9 }, - { "darkgreen", 0xff006400 }, - { "darkgrey", 0xffa9a9a9 }, - { "darkkhaki", 0xffbdb76b }, - { "darkmagenta", 0xff8b008b }, - { "darkolivegreen", 0xff556b2f }, - { "darkorange", 0xffff8c00 }, - { "darkorchid", 0xff9932cc }, - { "darkred", 0xff8b0000 }, - { "darksalmon", 0xffe9967a }, - { "darkseagreen", 0xff8fbc8f }, - { "darkslateblue", 0xff483d8b }, - { "darkslategray", 0xff2f4f4f }, - { "darkslategrey", 0xff2f4f4f }, - { "darkturquoise", 0xff00ced1 }, - { "darkviolet", 0xff9400d3 }, - { "deeppink", 0xffff1493 }, - { "deepskyblue", 0xff00bfff }, - { "dimgray", 0xff696969 }, - { "dimgrey", 0xff696969 }, - { "dodgerblue", 0xff1e90ff }, - { "feldspar", 0xffd19275 }, - { "firebrick", 0xffb22222 }, - { "floralwhite", 0xfffffaf0 }, - { "forestgreen", 0xff228b22 }, - { "fuchsia", 0xffff00ff }, - { "gainsboro", 0xffdcdcdc }, - { "ghostwhite", 0xfff8f8ff }, - { "gold", 0xffffd700 }, - { "goldenrod", 0xffdaa520 }, - { "gray", 0xff808080 }, - { "green", 0xff008000 }, - { "greenyellow", 0xffadff2f }, - { "grey", 0xff808080 }, - { "honeydew", 0xfff0fff0 }, - { "hotpink", 0xffff69b4 }, - { "indianred", 0xffcd5c5c }, - { "indigo", 0xff4b0082 }, - { "ivory", 0xfffffff0 }, - { "khaki", 0xfff0e68c }, - { "lavender", 0xffe6e6fa }, - { "lavenderblush", 0xfffff0f5 }, - { "lawngreen", 0xff7cfc00 }, - { "lemonchiffon", 0xfffffacd }, - { "lightblue", 0xffadd8e6 }, - { "lightcoral", 0xfff08080 }, - { "lightcyan", 0xffe0ffff }, - { "lightgoldenrodyellow", 0xfffafad2 }, - { "lightgray", 0xffd3d3d3 }, - { "lightgreen", 0xff90ee90 }, - { "lightgrey", 0xffd3d3d3 }, - { "lightpink", 0xffffb6c1 }, - { "lightsalmon", 0xffffa07a }, - { "lightseagreen", 0xff20b2aa }, - { "lightskyblue", 0xff87cefa }, - { "lightslateblue", 0xff8470ff }, - { "lightslategray", 0xff778899 }, - { "lightslategrey", 0xff778899 }, - { "lightsteelblue", 0xffb0c4de }, - { "lightyellow", 0xffffffe0 }, - { "lime", 0xff00ff00 }, - { "limegreen", 0xff32cd32 }, - { "linen", 0xfffaf0e6 }, - { "magenta", 0xffff00ff }, - { "maroon", 0xff800000 }, - { "mediumaquamarine", 0xff66cdaa }, - { "mediumblue", 0xff0000cd }, - { "mediumorchid", 0xffba55d3 }, - { "mediumpurple", 0xff9370db }, - { "mediumseagreen", 0xff3cb371 }, - { "mediumslateblue", 0xff7b68ee }, - { "mediumspringgreen", 0xff00fa9a }, - { "mediumturquoise", 0xff48d1cc }, - { "mediumvioletred", 0xffc71585 }, - { "midnightblue", 0xff191970 }, - { "mintcream", 0xfff5fffa }, - { "mistyrose", 0xffffe4e1 }, - { "moccasin", 0xffffe4b5 }, - { "navajowhite", 0xffffdead }, - { "navy", 0xff000080 }, - { "oldlace", 0xfffdf5e6 }, - { "olive", 0xff808000 }, - { "olivedrab", 0xff6b8e23 }, - { "orange", 0xffffa500 }, - { "orangered", 0xffff4500 }, - { "orchid", 0xffda70d6 }, - { "palegoldenrod", 0xffeee8aa }, - { "palegreen", 0xff98fb98 }, - { "paleturquoise", 0xffafeeee }, - { "palevioletred", 0xffdb7093 }, - { "papayawhip", 0xffffefd5 }, - { "peachpuff", 0xffffdab9 }, - { "peru", 0xffcd853f }, - { "pink", 0xffffc0cb }, - { "plum", 0xffdda0dd }, - { "powderblue", 0xffb0e0e6 }, - { "purple", 0xff800080 }, - { "red", 0xffff0000 }, - { "rosybrown", 0xffbc8f8f }, - { "royalblue", 0xff4169e1 }, - { "saddlebrown", 0xff8b4513 }, - { "salmon", 0xfffa8072 }, - { "sandybrown", 0xfff4a460 }, - { "seagreen", 0xff2e8b57 }, - { "seashell", 0xfffff5ee }, - { "sienna", 0xffa0522d }, - { "silver", 0xffc0c0c0 }, - { "skyblue", 0xff87ceeb }, - { "slateblue", 0xff6a5acd }, - { "slategray", 0xff708090 }, - { "slategrey", 0xff708090 }, - { "snow", 0xfffffafa }, - { "springgreen", 0xff00ff7f }, - { "steelblue", 0xff4682b4 }, - { "tan", 0xffd2b48c }, - { "teal", 0xff008080 }, - { "thistle", 0xffd8bfd8 }, - { "tomato", 0xffff6347 }, - { "turquoise", 0xff40e0d0 }, - { "violet", 0xffee82ee }, - { "violetred", 0xffd02090 }, - { "wheat", 0xfff5deb3 }, - { "white", 0xffffffff }, - { "whitesmoke", 0xfff5f5f5 }, - { "yellow", 0xffffff00 }, - { "yellowgreen", 0xff9acd32 } - }; - const struct colour_map *entry; - - entry = bsearch(name, named_colours, - sizeof(named_colours) / sizeof(named_colours[0]), - sizeof(named_colours[0]), - cmp_colour_name); - - if (entry != NULL) - *result = entry->color; - - return entry != NULL; -} - -/** - * Parser for colours specified in attribute values. - * - * \param data Data to parse (NUL-terminated) - * \param result Pointer to location to receive resulting css_color - * \return true on success, false on invalid input - */ -bool nscss_parse_colour(const char *data, css_color *result) -{ - size_t len = strlen(data); - uint8_t r, g, b; - - /* 2 */ - if (len == 0) - return false; - - /* 3 */ - if (len == SLEN("transparent") && strcasecmp(data, "transparent") == 0) - return false; - - /* 4 */ - if (parse_named_colour(data, result)) - return true; - - /** \todo Implement HTML5's utterly insane legacy colour parsing */ - - if (data[0] == '#') { - data++; - len--; - } - - if (len == 3 && isHex(data[0]) && isHex(data[1]) && isHex(data[2])) { - r = charToHex(data[0]); - g = charToHex(data[1]); - b = charToHex(data[2]); - - r |= (r << 4); - g |= (g << 4); - b |= (b << 4); - - *result = (0xff << 24) | (r << 16) | (g << 8) | b; - - return true; - } else if (len == 6 && isHex(data[0]) && isHex(data[1]) && - isHex(data[2]) && isHex(data[3]) && isHex(data[4]) && - isHex(data[5])) { - r = (charToHex(data[0]) << 4) | charToHex(data[1]); - g = (charToHex(data[2]) << 4) | charToHex(data[3]); - b = (charToHex(data[4]) << 4) | charToHex(data[5]); - - *result = (0xff << 24) | (r << 16) | (g << 8) | b; - - return true; - } - - return false; -} - -/** - * Parse a font \@size attribute - * - * \param size Data to parse (NUL-terminated) - * \param val Pointer to location to receive enum value - * \param len Pointer to location to receive length - * \param unit Pointer to location to receive unit - * \return True on success, false on failure - */ -static bool parse_font_size(const char *size, uint8_t *val, - css_fixed *len, css_unit *unit) -{ - static const uint8_t size_map[] = { - CSS_FONT_SIZE_XX_SMALL, - CSS_FONT_SIZE_SMALL, - CSS_FONT_SIZE_MEDIUM, - CSS_FONT_SIZE_LARGE, - CSS_FONT_SIZE_X_LARGE, - CSS_FONT_SIZE_XX_LARGE, - CSS_FONT_SIZE_DIMENSION /* xxx-large (see below) */ - }; - - const char *p = size; - char mode; - int value = 0; - - /* Skip whitespace */ - while (*p != '\0' && isWhitespace(*p)) - p++; - - mode = *p; - - /* Skip +/- */ - if (mode == '+' || mode == '-') - p++; - - /* Need at least one digit */ - if (*p < '0' || *p > '9') { - return false; - } - - /* Consume digits, computing value */ - while ('0' <= *p && *p <= '9') { - value = value * 10 + (*p - '0'); - p++; - } - - /* Resolve relative sizes */ - if (mode == '+') - value += 3; - else if (mode == '-') - value = 3 - value; - - /* Clamp to range [1,7] */ - if (value < 1) - value = 1; - else if (value > 7) - value = 7; - - if (value == 7) { - /* Manufacture xxx-large */ - *len = FDIV(FMUL(INTTOFIX(3), INTTOFIX(nsoption_int(font_size))), - F_10); - } else { - /* Len is irrelevant */ - *len = 0; - } - - *unit = CSS_UNIT_PT; - *val = size_map[value - 1]; - - return true; -} - - -/****************************************************************************** - * Hint context management * - ******************************************************************************/ - -#define MAX_HINTS_PER_ELEMENT 32 - -struct css_hint_ctx { - struct css_hint *hints; - uint32_t len; -}; - -struct css_hint_ctx hint_ctx; - -nserror css_hint_init(void) -{ - hint_ctx.hints = malloc(sizeof(struct css_hint) * - MAX_HINTS_PER_ELEMENT); - if (hint_ctx.hints == NULL) { - return NSERROR_NOMEM; - } - - return NSERROR_OK; -} - -void css_hint_fini(void) -{ - hint_ctx.len = 0; - free(hint_ctx.hints); -} - -static void css_hint_clean(void) -{ - hint_ctx.len = 0; -} - -static inline struct css_hint * css_hint_advance(struct css_hint *hint) -{ - hint_ctx.len++; - assert(hint_ctx.len < MAX_HINTS_PER_ELEMENT); - - return ++hint; -} - -static void css_hint_get_hints(struct css_hint **hints, uint32_t *nhints) -{ - *hints = hint_ctx.hints; - *nhints = hint_ctx.len; -} - - -/****************************************************************************** - * Presentational hint handlers * - ******************************************************************************/ - -static void css_hint_table_cell_border_padding( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - css_qname qs; - dom_string *attr = NULL; - dom_node *tablenode = NULL; - dom_exception exc; - - qs.ns = NULL; - qs.name = lwc_string_ref(corestring_lwc_table); - if (named_ancestor_node(ctx, node, &qs, - (void *)&tablenode) != CSS_OK) { - /* Didn't find, or had error */ - lwc_string_unref(qs.name); - return; - } - lwc_string_unref(qs.name); - - if (tablenode == NULL) { - return; - } - /* No need to unref tablenode, named_ancestor_node does not - * return a reffed node to the CSS - */ - - exc = dom_element_get_attribute(tablenode, - corestring_dom_border, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - uint32_t hint_prop; - css_hint_length hint_length; - - if (parse_dimension( - dom_string_data(attr), false, - &hint_length.value, - &hint_length.unit) && - INTTOFIX(0) != hint_length.value) { - - for (hint_prop = CSS_PROP_BORDER_TOP_STYLE; - hint_prop <= CSS_PROP_BORDER_LEFT_STYLE; - hint_prop++) { - hint->prop = hint_prop; - hint->status = CSS_BORDER_STYLE_INSET; - hint = css_hint_advance(hint); - } - - for (hint_prop = CSS_PROP_BORDER_TOP_WIDTH; - hint_prop <= CSS_PROP_BORDER_LEFT_WIDTH; - hint_prop++) { - hint->prop = hint_prop; - hint->data.length.value = INTTOFIX(1); - hint->data.length.unit = CSS_UNIT_PX; - hint->status = CSS_BORDER_WIDTH_WIDTH; - hint = css_hint_advance(hint); - } - } - dom_string_unref(attr); - } - - exc = dom_element_get_attribute(tablenode, - corestring_dom_bordercolor, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - uint32_t hint_prop; - css_color hint_color; - - if (nscss_parse_colour( - (const char *)dom_string_data(attr), - &hint_color)) { - - for (hint_prop = CSS_PROP_BORDER_TOP_COLOR; - hint_prop <= CSS_PROP_BORDER_LEFT_COLOR; - hint_prop++) { - hint->prop = hint_prop; - hint->data.color = hint_color; - hint->status = CSS_BORDER_COLOR_COLOR; - hint = css_hint_advance(hint); - } - } - dom_string_unref(attr); - } - - exc = dom_element_get_attribute(tablenode, - corestring_dom_cellpadding, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - uint32_t hint_prop; - css_hint_length hint_length; - - if (parse_dimension( - dom_string_data(attr), false, - &hint_length.value, - &hint_length.unit)) { - - for (hint_prop = CSS_PROP_PADDING_TOP; - hint_prop <= CSS_PROP_PADDING_LEFT; - hint_prop++) { - hint->prop = hint_prop; - hint->data.length.value = hint_length.value; - hint->data.length.unit = hint_length.unit; - hint->status = CSS_PADDING_SET; - hint = css_hint_advance(hint); - } - } - dom_string_unref(attr); - } -} - -static void css_hint_vertical_align_table_cells( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_valign, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_top)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_TOP; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_middle)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_MIDDLE; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_bottom)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_BOTTOM; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_baseline)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_BASELINE; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_vertical_align_replaced( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_valign, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_top)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_TOP; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_bottom) || - dom_string_caseless_lwc_isequal(attr, - corestring_lwc_baseline)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_BASELINE; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_texttop)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_TEXT_TOP; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_absmiddle) || - dom_string_caseless_lwc_isequal(attr, - corestring_lwc_abscenter)) { - hint->prop = CSS_PROP_VERTICAL_ALIGN; - hint->status = CSS_VERTICAL_ALIGN_MIDDLE; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_text_align_normal( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *align = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_align, &align); - if (err == DOM_NO_ERR && align != NULL) { - if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_left)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_LEFT; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_center)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_CENTER; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_right)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_RIGHT; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_justify)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_JUSTIFY; - hint = css_hint_advance(hint); - } - dom_string_unref(align); - } -} - -static void css_hint_text_align_center( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER; - hint = css_hint_advance(hint); -} - -static void css_hint_margin_left_right_align_center( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr; - dom_exception exc; - - exc = dom_element_get_attribute(node, - corestring_dom_align, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_center) || - dom_string_caseless_lwc_isequal(attr, - corestring_lwc_abscenter) || - dom_string_caseless_lwc_isequal(attr, - corestring_lwc_middle) || - dom_string_caseless_lwc_isequal(attr, - corestring_lwc_absmiddle)) { - hint->prop = CSS_PROP_MARGIN_LEFT; - hint->status = CSS_MARGIN_AUTO; - hint = css_hint_advance(hint); - - hint->prop = CSS_PROP_MARGIN_RIGHT; - hint->status = CSS_MARGIN_AUTO; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_text_align_special( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *align = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_align, &align); - - if (err == DOM_NO_ERR && align != NULL) { - if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_center)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_left)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_LIBCSS_LEFT; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_right)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_LIBCSS_RIGHT; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_justify)) { - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_JUSTIFY; - hint = css_hint_advance(hint); - } - dom_string_unref(align); - } -} - -static void css_hint_text_align_table_special( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - - hint->prop = CSS_PROP_TEXT_ALIGN; - hint->status = CSS_TEXT_ALIGN_INHERIT_IF_NON_MAGIC; - hint = css_hint_advance(hint); -} - -static void css_hint_margin_hspace_vspace( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr = NULL; - dom_exception exc; - - exc = dom_element_get_attribute(node, - corestring_dom_vspace, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - css_hint_length hint_length; - if (parse_dimension( - dom_string_data(attr), false, - &hint_length.value, - &hint_length.unit)) { - hint->prop = CSS_PROP_MARGIN_TOP; - hint->data.length.value = hint_length.value; - hint->data.length.unit = hint_length.unit; - hint->status = CSS_MARGIN_SET; - hint = css_hint_advance(hint); - - hint->prop = CSS_PROP_MARGIN_BOTTOM; - hint->data.length.value = hint_length.value; - hint->data.length.unit = hint_length.unit; - hint->status = CSS_MARGIN_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } - - exc = dom_element_get_attribute(node, - corestring_dom_hspace, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - css_hint_length hint_length; - if (parse_dimension( - dom_string_data(attr), false, - &hint_length.value, - &hint_length.unit)) { - hint->prop = CSS_PROP_MARGIN_LEFT; - hint->data.length.value = hint_length.value; - hint->data.length.unit = hint_length.unit; - hint->status = CSS_MARGIN_SET; - hint = css_hint_advance(hint); - - hint->prop = CSS_PROP_MARGIN_RIGHT; - hint->data.length.value = hint_length.value; - hint->data.length.unit = hint_length.unit; - hint->status = CSS_MARGIN_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_margin_left_right_hr( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr; - dom_exception exc; - - exc = dom_element_get_attribute(node, - corestring_dom_align, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_left)) { - hint->prop = CSS_PROP_MARGIN_LEFT; - hint->data.length.value = 0; - hint->data.length.unit = CSS_UNIT_PX; - hint->status = CSS_MARGIN_SET; - hint = css_hint_advance(hint); - - hint->prop = CSS_PROP_MARGIN_RIGHT; - hint->status = CSS_MARGIN_AUTO; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_center)) { - hint->prop = CSS_PROP_MARGIN_LEFT; - hint->status = CSS_MARGIN_AUTO; - hint = css_hint_advance(hint); - - hint->prop = CSS_PROP_MARGIN_RIGHT; - hint->status = CSS_MARGIN_AUTO; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(attr, - corestring_lwc_right)) { - hint->prop = CSS_PROP_MARGIN_LEFT; - hint->status = CSS_MARGIN_AUTO; - hint = css_hint_advance(hint); - - hint->prop = CSS_PROP_MARGIN_RIGHT; - hint->data.length.value = 0; - hint->data.length.unit = CSS_UNIT_PX; - hint->status = CSS_MARGIN_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_table_spacing_border( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception exc; - dom_string *attr = NULL; - - exc = dom_element_get_attribute(node, corestring_dom_border, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - uint32_t hint_prop; - css_hint_length hint_length; - - for (hint_prop = CSS_PROP_BORDER_TOP_STYLE; - hint_prop <= CSS_PROP_BORDER_LEFT_STYLE; - hint_prop++) { - hint->prop = hint_prop; - hint->status = CSS_BORDER_STYLE_OUTSET; - hint = css_hint_advance(hint); - } - - if (parse_dimension( - dom_string_data(attr), false, - &hint_length.value, - &hint_length.unit)) { - - for (hint_prop = CSS_PROP_BORDER_TOP_WIDTH; - hint_prop <= CSS_PROP_BORDER_LEFT_WIDTH; - hint_prop++) { - hint->prop = hint_prop; - hint->data.length.value = hint_length.value; - hint->data.length.unit = hint_length.unit; - hint->status = CSS_BORDER_WIDTH_WIDTH; - hint = css_hint_advance(hint); - } - } - dom_string_unref(attr); - } - - exc = dom_element_get_attribute(node, - corestring_dom_bordercolor, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - uint32_t hint_prop; - css_color hint_color; - - if (nscss_parse_colour( - (const char *)dom_string_data(attr), - &hint_color)) { - - for (hint_prop = CSS_PROP_BORDER_TOP_COLOR; - hint_prop <= CSS_PROP_BORDER_LEFT_COLOR; - hint_prop++) { - hint->prop = hint_prop; - hint->data.color = hint_color; - hint->status = CSS_BORDER_COLOR_COLOR; - hint = css_hint_advance(hint); - } - } - dom_string_unref(attr); - } - - exc = dom_element_get_attribute(node, - corestring_dom_cellspacing, &attr); - - if (exc == DOM_NO_ERR && attr != NULL) { - if (parse_dimension( - (const char *)dom_string_data(attr), false, - &hint->data.position.h.value, - &hint->data.position.h.unit)) { - hint->prop = CSS_PROP_BORDER_SPACING; - hint->data.position.v = hint->data.position.h; - hint->status = CSS_BORDER_SPACING_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_height( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_height, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (parse_dimension( - (const char *)dom_string_data(attr), false, - &hint->data.length.value, - &hint->data.length.unit)) { - hint->prop = CSS_PROP_HEIGHT; - hint->status = CSS_HEIGHT_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_width( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_width, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (parse_dimension( - (const char *)dom_string_data(attr), false, - &hint->data.length.value, - &hint->data.length.unit)) { - hint->prop = CSS_PROP_WIDTH; - hint->status = CSS_WIDTH_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_height_width_textarea( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_string *attr = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_rows, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (parse_dimension( - (const char *)dom_string_data(attr), false, - &hint->data.length.value, - &hint->data.length.unit)) { - hint->prop = CSS_PROP_HEIGHT; - hint->data.length.unit = CSS_UNIT_EM; - hint->status = CSS_HEIGHT_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } - - err = dom_element_get_attribute(node, - corestring_dom_cols, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (parse_dimension( - (const char *)dom_string_data(attr), false, - &hint->data.length.value, - &hint->data.length.unit)) { - hint->prop = CSS_PROP_WIDTH; - hint->data.length.unit = CSS_UNIT_EX; - hint->status = CSS_WIDTH_SET; - hint = css_hint_advance(hint); - } - dom_string_unref(attr); - } -} - -static void css_hint_width_input( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &(hint_ctx.hints[hint_ctx.len]); - dom_string *attr = NULL; - dom_exception err; - - err = dom_element_get_attribute(node, - corestring_dom_size, &attr); - - if (err == DOM_NO_ERR && attr != NULL) { - if (parse_dimension( - (const char *)dom_string_data(attr), false, - &hint->data.length.value, - &hint->data.length.unit)) { - dom_string *attr2 = NULL; - - err = dom_element_get_attribute(node, - corestring_dom_type, &attr2); - if (err == DOM_NO_ERR) { - - hint->prop = CSS_PROP_WIDTH; - hint->status = CSS_WIDTH_SET; - - if (attr2 == NULL || - dom_string_caseless_lwc_isequal( - attr2, - corestring_lwc_text) || - dom_string_caseless_lwc_isequal( - attr2, - corestring_lwc_search) || - dom_string_caseless_lwc_isequal( - attr2, - corestring_lwc_password) || - dom_string_caseless_lwc_isequal( - attr2, - corestring_lwc_file)) { - hint->data.length.unit = CSS_UNIT_EX; - } - if (attr2 != NULL) { - dom_string_unref(attr2); - } - hint = css_hint_advance(hint); - } - } - dom_string_unref(attr); - } -} - -static void css_hint_anchor_color( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - css_error error; - dom_exception err; - dom_string *color; - dom_node *bodynode = NULL; - - /* find body node */ - css_qname qs; - bool is_visited; - - qs.ns = NULL; - qs.name = lwc_string_ref(corestring_lwc_body); - if (named_ancestor_node(ctx, node, &qs, - (void *)&bodynode) != CSS_OK) { - /* Didn't find, or had error */ - lwc_string_unref(qs.name); - return ; - } - lwc_string_unref(qs.name); - - if (bodynode == NULL) { - return; - } - - error = node_is_visited(ctx, node, &is_visited); - if (error != CSS_OK) - return; - - if (is_visited) { - err = dom_element_get_attribute(bodynode, - corestring_dom_vlink, &color); - } else { - err = dom_element_get_attribute(bodynode, - corestring_dom_link, &color); - } - - if (err == DOM_NO_ERR && color != NULL) { - if (nscss_parse_colour( - (const char *)dom_string_data(color), - &hint->data.color)) { - hint->prop = CSS_PROP_COLOR; - hint->status = CSS_COLOR_COLOR; - hint = css_hint_advance(hint); - } - dom_string_unref(color); - } -} - -static void css_hint_body_color( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception err; - dom_string *color; - - err = dom_element_get_attribute(node, corestring_dom_text, &color); - - if (err == DOM_NO_ERR && color != NULL) { - if (nscss_parse_colour( - (const char *)dom_string_data(color), - &hint->data.color)) { - hint->prop = CSS_PROP_COLOR; - hint->status = CSS_COLOR_COLOR; - hint = css_hint_advance(hint); - } - dom_string_unref(color); - } -} - -static void css_hint_color( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception err; - dom_string *color; - - err = dom_element_get_attribute(node, corestring_dom_color, &color); - - if (err == DOM_NO_ERR && color != NULL) { - if (nscss_parse_colour( - (const char *)dom_string_data(color), - &hint->data.color)) { - hint->prop = CSS_PROP_COLOR; - hint->status = CSS_COLOR_COLOR; - hint = css_hint_advance(hint); - } - dom_string_unref(color); - } -} - -static void css_hint_font_size( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception err; - dom_string *size; - - err = dom_element_get_attribute(node, corestring_dom_size, &size); - if (err == DOM_NO_ERR && size != NULL) { - if (parse_font_size( - (const char *)dom_string_data(size), - &hint->status, - &hint->data.length.value, - &hint->data.length.unit)) { - hint->prop = CSS_PROP_FONT_SIZE; - hint = css_hint_advance(hint); - } - dom_string_unref(size); - } -} - -static void css_hint_float( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception err; - dom_string *align; - - err = dom_element_get_attribute(node, corestring_dom_align, &align); - if (err == DOM_NO_ERR && align != NULL) { - if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_left)) { - hint->prop = CSS_PROP_FLOAT; - hint->status = CSS_FLOAT_LEFT; - hint = css_hint_advance(hint); - - } else if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_right)) { - hint->prop = CSS_PROP_FLOAT; - hint->status = CSS_FLOAT_RIGHT; - hint = css_hint_advance(hint); - } - dom_string_unref(align); - } -} - -static void css_hint_caption_side( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception err; - dom_string *align = NULL; - - err = dom_element_get_attribute(node, corestring_dom_align, &align); - if (err == DOM_NO_ERR && align != NULL) { - if (dom_string_caseless_lwc_isequal(align, - corestring_lwc_bottom)) { - hint->prop = CSS_PROP_CAPTION_SIDE; - hint->status = CSS_CAPTION_SIDE_BOTTOM; - hint = css_hint_advance(hint); - } - dom_string_unref(align); - } -} - -static void css_hint_bg_color( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &hint_ctx.hints[hint_ctx.len]; - dom_exception err; - dom_string *bgcolor; - - err = dom_element_get_attribute(node, - corestring_dom_bgcolor, &bgcolor); - if (err == DOM_NO_ERR && bgcolor != NULL) { - if (nscss_parse_colour( - (const char *)dom_string_data(bgcolor), - &hint->data.color)) { - hint->prop = CSS_PROP_BACKGROUND_COLOR; - hint->status = CSS_BACKGROUND_COLOR_COLOR; - hint = css_hint_advance(hint); - } - dom_string_unref(bgcolor); - } -} - -static void css_hint_bg_image( - nscss_select_ctx *ctx, - dom_node *node) -{ - struct css_hint *hint = &(hint_ctx.hints[hint_ctx.len]); - dom_exception err; - dom_string *attr; - - err = dom_element_get_attribute(node, - corestring_dom_background, &attr); - if (err == DOM_NO_ERR && attr != NULL) { - nsurl *url; - nserror error = nsurl_join(ctx->base_url, - (const char *)dom_string_data(attr), &url); - dom_string_unref(attr); - - if (error == NSERROR_OK) { - lwc_string *iurl; - lwc_error lerror = lwc_intern_string(nsurl_access(url), - nsurl_length(url), &iurl); - nsurl_unref(url); - - if (lerror == lwc_error_ok) { - hint->prop = CSS_PROP_BACKGROUND_IMAGE; - hint->data.string = iurl; - hint->status = CSS_BACKGROUND_IMAGE_IMAGE; - hint = css_hint_advance(hint); - } - } - } -} - - -/* Exported function, documeted in css/hints.h */ -css_error node_presentational_hint(void *pw, void *node, - uint32_t *nhints, css_hint **hints) -{ - dom_exception exc; - dom_html_element_type tag_type; - - css_hint_clean(); - - exc = dom_html_element_get_tag_type(node, &tag_type); - if (exc != DOM_NO_ERR) { - tag_type = DOM_HTML_ELEMENT_TYPE__UNKNOWN; - } - - switch (tag_type) { - case DOM_HTML_ELEMENT_TYPE_TH: - case DOM_HTML_ELEMENT_TYPE_TD: - css_hint_width(pw, node); - css_hint_table_cell_border_padding(pw, node); - /* fallthrough */ - case DOM_HTML_ELEMENT_TYPE_TR: - css_hint_height(pw, node); - /* fallthrough */ - case DOM_HTML_ELEMENT_TYPE_THEAD: - case DOM_HTML_ELEMENT_TYPE_TBODY: - case DOM_HTML_ELEMENT_TYPE_TFOOT: - css_hint_text_align_special(pw, node); - /* fallthrough */ - case DOM_HTML_ELEMENT_TYPE_COL: - css_hint_vertical_align_table_cells(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_APPLET: - case DOM_HTML_ELEMENT_TYPE_IMG: - css_hint_margin_hspace_vspace(pw, node); - /* fallthrough */ - case DOM_HTML_ELEMENT_TYPE_EMBED: - case DOM_HTML_ELEMENT_TYPE_IFRAME: - case DOM_HTML_ELEMENT_TYPE_OBJECT: - css_hint_height(pw, node); - css_hint_width(pw, node); - css_hint_vertical_align_replaced(pw, node); - css_hint_float(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_P: - case DOM_HTML_ELEMENT_TYPE_H1: - case DOM_HTML_ELEMENT_TYPE_H2: - case DOM_HTML_ELEMENT_TYPE_H3: - case DOM_HTML_ELEMENT_TYPE_H4: - case DOM_HTML_ELEMENT_TYPE_H5: - case DOM_HTML_ELEMENT_TYPE_H6: - css_hint_text_align_normal(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_CENTER: - css_hint_text_align_center(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_CAPTION: - css_hint_caption_side(pw, node); - /* fallthrough */ - case DOM_HTML_ELEMENT_TYPE_DIV: - css_hint_text_align_special(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_TABLE: - css_hint_text_align_table_special(pw, node); - css_hint_table_spacing_border(pw, node); - css_hint_float(pw, node); - css_hint_margin_left_right_align_center(pw, node); - css_hint_width(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_HR: - css_hint_margin_left_right_hr(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_TEXTAREA: - css_hint_height_width_textarea(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_INPUT: - css_hint_width_input(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_A: - css_hint_anchor_color(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_FONT: - css_hint_font_size(pw, node); - break; - case DOM_HTML_ELEMENT_TYPE_BODY: - css_hint_body_color(pw, node); - break; - default: - break; - } - - if (tag_type != DOM_HTML_ELEMENT_TYPE__UNKNOWN) { - css_hint_color(pw, node); - css_hint_bg_color(pw, node); - css_hint_bg_image(pw, node); - } - -#ifdef LOG_STATS - LOG("Properties with hints: %i", hint_ctx.len); -#endif - - css_hint_get_hints(hints, nhints); - - return CSS_OK; -} - |