From 89ef7a8acf13143ac0283aa1cfa5ea504b92324b Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Fri, 13 Apr 2012 11:43:13 +0000 Subject: Complete widows and orphans support. Thanks to James Montgomerie. svn path=/trunk/libcss/; revision=13864 --- include/libcss/computed.h | 7 ++++ include/libcss/properties.h | 10 +++++ src/select/computed.c | 53 ++++++++++++++++++++++++ src/select/computed.h | 15 ++++--- src/select/properties/orphans.c | 25 +++++------- src/select/properties/windows.c | 25 +++++------- src/select/propget.h | 50 +++++++++++++++++++++++ src/select/propset.h | 89 +++++++++++++++++++++++++++++++++++++++-- 8 files changed, 236 insertions(+), 38 deletions(-) diff --git a/include/libcss/computed.h b/include/libcss/computed.h index 51fcb12..843795e 100644 --- a/include/libcss/computed.h +++ b/include/libcss/computed.h @@ -388,6 +388,13 @@ uint8_t css_computed_page_break_before( uint8_t css_computed_page_break_inside( const css_computed_style *style); +uint8_t css_computed_orphans( + const css_computed_style *style, + int32_t *orphans); + +uint8_t css_computed_widows( + const css_computed_style *style, + int32_t *widows); #ifdef __cplusplus } diff --git a/include/libcss/properties.h b/include/libcss/properties.h index 5257e19..feba9ce 100644 --- a/include/libcss/properties.h +++ b/include/libcss/properties.h @@ -585,6 +585,11 @@ enum css_overflow_e { CSS_OVERFLOW_AUTO = 0x4 }; +enum css_orphans_e { + CSS_ORPHANS_INHERIT = 0x0, + CSS_ORPHANS_SET = 0x1 +}; + enum css_padding_e { CSS_PADDING_INHERIT = 0x0, CSS_PADDING_SET = 0x1 @@ -718,6 +723,11 @@ enum css_white_space_e { CSS_WHITE_SPACE_PRE_LINE = 0x5 }; +enum css_widows_e { + CSS_WIDOWS_INHERIT = 0x0, + CSS_WIDOWS_SET = 0x1 +}; + enum css_width_e { CSS_WIDTH_INHERIT = 0x0, CSS_WIDTH_SET = 0x1, diff --git a/src/select/computed.c b/src/select/computed.c index 991a9a8..9f21d4a 100644 --- a/src/select/computed.c +++ b/src/select/computed.c @@ -2223,6 +2223,59 @@ uint8_t css_computed_page_break_inside( #undef CSS_PAGE_BREAK_INSIDE_SHIFT #undef CSS_PAGE_BREAK_INSIDE_INDEX +#define CSS_ORPHANS_INDEX 1 +#define CSS_ORPHANS_SHIFT 0 +#define CSS_ORPHANS_MASK 0x1 +uint8_t css_computed_orphans( + const css_computed_style *style, + int32_t *orphans) +{ + if (style->page != NULL) { + uint8_t bits = style->page->bits[CSS_ORPHANS_INDEX]; + bits &= CSS_ORPHANS_MASK; + bits >>= CSS_ORPHANS_SHIFT; + + *orphans = FIXTOINT(style->page->orphans);; + + /* 1bit: type */ + return bits; + } + + /* Use initial value */ + *orphans = 2; + + return CSS_ORPHANS_SET; +} +#undef CSS_ORPHANS_MASK +#undef CSS_ORPHANS_SHIFT +#undef CSS_ORPHANS_INDEX + +#define CSS_WIDOWS_INDEX 1 +#define CSS_WIDOWS_SHIFT 1 +#define CSS_WIDOWS_MASK 0x2 +uint8_t css_computed_widows( + const css_computed_style *style, + int32_t *widows) +{ + if (style->page != NULL) { + uint8_t bits = style->page->bits[CSS_WIDOWS_INDEX]; + bits &= CSS_WIDOWS_MASK; + bits >>= CSS_WIDOWS_SHIFT; + + *widows = FIXTOINT(style->page->widows); + + /* 1bit: type */ + return bits; + } + + /* Use initial value */ + *widows = 2; + + return CSS_WIDOWS_SET; +} +#undef CSS_WIDOWS_MASK +#undef CSS_WIDOWS_SHIFT +#undef CSS_WIDOWS_INDEX /****************************************************************************** diff --git a/src/select/computed.h b/src/select/computed.h index 6f19051..f891047 100644 --- a/src/select/computed.h +++ b/src/select/computed.h @@ -87,13 +87,16 @@ typedef struct css_computed_uncommon { typedef struct css_computed_page { /* - * page_break_after 3 - * page_break_before 3 - * page_break_inside 2 - * --- - * 8 bits + * Bit allocations: + * + * 76543210 + * 1 aaabbbii page_break_after | page_break_before | page_break_inside + * 2 ......wo widows | orphans */ - uint8_t bits[1]; + uint8_t bits[2]; + + css_fixed widows; + css_fixed orphans; } css_computed_page; struct css_computed_style { diff --git a/src/select/properties/orphans.c b/src/select/properties/orphans.c index 5129c5d..265c6f5 100644 --- a/src/select/properties/orphans.c +++ b/src/select/properties/orphans.c @@ -17,34 +17,31 @@ css_error css__cascade_orphans(uint32_t opv, css_style *style, css_select_state *state) { - /** \todo orphans */ - return css__cascade_number(opv, style, state, NULL); + return css__cascade_number(opv, style, state, set_orphans); } css_error css__set_orphans_from_hint(const css_hint *hint, css_computed_style *style) { - UNUSED(hint); - UNUSED(style); - - return CSS_OK; + return set_orphans(style, hint->status, hint->data.fixed); } css_error css__initial_orphans(css_select_state *state) { - UNUSED(state); - - return CSS_OK; + return set_orphans(state->computed, CSS_ORPHANS_SET, INTTOFIX(2)); } css_error css__compose_orphans(const css_computed_style *parent, const css_computed_style *child, css_computed_style *result) { - UNUSED(parent); - UNUSED(child); - UNUSED(result); - - return CSS_OK; + css_fixed count = 0; + uint8_t type = get_orphans(child, &count); + + if (type == CSS_ORPHANS_INHERIT) { + type = get_orphans(parent, &count); + } + + return set_orphans(result, type, count); } diff --git a/src/select/properties/windows.c b/src/select/properties/windows.c index 80b1eee..3f568cb 100644 --- a/src/select/properties/windows.c +++ b/src/select/properties/windows.c @@ -17,34 +17,31 @@ css_error css__cascade_widows(uint32_t opv, css_style *style, css_select_state *state) { - /** \todo widows */ - return css__cascade_number(opv, style, state, NULL); + return css__cascade_number(opv, style, state, set_widows); } css_error css__set_widows_from_hint(const css_hint *hint, css_computed_style *style) { - UNUSED(hint); - UNUSED(style); - - return CSS_OK; + return set_widows(style, hint->status, hint->data.fixed); } css_error css__initial_widows(css_select_state *state) { - UNUSED(state); - - return CSS_OK; + return set_widows(state->computed, CSS_WIDOWS_SET, INTTOFIX(2)); } css_error css__compose_widows(const css_computed_style *parent, const css_computed_style *child, css_computed_style *result) { - UNUSED(parent); - UNUSED(child); - UNUSED(result); - - return CSS_OK; + css_fixed count = 0; + uint8_t type = get_widows(child, &count); + + if (type == CSS_WIDOWS_INHERIT) { + type = get_widows(parent, &count); + } + + return set_widows(result, type, count); } diff --git a/src/select/propget.h b/src/select/propget.h index d1350ee..41f6315 100644 --- a/src/select/propget.h +++ b/src/select/propget.h @@ -1807,4 +1807,54 @@ static inline uint8_t get_page_break_inside( #undef PAGE_BREAK_INSIDE_SHIFT #undef PAGE_BREAK_INSIDE_INDEX +#define ORPHANS_INDEX 1 +#define ORPHANS_SHIFT 0 +#define ORPHANS_MASK 0x1 +static inline uint8_t get_orphans( + const css_computed_style *style, + css_fixed *count) +{ + if (style->page != NULL) { + uint8_t bits = style->page->bits[ORPHANS_INDEX]; + bits &= ORPHANS_MASK; + bits >>= ORPHANS_SHIFT; + + *count = style->page->orphans; + + /* 1bit: type */ + return bits; + } + + *count = INTTOFIX(2); + return CSS_ORPHANS_SET; +} +#undef ORPHANS_MASK +#undef ORPHANS_SHIFT +#undef ORPHANS_INDEX + +#define WIDOWS_INDEX 1 +#define WIDOWS_SHIFT 1 +#define WIDOWS_MASK 0x2 +static inline uint8_t get_widows( + const css_computed_style *style, + css_fixed *count) +{ + if (style->page != NULL) { + uint8_t bits = style->page->bits[WIDOWS_INDEX]; + bits &= WIDOWS_MASK; + bits >>= WIDOWS_SHIFT; + + *count = style->page->orphans; + + /* 1bit: type */ + return bits; + } + + *count = INTTOFIX(2); + return CSS_WIDOWS_SET; +} +#undef WIDOWS_MASK +#undef WIDOWS_SHIFT +#undef WIDOWS_INDEX + #endif diff --git a/src/select/propset.h b/src/select/propset.h index 738ec70..978a667 100644 --- a/src/select/propset.h +++ b/src/select/propset.h @@ -52,10 +52,15 @@ static const css_computed_uncommon default_uncommon = { } while(0) static const css_computed_page default_page = { - { (CSS_PAGE_BREAK_INSIDE_AUTO << 6) | - (CSS_PAGE_BREAK_BEFORE_AUTO << 3) | - CSS_PAGE_BREAK_AFTER_AUTO - } + { + (CSS_PAGE_BREAK_INSIDE_AUTO << 6) | + (CSS_PAGE_BREAK_BEFORE_AUTO << 3) | + CSS_PAGE_BREAK_AFTER_AUTO, + (CSS_WIDOWS_SET << 1) | + CSS_ORPHANS_SET + }, + 2 << CSS_RADIX_POINT, + 2 << CSS_RADIX_POINT }; #define ENSURE_PAGE do { \ @@ -1862,6 +1867,12 @@ static inline css_error set_page_break_after( { uint8_t *bits; + if (style->page == NULL) { + if (type == CSS_PAGE_BREAK_AFTER_AUTO) { + return CSS_OK; + } + } + ENSURE_PAGE; bits = &style->page->bits[PAGE_BREAK_AFTER_INDEX]; @@ -1884,6 +1895,12 @@ static inline css_error set_page_break_before( { uint8_t *bits; + if (style->page == NULL) { + if (type == CSS_PAGE_BREAK_BEFORE_AUTO) { + return CSS_OK; + } + } + ENSURE_PAGE; bits = &style->page->bits[PAGE_BREAK_BEFORE_INDEX]; @@ -1906,6 +1923,12 @@ static inline css_error set_page_break_inside( { uint8_t *bits; + if (style->page == NULL) { + if (type == CSS_PAGE_BREAK_INSIDE_AUTO) { + return CSS_OK; + } + } + ENSURE_PAGE; bits = &style->page->bits[PAGE_BREAK_INSIDE_INDEX]; @@ -1920,4 +1943,62 @@ static inline css_error set_page_break_inside( #undef PAGE_BREAK_INSIDE_SHIFT #undef PAGE_BREAK_INSIDE_MASK +#define ORPHANS_INDEX 1 +#define ORPHANS_SHIFT 0 +#define ORPHANS_MASK 0x1 +static inline css_error set_orphans( + css_computed_style *style, uint8_t type, css_fixed count) +{ + uint8_t *bits; + + if (style->page == NULL) { + if (type == CSS_ORPHANS_SET && count == INTTOFIX(2)) { + return CSS_OK; + } + } + + ENSURE_PAGE; + + bits = &style->page->bits[ORPHANS_INDEX]; + + /* 1bit: type */ + *bits = (*bits & ~ORPHANS_MASK) | ((type & 0x1) << ORPHANS_SHIFT); + + style->page->orphans = count; + + return CSS_OK; +} +#undef ORPHANS_INDEX +#undef ORPHANS_SHIFT +#undef ORPHANS_MASK + +#define WIDOWS_INDEX 1 +#define WIDOWS_SHIFT 1 +#define WIDOWS_MASK 0x2 +static inline css_error set_widows( + css_computed_style *style, uint8_t type, css_fixed count) +{ + uint8_t *bits; + + if (style->page == NULL) { + if (type == CSS_WIDOWS_SET && count == INTTOFIX(2)) { + return CSS_OK; + } + } + + ENSURE_PAGE; + + bits = &style->page->bits[WIDOWS_INDEX]; + + /* 1bit: type */ + *bits = (*bits & ~WIDOWS_MASK) | ((type & 0x1) << WIDOWS_SHIFT); + + style->page->widows = count; + + return CSS_OK; +} +#undef WIDOWS_INDEX +#undef WIDOWS_SHIFT +#undef WIDOWS_MASK + #endif -- cgit v1.2.3