From b1692363b809dfe3776866e4319b7a659ca159a4 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Sat, 14 Feb 2009 21:52:08 +0000 Subject: Finally, a representation of a computed content property. svn path=/trunk/libcss/; revision=6515 --- include/libcss/computed.h | 73 ++++++++++++++++++--- include/libcss/properties.h | 6 +- src/select/properties.c | 150 +++++++++++++++++++++++++++++++++----------- src/select/propset.h | 26 ++++++++ 4 files changed, 211 insertions(+), 44 deletions(-) diff --git a/include/libcss/computed.h b/include/libcss/computed.h index b2ec1d9..05959bb 100644 --- a/include/libcss/computed.h +++ b/include/libcss/computed.h @@ -23,6 +23,37 @@ typedef struct css_computed_page { uint8_t dummy; } css_computed_page; +enum css_computed_content_type { + CSS_COMPUTED_CONTENT_NONE = 0, + CSS_COMPUTED_CONTENT_STRING = 1, + CSS_COMPUTED_CONTENT_URI = 2, + CSS_COMPUTED_CONTENT_COUNTER = 3, + CSS_COMPUTED_CONTENT_COUNTERS = 4, + CSS_COMPUTED_CONTENT_ATTR = 5, + CSS_COMPUTED_CONTENT_OPEN_QUOTE = 6, + CSS_COMPUTED_CONTENT_CLOSE_QUOTE = 7, + CSS_COMPUTED_CONTENT_NO_OPEN_QUOTE = 8, + CSS_COMPUTED_CONTENT_NO_CLOSE_QUOTE = 9 +}; + +typedef struct css_computed_content_item { + uint8_t type; + union { + css_string string; + css_string uri; + css_string attr; + struct { + css_string name; + uint8_t style; + } counter; + struct { + css_string name; + css_string sep; + uint8_t style; + } counters; + } data; +} css_computed_content_item; + typedef struct css_computed_counter { css_string name; css_fixed value; @@ -73,18 +104,20 @@ typedef struct css_computed_uncommon { * Encode cursor uri(s) as an array of string objects, terminated with a * blank entry. * - * cursor 5 sizeof(ptr) + * cursor 5 sizeof(ptr) * --- --- - * 5 bits sizeof(ptr) bytes + * 5 bits sizeof(ptr) bytes * - * content ? + * content 2 sizeof(ptr) + * --- --- + * 2 bits sizeof(ptr) * * ___ ___ - * 61 bits 40 + 4sizeof(ptr) bytes + * 63 bits 40 + 5sizeof(ptr) bytes * - * 8 bytes 40 + 4sizeof(ptr) bytes + * 8 bytes 40 + 5sizeof(ptr) bytes * =================== - * 48 + 4sizeof(ptr) bytes + * 48 + 5sizeof(ptr) bytes * * Bit allocations: * @@ -96,7 +129,7 @@ typedef struct css_computed_uncommon { * 5 uuuuuqq. cursor | quotes | * 6 cccccccc clip * 7 cccccccc clip - * 8 cccccc.. clip | + * 8 ccccccoo clip | content */ uint8_t bits[8]; @@ -117,6 +150,8 @@ typedef struct css_computed_uncommon { css_string *quotes; css_string *cursor; + + css_computed_content_item *content; } css_computed_uncommon; struct css_computed_style { @@ -642,6 +677,30 @@ static inline uint8_t css_computed_clip( #undef CLIP_SHIFT #undef CLIP_INDEX +#define CONTENT_INDEX 7 +#define CONTENT_SHIFT 0 +#define CONTENT_MASK 0x3 +static inline uint8_t css_computed_content( + const css_computed_style *style, + const css_computed_content_item **content) +{ + if (style->uncommon != NULL) { + uint8_t bits = style->uncommon->bits[CONTENT_INDEX]; + bits &= CONTENT_MASK; + bits >>= CONTENT_SHIFT; + + /* 2bits: type */ + *content = style->uncommon->content; + + return bits; + } + + return CSS_CONTENT_NORMAL; +} +#undef CONTENT_MASK +#undef CONTENT_SHIFT +#undef CONTENT_INDEX + #define VERTICAL_ALIGN_INDEX 0 #define VERTICAL_ALIGN_SHIFT 0 #define VERTICAL_ALIGN_MASK 0xff diff --git a/include/libcss/properties.h b/include/libcss/properties.h index bb685e0..6e7efa8 100644 --- a/include/libcss/properties.h +++ b/include/libcss/properties.h @@ -110,10 +110,12 @@ enum css_color { CSS_COLOR_COLOR = 0x1 }; -/** \todo content enum css_content { + CSS_CONTENT_INHERIT = 0x0, + CSS_CONTENT_NONE = 0x1, + CSS_CONTENT_NORMAL = 0x2, + CSS_CONTENT_SET = 0x3 }; -*/ enum css_counter_increment { CSS_COUNTER_INCREMENT_INHERIT = 0x0, diff --git a/src/select/properties.c b/src/select/properties.c index d084bc5..7ac0e36 100644 --- a/src/select/properties.c +++ b/src/select/properties.c @@ -628,59 +628,139 @@ static css_error initial_color(css_computed_style *style) static css_error cascade_content(uint32_t opv, css_style *style, css_select_state *state) { - uint16_t value = 0; + uint16_t value = CSS_CONTENT_INHERIT; + css_computed_content_item *content = NULL; + uint32_t n_contents = 0; if (isInherit(opv) == false) { uint32_t v = getValue(opv); if (v == CONTENT_NORMAL) { - value = 0; + value = CSS_CONTENT_NORMAL; } else if (v == CONTENT_NONE) { - value = 0; - } + value = CSS_CONTENT_NONE; + } else { + value = CSS_CONTENT_SET; - while (v != CONTENT_NORMAL) { - parserutils_hash_entry *he = + while (v != CONTENT_NORMAL) { + css_computed_content_item *temp; + parserutils_hash_entry *he = *((parserutils_hash_entry **) style->bytecode); - switch (v & 0xff) { - case CONTENT_COUNTER: - advance_bytecode(style, sizeof(he)); - break; - case CONTENT_COUNTERS: - { - parserutils_hash_entry *sep; + temp = state->result->alloc(content, + (n_contents + 1) * + sizeof(css_computed_content_item), + state->result->pw); + if (temp == NULL) { + if (content != NULL) { + state->result->alloc(content, + 0, state->result->pw); + } + return CSS_NOMEM; + } - advance_bytecode(style, sizeof(he)); + content = temp; + + switch (v & 0xff) { + case CONTENT_COUNTER: + advance_bytecode(style, sizeof(he)); + + content[n_contents].type = + CSS_COMPUTED_CONTENT_COUNTER; + content[n_contents].data.counter.name.data = (uint8_t *) he->data; + content[n_contents].data.counter.name.len = he->len; + content[n_contents].data.counter.style = v >> CONTENT_COUNTER_STYLE_SHIFT; + break; + case CONTENT_COUNTERS: + { + parserutils_hash_entry *sep; + + advance_bytecode(style, sizeof(he)); + + sep = *((parserutils_hash_entry **) + style->bytecode); + advance_bytecode(style, sizeof(sep)); + + content[n_contents].type = + CSS_COMPUTED_CONTENT_COUNTERS; + content[n_contents].data.counters.name.data = (uint8_t *) he->data; + content[n_contents].data.counters.name.len = he->len; + content[n_contents].data.counters.sep.data = (uint8_t *) sep->data; + content[n_contents].data.counters.sep.len = sep->len; + content[n_contents].data.counters.style = v >> CONTENT_COUNTERS_STYLE_SHIFT; + } + break; + case CONTENT_URI: + advance_bytecode(style, sizeof(he)); + + content[n_contents].type = + CSS_COMPUTED_CONTENT_URI; + content[n_contents].data.uri.data = (uint8_t *) he->data; + content[n_contents].data.uri.len = he->len; + break; + case CONTENT_ATTR: + advance_bytecode(style, sizeof(he)); + + content[n_contents].type = + CSS_COMPUTED_CONTENT_ATTR; + content[n_contents].data.attr.data = (uint8_t *) he->data; + content[n_contents].data.attr.len = he->len; + break; + case CONTENT_STRING: + advance_bytecode(style, sizeof(he)); + + content[n_contents].type = + CSS_COMPUTED_CONTENT_STRING; + content[n_contents].data.string.data = (uint8_t *) he->data; + content[n_contents].data.string.len = he->len; + break; + case CONTENT_OPEN_QUOTE: + content[n_contents].type = + CSS_COMPUTED_CONTENT_OPEN_QUOTE; + break; + case CONTENT_CLOSE_QUOTE: + content[n_contents].type = + CSS_COMPUTED_CONTENT_CLOSE_QUOTE; + break; + case CONTENT_NO_OPEN_QUOTE: + content[n_contents].type = + CSS_COMPUTED_CONTENT_NO_OPEN_QUOTE; + break; + case CONTENT_NO_CLOSE_QUOTE: + content[n_contents].type = + CSS_COMPUTED_CONTENT_NO_CLOSE_QUOTE; + break; + } - sep = *((parserutils_hash_entry **) - style->bytecode); - advance_bytecode(style, sizeof(sep)); + n_contents++; + v = *((uint32_t *) style->bytecode); + advance_bytecode(style, sizeof(v)); } - break; - case CONTENT_URI: - case CONTENT_ATTR: - case CONTENT_STRING: - advance_bytecode(style, sizeof(he)); - break; - case CONTENT_OPEN_QUOTE: - break; - case CONTENT_CLOSE_QUOTE: - break; - case CONTENT_NO_OPEN_QUOTE: - break; - case CONTENT_NO_CLOSE_QUOTE: - break; - } + } + } - v = *((uint32_t *) style->bytecode); - advance_bytecode(style, sizeof(v)); + /* If we have some content, terminate the array with a blank entry */ + if (n_contents > 0) { + css_computed_content_item *temp; + + temp = state->result->alloc(content, + (n_contents + 1) * sizeof(css_computed_content_item), + state->result->pw); + if (temp == NULL) { + state->result->alloc(content, 0, state->result->pw); + return CSS_NOMEM; } + + content = temp; + + content[n_contents].type = CSS_COMPUTED_CONTENT_NONE; } if (outranks_existing(getOpcode(opv), isImportant(opv), state)) { - /** \todo content */ + return set_content(state->result, value, content); + } else if (content != NULL) { + state->result->alloc(content, 0, state->result->pw); } return CSS_OK; diff --git a/src/select/propset.h b/src/select/propset.h index 661913b..64f7829 100644 --- a/src/select/propset.h +++ b/src/select/propset.h @@ -323,6 +323,32 @@ static inline css_error set_clip( #undef CLIP_SHIFT #undef CLIP_INDEX +#define CONTENT_INDEX 7 +#define CONTENT_SHIFT 0 +#define CONTENT_MASK 0x3 +static inline css_error set_content( + css_computed_style *style, uint8_t type, + css_computed_content_item *content) +{ + uint8_t *bits; + + ENSURE_UNCOMMON; + + /* 2bits: type */ + bits = &style->uncommon->bits[CONTENT_INDEX]; + + *bits = (*bits & ~CONTENT_MASK) | + ((type & 0x3) << CONTENT_SHIFT); + + style->uncommon->content = content; + + return CSS_OK; +} +#undef CONTENT_MASK +#undef CONTENT_SHIFT +#undef CONTENT_INDEX + + #define VERTICAL_ALIGN_INDEX 0 #define VERTICAL_ALIGN_SHIFT 0 #define VERTICAL_ALIGN_MASK 0xff -- cgit v1.2.3