/* * This file is part of LibCSS * Licensed under the MIT License, * http://www.opensource.org/licenses/mit-license.php * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> */ #include <string.h> #include "select/computed.h"#include "select/dispatch.h"#include "select/propget.h"#include "select/propset.h"#include "utils/utils.h" static css_error compute_absolute_color(css_computed_style *style, uint8_t (*get)(const css_computed_style *style, css_color *color), css_error (*set)(css_computed_style *style, uint8_t type, css_color color));static css_error compute_border_colors(css_computed_style *style); static css_error compute_absolute_border_width(css_computed_style *style, const css_hint_length *ex_size);static css_error compute_absolute_border_side_width(css_computed_style *style, const css_hint_length *ex_size, uint8_t (*get)(const css_computed_style *style, css_fixed *len, css_unit *unit), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len, css_unit unit));static css_error compute_absolute_sides(css_computed_style *style, const css_hint_length *ex_size);static css_error compute_absolute_clip(css_computed_style *style, const css_hint_length *ex_size);static css_error compute_absolute_line_height(css_computed_style *style, const css_hint_length *ex_size);static css_error compute_absolute_margins(css_computed_style *style, const css_hint_length *ex_size);static css_error compute_absolute_padding(css_computed_style *style, const css_hint_length *ex_size);static css_error compute_absolute_vertical_align(css_computed_style *style, const css_hint_length *ex_size);static css_error compute_absolute_length(css_computed_style *style, const css_hint_length *ex_size, uint8_t (*get)(const css_computed_style *style, css_fixed *len, css_unit *unit), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len, css_unit unit));static css_error compute_absolute_length_auto(css_computed_style *style, const css_hint_length *ex_size, uint8_t (*get)(const css_computed_style *style, css_fixed *len, css_unit *unit), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len, css_unit unit));static css_error compute_absolute_length_none(css_computed_style *style, const css_hint_length *ex_size, uint8_t (*get)(const css_computed_style *style, css_fixed *len, css_unit *unit), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len, css_unit unit));static css_error compute_absolute_length_normal(css_computed_style *style, const css_hint_length *ex_size, uint8_t (*get)(const css_computed_style *style, css_fixed *len, css_unit *unit), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len, css_unit unit));static css_error compute_absolute_length_pair(css_computed_style *style, const css_hint_length *ex_size, uint8_t (*get)(const css_computed_style *style, css_fixed *len1, css_unit *unit1, css_fixed *len2, css_unit *unit2), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len1, css_unit unit1, css_fixed len2, css_unit unit2)); /** * Create a computed style * * \param alloc Memory (de)allocation function * \param pw Pointer to client-specific data * \param result Pointer to location to receive result * \return CSS_OK on success, * CSS_NOMEM on memory exhaustion, * CSS_BADPARM on bad parameters. */css_error css_computed_style_create(css_allocator_fn alloc, void *pw, css_computed_style **result){ css_computed_style *s; if (alloc == NULL || result == NULL) return CSS_BADPARM; s = alloc(NULL, sizeof(css_computed_style), pw); if (s == NULL) return CSS_NOMEM; memset(s, 0, sizeof(css_computed_style)); s->alloc = alloc; s->pw = pw; *result = s; return CSS_OK;} /** * Destroy a computed style * * \param style Style to destroy * \return CSS_OK on success, appropriate error otherwise */css_error css_computed_style_destroy(css_computed_style *style){ if (style == NULL) return CSS_BADPARM; if (style->uncommon != NULL) { if (style->uncommon->counter_increment != NULL) { css_computed_counter *c; for (c = style->uncommon->counter_increment; c->name != NULL; c++) { lwc_string_unref(c->name); } style->alloc(style->uncommon->counter_increment, 0, style->pw); } if (style->uncommon->counter_reset != NULL) { css_computed_counter *c; for (c = style->uncommon->counter_reset; c->name != NULL; c++) { lwc_string_unref(c->name); } style->alloc(style->uncommon->counter_reset, 0, style->pw); } if (style->uncommon->cursor != NULL) { lwc_string **s; for (s = style->uncommon->cursor; *s != NULL; s++) { lwc_string_unref(*s); } style->alloc(style->uncommon->cursor, 0, style->pw); } if (style->uncommon->content != NULL) { css_computed_content_item *c; for (c = style->uncommon->content; c->type != CSS_COMPUTED_CONTENT_NONE; c++) { switch (c->type) { case CSS_COMPUTED_CONTENT_STRING: lwc_string_unref(c->data.string); break; case CSS_COMPUTED_CONTENT_URI: lwc_string_unref(c->data.uri); break; case CSS_COMPUTED_CONTENT_ATTR: lwc_string_unref(c->data.attr); break; case CSS_COMPUTED_CONTENT_COUNTER: lwc_string_unref(c->data.counter.name); break; case CSS_COMPUTED_CONTENT_COUNTERS: lwc_string_unref(c->data.counters.name); lwc_string_unref(c->data.counters.sep); break; default: break; } } style->alloc(style->uncommon->content, 0, style->pw); } style->alloc(style->uncommon, 0, style->pw); } if (style->page != NULL) { style->alloc(style->page, 0, style->pw); } if (style->aural != NULL) { style->alloc(style->aural, 0, style->pw); } if (style->font_family != NULL) { lwc_string **s; for (s = style->font_family; *s != NULL; s++) { lwc_string_unref(*s); } style->alloc(style->font_family, 0, style->pw); } if (style->quotes != NULL) { lwc_string **s; for (s = style->quotes; *s != NULL; s++) { lwc_string_unref(*s); } style->alloc(style->quotes, 0, style->pw); } if (style->list_style_image != NULL) lwc_string_unref(style->list_style_image); if (style->background_image != NULL) lwc_string_unref(style->background_image); style->alloc(style, 0, style->pw); return CSS_OK;} /** * Populate a blank computed style with Initial values * * \param style Computed style to populate * \param handler Dispatch table of handler functions * \param pw Client-specific private data for handler functions * \return CSS_OK on success. */css_error css_computed_style_initialise(css_computed_style *style, css_select_handler *handler, void *pw){ css_select_state state; uint32_t i; css_error error; if (style == NULL) return CSS_BADPARM; state.node = NULL; state.media = CSS_MEDIA_ALL; state.results = NULL; state.computed = style; state.handler = handler; state.pw = pw; for (i = 0; i < CSS_N_PROPERTIES; i++) { /* No need to initialise anything other than the normal * properties -- the others are handled by the accessors */ if (prop_dispatch[i].inherited == false && prop_dispatch[i].group == GROUP_NORMAL) { error = prop_dispatch[i].initial(&state); if (error != CSS_OK) return error; } } return CSS_OK;} /** * Compose two computed styles * * \param parent Parent style * \param child Child style * \param compute_font_size Function to compute an absolute font size * \param pw Client data for compute_font_size * \param result Pointer to style to compose into * \return CSS_OK on success, appropriate error otherwise. * * \pre \a parent is a fully composed style (thus has no inherited properties) * * \note \a child and \a result may point at the same object */css_error css_computed_style_compose(const css_computed_style *parent, const css_computed_style *child, css_error (*compute_font_size)(void *pw, const css_hint *parent, css_hint *size), void *pw, css_computed_style *result){ css_error error = CSS_OK; size_t i; /* Iterate through the properties */ for (i = 0; i < CSS_N_PROPERTIES; i++) { /* Skip any in extension blocks if the block does not exist */ if (prop_dispatch[i].group == GROUP_UNCOMMON && parent->uncommon == NULL && child->uncommon == NULL) continue; if (prop_dispatch[i].group == GROUP_PAGE && parent->page == NULL && child->page == NULL) continue; if (prop_dispatch[i].group == GROUP_AURAL && parent->aural == NULL && child->aural == NULL) continue; /* Compose the property */ error = prop_dispatch[i].compose(parent, child, result); if (error != CSS_OK) break; } /* Finally, compute absolute values for everything */ return css__compute_absolute_values(parent, result, compute_font_size, pw);} /****************************************************************************** * Property accessors * ******************************************************************************/ #define CSS_LETTER_SPACING_INDEX 0#define CSS_LETTER_SPACING_SHIFT 2#define CSS_LETTER_SPACING_MASK 0xfcuint8_t css_computed_letter_spacing( const css_computed_style *style, css_fixed *length, css_unit *unit){ if (style->uncommon != NULL) { uint8_t bits = style->uncommon->bits[CSS_LETTER_SPACING_INDEX]; bits &= CSS_LETTER_SPACING_MASK; bits >>= CSS_LETTER_SPACING_SHIFT; /* 6bits: uuuutt : unit | type */ if ((bits & 3) == CSS_LETTER_SPACING_SET) { *length = style->uncommon->letter_spacing; *unit = (css_unit) (bits >> 2); } return (bits & 3); } return CSS_LETTER_SPACING_NORMAL;}#undef CSS_LETTER_SPACING_MASK#undef CSS_LETTER_SPACING_SHIFT#undef CSS_LETTER_SPACING_INDEX #define CSS_OUTLINE_COLOR_INDEX 0#define CSS_OUTLINE_COLOR_SHIFT 0#define CSS_OUTLINE_COLOR_MASK 0x3uint8_t css_computed_outline_color( const css_computed_style *style, css_color *color){ if (style->uncommon != NULL) { uint8_t bits = style->uncommon->bits[CSS_OUTLINE_COLOR_INDEX]; bits &= CSS_OUTLINE_COLOR_MASK; bits >>= CSS_OUTLINE_COLOR_SHIFT; /* 2bits: tt : type */ if ((bits & 3) == CSS_OUTLINE_COLOR_COLOR) { *color = style->uncommon->outline_color; } return (bits & 3); } return CSS_OUTLINE_COLOR_INVERT;}#undef CSS_OUTLINE_COLOR_MASK#undef CSS_OUTLINE_COLOR_SHIFT#undef CSS_OUTLINE_COLOR_INDEX #define CSS_OUTLINE_WIDTH_INDEX 1#define CSS_OUTLINE_WIDTH_SHIFT 1#define CSS_OUTLINE_WIDTH_MASK 0xfeuint8_t css_computed_outline_width( const css_computed_style *style, css_fixed *length, css_unit *unit){ if (style->uncommon != NULL) { uint8_t bits = style->uncommon->bits[CSS_OUTLINE_WIDTH_INDEX]; bits &= CSS_OUTLINE_WIDTH_MASK; bits >>= CSS_OUTLINE_WIDTH_SHIFT; /* 7bits: uuuuttt : unit | type */ if ((bits & 7) == CSS_OUTLINE_WIDTH_WIDTH) { *length = style->uncommon->outline_width; *unit = (css_unit) (bits >> 3); } return (bits & 7); } *length = INTTOFIX(2); *unit = CSS_UNIT_PX; return CSS_OUTLINE_WIDTH_WIDTH;}#undef CSS_OUTLINE_WIDTH_MASK#undef CSS_OUTLINE_WIDTH_SHIFT#undef CSS_OUTLINE_WIDTH_INDEX #define CSS_BORDER_SPACING_INDEX 1#define CSS_BORDER_SPACING_SHIFT 0#define CSS_BORDER_SPACING_MASK 0x1#define CSS_BORDER_SPACING_INDEX1 2#define CSS_BORDER_SPACING_SHIFT1 0#define CSS_BORDER_SPACING_MASK1 0xffuint8_t css_computed_border_spacing( const css_computed_style *style, css_fixed *hlength, css_unit *hunit, css_fixed *vlength, css_unit *vunit){ if (style->uncommon != NULL) { uint8_t bits = style->uncommon->bits[CSS_BORDER_SPACING_INDEX]; bits &= CSS_BORDER_SPACING_MASK; bits >>= CSS_BORDER_SPACING_SHIFT; /* 1 bit: type */ if (bits == CSS_BORDER_SPACING_SET) { uint8_t bits1 = style->uncommon->bits[CSS_BORDER_SPACING_INDEX1]; bits1 &= CSS_BORDER_SPACING_MASK1; bits1 >>= CSS_BORDER_SPACING_SHIFT1; /* 8bits: hhhhvvvv : hunit | vunit */ *hlength = style->uncommon->border_spacing[0]; *hunit = (css_unit) (bits1 >> 4); *vlength = style->uncommon->border_spacing[1]; *vunit = (css_unit) (bits1 & 0xf); } return bits; } else { *hlength = *vlength = 0; *hunit = *vunit = CSS_UNIT_PX; } return CSS_BORDER_SPACING_SET;}#undef CSS_BORDER_SPACING_MASK1#undef CSS_BORDER_SPACING_SHIFT1#undef CSS_BORDER_SPACING_INDEX1#undef CSS_BORDER_SPACING_MASK#undef CSS_BORDER_SPACING_SHIFT#undef CSS_BORDER_SPACING_INDEX #define CSS_WORD_SPACING_INDEX 3#define CSS_WORD_SPACING_SHIFT 2#define CSS_WORD_SPACING_MASK 0xfcuint8_t css_computed_word_spacing( const css_computed_style *style, css_fixed *length, css_unit *unit){ if (style->uncommon != NULL) { uint8_t bits = style->uncommon->bits[CSS_WORD_SPACING_INDEX]; bits &= CSS_WORD_SPACING_MASK; bits >>= CSS_WORD_SPACING_SHIFT; /* 6bits: uuuutt : unit | type */ if ((bits & 3) == CSS_WORD_SPACING_SET) { *length = style->uncommon->word_spacing; *unit = (css_unit) (bits >> 2); } return (bits & 3); } return CSS_WORD_SPACING_NORMAL;}#undef CSS_WORD_SPACING_MASK#undef CSS_WORD_SPACING_SHIFT#undef CSS_WORD_SPACING_INDEX #define CSS_COUNTER_INCREMENT_INDEX 3#define CSS_COUNTER_INCREMENT_SHIFT 1#define CSS_COUNTER_INCREMENT_MASK 0x2uint8_t css_computed_counter_increment( const css_computed_style *style, const css_computed_counter **counters){ if (style->uncommon != NULL) { uint8_t bits = style->uncommon->bits[CSS_COUNTER_INCREMENT_INDEX]; bits &= CSS_COUNTER_INCREMENT_MASK; bits >>= CSS_COUNTER_INCREMENT_SHIFT; /* 1bit: type */ *counters = style->uncommon->counter_increment; return bits; } Lines 1–500 of 2968. Load more
/* * This file is part of LibCSS * Licensed under the MIT License, * http://www.opensource.org/licenses/mit-license.php * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> */ #include <string.h> #include "select/computed.h" #include "select/dispatch.h" #include "select/propget.h" #include "select/propset.h" #include "utils/utils.h" static css_error compute_absolute_color(css_computed_style *style, uint8_t (*get)(const css_computed_style *style, css_color *color), css_error (*set)(css_computed_style *style, uint8_t type, css_color color)); static css_error compute_border_colors(css_computed_style *style); static css_error compute_absolute_border_width(css_computed_style *style, const css_hint_length *ex_size); static css_error compute_absolute_border_side_width(css_computed_style *style, const css_hint_length *ex_size, uint8_t (*get)(const css_computed_style *style, css_fixed *len, css_unit *unit), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len, css_unit unit)); static css_error compute_absolute_sides(css_computed_style *style, const css_hint_length *ex_size); static css_error compute_absolute_clip(css_computed_style *style, const css_hint_length *ex_size); static css_error compute_absolute_line_height(css_computed_style *style, const css_hint_length *ex_size); static css_error compute_absolute_margins(css_computed_style *style, const css_hint_length *ex_size); static css_error compute_absolute_padding(css_computed_style *style, const css_hint_length *ex_size); static css_error compute_absolute_vertical_align(css_computed_style *style, const css_hint_length *ex_size); static css_error compute_absolute_length(css_computed_style *style, const css_hint_length *ex_size, uint8_t (*get)(const css_computed_style *style, css_fixed *len, css_unit *unit), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len, css_unit unit)); static css_error compute_absolute_length_auto(css_computed_style *style, const css_hint_length *ex_size, uint8_t (*get)(const css_computed_style *style, css_fixed *len, css_unit *unit), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len, css_unit unit)); static css_error compute_absolute_length_none(css_computed_style *style, const css_hint_length *ex_size, uint8_t (*get)(const css_computed_style *style, css_fixed *len, css_unit *unit), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len, css_unit unit)); static css_error compute_absolute_length_normal(css_computed_style *style, const css_hint_length *ex_size, uint8_t (*get)(const css_computed_style *style, css_fixed *len, css_unit *unit), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len, css_unit unit)); static css_error compute_absolute_length_pair(css_computed_style *style, const css_hint_length *ex_size, uint8_t (*get)(const css_computed_style *style, css_fixed *len1, css_unit *unit1, css_fixed *len2, css_unit *unit2), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len1, css_unit unit1, css_fixed len2, css_unit unit2)); /** * Create a computed style * * \param alloc Memory (de)allocation function * \param pw Pointer to client-specific data * \param result Pointer to location to receive result * \return CSS_OK on success, * CSS_NOMEM on memory exhaustion, * CSS_BADPARM on bad parameters. */ css_error css_computed_style_create(css_allocator_fn alloc, void *pw, css_computed_style **result) { css_computed_style *s; if (alloc == NULL || result == NULL) return CSS_BADPARM; s = alloc(NULL, sizeof(css_computed_style), pw); if (s == NULL) return CSS_NOMEM; memset(s, 0, sizeof(css_computed_style)); s->alloc = alloc; s->pw = pw; *result = s; return CSS_OK; } /** * Destroy a computed style * * \param style Style to destroy * \return CSS_OK on success, appropriate error otherwise */ css_error css_computed_style_destroy(css_computed_style *style) { if (style == NULL) return CSS_BADPARM; if (style->uncommon != NULL) { if (style->uncommon->counter_increment != NULL) { css_computed_counter *c; for (c = style->uncommon->counter_increment; c->name != NULL; c++) { lwc_string_unref(c->name); } style->alloc(style->uncommon->counter_increment, 0, style->pw); } if (style->uncommon->counter_reset != NULL) { css_computed_counter *c; for (c = style->uncommon->counter_reset; c->name != NULL; c++) { lwc_string_unref(c->name); } style->alloc(style->uncommon->counter_reset, 0, style->pw); } if (style->uncommon->cursor != NULL) { lwc_string **s; for (s = style->uncommon->cursor; *s != NULL; s++) { lwc_string_unref(*s); } style->alloc(style->uncommon->cursor, 0, style->pw); } if (style->uncommon->content != NULL) { css_computed_content_item *c; for (c = style->uncommon->content; c->type != CSS_COMPUTED_CONTENT_NONE; c++) { switch (c->type) { case CSS_COMPUTED_CONTENT_STRING: lwc_string_unref(c->data.string); break; case CSS_COMPUTED_CONTENT_URI: lwc_string_unref(c->data.uri); break; case CSS_COMPUTED_CONTENT_ATTR: lwc_string_unref(c->data.attr); break; case CSS_COMPUTED_CONTENT_COUNTER: lwc_string_unref(c->data.counter.name); break; case CSS_COMPUTED_CONTENT_COUNTERS: lwc_string_unref(c->data.counters.name); lwc_string_unref(c->data.counters.sep); break; default: break; } } style->alloc(style->uncommon->content, 0, style->pw); } style->alloc(style->uncommon, 0, style->pw); } if (style->page != NULL) { style->alloc(style->page, 0, style->pw); } if (style->aural != NULL) { style->alloc(style->aural, 0, style->pw); } if (style->font_family != NULL) { lwc_string **s; for (s = style->font_family; *s != NULL; s++) { lwc_string_unref(*s); } style->alloc(style->font_family, 0, style->pw); } if (style->quotes != NULL) { lwc_string **s; for (s = style->quotes; *s != NULL; s++) { lwc_string_unref(*s); } style->alloc(style->quotes, 0, style->pw); } if (style->list_style_image != NULL) lwc_string_unref(style->list_style_image); if (style->background_image != NULL) lwc_string_unref(style->background_image); style->alloc(style, 0, style->pw); return CSS_OK; } /** * Populate a blank computed style with Initial values * * \param style Computed style to populate * \param handler Dispatch table of handler functions * \param pw Client-specific private data for handler functions * \return CSS_OK on success. */ css_error css_computed_style_initialise(css_computed_style *style, css_select_handler *handler, void *pw) { css_select_state state; uint32_t i; css_error error; if (style == NULL) return CSS_BADPARM; state.node = NULL; state.media = CSS_MEDIA_ALL; state.results = NULL; state.computed = style; state.handler = handler; state.pw = pw; for (i = 0; i < CSS_N_PROPERTIES; i++) { /* No need to initialise anything other than the normal * properties -- the others are handled by the accessors */ if (prop_dispatch[i].inherited == false && prop_dispatch[i].group == GROUP_NORMAL) { error = prop_dispatch[i].initial(&state); if (error != CSS_OK) return error; } } return CSS_OK; } /** * Compose two computed styles * * \param parent Parent style * \param child Child style * \param compute_font_size Function to compute an absolute font size * \param pw Client data for compute_font_size * \param result Pointer to style to compose into * \return CSS_OK on success, appropriate error otherwise. * * \pre \a parent is a fully composed style (thus has no inherited properties) * * \note \a child and \a result may point at the same object */ css_error css_computed_style_compose(const css_computed_style *parent, const css_computed_style *child, css_error (*compute_font_size)(void *pw, const css_hint *parent, css_hint *size), void *pw, css_computed_style *result) { css_error error = CSS_OK; size_t i; /* Iterate through the properties */ for (i = 0; i < CSS_N_PROPERTIES; i++) { /* Skip any in extension blocks if the block does not exist */ if (prop_dispatch[i].group == GROUP_UNCOMMON && parent->uncommon == NULL && child->uncommon == NULL) continue; if (prop_dispatch[i].group == GROUP_PAGE && parent->page == NULL && child->page == NULL) continue; if (prop_dispatch[i].group == GROUP_AURAL && parent->aural == NULL && child->aural == NULL) continue; /* Compose the property */ error = prop_dispatch[i].compose(parent, child, result); if (error != CSS_OK) break; } /* Finally, compute absolute values for everything */ return css__compute_absolute_values(parent, result, compute_font_size, pw); } /****************************************************************************** * Property accessors * ******************************************************************************/ #define CSS_LETTER_SPACING_INDEX 0 #define CSS_LETTER_SPACING_SHIFT 2 #define CSS_LETTER_SPACING_MASK 0xfc uint8_t css_computed_letter_spacing( const css_computed_style *style, css_fixed *length, css_unit *unit) { if (style->uncommon != NULL) { uint8_t bits = style->uncommon->bits[CSS_LETTER_SPACING_INDEX]; bits &= CSS_LETTER_SPACING_MASK; bits >>= CSS_LETTER_SPACING_SHIFT; /* 6bits: uuuutt : unit | type */ if ((bits & 3) == CSS_LETTER_SPACING_SET) { *length = style->uncommon->letter_spacing; *unit = (css_unit) (bits >> 2); } return (bits & 3); } return CSS_LETTER_SPACING_NORMAL; } #undef CSS_LETTER_SPACING_MASK #undef CSS_LETTER_SPACING_SHIFT #undef CSS_LETTER_SPACING_INDEX #define CSS_OUTLINE_COLOR_INDEX 0 #define CSS_OUTLINE_COLOR_SHIFT 0 #define CSS_OUTLINE_COLOR_MASK 0x3 uint8_t css_computed_outline_color( const css_computed_style *style, css_color *color) { if (style->uncommon != NULL) { uint8_t bits = style->uncommon->bits[CSS_OUTLINE_COLOR_INDEX]; bits &= CSS_OUTLINE_COLOR_MASK; bits >>= CSS_OUTLINE_COLOR_SHIFT; /* 2bits: tt : type */ if ((bits & 3) == CSS_OUTLINE_COLOR_COLOR) { *color = style->uncommon->outline_color; } return (bits & 3); } return CSS_OUTLINE_COLOR_INVERT; } #undef CSS_OUTLINE_COLOR_MASK #undef CSS_OUTLINE_COLOR_SHIFT #undef CSS_OUTLINE_COLOR_INDEX #define CSS_OUTLINE_WIDTH_INDEX 1 #define CSS_OUTLINE_WIDTH_SHIFT 1 #define CSS_OUTLINE_WIDTH_MASK 0xfe uint8_t css_computed_outline_width( const css_computed_style *style, css_fixed *length, css_unit *unit) { if (style->uncommon != NULL) { uint8_t bits = style->uncommon->bits[CSS_OUTLINE_WIDTH_INDEX]; bits &= CSS_OUTLINE_WIDTH_MASK; bits >>= CSS_OUTLINE_WIDTH_SHIFT; /* 7bits: uuuuttt : unit | type */ if ((bits & 7) == CSS_OUTLINE_WIDTH_WIDTH) { *length = style->uncommon->outline_width; *unit = (css_unit) (bits >> 3); } return (bits & 7); } *length = INTTOFIX(2); *unit = CSS_UNIT_PX; return CSS_OUTLINE_WIDTH_WIDTH; } #undef CSS_OUTLINE_WIDTH_MASK #undef CSS_OUTLINE_WIDTH_SHIFT #undef CSS_OUTLINE_WIDTH_INDEX #define CSS_BORDER_SPACING_INDEX 1 #define CSS_BORDER_SPACING_SHIFT 0 #define CSS_BORDER_SPACING_MASK 0x1 #define CSS_BORDER_SPACING_INDEX1 2 #define CSS_BORDER_SPACING_SHIFT1 0 #define CSS_BORDER_SPACING_MASK1 0xff uint8_t css_computed_border_spacing( const css_computed_style *style, css_fixed *hlength, css_unit *hunit, css_fixed *vlength, css_unit *vunit) { if (style->uncommon != NULL) { uint8_t bits = style->uncommon->bits[CSS_BORDER_SPACING_INDEX]; bits &= CSS_BORDER_SPACING_MASK; bits >>= CSS_BORDER_SPACING_SHIFT; /* 1 bit: type */ if (bits == CSS_BORDER_SPACING_SET) { uint8_t bits1 = style->uncommon->bits[CSS_BORDER_SPACING_INDEX1]; bits1 &= CSS_BORDER_SPACING_MASK1; bits1 >>= CSS_BORDER_SPACING_SHIFT1; /* 8bits: hhhhvvvv : hunit | vunit */ *hlength = style->uncommon->border_spacing[0]; *hunit = (css_unit) (bits1 >> 4); *vlength = style->uncommon->border_spacing[1]; *vunit = (css_unit) (bits1 & 0xf); } return bits; } else { *hlength = *vlength = 0; *hunit = *vunit = CSS_UNIT_PX; } return CSS_BORDER_SPACING_SET; } #undef CSS_BORDER_SPACING_MASK1 #undef CSS_BORDER_SPACING_SHIFT1 #undef CSS_BORDER_SPACING_INDEX1 #undef CSS_BORDER_SPACING_MASK #undef CSS_BORDER_SPACING_SHIFT #undef CSS_BORDER_SPACING_INDEX #define CSS_WORD_SPACING_INDEX 3 #define CSS_WORD_SPACING_SHIFT 2 #define CSS_WORD_SPACING_MASK 0xfc uint8_t css_computed_word_spacing( const css_computed_style *style, css_fixed *length, css_unit *unit) { if (style->uncommon != NULL) { uint8_t bits = style->uncommon->bits[CSS_WORD_SPACING_INDEX]; bits &= CSS_WORD_SPACING_MASK; bits >>= CSS_WORD_SPACING_SHIFT; /* 6bits: uuuutt : unit | type */ if ((bits & 3) == CSS_WORD_SPACING_SET) { *length = style->uncommon->word_spacing; *unit = (css_unit) (bits >> 2); } return (bits & 3); } return CSS_WORD_SPACING_NORMAL; } #undef CSS_WORD_SPACING_MASK #undef CSS_WORD_SPACING_SHIFT #undef CSS_WORD_SPACING_INDEX #define CSS_COUNTER_INCREMENT_INDEX 3 #define CSS_COUNTER_INCREMENT_SHIFT 1 #define CSS_COUNTER_INCREMENT_MASK 0x2 uint8_t css_computed_counter_increment( const css_computed_style *style, const css_computed_counter **counters) { if (style->uncommon != NULL) { uint8_t bits = style->uncommon->bits[CSS_COUNTER_INCREMENT_INDEX]; bits &= CSS_COUNTER_INCREMENT_MASK; bits >>= CSS_COUNTER_INCREMENT_SHIFT; /* 1bit: type */ *counters = style->uncommon->counter_increment; return bits; }