mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-23 04:26:50 +03:00
CSS computed style composition: Update for new CSS units.
Since the nscss_compute_font_size callback now needs to convert new units to absolute values, and some of these units require info from the root element's style, there are knock-on changes to ensure that the required info is available where its needed.
This commit is contained in:
parent
d1c656b55f
commit
5776d3448c
@ -278,7 +278,7 @@ css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node *n,
|
||||
* element's style */
|
||||
error = css_computed_style_compose(ctx->parent_style,
|
||||
styles->styles[CSS_PSEUDO_ELEMENT_NONE],
|
||||
nscss_compute_font_size, NULL,
|
||||
nscss_compute_font_size, ctx,
|
||||
&composed);
|
||||
if (error != CSS_OK) {
|
||||
css_select_results_destroy(styles);
|
||||
@ -310,7 +310,7 @@ css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node *n,
|
||||
error = css_computed_style_compose(
|
||||
styles->styles[CSS_PSEUDO_ELEMENT_NONE],
|
||||
styles->styles[pseudo_element],
|
||||
nscss_compute_font_size, NULL,
|
||||
nscss_compute_font_size, ctx,
|
||||
&composed);
|
||||
if (error != CSS_OK) {
|
||||
/* TODO: perhaps this shouldn't be quite so
|
||||
@ -349,7 +349,7 @@ css_computed_style *nscss_get_blank_style(nscss_select_ctx *ctx,
|
||||
/* TODO: Do we really need to compose? Initial style shouldn't
|
||||
* have any inherited properties. */
|
||||
error = css_computed_style_compose(parent, partial,
|
||||
nscss_compute_font_size, NULL, &composed);
|
||||
nscss_compute_font_size, ctx, &composed);
|
||||
css_computed_style_destroy(partial);
|
||||
if (error != CSS_OK) {
|
||||
css_computed_style_destroy(composed);
|
||||
@ -422,14 +422,37 @@ css_error nscss_compute_font_size(void *pw, const css_hint *parent,
|
||||
FDIV(parent_size.value, FLTTOFIX(1.2));
|
||||
size->data.length.unit = parent_size.unit;
|
||||
} else if (size->data.length.unit == CSS_UNIT_EM ||
|
||||
size->data.length.unit == CSS_UNIT_EX) {
|
||||
size->data.length.unit == CSS_UNIT_EX ||
|
||||
size->data.length.unit == CSS_UNIT_CAP ||
|
||||
size->data.length.unit == CSS_UNIT_CH ||
|
||||
size->data.length.unit == CSS_UNIT_IC) {
|
||||
size->data.length.value =
|
||||
FMUL(size->data.length.value, parent_size.value);
|
||||
|
||||
if (size->data.length.unit == CSS_UNIT_EX) {
|
||||
switch (size->data.length.unit) {
|
||||
case CSS_UNIT_EX:
|
||||
/* 1ex = 0.6em in NetSurf */
|
||||
size->data.length.value = FMUL(size->data.length.value,
|
||||
FLTTOFIX(0.6));
|
||||
break;
|
||||
case CSS_UNIT_CAP:
|
||||
/* Height of captals. 1cap = 0.9em in NetSurf. */
|
||||
size->data.length.value = FMUL(size->data.length.value,
|
||||
FLTTOFIX(0.9));
|
||||
break;
|
||||
case CSS_UNIT_CH:
|
||||
/* Width of '0'. 1ch = 0.4em in NetSurf. */
|
||||
size->data.length.value = FMUL(size->data.length.value,
|
||||
FLTTOFIX(0.4));
|
||||
break;
|
||||
case CSS_UNIT_IC:
|
||||
/* Width of U+6C43. 1ic = 1.1em in NetSurf. */
|
||||
size->data.length.value = FMUL(size->data.length.value,
|
||||
FLTTOFIX(1.1));
|
||||
break;
|
||||
default:
|
||||
/* No scaling required for EM. */
|
||||
break;
|
||||
}
|
||||
|
||||
size->data.length.unit = parent_size.unit;
|
||||
@ -437,6 +460,25 @@ css_error nscss_compute_font_size(void *pw, const css_hint *parent,
|
||||
size->data.length.value = FDIV(FMUL(size->data.length.value,
|
||||
parent_size.value), INTTOFIX(100));
|
||||
size->data.length.unit = parent_size.unit;
|
||||
} else if (size->data.length.unit == CSS_UNIT_REM) {
|
||||
nscss_select_ctx *ctx = pw;
|
||||
if (parent == NULL) {
|
||||
size->data.length.value = parent_size.value;
|
||||
size->data.length.unit = parent_size.unit;
|
||||
} else {
|
||||
css_computed_font_size(ctx->root_style,
|
||||
&parent_size.value,
|
||||
&size->data.length.unit);
|
||||
size->data.length.value = FMUL(
|
||||
size->data.length.value,
|
||||
parent_size.value);
|
||||
}
|
||||
} else if (size->data.length.unit == CSS_UNIT_RLH) {
|
||||
/** TODO: Convert root element line-height to absolute value. */
|
||||
size->data.length.value = FMUL(size->data.length.value, FDIV(
|
||||
INTTOFIX(nsoption_int(font_size)),
|
||||
INTTOFIX(10)));
|
||||
size->data.length.unit = CSS_UNIT_PT;
|
||||
}
|
||||
|
||||
size->status = CSS_FONT_SIZE_DIMENSION;
|
||||
|
@ -37,6 +37,7 @@ typedef struct nscss_select_ctx
|
||||
bool quirks;
|
||||
struct nsurl *base_url;
|
||||
lwc_string *universal;
|
||||
const css_computed_style *root_style;
|
||||
const css_computed_style *parent_style;
|
||||
} nscss_select_ctx;
|
||||
|
||||
|
@ -356,6 +356,9 @@ bool box_hscrollbar_present(const struct box *box);
|
||||
nserror dom_to_box(struct dom_node *n, struct html_content *c,
|
||||
box_construct_complete_cb cb);
|
||||
|
||||
bool box_normalise_block(struct box *block, struct html_content *c);
|
||||
bool box_normalise_block(
|
||||
struct box *block,
|
||||
const struct box *root,
|
||||
struct html_content *c);
|
||||
|
||||
#endif
|
||||
|
@ -104,7 +104,8 @@ static bool box_construct_element(struct box_construct_ctx *ctx,
|
||||
static void box_construct_element_after(dom_node *n, html_content *content);
|
||||
static bool box_construct_text(struct box_construct_ctx *ctx);
|
||||
static css_select_results * box_get_style(html_content *c,
|
||||
const css_computed_style *parent_style, dom_node *n);
|
||||
const css_computed_style *parent_style,
|
||||
const css_computed_style *root_style, dom_node *n);
|
||||
static void box_text_transform(char *s, unsigned int len,
|
||||
enum css_text_transform_e tt);
|
||||
#define BOX_SPECIAL_PARAMS dom_node *n, html_content *content, \
|
||||
@ -429,7 +430,8 @@ void convert_xml_to_box(struct box_construct_ctx *ctx)
|
||||
root.children->parent = &root;
|
||||
|
||||
/** \todo Remove box_normalise_block */
|
||||
if (box_normalise_block(&root, ctx->content) == false) {
|
||||
if (box_normalise_block(&root, ctx->root_box,
|
||||
ctx->content) == false) {
|
||||
ctx->cb(ctx->content, false);
|
||||
} else {
|
||||
ctx->content->layout = root.children;
|
||||
@ -741,6 +743,7 @@ bool box_construct_element(struct box_construct_ctx *ctx,
|
||||
lwc_string *bgimage_uri;
|
||||
dom_exception err;
|
||||
struct box_construct_props props;
|
||||
const css_computed_style *root_style = NULL;
|
||||
|
||||
assert(ctx->n != NULL);
|
||||
|
||||
@ -753,7 +756,12 @@ bool box_construct_element(struct box_construct_ctx *ctx,
|
||||
props.containing_block->flags &= ~PRE_STRIP;
|
||||
}
|
||||
|
||||
styles = box_get_style(ctx->content, props.parent_style, ctx->n);
|
||||
if (props.node_is_root == false) {
|
||||
root_style = ctx->root_box->style;
|
||||
}
|
||||
|
||||
styles = box_get_style(ctx->content, props.parent_style, root_style,
|
||||
ctx->n);
|
||||
if (styles == NULL)
|
||||
return false;
|
||||
|
||||
@ -1321,13 +1329,15 @@ bool box_construct_text(struct box_construct_ctx *ctx)
|
||||
/**
|
||||
* Get the style for an element.
|
||||
*
|
||||
* \param c content of type CONTENT_HTML that is being processed
|
||||
* \param c content of type CONTENT_HTML that is being processed
|
||||
* \param parent_style style at this point in xml tree, or NULL for root
|
||||
* \param n node in xml tree
|
||||
* \param root_style root node's style, or NULL for root
|
||||
* \param n node in xml tree
|
||||
* \return the new style, or NULL on memory exhaustion
|
||||
*/
|
||||
css_select_results *box_get_style(html_content *c,
|
||||
const css_computed_style *parent_style, dom_node *n)
|
||||
const css_computed_style *parent_style,
|
||||
const css_computed_style *root_style, dom_node *n)
|
||||
{
|
||||
dom_string *s;
|
||||
dom_exception err;
|
||||
@ -1359,6 +1369,7 @@ css_select_results *box_get_style(html_content *c,
|
||||
ctx.quirks = (c->quirks == DOM_DOCUMENT_QUIRKS_MODE_FULL);
|
||||
ctx.base_url = c->base_url;
|
||||
ctx.universal = c->universal;
|
||||
ctx.root_style = root_style;
|
||||
ctx.parent_style = parent_style;
|
||||
|
||||
/* Select style for element */
|
||||
|
@ -65,24 +65,38 @@ struct columns {
|
||||
};
|
||||
|
||||
|
||||
static bool box_normalise_table(struct box *table, html_content *c);
|
||||
static bool box_normalise_table_spans(struct box *table,
|
||||
struct span_info *spans, html_content *c);
|
||||
static bool box_normalise_table_row_group(struct box *row_group,
|
||||
static bool box_normalise_table(
|
||||
struct box *table,
|
||||
const struct box *root,
|
||||
html_content *c);
|
||||
static bool box_normalise_table_spans(
|
||||
struct box *table,
|
||||
const struct box *root,
|
||||
struct span_info *spans,
|
||||
html_content *c);
|
||||
static bool box_normalise_table_row_group(
|
||||
struct box *row_group,
|
||||
const struct box *root,
|
||||
struct columns *col_info,
|
||||
html_content *c);
|
||||
static bool box_normalise_table_row(struct box *row,
|
||||
static bool box_normalise_table_row(
|
||||
struct box *row,
|
||||
const struct box *root,
|
||||
struct columns *col_info,
|
||||
html_content *c);
|
||||
static bool calculate_table_row(struct columns *col_info,
|
||||
unsigned int col_span, unsigned int row_span,
|
||||
unsigned int *start_column, struct box *cell);
|
||||
static bool box_normalise_inline_container(struct box *cont, html_content *c);
|
||||
static bool box_normalise_inline_container(
|
||||
struct box *cont,
|
||||
const struct box *root,
|
||||
html_content *c);
|
||||
|
||||
/**
|
||||
* Ensure the box tree is correctly nested by adding and removing nodes.
|
||||
*
|
||||
* \param block box of type BLOCK, INLINE_BLOCK, or TABLE_CELL
|
||||
* \param root root box of document
|
||||
* \param c content of boxes
|
||||
* \return true on success, false on memory exhaustion
|
||||
*
|
||||
@ -100,7 +114,10 @@ static bool box_normalise_inline_container(struct box *cont, html_content *c);
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
bool box_normalise_block(struct box *block, html_content *c)
|
||||
bool box_normalise_block(
|
||||
struct box *block,
|
||||
const struct box *root,
|
||||
html_content *c)
|
||||
{
|
||||
struct box *child;
|
||||
struct box *next_child;
|
||||
@ -109,6 +126,9 @@ bool box_normalise_block(struct box *block, html_content *c)
|
||||
nscss_select_ctx ctx;
|
||||
|
||||
assert(block != NULL);
|
||||
assert(root != NULL);
|
||||
|
||||
ctx.root_style = root->style;
|
||||
|
||||
#ifdef BOX_NORMALISE_DEBUG
|
||||
NSLOG(netsurf, INFO, "block %p, block->type %u", block, block->type);
|
||||
@ -128,15 +148,15 @@ bool box_normalise_block(struct box *block, html_content *c)
|
||||
switch (child->type) {
|
||||
case BOX_BLOCK:
|
||||
/* ok */
|
||||
if (box_normalise_block(child, c) == false)
|
||||
if (box_normalise_block(child, root, c) == false)
|
||||
return false;
|
||||
break;
|
||||
case BOX_INLINE_CONTAINER:
|
||||
if (box_normalise_inline_container(child, c) == false)
|
||||
if (box_normalise_inline_container(child, root, c) == false)
|
||||
return false;
|
||||
break;
|
||||
case BOX_TABLE:
|
||||
if (box_normalise_table(child, c) == false)
|
||||
if (box_normalise_table(child, root, c) == false)
|
||||
return false;
|
||||
break;
|
||||
case BOX_INLINE:
|
||||
@ -199,7 +219,7 @@ bool box_normalise_block(struct box *block, html_content *c)
|
||||
block->last = table;
|
||||
table->parent = block;
|
||||
|
||||
if (box_normalise_table(table, c) == false)
|
||||
if (box_normalise_table(table, root, c) == false)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
@ -211,7 +231,10 @@ bool box_normalise_block(struct box *block, html_content *c)
|
||||
}
|
||||
|
||||
|
||||
bool box_normalise_table(struct box *table, html_content * c)
|
||||
bool box_normalise_table(
|
||||
struct box *table,
|
||||
const struct box *root,
|
||||
html_content * c)
|
||||
{
|
||||
struct box *child;
|
||||
struct box *next_child;
|
||||
@ -223,6 +246,8 @@ bool box_normalise_table(struct box *table, html_content * c)
|
||||
assert(table != NULL);
|
||||
assert(table->type == BOX_TABLE);
|
||||
|
||||
ctx.root_style = root->style;
|
||||
|
||||
#ifdef BOX_NORMALISE_DEBUG
|
||||
NSLOG(netsurf, INFO, "table %p", table);
|
||||
#endif
|
||||
@ -243,7 +268,7 @@ bool box_normalise_table(struct box *table, html_content * c)
|
||||
switch (child->type) {
|
||||
case BOX_TABLE_ROW_GROUP:
|
||||
/* ok */
|
||||
if (box_normalise_table_row_group(child,
|
||||
if (box_normalise_table_row_group(child, root,
|
||||
&col_info, c) == false) {
|
||||
free(col_info.spans);
|
||||
return false;
|
||||
@ -308,7 +333,7 @@ bool box_normalise_table(struct box *table, html_content * c)
|
||||
table->last = row_group;
|
||||
row_group->parent = table;
|
||||
|
||||
if (box_normalise_table_row_group(row_group,
|
||||
if (box_normalise_table_row_group(row_group, root,
|
||||
&col_info, c) == false) {
|
||||
free(col_info.spans);
|
||||
return false;
|
||||
@ -390,7 +415,7 @@ bool box_normalise_table(struct box *table, html_content * c)
|
||||
table->rows = 1;
|
||||
}
|
||||
|
||||
if (box_normalise_table_spans(table, col_info.spans, c) == false) {
|
||||
if (box_normalise_table_spans(table, root, col_info.spans, c) == false) {
|
||||
free(col_info.spans);
|
||||
return false;
|
||||
}
|
||||
@ -413,12 +438,16 @@ bool box_normalise_table(struct box *table, html_content * c)
|
||||
* Additionally, generate empty cells.
|
||||
*
|
||||
* \param table Table to process
|
||||
* \param root root box of document
|
||||
* \param spans Array of length table->columns for use in empty cell detection
|
||||
* \param c Content containing table
|
||||
* \return True on success, false on memory exhaustion.
|
||||
*/
|
||||
|
||||
bool box_normalise_table_spans(struct box *table, struct span_info *spans,
|
||||
bool box_normalise_table_spans(
|
||||
struct box *table,
|
||||
const struct box *root,
|
||||
struct span_info *spans,
|
||||
html_content *c)
|
||||
{
|
||||
struct box *table_row_group;
|
||||
@ -429,6 +458,8 @@ bool box_normalise_table_spans(struct box *table, struct span_info *spans,
|
||||
unsigned int col;
|
||||
nscss_select_ctx ctx;
|
||||
|
||||
ctx.root_style = root->style;
|
||||
|
||||
/* Clear span data */
|
||||
memset(spans, 0, table->columns * sizeof(struct span_info));
|
||||
|
||||
@ -572,7 +603,9 @@ bool box_normalise_table_spans(struct box *table, struct span_info *spans,
|
||||
}
|
||||
|
||||
|
||||
bool box_normalise_table_row_group(struct box *row_group,
|
||||
bool box_normalise_table_row_group(
|
||||
struct box *row_group,
|
||||
const struct box *root,
|
||||
struct columns *col_info,
|
||||
html_content * c)
|
||||
{
|
||||
@ -586,6 +619,8 @@ bool box_normalise_table_row_group(struct box *row_group,
|
||||
assert(row_group != 0);
|
||||
assert(row_group->type == BOX_TABLE_ROW_GROUP);
|
||||
|
||||
ctx.root_style = root->style;
|
||||
|
||||
#ifdef BOX_NORMALISE_DEBUG
|
||||
NSLOG(netsurf, INFO, "row_group %p", row_group);
|
||||
#endif
|
||||
@ -597,7 +632,7 @@ bool box_normalise_table_row_group(struct box *row_group,
|
||||
case BOX_TABLE_ROW:
|
||||
/* ok */
|
||||
group_row_count++;
|
||||
if (box_normalise_table_row(child, col_info,
|
||||
if (box_normalise_table_row(child, root, col_info,
|
||||
c) == false)
|
||||
return false;
|
||||
break;
|
||||
@ -657,7 +692,7 @@ bool box_normalise_table_row_group(struct box *row_group,
|
||||
row->parent = row_group;
|
||||
|
||||
group_row_count++;
|
||||
if (box_normalise_table_row(row, col_info,
|
||||
if (box_normalise_table_row(row, root, col_info,
|
||||
c) == false)
|
||||
return false;
|
||||
break;
|
||||
@ -722,7 +757,9 @@ bool box_normalise_table_row_group(struct box *row_group,
|
||||
}
|
||||
|
||||
|
||||
bool box_normalise_table_row(struct box *row,
|
||||
bool box_normalise_table_row(
|
||||
struct box *row,
|
||||
const struct box *root,
|
||||
struct columns *col_info,
|
||||
html_content * c)
|
||||
{
|
||||
@ -736,6 +773,8 @@ bool box_normalise_table_row(struct box *row,
|
||||
assert(row != NULL);
|
||||
assert(row->type == BOX_TABLE_ROW);
|
||||
|
||||
ctx.root_style = root->style;
|
||||
|
||||
#ifdef BOX_NORMALISE_DEBUG
|
||||
NSLOG(netsurf, INFO, "row %p", row);
|
||||
#endif
|
||||
@ -746,7 +785,7 @@ bool box_normalise_table_row(struct box *row,
|
||||
switch (child->type) {
|
||||
case BOX_TABLE_CELL:
|
||||
/* ok */
|
||||
if (box_normalise_block(child, c) == false)
|
||||
if (box_normalise_block(child, root, c) == false)
|
||||
return false;
|
||||
cell = child;
|
||||
break;
|
||||
@ -805,7 +844,7 @@ bool box_normalise_table_row(struct box *row,
|
||||
row->last = cell;
|
||||
cell->parent = row;
|
||||
|
||||
if (box_normalise_block(cell, c) == false)
|
||||
if (box_normalise_block(cell, root, c) == false)
|
||||
return false;
|
||||
break;
|
||||
case BOX_INLINE:
|
||||
@ -928,7 +967,10 @@ bool calculate_table_row(struct columns *col_info,
|
||||
}
|
||||
|
||||
|
||||
bool box_normalise_inline_container(struct box *cont, html_content * c)
|
||||
bool box_normalise_inline_container(
|
||||
struct box *cont,
|
||||
const struct box *root,
|
||||
html_content * c)
|
||||
{
|
||||
struct box *child;
|
||||
struct box *next_child;
|
||||
@ -951,7 +993,7 @@ bool box_normalise_inline_container(struct box *cont, html_content * c)
|
||||
break;
|
||||
case BOX_INLINE_BLOCK:
|
||||
/* ok */
|
||||
if (box_normalise_block(child, c) == false)
|
||||
if (box_normalise_block(child, root, c) == false)
|
||||
return false;
|
||||
break;
|
||||
case BOX_FLOAT_LEFT:
|
||||
@ -961,12 +1003,12 @@ bool box_normalise_inline_container(struct box *cont, html_content * c)
|
||||
|
||||
switch (child->children->type) {
|
||||
case BOX_BLOCK:
|
||||
if (box_normalise_block(child->children,
|
||||
if (box_normalise_block(child->children, root,
|
||||
c) == false)
|
||||
return false;
|
||||
break;
|
||||
case BOX_TABLE:
|
||||
if (box_normalise_table(child->children,
|
||||
if (box_normalise_table(child->children, root,
|
||||
c) == false)
|
||||
return false;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user