summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2011-08-23 20:12:41 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2011-08-23 20:12:41 +0000
commit0b6d7198f4fc46961c57530e654691b5a66b36f0 (patch)
tree3e2a25ec514b4d9c34ea92dd79c4eafdc6008b76
parentda47188a8369bb79884d37f3222c8bf8fabb7ea4 (diff)
downloadlibcss-0b6d7198f4fc46961c57530e654691b5a66b36f0.tar.gz
libcss-0b6d7198f4fc46961c57530e654691b5a66b36f0.tar.bz2
Add support for selecting page-break-{before, after, inside}
Credit: James Montgomerie svn path=/trunk/libcss/; revision=12645
-rw-r--r--include/libcss/computed.h9
-rw-r--r--include/libcss/properties.h24
-rw-r--r--src/select/computed.c64
-rw-r--r--src/select/computed.h13
-rw-r--r--src/select/properties/helpers.c16
-rw-r--r--src/select/properties/helpers.h4
-rw-r--r--src/select/properties/page_break_after.c24
-rw-r--r--src/select/properties/page_break_before.c27
-rw-r--r--src/select/properties/page_break_inside.c41
-rw-r--r--src/select/propget.h63
-rw-r--r--src/select/propset.h79
11 files changed, 300 insertions, 64 deletions
diff --git a/include/libcss/computed.h b/include/libcss/computed.h
index c327536..51fcb12 100644
--- a/include/libcss/computed.h
+++ b/include/libcss/computed.h
@@ -379,6 +379,15 @@ uint8_t css_computed_list_style_position(
uint8_t css_computed_text_align(
const css_computed_style *style);
+uint8_t css_computed_page_break_after(
+ const css_computed_style *style);
+
+uint8_t css_computed_page_break_before(
+ const css_computed_style *style);
+
+uint8_t css_computed_page_break_inside(
+ const css_computed_style *style);
+
#ifdef __cplusplus
}
diff --git a/include/libcss/properties.h b/include/libcss/properties.h
index d96cade..6b474ce 100644
--- a/include/libcss/properties.h
+++ b/include/libcss/properties.h
@@ -488,6 +488,30 @@ enum css_padding_e {
CSS_PADDING_SET = 0x1
};
+enum css_page_break_after_e {
+ CSS_PAGE_BREAK_AFTER_INHERIT = 0x0,
+ CSS_PAGE_BREAK_AFTER_AUTO = 0x1,
+ CSS_PAGE_BREAK_AFTER_AVOID = 0x2,
+ CSS_PAGE_BREAK_AFTER_ALWAYS = 0x3,
+ CSS_PAGE_BREAK_AFTER_LEFT = 0x4,
+ CSS_PAGE_BREAK_AFTER_RIGHT = 0x5
+};
+
+enum css_page_break_before_e {
+ CSS_PAGE_BREAK_BEFORE_INHERIT = CSS_PAGE_BREAK_AFTER_INHERIT,
+ CSS_PAGE_BREAK_BEFORE_AUTO = CSS_PAGE_BREAK_AFTER_AUTO,
+ CSS_PAGE_BREAK_BEFORE_AVOID = CSS_PAGE_BREAK_AFTER_AVOID,
+ CSS_PAGE_BREAK_BEFORE_ALWAYS = CSS_PAGE_BREAK_AFTER_ALWAYS,
+ CSS_PAGE_BREAK_BEFORE_LEFT = CSS_PAGE_BREAK_AFTER_LEFT,
+ CSS_PAGE_BREAK_BEFORE_RIGHT = CSS_PAGE_BREAK_AFTER_RIGHT
+};
+
+enum css_page_break_inside_e {
+ CSS_PAGE_BREAK_INSIDE_INHERIT = CSS_PAGE_BREAK_AFTER_INHERIT,
+ CSS_PAGE_BREAK_INSIDE_AUTO = CSS_PAGE_BREAK_AFTER_AUTO,
+ CSS_PAGE_BREAK_INSIDE_AVOID = CSS_PAGE_BREAK_AFTER_AVOID
+};
+
enum css_position_e {
CSS_POSITION_INHERIT = 0x0,
CSS_POSITION_STATIC = 0x1,
diff --git a/src/select/computed.c b/src/select/computed.c
index 198b243..991a9a8 100644
--- a/src/select/computed.c
+++ b/src/select/computed.c
@@ -2160,6 +2160,70 @@ uint8_t css_computed_text_align(
#undef CSS_TEXT_ALIGN_SHIFT
#undef CSS_TEXT_ALIGN_INDEX
+#define CSS_PAGE_BREAK_AFTER_INDEX 0
+#define CSS_PAGE_BREAK_AFTER_SHIFT 0
+#define CSS_PAGE_BREAK_AFTER_MASK 0x7
+uint8_t css_computed_page_break_after(
+ const css_computed_style *style)
+{
+ if (style->page != NULL) {
+ uint8_t bits = style->page->bits[CSS_PAGE_BREAK_AFTER_INDEX];
+ bits &= CSS_PAGE_BREAK_AFTER_MASK;
+ bits >>= CSS_PAGE_BREAK_AFTER_SHIFT;
+
+ /* 3bits: type */
+ return bits;
+ }
+
+ return CSS_PAGE_BREAK_AFTER_AUTO;
+}
+#undef CSS_PAGE_BREAK_AFTER_MASK
+#undef CSS_PAGE_BREAK_AFTER_SHIFT
+#undef CSS_PAGE_BREAK_AFTER_INDEX
+
+#define CSS_PAGE_BREAK_BEFORE_INDEX 0
+#define CSS_PAGE_BREAK_BEFORE_SHIFT 3
+#define CSS_PAGE_BREAK_BEFORE_MASK 0x38
+uint8_t css_computed_page_break_before(
+ const css_computed_style *style)
+{
+ if (style->page != NULL) {
+ uint8_t bits = style->page->bits[CSS_PAGE_BREAK_BEFORE_INDEX];
+ bits &= CSS_PAGE_BREAK_BEFORE_MASK;
+ bits >>= CSS_PAGE_BREAK_BEFORE_SHIFT;
+
+ /* 3bits: type */
+ return bits;
+ }
+
+ return CSS_PAGE_BREAK_BEFORE_AUTO;
+}
+#undef CSS_PAGE_BREAK_BEFORE_MASK
+#undef CSS_PAGE_BREAK_BEFORE_SHIFT
+#undef CSS_PAGE_BREAK_BEFORE_INDEX
+
+#define CSS_PAGE_BREAK_INSIDE_INDEX 0
+#define CSS_PAGE_BREAK_INSIDE_SHIFT 6
+#define CSS_PAGE_BREAK_INSIDE_MASK 0xc0
+uint8_t css_computed_page_break_inside(
+ const css_computed_style *style)
+{
+ if (style->page != NULL) {
+ uint8_t bits = style->page->bits[CSS_PAGE_BREAK_INSIDE_INDEX];
+ bits &= CSS_PAGE_BREAK_INSIDE_MASK;
+ bits >>= CSS_PAGE_BREAK_INSIDE_SHIFT;
+
+ /* 2bits: type */
+ return bits;
+ }
+
+ return CSS_PAGE_BREAK_INSIDE_AUTO;
+}
+#undef CSS_PAGE_BREAK_INSIDE_MASK
+#undef CSS_PAGE_BREAK_INSIDE_SHIFT
+#undef CSS_PAGE_BREAK_INSIDE_INDEX
+
+
/******************************************************************************
* Library internals *
diff --git a/src/select/computed.h b/src/select/computed.h
index e77c0cc..6f19051 100644
--- a/src/select/computed.h
+++ b/src/select/computed.h
@@ -85,6 +85,17 @@ typedef struct css_computed_uncommon {
css_computed_content_item *content;
} css_computed_uncommon;
+typedef struct css_computed_page {
+/*
+ * page_break_after 3
+ * page_break_before 3
+ * page_break_inside 2
+ * ---
+ * 8 bits
+ */
+ uint8_t bits[1];
+} css_computed_page;
+
struct css_computed_style {
/*
* background_attachment 2
@@ -270,7 +281,7 @@ struct css_computed_style {
css_computed_uncommon *uncommon;/**< Uncommon properties */
void *aural; /**< Aural properties */
- void *page; /**< Page properties */
+ css_computed_page *page; /**< Page properties */
css_allocator_fn alloc;
void *pw;
diff --git a/src/select/properties/helpers.c b/src/select/properties/helpers.c
index 3851b36..24e193d 100644
--- a/src/select/properties/helpers.c
+++ b/src/select/properties/helpers.c
@@ -356,22 +356,30 @@ css_error css__cascade_number(uint32_t opv, css_style *style,
return CSS_OK;
}
-css_error css__cascade_page_break_after_before(uint32_t opv, css_style *style,
- css_select_state *state,
+css_error css__cascade_page_break_after_before_inside(uint32_t opv,
+ css_style *style, css_select_state *state,
css_error (*fun)(css_computed_style *, uint8_t))
{
- uint16_t value = 0;
+ uint16_t value = CSS_PAGE_BREAK_AFTER_INHERIT;
UNUSED(style);
if (isInherit(opv) == false) {
switch (getValue(opv)) {
case PAGE_BREAK_AFTER_AUTO:
+ value = CSS_PAGE_BREAK_AFTER_AUTO;
+ break;
case PAGE_BREAK_AFTER_ALWAYS:
+ value = CSS_PAGE_BREAK_AFTER_ALWAYS;
+ break;
case PAGE_BREAK_AFTER_AVOID:
+ value = CSS_PAGE_BREAK_AFTER_AVOID;
+ break;
case PAGE_BREAK_AFTER_LEFT:
+ value = CSS_PAGE_BREAK_AFTER_LEFT;
+ break;
case PAGE_BREAK_AFTER_RIGHT:
- /** \todo convert to public values */
+ value = CSS_PAGE_BREAK_AFTER_RIGHT;
break;
}
}
diff --git a/src/select/properties/helpers.h b/src/select/properties/helpers.h
index 9e3e327..098fe1e 100644
--- a/src/select/properties/helpers.h
+++ b/src/select/properties/helpers.h
@@ -48,8 +48,8 @@ css_error css__cascade_length(uint32_t opv, css_style *style,
css_error css__cascade_number(uint32_t opv, css_style *style,
css_select_state *state,
css_error (*fun)(css_computed_style *, uint8_t, css_fixed));
-css_error css__cascade_page_break_after_before(uint32_t opv, css_style *style,
- css_select_state *state,
+css_error css__cascade_page_break_after_before_inside(uint32_t opv,
+ css_style *style, css_select_state *state,
css_error (*fun)(css_computed_style *, uint8_t));
css_error css__cascade_counter_increment_reset(uint32_t opv, css_style *style,
css_select_state *state,
diff --git a/src/select/properties/page_break_after.c b/src/select/properties/page_break_after.c
index c2c3051..0fd44c4 100644
--- a/src/select/properties/page_break_after.c
+++ b/src/select/properties/page_break_after.c
@@ -17,34 +17,32 @@
css_error css__cascade_page_break_after(uint32_t opv, css_style *style,
css_select_state *state)
{
- /** \todo page-break-after */
- return css__cascade_page_break_after_before(opv, style, state, NULL);
+ return css__cascade_page_break_after_before_inside(opv, style, state,
+ set_page_break_after);
}
css_error css__set_page_break_after_from_hint(const css_hint *hint,
css_computed_style *style)
{
- UNUSED(hint);
- UNUSED(style);
-
- return CSS_OK;
+ return set_page_break_after(style, hint->status);
}
css_error css__initial_page_break_after(css_select_state *state)
{
- UNUSED(state);
-
- return CSS_OK;
+ return set_page_break_after(state->computed,
+ CSS_PAGE_BREAK_AFTER_AUTO);
}
css_error css__compose_page_break_after(const css_computed_style *parent,
const css_computed_style *child,
css_computed_style *result)
{
- UNUSED(parent);
- UNUSED(child);
- UNUSED(result);
+ uint8_t type = get_page_break_after(child);
+
+ if (type == CSS_PAGE_BREAK_AFTER_INHERIT) {
+ type = get_page_break_after(parent);
+ }
- return CSS_OK;
+ return set_page_break_after(result, type);
}
diff --git a/src/select/properties/page_break_before.c b/src/select/properties/page_break_before.c
index a0799fd..0acae48 100644
--- a/src/select/properties/page_break_before.c
+++ b/src/select/properties/page_break_before.c
@@ -17,34 +17,31 @@
css_error css__cascade_page_break_before(uint32_t opv, css_style *style,
css_select_state *state)
{
- /** \todo page-break-before */
- return css__cascade_page_break_after_before(opv, style, state, NULL);
+ return css__cascade_page_break_after_before_inside(opv, style, state,
+ set_page_break_before);
}
css_error css__set_page_break_before_from_hint(const css_hint *hint,
css_computed_style *style)
{
- UNUSED(hint);
- UNUSED(style);
-
- return CSS_OK;
+ return set_page_break_before(style, hint->status);
}
css_error css__initial_page_break_before(css_select_state *state)
{
- UNUSED(state);
-
- return CSS_OK;
+ return set_page_break_before(state->computed,
+ CSS_PAGE_BREAK_BEFORE_AUTO);
}
css_error css__compose_page_break_before(const css_computed_style *parent,
const css_computed_style *child,
css_computed_style *result)
{
- UNUSED(parent);
- UNUSED(child);
- UNUSED(result);
-
- return CSS_OK;
+ uint8_t type = get_page_break_before(child);
+
+ if (type == CSS_PAGE_BREAK_BEFORE_INHERIT) {
+ type = get_page_break_before(parent);
+ }
+
+ return set_page_break_before(result, type);
}
-
diff --git a/src/select/properties/page_break_inside.c b/src/select/properties/page_break_inside.c
index 2e27298..20b8bf5 100644
--- a/src/select/properties/page_break_inside.c
+++ b/src/select/properties/page_break_inside.c
@@ -17,49 +17,32 @@
css_error css__cascade_page_break_inside(uint32_t opv, css_style *style,
css_select_state *state)
{
- UNUSED(style);
-
- if (isInherit(opv) == false) {
- switch (getValue(opv)) {
- case PAGE_BREAK_INSIDE_AUTO:
- case PAGE_BREAK_INSIDE_AVOID:
- /** \todo convert to public values */
- break;
- }
- }
-
- if (css__outranks_existing(getOpcode(opv), isImportant(opv), state,
- isInherit(opv))) {
- /** \todo page-break-inside */
- }
-
- return CSS_OK;
+ return css__cascade_page_break_after_before_inside(opv, style, state,
+ set_page_break_inside);
}
css_error css__set_page_break_inside_from_hint(const css_hint *hint,
css_computed_style *style)
{
- UNUSED(hint);
- UNUSED(style);
-
- return CSS_OK;
+ return set_page_break_inside(style, hint->status);
}
css_error css__initial_page_break_inside(css_select_state *state)
{
- UNUSED(state);
-
- return CSS_OK;
+ return set_page_break_inside(state->computed,
+ CSS_PAGE_BREAK_INSIDE_AUTO);
}
css_error css__compose_page_break_inside(const css_computed_style *parent,
const css_computed_style *child,
css_computed_style *result)
{
- UNUSED(parent);
- UNUSED(child);
- UNUSED(result);
-
- return CSS_OK;
+ uint8_t type = get_page_break_inside(child);
+
+ if (type == CSS_PAGE_BREAK_INSIDE_INHERIT) {
+ type = get_page_break_inside(parent);
+ }
+
+ return set_page_break_inside(result, type);
}
diff --git a/src/select/propget.h b/src/select/propget.h
index 05bdba6..d1350ee 100644
--- a/src/select/propget.h
+++ b/src/select/propget.h
@@ -1744,4 +1744,67 @@ static inline uint8_t get_text_align(
#undef TEXT_ALIGN_SHIFT
#undef TEXT_ALIGN_INDEX
+#define PAGE_BREAK_AFTER_INDEX 0
+#define PAGE_BREAK_AFTER_SHIFT 0
+#define PAGE_BREAK_AFTER_MASK 0x7
+static inline uint8_t get_page_break_after(
+ const css_computed_style *style)
+{
+ if (style->page != NULL) {
+ uint8_t bits = style->page->bits[PAGE_BREAK_AFTER_INDEX];
+ bits &= PAGE_BREAK_AFTER_MASK;
+ bits >>= PAGE_BREAK_AFTER_SHIFT;
+
+ /* 3bits: type */
+ return bits;
+ }
+
+ return CSS_PAGE_BREAK_AFTER_AUTO;
+}
+#undef PAGE_BREAK_AFTER_MASK
+#undef PAGE_BREAK_AFTER_SHIFT
+#undef PAGE_BREAK_AFTER_INDEX
+
+#define PAGE_BREAK_BEFORE_INDEX 0
+#define PAGE_BREAK_BEFORE_SHIFT 3
+#define PAGE_BREAK_BEFORE_MASK 0x38
+static inline uint8_t get_page_break_before(
+ const css_computed_style *style)
+{
+ if (style->page != NULL) {
+ uint8_t bits = style->page->bits[PAGE_BREAK_BEFORE_INDEX];
+ bits &= PAGE_BREAK_BEFORE_MASK;
+ bits >>= PAGE_BREAK_BEFORE_SHIFT;
+
+ /* 3bits: type */
+ return bits;
+ }
+
+ return CSS_PAGE_BREAK_BEFORE_AUTO;
+}
+#undef PAGE_BREAK_BEFORE_MASK
+#undef PAGE_BREAK_BEFORE_SHIFT
+#undef PAGE_BREAK_BEFORE_INDEX
+
+#define PAGE_BREAK_INSIDE_INDEX 0
+#define PAGE_BREAK_INSIDE_SHIFT 6
+#define PAGE_BREAK_INSIDE_MASK 0xc0
+static inline uint8_t get_page_break_inside(
+ const css_computed_style *style)
+{
+ if (style->page != NULL) {
+ uint8_t bits = style->page->bits[PAGE_BREAK_INSIDE_INDEX];
+ bits &= PAGE_BREAK_INSIDE_MASK;
+ bits >>= PAGE_BREAK_INSIDE_SHIFT;
+
+ /* 2bits: type */
+ return bits;
+ }
+
+ return CSS_PAGE_BREAK_INSIDE_AUTO;
+}
+#undef PAGE_BREAK_INSIDE_MASK
+#undef PAGE_BREAK_INSIDE_SHIFT
+#undef PAGE_BREAK_INSIDE_INDEX
+
#endif
diff --git a/src/select/propset.h b/src/select/propset.h
index 7c29db4..6337536 100644
--- a/src/select/propset.h
+++ b/src/select/propset.h
@@ -51,6 +51,25 @@ 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
+ }
+};
+
+#define ENSURE_PAGE do { \
+ if (style->page == NULL) { \
+ style->page = style->alloc(NULL, \
+ sizeof(css_computed_page), style->pw); \
+ if (style->page == NULL) \
+ return CSS_NOMEM; \
+ \
+ memcpy(style->page, &default_page, \
+ sizeof(css_computed_page)); \
+ } \
+} while(0)
+
#define LETTER_SPACING_INDEX 0
#define LETTER_SPACING_SHIFT 2
#define LETTER_SPACING_MASK 0xfc
@@ -1835,4 +1854,64 @@ static inline uint8_t set_text_align(
#undef TEXT_ALIGN_SHIFT
#undef TEXT_ALIGN_INDEX
+#define PAGE_BREAK_AFTER_INDEX 0
+#define PAGE_BREAK_AFTER_SHIFT 0
+#define PAGE_BREAK_AFTER_MASK 0x7
+static inline css_error set_page_break_after(
+ css_computed_style *style, uint8_t type)
+{
+ ENSURE_PAGE;
+
+ uint8_t *bits = &style->page->bits[PAGE_BREAK_AFTER_INDEX];
+
+ /* 3bits: type */
+ *bits = (*bits & ~PAGE_BREAK_AFTER_MASK) |
+ ((type & 0x7) << PAGE_BREAK_AFTER_SHIFT);
+
+ return CSS_OK;
+}
+#undef PAGE_BREAK_AFTER_INDEX
+#undef PAGE_BREAK_AFTER_SHIFT
+#undef PAGE_BREAK_AFTER_MASK
+
+#define PAGE_BREAK_BEFORE_INDEX 0
+#define PAGE_BREAK_BEFORE_SHIFT 3
+#define PAGE_BREAK_BEFORE_MASK 0x38
+static inline css_error set_page_break_before(
+ css_computed_style *style, uint8_t type)
+{
+ ENSURE_PAGE;
+
+ uint8_t *bits = &style->page->bits[PAGE_BREAK_BEFORE_INDEX];
+
+ /* 3bits: type */
+ *bits = (*bits & ~PAGE_BREAK_BEFORE_MASK) |
+ ((type & 0x7) << PAGE_BREAK_BEFORE_SHIFT);
+
+ return CSS_OK;
+}
+#undef PAGE_BREAK_BEFORE_INDEX
+#undef PAGE_BREAK_BEFORE_SHIFT
+#undef PAGE_BREAK_BEFORE_MASK
+
+#define PAGE_BREAK_INSIDE_INDEX 0
+#define PAGE_BREAK_INSIDE_SHIFT 6
+#define PAGE_BREAK_INSIDE_MASK 0xc0
+static inline css_error set_page_break_inside(
+ css_computed_style *style, uint8_t type)
+{
+ ENSURE_PAGE;
+
+ uint8_t *bits = &style->page->bits[PAGE_BREAK_INSIDE_INDEX];
+
+ /* 2bits: type */
+ *bits = (*bits & ~PAGE_BREAK_INSIDE_MASK) |
+ ((type & 0x3) << PAGE_BREAK_INSIDE_SHIFT);
+
+ return CSS_OK;
+}
+#undef PAGE_BREAK_INSIDE_INDEX
+#undef PAGE_BREAK_INSIDE_SHIFT
+#undef PAGE_BREAK_INSIDE_MASK
+
#endif