diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/libcss/computed.h | 541 |
1 files changed, 515 insertions, 26 deletions
diff --git a/include/libcss/computed.h b/include/libcss/computed.h index df2f5cf..f47b086 100644 --- a/include/libcss/computed.h +++ b/include/libcss/computed.h @@ -350,6 +350,13 @@ css_error css_computed_style_compose(const css_computed_style *parent, * Property accessors below here * ******************************************************************************/ +static inline uint8_t css_computed_font_size(const css_computed_style *style, + css_fixed *length, css_unit *unit); +static inline uint8_t css_computed_line_height(const css_computed_style *style, + css_fixed *length, css_unit *unit); +static inline uint8_t css_computed_position(const css_computed_style *style); + + #define LETTER_SPACING_INDEX 0 #define LETTER_SPACING_SHIFT 2 #define LETTER_SPACING_MASK 0xfc @@ -367,6 +374,17 @@ static inline uint8_t css_computed_letter_spacing( if ((bits & 3) == CSS_LETTER_SPACING_SET) { *length = style->uncommon->letter_spacing; *unit = bits >> 2; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, + &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 3); @@ -421,6 +439,17 @@ static inline uint8_t css_computed_outline_width( if ((bits & 7) == CSS_OUTLINE_WIDTH_WIDTH) { *length = style->uncommon->outline_width; *unit = bits >> 3; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, + &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 7); @@ -465,6 +494,24 @@ static inline uint8_t css_computed_border_spacing( *vlength = style->uncommon->border_spacing[1]; *vunit = bits1 & 0xf; + + if (*hunit == CSS_UNIT_EM || *vunit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, + &font_unit); + + if (*hunit == CSS_UNIT_EM) { + *hlength = FMUL(*hlength, font_size); + *hunit = font_unit; + } + + if (*vunit == CSS_UNIT_EM) { + *hlength = FMUL(*vunit, font_size); + *vunit = font_unit; + } + } } return bits; @@ -499,6 +546,17 @@ static inline uint8_t css_computed_word_spacing( if ((bits & 3) == CSS_WORD_SPACING_SET) { *length = style->uncommon->word_spacing; *unit = bits >> 2; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, + &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 3); @@ -640,6 +698,40 @@ static inline uint8_t css_computed_clip( rect->left = style->uncommon->clip[3]; rect->lunit = bits1 & 0xf; + + if (rect->tunit == CSS_UNIT_EM || + rect->runit == CSS_UNIT_EM || + rect->bunit == CSS_UNIT_EM || + rect->lunit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, + &font_unit); + + if (rect->tunit == CSS_UNIT_EM) { + rect->top = FMUL(rect->top, font_size); + rect->tunit = font_unit; + } + + if (rect->runit == CSS_UNIT_EM) { + rect->right = FMUL(rect->right, + font_size); + rect->runit = font_unit; + } + + if (rect->bunit == CSS_UNIT_EM) { + rect->bottom = FMUL(rect->bottom, + font_size); + rect->bunit = font_unit; + } + + if (rect->lunit == CSS_UNIT_EM) { + rect->left = FMUL(rect->left, + font_size); + rect->lunit = font_unit; + } + } } return (bits & 0x3); @@ -696,6 +788,24 @@ static inline uint8_t css_computed_vertical_align( if ((bits & 0xf) == CSS_VERTICAL_ALIGN_SET) { *length = style->vertical_align; *unit = bits >> 4; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } else if (*unit == CSS_UNIT_PCT) { + css_fixed line_height; + css_unit lh_unit; + + css_computed_line_height(style, &line_height, &lh_unit); + + *length = FDIVI(FMUL(*length, line_height), 100); + *unit = lh_unit; + } } return (bits & 0xf); @@ -742,6 +852,16 @@ static inline uint8_t css_computed_border_top_width( if ((bits & 0x7) == CSS_BORDER_WIDTH_WIDTH) { *length = style->border_width[0]; *unit = bits >> 3; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x7); @@ -765,6 +885,16 @@ static inline uint8_t css_computed_border_right_width( if ((bits & 0x7) == CSS_BORDER_WIDTH_WIDTH) { *length = style->border_width[1]; *unit = bits >> 3; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x7); @@ -788,6 +918,16 @@ static inline uint8_t css_computed_border_bottom_width( if ((bits & 0x7) == CSS_BORDER_WIDTH_WIDTH) { *length = style->border_width[2]; *unit = bits >> 3; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x7); @@ -811,6 +951,16 @@ static inline uint8_t css_computed_border_left_width( if ((bits & 0x7) == CSS_BORDER_WIDTH_WIDTH) { *length = style->border_width[3]; *unit = bits >> 3; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x7); @@ -902,6 +1052,15 @@ static inline uint8_t css_computed_quotes( #define TOP_INDEX 6 #define TOP_SHIFT 2 #define TOP_MASK 0xfc +#define RIGHT_INDEX 7 +#define RIGHT_SHIFT 2 +#define RIGHT_MASK 0xfc +#define BOTTOM_INDEX 8 +#define BOTTOM_SHIFT 2 +#define BOTTOM_MASK 0xfc +#define LEFT_INDEX 9 +#define LEFT_SHIFT 2 +#define LEFT_MASK 0xfc static inline uint8_t css_computed_top( const css_computed_style *style, css_fixed *length, css_unit *unit) @@ -910,21 +1069,52 @@ static inline uint8_t css_computed_top( bits &= TOP_MASK; bits >>= TOP_SHIFT; - /* 6bits: uuuutt : units | type */ - if ((bits & 0x3) == CSS_TOP_SET) { + /* Fix up, based on computed position */ + if (css_computed_position(style) == CSS_POSITION_STATIC) { + /* Static -> auto */ + bits = CSS_TOP_AUTO; + } else if (css_computed_position(style) == CSS_POSITION_RELATIVE) { + /* Relative -> follow $9.4.3 */ + uint8_t bottom = style->bits[BOTTOM_INDEX]; + bottom &= BOTTOM_MASK; + bottom >>= BOTTOM_SHIFT; + + if ((bits & 0x3) == CSS_TOP_AUTO && + (bottom & 0x3) == CSS_BOTTOM_AUTO) { + /* Both auto => 0px */ + *length = 0; + *unit = CSS_UNIT_PX; + } else if ((bits & 0x3) == CSS_TOP_AUTO) { + /* Top is auto => -bottom */ + *length = -style->bottom; + *unit = bottom >> 2; + } else { + *length = style->top; + *unit = bits >> 2; + } + + bits = CSS_TOP_SET; + } else if ((bits & 0x3) == CSS_TOP_SET) { *length = style->top; *unit = bits >> 2; } + /* 6bits: uuuutt : units | type */ + if ((bits & 0x3) == CSS_TOP_SET) { + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } + } + return (bits & 0x3); } -#undef TOP_MASK -#undef TOP_SHIFT -#undef TOP_INDEX -#define RIGHT_INDEX 7 -#define RIGHT_SHIFT 2 -#define RIGHT_MASK 0xfc static inline uint8_t css_computed_right( const css_computed_style *style, css_fixed *length, css_unit *unit) @@ -933,21 +1123,54 @@ static inline uint8_t css_computed_right( bits &= RIGHT_MASK; bits >>= RIGHT_SHIFT; - /* 6bits: uuuutt : units | type */ - if ((bits & 0x3) == CSS_RIGHT_SET) { + /* Fix up, based on computed position */ + if (css_computed_position(style) == CSS_POSITION_STATIC) { + /* Static -> auto */ + bits = CSS_RIGHT_AUTO; + } else if (css_computed_position(style) == CSS_POSITION_RELATIVE) { + /* Relative -> follow $9.4.3 */ + uint8_t left = style->bits[LEFT_INDEX]; + left &= LEFT_MASK; + left >>= LEFT_SHIFT; + + if ((bits & 0x3) == CSS_RIGHT_AUTO && + (left & 0x3) == CSS_LEFT_AUTO) { + /* Both auto => 0px */ + *length = 0; + *unit = CSS_UNIT_PX; + } else if ((bits & 0x3) == CSS_RIGHT_AUTO) { + /* Right is auto => -left */ + *length = -style->left; + *unit = left >> 2; + } else { + /** \todo Consider containing block's direction + * if overconstrained */ + *length = style->right; + *unit = bits >> 2; + } + + bits = CSS_RIGHT_SET; + } else if ((bits & 0x3) == CSS_RIGHT_SET) { *length = style->right; *unit = bits >> 2; } + /* 6bits: uuuutt : units | type */ + if ((bits & 0x3) == CSS_RIGHT_SET) { + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } + } + return (bits & 0x3); } -#undef RIGHT_MASK -#undef RIGHT_SHIFT -#undef RIGHT_INDEX -#define BOTTOM_INDEX 8 -#define BOTTOM_SHIFT 2 -#define BOTTOM_MASK 0xfc static inline uint8_t css_computed_bottom( const css_computed_style *style, css_fixed *length, css_unit *unit) @@ -956,21 +1179,53 @@ static inline uint8_t css_computed_bottom( bits &= BOTTOM_MASK; bits >>= BOTTOM_SHIFT; - /* 6bits: uuuutt : units | type */ - if ((bits & 0x3) == CSS_BOTTOM_SET) { + /* Fix up, based on computed position */ + if (css_computed_position(style) == CSS_POSITION_STATIC) { + /* Static -> auto */ + bits = CSS_BOTTOM_AUTO; + } else if (css_computed_position(style) == CSS_POSITION_RELATIVE) { + /* Relative -> follow $9.4.3 */ + uint8_t top = style->bits[TOP_INDEX]; + top &= TOP_MASK; + top >>= TOP_SHIFT; + + if ((bits & 0x3) == CSS_BOTTOM_AUTO && + (top & 0x3) == CSS_TOP_AUTO) { + /* Both auto => 0px */ + *length = 0; + *unit = CSS_UNIT_PX; + } else if ((bits & 0x3) == CSS_BOTTOM_AUTO || + (top & 0x3) != CSS_TOP_AUTO) { + /* Bottom is auto or top is not auto => -top */ + *length = -style->top; + *unit = top >> 2; + } else { + *length = style->bottom; + *unit = bits >> 2; + } + + bits = CSS_BOTTOM_SET; + } else if ((bits & 0x3) == CSS_BOTTOM_SET) { *length = style->bottom; *unit = bits >> 2; } + /* 6bits: uuuutt : units | type */ + if ((bits & 0x3) == CSS_BOTTOM_SET) { + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } + } + return (bits & 0x3); } -#undef BOTTOM_MASK -#undef BOTTOM_SHIFT -#undef BOTTOM_INDEX -#define LEFT_INDEX 9 -#define LEFT_SHIFT 2 -#define LEFT_MASK 0xfc static inline uint8_t css_computed_left( const css_computed_style *style, css_fixed *length, css_unit *unit) @@ -979,17 +1234,65 @@ static inline uint8_t css_computed_left( bits &= LEFT_MASK; bits >>= LEFT_SHIFT; - /* 6bits: uuuutt : units | type */ - if ((bits & 0x3) == CSS_LEFT_SET) { + /* Fix up, based on computed position */ + if (css_computed_position(style) == CSS_POSITION_STATIC) { + /* Static -> auto */ + bits = CSS_LEFT_AUTO; + } else if (css_computed_position(style) == CSS_POSITION_RELATIVE) { + /* Relative -> follow $9.4.3 */ + uint8_t right = style->bits[RIGHT_INDEX]; + right &= RIGHT_MASK; + right >>= RIGHT_SHIFT; + + if ((bits & 0x3) == CSS_LEFT_AUTO && + (right & 0x3) == CSS_RIGHT_AUTO) { + /* Both auto => 0px */ + *length = 0; + *unit = CSS_UNIT_PX; + } else if ((bits & 0x3) == CSS_LEFT_AUTO) { + /* Left is auto => -right */ + *length = -style->right; + *unit = right >> 2; + } else { + /** \todo Consider containing block's direction + * if overconstrained */ + *length = style->left; + *unit = bits >> 2; + } + + bits = CSS_LEFT_SET; + } else if ((bits & 0x3) == CSS_LEFT_SET) { *length = style->left; *unit = bits >> 2; } + /* 6bits: uuuutt : units | type */ + if ((bits & 0x3) == CSS_RIGHT_SET) { + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } + } + return (bits & 0x3); } #undef LEFT_MASK #undef LEFT_SHIFT #undef LEFT_INDEX +#undef BOTTOM_MASK +#undef BOTTOM_SHIFT +#undef BOTTOM_INDEX +#undef RIGHT_MASK +#undef RIGHT_SHIFT +#undef RIGHT_INDEX +#undef TOP_MASK +#undef TOP_SHIFT +#undef TOP_INDEX #define BORDER_TOP_COLOR_INDEX 6 #define BORDER_TOP_COLOR_SHIFT 0 @@ -1086,6 +1389,16 @@ static inline uint8_t css_computed_height( if ((bits & 0x3) == CSS_HEIGHT_SET) { *length = style->height; *unit = bits >> 2; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x3); @@ -1113,6 +1426,20 @@ static inline uint8_t css_computed_line_height( if ((bits & 0x3) == CSS_LINE_HEIGHT_DIMENSION) { *unit = bits >> 2; + + if (*unit == CSS_UNIT_EM || *unit == CSS_UNIT_PCT) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + + if (*unit == CSS_UNIT_PCT) + *length = FDIVI(*length, 100); + + *unit = font_unit; + } } return (bits & 0x3); @@ -1176,6 +1503,16 @@ static inline uint8_t css_computed_margin_top( if ((bits & 0x3) == CSS_MARGIN_SET) { *length = style->margin[0]; *unit = bits >> 2; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x3); @@ -1199,6 +1536,16 @@ static inline uint8_t css_computed_margin_right( if ((bits & 0x3) == CSS_MARGIN_SET) { *length = style->margin[1]; *unit = bits >> 2; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x3); @@ -1222,6 +1569,16 @@ static inline uint8_t css_computed_margin_bottom( if ((bits & 0x3) == CSS_MARGIN_SET) { *length = style->margin[2]; *unit = bits >> 2; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x3); @@ -1245,6 +1602,16 @@ static inline uint8_t css_computed_margin_left( if ((bits & 0x3) == CSS_MARGIN_SET) { *length = style->margin[3]; *unit = bits >> 2; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x3); @@ -1336,6 +1703,16 @@ static inline uint8_t css_computed_max_height( if ((bits & 0x3) == CSS_MAX_HEIGHT_SET) { *length = style->max_height; *unit = bits >> 2; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x3); @@ -1359,6 +1736,16 @@ static inline uint8_t css_computed_max_width( if ((bits & 0x3) == CSS_MAX_WIDTH_SET) { *length = style->max_width; *unit = bits >> 2; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x3); @@ -1382,6 +1769,16 @@ static inline uint8_t css_computed_width( if ((bits & 0x3) == CSS_WIDTH_SET) { *length = style->width; *unit = bits >> 2; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x3); @@ -1417,6 +1814,11 @@ static inline uint8_t css_computed_float( bits &= FLOAT_MASK; bits >>= FLOAT_SHIFT; + /* Fix up as per $9.7:2 */ + if (css_computed_position(style) == CSS_POSITION_ABSOLUTE || + css_computed_position(style) == CSS_POSITION_FIXED) + return CSS_FLOAT_NONE; + /* 2bits: type */ return bits; } @@ -1456,6 +1858,16 @@ static inline uint8_t css_computed_min_height( if ((bits & 0x1) == CSS_MIN_HEIGHT_SET) { *length = style->min_height; *unit = bits >> 1; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x1); @@ -1479,6 +1891,16 @@ static inline uint8_t css_computed_min_width( if ((bits & 0x1) == CSS_MIN_WIDTH_SET) { *length = style->min_width; *unit = bits >> 1; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x1); @@ -1536,6 +1958,16 @@ static inline uint8_t css_computed_padding_top( if ((bits & 0x1) == CSS_PADDING_SET) { *length = style->padding[0]; *unit = bits >> 1; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x1); @@ -1559,6 +1991,16 @@ static inline uint8_t css_computed_padding_right( if ((bits & 0x1) == CSS_PADDING_SET) { *length = style->padding[1]; *unit = bits >> 1; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x1); @@ -1582,6 +2024,16 @@ static inline uint8_t css_computed_padding_bottom( if ((bits & 0x1) == CSS_PADDING_SET) { *length = style->padding[2]; *unit = bits >> 1; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x1); @@ -1605,6 +2057,16 @@ static inline uint8_t css_computed_padding_left( if ((bits & 0x1) == CSS_PADDING_SET) { *length = style->padding[3]; *unit = bits >> 1; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x1); @@ -1696,6 +2158,16 @@ static inline uint8_t css_computed_text_indent( if ((bits & 0x1) == CSS_TEXT_INDENT_SET) { *length = style->text_indent; *unit = bits >> 1; + + if (*unit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + *length = FMUL(*length, font_size); + *unit = font_unit; + } } return (bits & 0x1); @@ -1748,6 +2220,23 @@ static inline uint8_t css_computed_background_position( *vlength = style->background_position[1]; *vunit = bits1 & 0xf; + + if (*hunit == CSS_UNIT_EM || *vunit == CSS_UNIT_EM) { + css_fixed font_size; + css_unit font_unit; + + css_computed_font_size(style, &font_size, &font_unit); + + if (*hunit == CSS_UNIT_EM) { + *hlength = FMUL(*hlength, font_size); + *hunit = font_unit; + } + + if (*vunit == CSS_UNIT_EM) { + *hlength = FMUL(*vunit, font_size); + *vunit = font_unit; + } + } } return bits; |