CSS utils: Handle new units in length conversion routines.

This causes a ripple effect of all the callsites needing
information they didn't have.
This commit is contained in:
Michael Drake 2018-01-03 23:58:18 +00:00
parent a67973f312
commit 6be6fa1b21
24 changed files with 956 additions and 456 deletions

View File

@ -27,11 +27,75 @@
/** Screen DPI in fixed point units: defaults to 90, which RISC OS uses */
css_fixed nscss_screen_dpi = F_90;
/**
* Map viewport-relative length units to either vh or vw.
*
* Non-viewport-relative units are unchanged.
*
* \param[in] ctx Length conversion context.
* \param[in] unit Unit to map.
* \return the mapped unit.
*/
static inline css_unit css_utils__fudge_viewport_units(
const nscss_len_ctx *ctx,
css_unit unit)
{
switch (unit) {
case CSS_UNIT_VI:
assert(ctx->root_style != NULL);
if (css_computed_writing_mode(ctx->root_style) ==
CSS_WRITING_MODE_HORIZONTAL_TB) {
unit = CSS_UNIT_VW;
} else {
unit = CSS_UNIT_VH;
}
break;
case CSS_UNIT_VB:
assert(ctx->root_style != NULL);
if (css_computed_writing_mode(ctx->root_style) ==
CSS_WRITING_MODE_HORIZONTAL_TB) {
unit = CSS_UNIT_VH;
} else {
unit = CSS_UNIT_VW;
}
break;
case CSS_UNIT_VMIN:
if (ctx->vh < ctx->vw) {
unit = CSS_UNIT_VH;
} else {
unit = CSS_UNIT_VW;
}
break;
case CSS_UNIT_VMAX:
if (ctx->vh > ctx->vw) {
unit = CSS_UNIT_VH;
} else {
unit = CSS_UNIT_VW;
}
break;
default: break;
}
return unit;
}
/* exported interface documented in content/handlers/css/utils.h */
css_fixed nscss_len2pt(css_fixed length, css_unit unit)
css_fixed nscss_len2pt(
const nscss_len_ctx *ctx,
css_fixed length,
css_unit unit)
{
/* Length must not be relative */
assert(unit != CSS_UNIT_EM && unit != CSS_UNIT_EX);
assert(unit != CSS_UNIT_EM &&
unit != CSS_UNIT_EX &&
unit != CSS_UNIT_CAP &&
unit != CSS_UNIT_CH &&
unit != CSS_UNIT_IC &&
unit != CSS_UNIT_REM &&
unit != CSS_UNIT_RLH);
unit = css_utils__fudge_viewport_units(ctx, unit);
switch (unit) {
/* We assume the screen and any other output has the same dpi */
@ -45,36 +109,50 @@ css_fixed nscss_len2pt(css_fixed length, css_unit unit)
/* 1in = 25.4mm => 1mm = (72/25.4)pt */
case CSS_UNIT_MM: return FMUL(length,
FDIV(F_72, FLTTOFIX(25.4)));
/* 1in = 101.6q => 1mm = (72/101.6)pt */
case CSS_UNIT_Q: return FMUL(length,
FDIV(F_72, FLTTOFIX(101.6)));
case CSS_UNIT_PT: return length;
/* 1pc = 12pt */
case CSS_UNIT_PC: return FMUL(length, INTTOFIX(12));
case CSS_UNIT_VH: return FDIV(FMUL(FDIV((length * ctx->vh), F_100),
F_72), nscss_screen_dpi);
case CSS_UNIT_VW: return FDIV(FMUL(FDIV((length * ctx->vw), F_100),
F_72), nscss_screen_dpi);
default: break;
}
return 0;
}
/* exported interface documented in content/handlers/css/utils.h */
css_fixed nscss_len2px(css_fixed length, css_unit unit,
css_fixed nscss_len2px(
const nscss_len_ctx *ctx,
css_fixed length,
css_unit unit,
const css_computed_style *style)
{
/* We assume the screen and any other output has the same dpi */
css_fixed px_per_unit;
assert(style != NULL || (unit != CSS_UNIT_EM && unit != CSS_UNIT_EX));
unit = css_utils__fudge_viewport_units(ctx, unit);
switch (unit) {
case CSS_UNIT_EM:
case CSS_UNIT_EX:
case CSS_UNIT_CAP:
case CSS_UNIT_CH:
case CSS_UNIT_IC:
{
css_fixed font_size = 0;
css_unit font_unit = CSS_UNIT_PT;
assert(style != NULL);
css_computed_font_size(style, &font_size, &font_unit);
/* Convert to points */
font_size = nscss_len2pt(font_size, font_unit);
font_size = nscss_len2pt(ctx, font_size, font_unit);
/* Clamp to configured minimum */
if (font_size < FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10)) {
@ -85,9 +163,22 @@ css_fixed nscss_len2px(css_fixed length, css_unit unit,
* 1in = 72pt => 1pt = (DPI/72)px */
px_per_unit = FDIV(FMUL(font_size, nscss_screen_dpi), F_72);
/* Scale ex units: we use a fixed ratio of 1ex = 0.6em */
if (unit == CSS_UNIT_EX)
/* Scale non-em units to em. We have fixed ratios. */
switch (unit) {
case CSS_UNIT_EX:
px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.6));
break;
case CSS_UNIT_CAP:
px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.9));
break;
case CSS_UNIT_CH:
px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.4));
break;
case CSS_UNIT_IC:
px_per_unit = FMUL(px_per_unit, FLTTOFIX(1.1));
break;
default: break;
}
}
break;
case CSS_UNIT_PX:
@ -105,6 +196,10 @@ css_fixed nscss_len2px(css_fixed length, css_unit unit,
case CSS_UNIT_MM:
px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(25.4));
break;
/* 1in = 101.6q => 1q = (DPI/101.6)px */
case CSS_UNIT_Q:
px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(101.6));
break;
/* 1in = 72pt => 1pt = (DPI/72)px */
case CSS_UNIT_PT:
px_per_unit = FDIV(nscss_screen_dpi, F_72);
@ -113,6 +208,39 @@ css_fixed nscss_len2px(css_fixed length, css_unit unit,
case CSS_UNIT_PC:
px_per_unit = FDIV(nscss_screen_dpi, INTTOFIX(6));
break;
case CSS_UNIT_REM:
{
css_fixed font_size = 0;
css_unit font_unit = CSS_UNIT_PT;
assert(ctx->root_style != NULL);
css_computed_font_size(ctx->root_style,
&font_size, &font_unit);
/* Convert to points */
font_size = nscss_len2pt(ctx, font_size, font_unit);
/* Clamp to configured minimum */
if (font_size < FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10)) {
font_size = FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10);
}
/* Convert to pixels (manually, to maximise precision)
* 1in = 72pt => 1pt = (DPI/72)px */
px_per_unit = FDIV(FMUL(font_size, nscss_screen_dpi), F_72);
break;
}
/* 1rlh = <user_font_size>pt => 1rlh = (DPI/user_font_size)px */
case CSS_UNIT_RLH:
px_per_unit = FDIV(nscss_screen_dpi, FDIV(
INTTOFIX(nsoption_int(font_size)),
INTTOFIX(10)));
break;
case CSS_UNIT_VH:
return TRUNCATEFIX((FDIV((length * ctx->vh), F_100) + F_0_5));
case CSS_UNIT_VW:
return TRUNCATEFIX((FDIV((length * ctx->vw), F_100) + F_0_5));
default:
px_per_unit = 0;
break;

View File

@ -26,25 +26,55 @@
/** DPI of the screen, in fixed point units */
extern css_fixed nscss_screen_dpi;
/**
* Length conversion context data.
*/
typedef struct nscss_len_ctx {
/**
* Viewport width in px.
* Only used if unit is vh, vw, vi, vb, vmin, or vmax.
*/
int vw;
/**
* Viewport height in px.
* Only used if unit is vh, vw, vi, vb, vmin, or vmax.
*/
int vh;
/**
* Computed style for the document root element.
* May be NULL if unit is not rem, or rlh.
*/
const css_computed_style *root_style;
} nscss_len_ctx;
/**
* Convert an absolute CSS length to points.
*
* \param[in] length Absolute CSS length.
* \param[in] unit Unit of the length.
* \param[in] ctx Length conversion context.
* \param[in] length Absolute CSS length.
* \param[in] unit Unit of the length.
* \return length in points
*/
css_fixed nscss_len2pt(css_fixed length, css_unit unit);
css_fixed nscss_len2pt(
const nscss_len_ctx *ctx,
css_fixed length,
css_unit unit);
/**
* Convert a CSS length to pixels.
*
* \param length Length to convert
* \param unit Corresponding unit
* \param style Computed style applying to length. May be NULL if unit is
* neither em nor ex
* \param[in] ctx Length conversion context.
* \param[in] length Length to convert.
* \param[in] unit Corresponding unit.
* \param[in] style Computed style applying to length.
* May be NULL if unit is not em, ex, cap, ch, or ic.
* \return length in pixels
*/
css_fixed nscss_len2px(css_fixed length, css_unit unit, const css_computed_style *style);
css_fixed nscss_len2px(
const nscss_len_ctx *ctx,
css_fixed length,
css_unit unit,
const css_computed_style *style);
/**

View File

@ -257,6 +257,11 @@ struct print_settings *print_make_settings(print_configuration configuration,
struct print_settings *settings;
css_fixed length = 0;
css_unit unit = CSS_UNIT_MM;
nscss_len_ctx len_ctx = {
.vw = DEFAULT_PAGE_WIDTH,
.vh = DEFAULT_PAGE_HEIGHT,
.root_style = NULL,
};
switch (configuration){
case PRINT_DEFAULT:
@ -272,17 +277,17 @@ struct print_settings *print_make_settings(print_configuration configuration,
settings->scale = DEFAULT_EXPORT_SCALE;
length = INTTOFIX(DEFAULT_MARGIN_LEFT_MM);
settings->margins[MARGINLEFT] =
nscss_len2px(length, unit, NULL);
settings->margins[MARGINLEFT] = nscss_len2px(
&len_ctx, length, unit, NULL);
length = INTTOFIX(DEFAULT_MARGIN_RIGHT_MM);
settings->margins[MARGINRIGHT] =
nscss_len2px(length, unit, NULL);
settings->margins[MARGINRIGHT] = nscss_len2px(
&len_ctx, length, unit, NULL);
length = INTTOFIX(DEFAULT_MARGIN_TOP_MM);
settings->margins[MARGINTOP] =
nscss_len2px(length, unit, NULL);
settings->margins[MARGINTOP] = nscss_len2px(
&len_ctx, length, unit, NULL);
length = INTTOFIX(DEFAULT_MARGIN_BOTTOM_MM);
settings->margins[MARGINBOTTOM] =
nscss_len2px(length, unit, NULL);
settings->margins[MARGINBOTTOM] = nscss_len2px(
&len_ctx, length, unit, NULL);
break;
/* use settings from the Export options tab */
case PRINT_OPTIONS:
@ -298,17 +303,17 @@ struct print_settings *print_make_settings(print_configuration configuration,
settings->scale = (float)nsoption_int(export_scale) / 100;
length = INTTOFIX(nsoption_int(margin_left));
settings->margins[MARGINLEFT] =
nscss_len2px(length, unit, NULL);
settings->margins[MARGINLEFT] = nscss_len2px(
&len_ctx, length, unit, NULL);
length = INTTOFIX(nsoption_int(margin_right));
settings->margins[MARGINRIGHT] =
nscss_len2px(length, unit, NULL);
settings->margins[MARGINRIGHT] = nscss_len2px(
&len_ctx, length, unit, NULL);
length = INTTOFIX(nsoption_int(margin_top));
settings->margins[MARGINTOP] =
nscss_len2px(length, unit, NULL);
settings->margins[MARGINTOP] = nscss_len2px(
&len_ctx, length, unit, NULL);
length = INTTOFIX(nsoption_int(margin_bottom));
settings->margins[MARGINBOTTOM] =
nscss_len2px(length, unit, NULL);
settings->margins[MARGINBOTTOM] = nscss_len2px(
&len_ctx, length, unit, NULL);
break;
default:
return NULL;

View File

@ -70,18 +70,20 @@ struct selection_string {
typedef bool (*seln_traverse_handler)(const char *text, size_t length,
struct box *box, void *handle, const char *whitespace_text,
size_t whitespace_length);
struct box *box, const nscss_len_ctx *len_ctx, void *handle,
const char *whitespace_text, size_t whitespace_length);
static bool redraw_handler(const char *text, size_t length, struct box *box,
static bool redraw_handler(const char *text, size_t length,
struct box *box, const nscss_len_ctx *len_ctx,
void *handle, const char *whitespace_text,
size_t whitespace_length);
static void selection_redraw(struct selection *s, unsigned start_idx,
unsigned end_idx);
static bool selected_part(struct box *box, unsigned start_idx, unsigned end_idx,
unsigned *start_offset, unsigned *end_offset);
static bool traverse_tree(struct box *box, unsigned start_idx, unsigned end_idx,
static bool traverse_tree(struct box *box, const nscss_len_ctx *len_ctx,
unsigned start_idx, unsigned end_idx,
seln_traverse_handler handler,
void *handle, save_text_whitespace *before, bool *first,
bool do_marker);
@ -198,7 +200,10 @@ void selection_reinit(struct selection *s, struct box *root)
* \param root the root box for html document or NULL for text/plain
*/
void selection_init(struct selection *s, struct box *root)
void selection_init(
struct selection *s,
struct box *root,
const nscss_len_ctx *len_ctx)
{
if (s->defined)
selection_clear(s, true);
@ -207,6 +212,13 @@ void selection_init(struct selection *s, struct box *root)
s->start_idx = 0;
s->end_idx = 0;
s->drag_state = DRAG_NONE;
if (len_ctx != NULL) {
s->len_ctx = *len_ctx;
} else {
s->len_ctx.vw = 0;
s->len_ctx.vh = 0;
s->len_ctx.root_style = NULL;
}
selection_reinit(s, root);
}
@ -442,6 +454,7 @@ bool selected_part(struct box *box, unsigned start_idx, unsigned end_idx,
* for all boxes that lie (partially) within the given range
*
* \param box box subtree
* \param len_ctx Length conversion context.
* \param start_idx start of range within textual representation (bytes)
* \param end_idx end of range
* \param handler handler function to call
@ -452,7 +465,9 @@ bool selected_part(struct box *box, unsigned start_idx, unsigned end_idx,
* \return false iff traversal abandoned part-way through
*/
bool traverse_tree(struct box *box, unsigned start_idx, unsigned end_idx,
bool traverse_tree(
struct box *box, const nscss_len_ctx *len_ctx,
unsigned start_idx, unsigned end_idx,
seln_traverse_handler handler,
void *handle, save_text_whitespace *before, bool *first,
bool do_marker)
@ -473,9 +488,9 @@ bool traverse_tree(struct box *box, unsigned start_idx, unsigned end_idx,
if (box->list_marker) {
/* do the marker box before continuing with the rest of the
* list element */
if (!traverse_tree(box->list_marker, start_idx, end_idx,
handler, handle, before, first,
true))
if (!traverse_tree(box->list_marker, len_ctx,
start_idx, end_idx, handler, handle,
before, first, true))
return false;
}
@ -506,7 +521,7 @@ bool traverse_tree(struct box *box, unsigned start_idx, unsigned end_idx,
&end_offset)) {
if (!handler(box->text + start_offset, min(box->length,
end_offset) - start_offset,
box, handle, whitespace_text,
box, len_ctx, handle, whitespace_text,
whitespace_length))
return false;
if (before) {
@ -533,7 +548,7 @@ bool traverse_tree(struct box *box, unsigned start_idx, unsigned end_idx,
* the tree */
struct box *next = child->next;
if (!traverse_tree(child, start_idx, end_idx,
if (!traverse_tree(child, len_ctx, start_idx, end_idx,
handler, handle, before, first, false))
return false;
@ -568,14 +583,16 @@ static bool selection_traverse(struct selection *s,
if (s->root) {
/* HTML */
return traverse_tree(s->root, s->start_idx, s->end_idx,
handler, handle, &before, &first, false);
return traverse_tree(s->root, &s->len_ctx,
s->start_idx, s->end_idx,
handler, handle,
&before, &first, false);
}
/* Text */
text = textplain_get_raw_data(s->c, s->start_idx, s->end_idx, &length);
if (text && !handler(text, length, NULL, handle, NULL, 0))
if (text && !handler(text, length, NULL, NULL, handle, NULL, 0))
return false;
return true;
@ -597,8 +614,8 @@ static bool selection_traverse(struct selection *s,
*/
bool redraw_handler(const char *text, size_t length, struct box *box,
void *handle, const char *whitespace_text,
size_t whitespace_length)
const nscss_len_ctx *len_ctx, void *handle,
const char *whitespace_text, size_t whitespace_length)
{
if (box) {
struct rdw_info *r = (struct rdw_info*)handle;
@ -606,7 +623,7 @@ bool redraw_handler(const char *text, size_t length, struct box *box,
int x, y;
plot_font_style_t fstyle;
font_plot_style_from_css(box->style, &fstyle);
font_plot_style_from_css(len_ctx, box->style, &fstyle);
/* \todo - it should be possible to reduce the redrawn area by
* considering the 'text', 'length' and 'space' parameters */
@ -652,7 +669,7 @@ void selection_redraw(struct selection *s, unsigned start_idx, unsigned end_idx)
rdw.inited = false;
if (s->root) {
if (!traverse_tree(s->root, start_idx, end_idx,
if (!traverse_tree(s->root, &s->len_ctx, start_idx, end_idx,
redraw_handler, &rdw,
NULL, NULL, false))
return;
@ -739,10 +756,11 @@ static bool selection_string_append(const char *text, size_t length, bool space,
/**
* Selection traversal routine for appending text to a string
*
* \param text pointer to text being added, or NULL for newline
* \param length length of text to be appended (bytes)
* \param box pointer to text box, or NULL if from textplain
* \param handle selection string to append to
* \param text pointer to text being added, or NULL for newline
* \param length length of text to be appended (bytes)
* \param box pointer to text box, or NULL if from textplain
* \param len_ctx Length conversion context
* \param handle selection string to append to
* \param whitespace_text whitespace to place before text for formatting
* may be NULL
* \param whitespace_length length of whitespace_text
@ -750,7 +768,8 @@ static bool selection_string_append(const char *text, size_t length, bool space,
*/
static bool selection_copy_handler(const char *text, size_t length,
struct box *box, void *handle, const char *whitespace_text,
struct box *box, const nscss_len_ctx *len_ctx,
void *handle, const char *whitespace_text,
size_t whitespace_length)
{
bool add_space = false;
@ -771,7 +790,7 @@ static bool selection_copy_handler(const char *text, size_t length,
if (box->style != NULL) {
/* Override default font style */
font_plot_style_from_css(box->style, &style);
font_plot_style_from_css(len_ctx, box->style, &style);
pstyle = &style;
} else {
/* If there's no style, there must be no text */

View File

@ -25,6 +25,7 @@
#include <stdbool.h>
#include "netsurf/mouse.h"
#include "content/handlers/css/utils.h"
struct box;
@ -43,6 +44,7 @@ struct selection
{
struct content *c;
struct box *root;
nscss_len_ctx len_ctx;
unsigned max_idx; /* total bytes in text representation */
@ -60,7 +62,10 @@ struct selection *selection_create(struct content *c, bool is_html);
void selection_prepare(struct selection *s, struct content *c, bool is_html);
void selection_destroy(struct selection *s);
void selection_init(struct selection *s, struct box *root);
void selection_init(
struct selection *s,
struct box *root,
const nscss_len_ctx *len_ctx);
void selection_reinit(struct selection *s, struct box *root);
/* struct box *selection_root(struct selection *s); */

View File

@ -1803,6 +1803,10 @@ static void textarea_setup_text_offsets(struct textarea *ta)
{
int text_y_offset, text_y_offset_baseline;
ta->line_height = FIXTOINT(FMUL(FLTTOFIX(1.3), FDIV(FMUL(
nscss_screen_dpi, FDIV(INTTOFIX(ta->fstyle.size),
INTTOFIX(FONT_SIZE_SCALE))), F_72)));
text_y_offset = text_y_offset_baseline = ta->border_width;
if (ta->flags & TEXTAREA_MULTILINE) {
/* Multiline textarea */
@ -1822,6 +1826,27 @@ static void textarea_setup_text_offsets(struct textarea *ta)
}
/**
* Set font styles up for a textarea.
*
* \param[in] ta Textarea to update.
* \param[in] fstyle Font style to set in textarea.
* \param[in] selected_text Textarea selected text colour.
* \param[in] selected_bg Textarea selection background colour.
*/
static void textarea_set_text_style(
struct textarea *ta,
const plot_font_style_t *fstyle,
colour selected_text,
colour selected_bg)
{
ta->fstyle = *fstyle;
ta->sel_fstyle = *fstyle;
ta->sel_fstyle.foreground = selected_text;
ta->sel_fstyle.background = selected_bg;
}
/* exported interface, documented in textarea.h */
struct textarea *textarea_create(const textarea_flags flags,
@ -1861,11 +1886,10 @@ struct textarea *textarea_create(const textarea_flags flags,
ret->border_width = setup->border_width;
ret->border_col = setup->border_col;
ret->fstyle = setup->text;
ret->sel_fstyle = setup->text;
ret->sel_fstyle.foreground = setup->selected_text;
ret->sel_fstyle.background = setup->selected_bg;
textarea_set_text_style(ret,
&setup->text,
setup->selected_text,
setup->selected_bg);
ret->scroll_x = 0;
ret->scroll_y = 0;
@ -3220,8 +3244,12 @@ void textarea_set_dimensions(struct textarea *ta, int width, int height)
/* exported interface, documented in textarea.h */
void textarea_set_layout(struct textarea *ta, int width, int height,
int top, int right, int bottom, int left)
void textarea_set_layout(
struct textarea *ta,
const plot_font_style_t *fstyle,
int width, int height,
int top, int right,
int bottom, int left)
{
struct rect r = {0, 0, 0, 0};
@ -3232,6 +3260,10 @@ void textarea_set_layout(struct textarea *ta, int width, int height,
ta->pad_bottom = bottom + ((ta->bar_x == NULL) ? 0 : SCROLLBAR_WIDTH);
ta->pad_left = left;
textarea_set_text_style(ta, fstyle,
ta->sel_fstyle.foreground,
ta->sel_fstyle.background);
textarea_setup_text_offsets(ta);
if (ta->flags & TEXTAREA_MULTILINE) {

View File

@ -329,8 +329,12 @@ void textarea_set_dimensions(struct textarea *ta, int width, int height);
* \param bottom the new bottom padding of the textarea
* \param left the new left padding of the textarea
*/
void textarea_set_layout(struct textarea *ta, int width, int height,
int top, int right, int bottom, int left);
void textarea_set_layout(
struct textarea *ta,
const plot_font_style_t *fstyle,
int width, int height,
int top, int right,
int bottom, int left);
/**

View File

@ -342,20 +342,27 @@ void box_bounds(struct box *box, struct rect *r)
/**
* Determine if a point lies within a box.
*
* \param box box to consider
* \param x coordinate relative to box
* \param y coordinate relative to box
* \param physically if function returning true, physically is set true if
* point is within the box's physical dimensions and false
* if the point is not within the box's physical dimensions
* but is in the area defined by the box's descendants.
* if function returning false, physically is undefined.
* \param[in] len_ctx CSS length conversion context to use.
* \param[in] box Box to consider
* \param[in] x Coordinate relative to box
* \param[in] y Coordinate relative to box
* \param[out] physically If function returning true, physically is set true
* iff point is within the box's physical dimensions and
* false if the point is not within the box's physical
* dimensions but is in the area defined by the box's
* descendants. If function returns false, physically
* is undefined.
* \return true if the point is within the box or a descendant box
*
* This is a helper function for box_at_point().
*/
static bool box_contains_point(struct box *box, int x, int y, bool *physically)
static bool box_contains_point(
const nscss_len_ctx *len_ctx,
const struct box *box,
int x,
int y,
bool *physically)
{
css_computed_clip_rect css_rect;
@ -382,25 +389,25 @@ static bool box_contains_point(struct box *box, int x, int y, bool *physically)
/* Adjust rect to css clip region */
if (css_rect.left_auto == false) {
r.x0 += FIXTOINT(nscss_len2px(
r.x0 += FIXTOINT(nscss_len2px(len_ctx,
css_rect.left, css_rect.lunit,
box->style));
}
if (css_rect.top_auto == false) {
r.y0 += FIXTOINT(nscss_len2px(
r.y0 += FIXTOINT(nscss_len2px(len_ctx,
css_rect.top, css_rect.tunit,
box->style));
}
if (css_rect.right_auto == false) {
r.x1 = box->border[LEFT].width +
FIXTOINT(nscss_len2px(
FIXTOINT(nscss_len2px(len_ctx,
css_rect.right,
css_rect.runit,
box->style));
}
if (css_rect.bottom_auto == false) {
r.y1 = box->border[TOP].width +
FIXTOINT(nscss_len2px(
FIXTOINT(nscss_len2px(len_ctx,
css_rect.bottom,
css_rect.bunit,
box->style));
@ -659,6 +666,7 @@ skip_children:
/**
* Find the boxes at a point.
*
* \param len_ctx CSS length conversion context for document.
* \param box box to search children of
* \param x point to find, in global document coordinates
* \param y point to find, in global document coordinates
@ -674,13 +682,14 @@ skip_children:
* struct box *box = top_of_document_to_search;
* int box_x = 0, box_y = 0;
*
* while ((box = box_at_point(box, x, y, &box_x, &box_y))) {
* while ((box = box_at_point(len_ctx, box, x, y, &box_x, &box_y))) {
* // process box
* }
* \endcode
*/
struct box *box_at_point(struct box *box, const int x, const int y,
struct box *box_at_point(const nscss_len_ctx *len_ctx,
struct box *box, const int x, const int y,
int *box_x, int *box_y)
{
bool skip_children;
@ -690,7 +699,7 @@ struct box *box_at_point(struct box *box, const int x, const int y,
skip_children = false;
while ((box = box_next_xy(box, box_x, box_y, skip_children))) {
if (box_contains_point(box, x - *box_x, y - *box_y,
if (box_contains_point(len_ctx, box, x - *box_x, y - *box_y,
&physically)) {
*box_x -= scrollbar_get_offset(box->scroll_x);
*box_y -= scrollbar_get_offset(box->scroll_y);

View File

@ -91,6 +91,8 @@
#include <stdio.h>
#include <libcss/libcss.h>
#include "content/handlers/css/utils.h"
struct content;
struct box;
struct browser_window;
@ -328,7 +330,9 @@ void box_free(struct box *box);
void box_free_box(struct box *box);
void box_bounds(struct box *box, struct rect *r);
void box_coords(struct box *box, int *x, int *y);
struct box *box_at_point(struct box *box, const int x, const int y,
struct box *box_at_point(
const nscss_len_ctx *len_ctx,
struct box *box, const int x, const int y,
int *box_x, int *box_y);
struct box *box_pick_text_box(struct html_content *html,
int x, int y, int dir, int *dx, int *dy);

View File

@ -422,9 +422,6 @@ bool box_normalise_table(
free(col_info.spans);
if (table_calculate_column_types(table) == false)
return false;
#ifdef BOX_NORMALISE_DEBUG
NSLOG(netsurf, INFO, "table %p done", table);
#endif

View File

@ -239,7 +239,14 @@ bool box_textarea_create_textarea(html_content *html,
dom_exception err;
textarea_setup ta_setup;
textarea_flags ta_flags;
plot_font_style_t fstyle;
plot_font_style_t fstyle = {
.family = PLOT_FONT_FAMILY_SANS_SERIF,
.size = 10 * FONT_SIZE_SCALE,
.weight = 400,
.flags = FONTF_NONE,
.background = 0,
.foreground = 0,
};
bool read_only = false;
bool disabled = false;
struct form_control *gadget = box->gadget;
@ -307,8 +314,6 @@ bool box_textarea_create_textarea(html_content *html,
gadget->data.text.data.gadget = gadget;
font_plot_style_from_css(gadget->box->style, &fstyle);
/* Reset to correct values by layout */
ta_setup.width = 200;
ta_setup.height = 20;

View File

@ -131,8 +131,10 @@ static plot_font_flags_t plot_font_flags(enum css_font_style_e style,
}
/* exported function documented in render/font_internal.h */
void font_plot_style_from_css(const css_computed_style *css,
/* exported function documented in render/font.h */
void font_plot_style_from_css(
const nscss_len_ctx *len_ctx,
const css_computed_style *css,
plot_font_style_t *fstyle)
{
lwc_string **families;
@ -144,7 +146,7 @@ void font_plot_style_from_css(const css_computed_style *css,
css_computed_font_family(css, &families));
css_computed_font_size(css, &length, &unit);
fstyle->size = FIXTOINT(FMUL(nscss_len2pt(length, unit),
fstyle->size = FIXTOINT(FMUL(nscss_len2pt(len_ctx, length, unit),
INTTOFIX(FONT_SIZE_SCALE)));
/* Clamp font size to configured minimum */

View File

@ -32,10 +32,13 @@ struct plot_font_style;
/**
* Populate a font style using data from a computed CSS style
*
* \param css Computed style to consider
* \param fstyle Font style to populate
* \param len_ctx Length conversion context
* \param css Computed style to consider
* \param fstyle Font style to populate
*/
void font_plot_style_from_css(const css_computed_style *css,
struct plot_font_style *fstyle);
void font_plot_style_from_css(
const nscss_len_ctx *len_ctx,
const css_computed_style *css,
struct plot_font_style *fstyle);
#endif

View File

@ -1133,6 +1133,7 @@ bool form_open_select_menu(void *client_data,
plot_font_style_t fstyle;
int total_height;
struct form_select_menu *menu;
html_content *html = (html_content *)c;
/* if the menu is opened for the first time */
@ -1153,7 +1154,7 @@ bool form_open_select_menu(void *client_data,
box->border[LEFT].width +
box->padding[RIGHT] + box->padding[LEFT];
font_plot_style_from_css(control->box->style,
font_plot_style_from_css(&html->len_ctx, control->box->style,
&fstyle);
menu->f_size = fstyle.size;

View File

@ -1398,6 +1398,10 @@ static void html_reformat(struct content *c, int width, int height)
htmlc->reflowing = true;
htmlc->len_ctx.vw = width;
htmlc->len_ctx.vh = height;
htmlc->len_ctx.root_style = htmlc->layout->style;
layout_document(htmlc, width, height);
layout = htmlc->layout;
@ -1647,7 +1651,7 @@ html_open(struct content *c,
html->drag_owner.no_owner = true;
/* text selection */
selection_init(&html->sel, html->layout);
selection_init(&html->sel, html->layout, &html->len_ctx);
html->selection_type = HTML_SELECTION_NONE;
html->selection_owner.none = true;
@ -1768,7 +1772,8 @@ html_get_contextual_content(struct content *c, int x, int y,
struct box *next;
int box_x = 0, box_y = 0;
while ((next = box_at_point(box, x, y, &box_x, &box_y)) != NULL) {
while ((next = box_at_point(&html->len_ctx, box, x, y,
&box_x, &box_y)) != NULL) {
box = next;
/* hidden boxes are ignored */
@ -1845,7 +1850,8 @@ html_scroll_at_point(struct content *c, int x, int y, int scrx, int scry)
/* TODO: invert order; visit deepest box first */
while ((next = box_at_point(box, x, y, &box_x, &box_y)) != NULL) {
while ((next = box_at_point(&html->len_ctx, box, x, y,
&box_x, &box_y)) != NULL) {
box = next;
if (box->style && css_computed_visibility(box->style) ==
@ -1987,7 +1993,8 @@ static bool html_drop_file_at_point(struct content *c, int x, int y, char *file)
int box_x = 0, box_y = 0;
/* Scan box tree for boxes that can handle drop */
while ((next = box_at_point(box, x, y, &box_x, &box_y)) != NULL) {
while ((next = box_at_point(&html->len_ctx, box, x, y,
&box_x, &box_y)) != NULL) {
box = next;
if (box->style && css_computed_visibility(box->style) ==

View File

@ -208,7 +208,7 @@ static size_t html_selection_drag_end(struct html_content *html,
if (box) {
plot_font_style_t fstyle;
font_plot_style_from_css(box->style, &fstyle);
font_plot_style_from_css(&html->len_ctx, box->style, &fstyle);
guit->layout->position(&fstyle, box->text, box->length,
dx, &idx, &pixel_offset);
@ -415,7 +415,8 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
size_t idx;
plot_font_style_t fstyle;
font_plot_style_from_css(box->style, &fstyle);
font_plot_style_from_css(&html->len_ctx,
box->style, &fstyle);
guit->layout->position(&fstyle,
box->text, box->length,
@ -649,7 +650,8 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
text_box = box;
text_box_x = box_x;
}
} while ((box = box_at_point(box, x, y, &box_x, &box_y)) != NULL);
} while ((box = box_at_point(&html->len_ctx, box, x, y,
&box_x, &box_y)) != NULL);
/* use of box_x, box_y, or content below this point is probably a
* mistake; they will refer to the last box returned by box_at_point */
@ -910,8 +912,8 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
int pixel_offset;
size_t idx;
font_plot_style_from_css(text_box->style,
&fstyle);
font_plot_style_from_css(&html->len_ctx,
text_box->style, &fstyle);
guit->layout->position(&fstyle,
text_box->text,

View File

@ -26,6 +26,7 @@
#include <libcss/libcss.h>
#include "content/handlers/css/utils.h"
#include "content/content_protected.h"
#include "desktop/selection.h"
#include "render/html.h"
@ -94,6 +95,9 @@ typedef struct html_content {
/** Base target */
char *base_target;
/** CSS length conversion context for document. */
nscss_len_ctx len_ctx;
/** Content has been aborted in the LOADING state */
bool aborted;

View File

@ -227,7 +227,8 @@ html_object_callback(hlcache_handle *object,
if (hunit == CSS_UNIT_PCT) {
l = (width - w) * hpos / INTTOFIX(100);
} else {
l = FIXTOINT(nscss_len2px(hpos, hunit,
l = FIXTOINT(nscss_len2px(&c->len_ctx,
hpos, hunit,
box->style));
}
@ -235,7 +236,8 @@ html_object_callback(hlcache_handle *object,
if (vunit == CSS_UNIT_PCT) {
t = (height - h) * vpos / INTTOFIX(100);
} else {
t = FIXTOINT(nscss_len2px(vpos, vunit,
t = FIXTOINT(nscss_len2px(&c->len_ctx,
vpos, vunit,
box->style));
}

View File

@ -521,12 +521,14 @@ static bool html_redraw_radio(int x, int y, int width, int height,
* \param box box of input
* \param scale scale for redraw
* \param background_colour current background colour
* \param len_ctx Length conversion context
* \param ctx current redraw context
* \return true if successful, false otherwise
*/
static bool html_redraw_file(int x, int y, int width, int height,
struct box *box, float scale, colour background_colour,
const nscss_len_ctx *len_ctx,
const struct redraw_context *ctx)
{
int text_width;
@ -535,7 +537,7 @@ static bool html_redraw_file(int x, int y, int width, int height,
plot_font_style_t fstyle;
nserror res;
font_plot_style_from_css(box->style, &fstyle);
font_plot_style_from_css(len_ctx, box->style, &fstyle);
fstyle.background = background_colour;
if (box->gadget->value) {
@ -578,13 +580,16 @@ static bool html_redraw_file(int x, int y, int width, int height,
* \param clip current clip rectangle
* \param background_colour current background colour
* \param background box containing background details (usually \a box)
* \param ctx current redraw context
* \param len_ctx Length conversion context
* \param ctx current redraw context
* \return true if successful, false otherwise
*/
static bool html_redraw_background(int x, int y, struct box *box, float scale,
const struct rect *clip, colour *background_colour,
struct box *background, const struct redraw_context *ctx)
struct box *background,
const nscss_len_ctx *len_ctx,
const struct redraw_context *ctx)
{
bool repeat_x = false;
bool repeat_y = false;
@ -660,7 +665,7 @@ static bool html_redraw_background(int x, int y, struct box *box, float scale,
content_get_width(background->background)) *
scale * FIXTOFLT(hpos) / 100.;
} else {
x += (int) (FIXTOFLT(nscss_len2px(hpos, hunit,
x += (int) (FIXTOFLT(nscss_len2px(len_ctx, hpos, hunit,
background->style)) * scale);
}
@ -669,7 +674,7 @@ static bool html_redraw_background(int x, int y, struct box *box, float scale,
content_get_height(background->background)) *
scale * FIXTOFLT(vpos) / 100.;
} else {
y += (int) (FIXTOFLT(nscss_len2px(vpos, vunit,
y += (int) (FIXTOFLT(nscss_len2px(len_ctx, vpos, vunit,
background->style)) * scale);
}
}
@ -802,13 +807,15 @@ static bool html_redraw_background(int x, int y, struct box *box, float scale,
* \param first true if this is the first rectangle associated with the inline
* \param last true if this is the last rectangle associated with the inline
* \param background_colour updated to current background colour if plotted
* \param ctx current redraw context
* \param len_ctx Length conversion context
* \param ctx current redraw context
* \return true if successful, false otherwise
*/
static bool html_redraw_inline_background(int x, int y, struct box *box,
float scale, const struct rect *clip, struct rect b,
bool first, bool last, colour *background_colour,
const nscss_len_ctx *len_ctx,
const struct redraw_context *ctx)
{
struct rect r = *clip;
@ -869,7 +876,7 @@ static bool html_redraw_inline_background(int x, int y, struct box *box,
plot_content = false;
}
} else {
x += (int) (FIXTOFLT(nscss_len2px(hpos, hunit,
x += (int) (FIXTOFLT(nscss_len2px(len_ctx, hpos, hunit,
box->style)) * scale);
}
@ -878,7 +885,7 @@ static bool html_redraw_inline_background(int x, int y, struct box *box,
content_get_height(box->background) *
scale) * FIXTOFLT(vpos) / 100.;
} else {
y += (int) (FIXTOFLT(nscss_len2px(vpos, vunit,
y += (int) (FIXTOFLT(nscss_len2px(len_ctx, vpos, vunit,
box->style)) * scale);
}
}
@ -1120,7 +1127,7 @@ static bool html_redraw_text_box(const html_content *html, struct box *box,
bool excluded = (box->object != NULL);
plot_font_style_t fstyle;
font_plot_style_from_css(box->style, &fstyle);
font_plot_style_from_css(&html->len_ctx, box->style, &fstyle);
fstyle.background = current_background_color;
if (!text_redraw(box->text, box->length, box->byte_offset,
@ -1382,21 +1389,25 @@ bool html_redraw_box(const html_content *html, struct box *box,
/* We have an absolutly positioned box with a clip rect */
if (css_rect.left_auto == false)
r.x0 = x - border_left + FIXTOINT(nscss_len2px(
&html->len_ctx,
css_rect.left, css_rect.lunit,
box->style));
if (css_rect.top_auto == false)
r.y0 = y - border_top + FIXTOINT(nscss_len2px(
&html->len_ctx,
css_rect.top, css_rect.tunit,
box->style));
if (css_rect.right_auto == false)
r.x1 = x - border_left + FIXTOINT(nscss_len2px(
&html->len_ctx,
css_rect.right, css_rect.runit,
box->style));
if (css_rect.bottom_auto == false)
r.y1 = y - border_top + FIXTOINT(nscss_len2px(
&html->len_ctx,
css_rect.bottom, css_rect.bunit,
box->style));
@ -1486,7 +1497,8 @@ bool html_redraw_box(const html_content *html, struct box *box,
if ((p.x0 < p.x1) && (p.y0 < p.y1)) {
/* plot background */
if (!html_redraw_background(x, y, box, scale, &p,
&current_background_color, bg_box, ctx))
&current_background_color, bg_box,
&html->len_ctx, ctx))
return false;
/* restore previous graphics window */
if (ctx->plot->clip(ctx, &r) != NSERROR_OK)
@ -1565,7 +1577,8 @@ bool html_redraw_box(const html_content *html, struct box *box,
if (!html_redraw_inline_background(
x, y, box, scale, &p, b,
first, false,
&current_background_color, ctx))
&current_background_color,
&html->len_ctx, ctx))
return false;
/* restore previous graphics window */
if (ctx->plot->clip(ctx, &r) != NSERROR_OK)
@ -1597,7 +1610,8 @@ bool html_redraw_box(const html_content *html, struct box *box,
/* plot background and borders for last rectangle of
* the inline */
if (!html_redraw_inline_background(x, ib_y, box, scale, &p, b,
first, true, &current_background_color, ctx))
first, true, &current_background_color,
&html->len_ctx, ctx))
return false;
/* restore previous graphics window */
if (ctx->plot->clip(ctx, &r) != NSERROR_OK)
@ -1768,7 +1782,6 @@ bool html_redraw_box(const html_content *html, struct box *box,
obj, sizeof(obj) - 1) != NSERROR_OK)
return false;
}
} else if (box->iframe) {
/* Offset is passed to browser window redraw unscaled */
@ -1789,7 +1802,7 @@ bool html_redraw_box(const html_content *html, struct box *box,
} else if (box->gadget && box->gadget->type == GADGET_FILE) {
if (!html_redraw_file(x + padding_left, y + padding_top,
width, height, box, scale,
current_background_color, ctx))
current_background_color, &html->len_ctx, ctx))
return false;
} else if (box->gadget &&

File diff suppressed because it is too large Load Diff

View File

@ -621,13 +621,14 @@ void search_show_all(bool all, struct search_context *context)
if (!a->sel)
continue;
selection_init(a->sel, html->layout);
selection_init(a->sel, html->layout,
&html->len_ctx);
} else {
a->sel = selection_create(context->c, false);
if (!a->sel)
continue;
selection_init(a->sel, NULL);
selection_init(a->sel, NULL, NULL);
}
selection_set_start(a->sel, a->start_idx);

View File

@ -45,31 +45,57 @@ struct border {
css_unit unit; /**< border-width units */
};
static void table_used_left_border_for_cell(struct box *cell);
static void table_used_top_border_for_cell(struct box *cell);
static void table_used_right_border_for_cell(struct box *cell);
static void table_used_bottom_border_for_cell(struct box *cell);
static bool table_border_is_more_eyecatching(const struct border *a,
box_type a_src, const struct border *b, box_type b_src);
static void table_cell_top_process_table(struct box *table, struct border *a,
static void table_used_left_border_for_cell(
const nscss_len_ctx *len_ctx,
struct box *cell);
static void table_used_top_border_for_cell(
const nscss_len_ctx *len_ctx,
struct box *cell);
static void table_used_right_border_for_cell(
const nscss_len_ctx *len_ctx,
struct box *cell);
static void table_used_bottom_border_for_cell(
const nscss_len_ctx *len_ctx,
struct box *cell);
static bool table_border_is_more_eyecatching(
const nscss_len_ctx *len_ctx,
const struct border *a,
box_type a_src,
const struct border *b,
box_type b_src);
static void table_cell_top_process_table(
const nscss_len_ctx *len_ctx,
struct box *table,
struct border *a,
box_type *a_src);
static bool table_cell_top_process_group(
const nscss_len_ctx *len_ctx,
struct box *cell,
struct box *group,
struct border *a,
box_type *a_src);
static bool table_cell_top_process_row(
const nscss_len_ctx *len_ctx,
struct box *cell,
struct box *row,
struct border *a,
box_type *a_src);
static bool table_cell_top_process_group(struct box *cell, struct box *group,
struct border *a, box_type *a_src);
static bool table_cell_top_process_row(struct box *cell, struct box *row,
struct border *a, box_type *a_src);
/**
* Determine the column width types for a table.
*
* \param table box of type BOX_TABLE
* \param len_ctx Length conversion context
* \param table box of type BOX_TABLE
* \return true on success, false on memory exhaustion
*
* The table->col array is allocated and type and width are filled in for each
* column.
*/
bool table_calculate_column_types(struct box *table)
bool table_calculate_column_types(
const nscss_len_ctx *len_ctx,
struct box *table)
{
unsigned int i, j;
struct column *col;
@ -109,7 +135,7 @@ bool table_calculate_column_types(struct box *table)
css_computed_position(cell->style) !=
CSS_POSITION_FIXED) {
col[i].positioned = false;
}
}
type = css_computed_width(cell->style, &value, &unit);
@ -117,8 +143,8 @@ bool table_calculate_column_types(struct box *table)
if (col[i].type != COLUMN_WIDTH_FIXED &&
type == CSS_WIDTH_SET && unit != CSS_UNIT_PCT) {
col[i].type = COLUMN_WIDTH_FIXED;
col[i].width = FIXTOINT(nscss_len2px(value, unit,
cell->style));
col[i].width = FIXTOINT(nscss_len2px(len_ctx,
value, unit, cell->style));
if (col[i].width < 0)
col[i].width = 0;
continue;
@ -181,7 +207,7 @@ bool table_calculate_column_types(struct box *table)
if (type == CSS_WIDTH_SET && unit != CSS_UNIT_PCT &&
fixed_columns + unknown_columns ==
cell->columns) {
int width = (FIXTOFLT(nscss_len2px(value, unit,
int width = (FIXTOFLT(nscss_len2px(len_ctx, value, unit,
cell->style)) - fixed_width) /
unknown_columns;
if (width < 0)
@ -235,11 +261,14 @@ bool table_calculate_column_types(struct box *table)
/**
* Calculate used values of border-{trbl}-{style,color,width} for table cells.
*
* \param cell Table cell to consider
* \param len_ctx Length conversion context
* \param cell Table cell to consider
*
* \post \a cell's border array is populated
*/
void table_used_border_for_cell(struct box *cell)
void table_used_border_for_cell(
const nscss_len_ctx *len_ctx,
struct box *cell)
{
int side;
@ -257,7 +286,8 @@ void table_used_border_for_cell(struct box *cell)
&cell->border[LEFT].c);
css_computed_border_left_width(cell->style, &width, &unit);
cell->border[LEFT].width =
FIXTOINT(nscss_len2px(width, unit, cell->style));
FIXTOINT(nscss_len2px(len_ctx,
width, unit, cell->style));
/* Top border */
cell->border[TOP].style =
@ -266,7 +296,8 @@ void table_used_border_for_cell(struct box *cell)
&cell->border[TOP].c);
css_computed_border_top_width(cell->style, &width, &unit);
cell->border[TOP].width =
FIXTOINT(nscss_len2px(width, unit, cell->style));
FIXTOINT(nscss_len2px(len_ctx,
width, unit, cell->style));
/* Right border */
cell->border[RIGHT].style =
@ -275,7 +306,8 @@ void table_used_border_for_cell(struct box *cell)
&cell->border[RIGHT].c);
css_computed_border_right_width(cell->style, &width, &unit);
cell->border[RIGHT].width =
FIXTOINT(nscss_len2px(width, unit, cell->style));
FIXTOINT(nscss_len2px(len_ctx,
width, unit, cell->style));
/* Bottom border */
cell->border[BOTTOM].style =
@ -284,19 +316,20 @@ void table_used_border_for_cell(struct box *cell)
&cell->border[BOTTOM].c);
css_computed_border_bottom_width(cell->style, &width, &unit);
cell->border[BOTTOM].width =
FIXTOINT(nscss_len2px(width, unit, cell->style));
FIXTOINT(nscss_len2px(len_ctx,
width, unit, cell->style));
} else {
/* Left border */
table_used_left_border_for_cell(cell);
table_used_left_border_for_cell(len_ctx, cell);
/* Top border */
table_used_top_border_for_cell(cell);
table_used_top_border_for_cell(len_ctx, cell);
/* Right border */
table_used_right_border_for_cell(cell);
table_used_right_border_for_cell(len_ctx, cell);
/* Bottom border */
table_used_bottom_border_for_cell(cell);
table_used_bottom_border_for_cell(len_ctx, cell);
}
/* Finally, ensure that any borders configured as
@ -316,9 +349,12 @@ void table_used_border_for_cell(struct box *cell)
/**
* Calculate used values of border-left-{style,color,width}
*
* \param cell Table cell to consider
* \param len_ctx Length conversion context
* \param cell Table cell to consider
*/
void table_used_left_border_for_cell(struct box *cell)
void table_used_left_border_for_cell(
const nscss_len_ctx *len_ctx,
struct box *cell)
{
struct border a, b;
box_type a_src, b_src;
@ -329,7 +365,7 @@ void table_used_left_border_for_cell(struct box *cell)
a.style = css_computed_border_left_style(cell->style);
a.color = css_computed_border_left_color(cell->style, &a.c);
css_computed_border_left_width(cell->style, &a.width, &a.unit);
a.width = nscss_len2px(a.width, a.unit, cell->style);
a.width = nscss_len2px(len_ctx, a.width, a.unit, cell->style);
a.unit = CSS_UNIT_PX;
a_src = BOX_TABLE_CELL;
@ -362,11 +398,12 @@ void table_used_left_border_for_cell(struct box *cell)
b.style = css_computed_border_right_style(prev->style);
b.color = css_computed_border_right_color(prev->style, &b.c);
css_computed_border_right_width(prev->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, prev->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, prev->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_CELL;
if (table_border_is_more_eyecatching(&a, a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
&a, a_src, &b, b_src)) {
a = b;
a_src = b_src;
}
@ -384,12 +421,13 @@ void table_used_left_border_for_cell(struct box *cell)
row->style, &b.c);
css_computed_border_left_width(
row->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, row->style);
b.width = nscss_len2px(len_ctx,
b.width, b.unit, row->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_ROW;
if (table_border_is_more_eyecatching(&a, a_src,
&b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
&a, a_src, &b, b_src)) {
a = b;
a_src = b_src;
}
@ -403,11 +441,12 @@ void table_used_left_border_for_cell(struct box *cell)
b.style = css_computed_border_left_style(group->style);
b.color = css_computed_border_left_color(group->style, &b.c);
css_computed_border_left_width(group->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, group->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, group->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_ROW_GROUP;
if (table_border_is_more_eyecatching(&a, a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
&a, a_src, &b, b_src)) {
a = b;
a_src = b_src;
}
@ -416,11 +455,12 @@ void table_used_left_border_for_cell(struct box *cell)
b.style = css_computed_border_left_style(table->style);
b.color = css_computed_border_left_color(table->style, &b.c);
css_computed_border_left_width(table->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, table->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, table->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE;
if (table_border_is_more_eyecatching(&a, a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
&a, a_src, &b, b_src)) {
a = b;
a_src = b_src;
}
@ -429,16 +469,19 @@ void table_used_left_border_for_cell(struct box *cell)
/* a now contains the used left border for the cell */
cell->border[LEFT].style = a.style;
cell->border[LEFT].c = a.c;
cell->border[LEFT].width =
FIXTOINT(nscss_len2px(a.width, a.unit, cell->style));
cell->border[LEFT].width = FIXTOINT(nscss_len2px(len_ctx,
a.width, a.unit, cell->style));
}
/**
* Calculate used values of border-top-{style,color,width}
*
* \param cell Table cell to consider
* \param len_ctx Length conversion context
* \param cell Table cell to consider
*/
void table_used_top_border_for_cell(struct box *cell)
void table_used_top_border_for_cell(
const nscss_len_ctx *len_ctx,
struct box *cell)
{
struct border a, b;
box_type a_src, b_src;
@ -449,7 +492,7 @@ void table_used_top_border_for_cell(struct box *cell)
a.style = css_computed_border_top_style(cell->style);
css_computed_border_top_color(cell->style, &a.c);
css_computed_border_top_width(cell->style, &a.width, &a.unit);
a.width = nscss_len2px(a.width, a.unit, cell->style);
a.width = nscss_len2px(len_ctx, a.width, a.unit, cell->style);
a.unit = CSS_UNIT_PX;
a_src = BOX_TABLE_CELL;
@ -457,18 +500,18 @@ void table_used_top_border_for_cell(struct box *cell)
b.style = css_computed_border_top_style(row->style);
css_computed_border_top_color(row->style, &b.c);
css_computed_border_top_width(row->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, row->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, row->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_ROW;
if (table_border_is_more_eyecatching(&a, a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx, &a, a_src, &b, b_src)) {
a = b;
a_src = b_src;
}
if (row->prev != NULL) {
/* Consider row(s) above */
while (table_cell_top_process_row(cell, row->prev,
while (table_cell_top_process_row(len_ctx, cell, row->prev,
&a, &a_src) == false) {
if (row->prev->prev == NULL) {
/* Consider row group */
@ -489,26 +532,29 @@ void table_used_top_border_for_cell(struct box *cell)
b.style = css_computed_border_top_style(group->style);
b.color = css_computed_border_top_color(group->style, &b.c);
css_computed_border_top_width(group->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, group->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, group->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_ROW_GROUP;
if (table_border_is_more_eyecatching(&a, a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
&a, a_src, &b, b_src)) {
a = b;
a_src = b_src;
}
if (group->prev == NULL) {
/* Top border of table */
table_cell_top_process_table(group->parent, &a, &a_src);
table_cell_top_process_table(len_ctx,
group->parent, &a, &a_src);
} else {
/* Process previous group(s) */
while (table_cell_top_process_group(cell, group->prev,
while (table_cell_top_process_group(len_ctx,
cell, group->prev,
&a, &a_src) == false) {
if (group->prev->prev == NULL) {
/* Top border of table */
table_cell_top_process_table(
group->parent,
table_cell_top_process_table(len_ctx,
group->parent,
&a, &a_src);
break;
} else {
@ -521,16 +567,19 @@ void table_used_top_border_for_cell(struct box *cell)
/* a now contains the used top border for the cell */
cell->border[TOP].style = a.style;
cell->border[TOP].c = a.c;
cell->border[TOP].width =
FIXTOINT(nscss_len2px(a.width, a.unit, cell->style));
cell->border[TOP].width = FIXTOINT(nscss_len2px(len_ctx,
a.width, a.unit, cell->style));
}
/**
* Calculate used values of border-right-{style,color,width}
*
* \param cell Table cell to consider
* \param len_ctx Length conversion context
* \param cell Table cell to consider
*/
void table_used_right_border_for_cell(struct box *cell)
void table_used_right_border_for_cell(
const nscss_len_ctx *len_ctx,
struct box *cell)
{
struct border a, b;
box_type a_src, b_src;
@ -541,7 +590,7 @@ void table_used_right_border_for_cell(struct box *cell)
a.style = css_computed_border_right_style(cell->style);
css_computed_border_right_color(cell->style, &a.c);
css_computed_border_right_width(cell->style, &a.width, &a.unit);
a.width = nscss_len2px(a.width, a.unit, cell->style);
a.width = nscss_len2px(len_ctx, a.width, a.unit, cell->style);
a.unit = CSS_UNIT_PX;
a_src = BOX_TABLE_CELL;
@ -565,12 +614,13 @@ void table_used_right_border_for_cell(struct box *cell)
row->style, &b.c);
css_computed_border_right_width(
row->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, row->style);
b.width = nscss_len2px(len_ctx,
b.width, b.unit, row->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_ROW;
if (table_border_is_more_eyecatching(&a, a_src,
&b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
&a, a_src, &b, b_src)) {
a = b;
a_src = b_src;
}
@ -583,13 +633,14 @@ void table_used_right_border_for_cell(struct box *cell)
/* Row group -- consider its right border */
b.style = css_computed_border_right_style(group->style);
b.color = css_computed_border_right_color(group->style, &b.c);
css_computed_border_right_width(group->style,
css_computed_border_right_width(group->style,
&b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, group->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, group->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_ROW_GROUP;
if (table_border_is_more_eyecatching(&a, a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
&a, a_src, &b, b_src)) {
a = b;
a_src = b_src;
}
@ -599,11 +650,12 @@ void table_used_right_border_for_cell(struct box *cell)
b.color = css_computed_border_right_color(table->style, &b.c);
css_computed_border_right_width(table->style,
&b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, table->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, table->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE;
if (table_border_is_more_eyecatching(&a, a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
&a, a_src, &b, b_src)) {
a = b;
a_src = b_src;
}
@ -612,16 +664,19 @@ void table_used_right_border_for_cell(struct box *cell)
/* a now contains the used right border for the cell */
cell->border[RIGHT].style = a.style;
cell->border[RIGHT].c = a.c;
cell->border[RIGHT].width =
FIXTOINT(nscss_len2px(a.width, a.unit, cell->style));
cell->border[RIGHT].width = FIXTOINT(nscss_len2px(len_ctx,
a.width, a.unit, cell->style));
}
/**
* Calculate used values of border-bottom-{style,color,width}
*
* \param cell Table cell to consider
* \param len_ctx Length conversion context
* \param cell Table cell to consider
*/
void table_used_bottom_border_for_cell(struct box *cell)
void table_used_bottom_border_for_cell(
const nscss_len_ctx *len_ctx,
struct box *cell)
{
struct border a, b;
box_type a_src, b_src;
@ -632,7 +687,7 @@ void table_used_bottom_border_for_cell(struct box *cell)
a.style = css_computed_border_bottom_style(cell->style);
css_computed_border_bottom_color(cell->style, &a.c);
css_computed_border_bottom_width(cell->style, &a.width, &a.unit);
a.width = nscss_len2px(a.width, a.unit, cell->style);
a.width = nscss_len2px(len_ctx, a.width, a.unit, cell->style);
a.unit = CSS_UNIT_PX;
a_src = BOX_TABLE_CELL;
@ -656,11 +711,12 @@ void table_used_bottom_border_for_cell(struct box *cell)
b.style = css_computed_border_bottom_style(row->style);
b.color = css_computed_border_bottom_color(row->style, &b.c);
css_computed_border_bottom_width(row->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, row->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, row->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_ROW;
if (table_border_is_more_eyecatching(&a, a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
&a, a_src, &b, b_src)) {
a = b;
a_src = b_src;
}
@ -670,11 +726,12 @@ void table_used_bottom_border_for_cell(struct box *cell)
b.color = css_computed_border_bottom_color(group->style, &b.c);
css_computed_border_bottom_width(group->style,
&b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, group->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, group->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_ROW_GROUP;
if (table_border_is_more_eyecatching(&a, a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
&a, a_src, &b, b_src)) {
a = b;
a_src = b_src;
}
@ -684,11 +741,12 @@ void table_used_bottom_border_for_cell(struct box *cell)
b.color = css_computed_border_bottom_color(table->style, &b.c);
css_computed_border_bottom_width(table->style,
&b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, table->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, table->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE;
if (table_border_is_more_eyecatching(&a, a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
&a, a_src, &b, b_src)) {
a = b;
}
}
@ -696,21 +754,26 @@ void table_used_bottom_border_for_cell(struct box *cell)
/* a now contains the used bottom border for the cell */
cell->border[BOTTOM].style = a.style;
cell->border[BOTTOM].c = a.c;
cell->border[BOTTOM].width =
FIXTOINT(nscss_len2px(a.width, a.unit, cell->style));
cell->border[BOTTOM].width = FIXTOINT(nscss_len2px(len_ctx,
a.width, a.unit, cell->style));
}
/**
* Determine if a border style is more eyecatching than another
*
* \param a Reference border style
* \param a_src Source of \a a
* \param b Candidate border style
* \param b_src Source of \a b
* \param len_ctx Length conversion context
* \param a Reference border style
* \param a_src Source of \a a
* \param b Candidate border style
* \param b_src Source of \a b
* \return True if \a b is more eyecatching than \a a
*/
bool table_border_is_more_eyecatching(const struct border *a,
box_type a_src, const struct border *b, box_type b_src)
bool table_border_is_more_eyecatching(
const nscss_len_ctx *len_ctx,
const struct border *a,
box_type a_src,
const struct border *b,
box_type b_src)
{
css_fixed awidth, bwidth;
int impact = 0;
@ -731,8 +794,8 @@ bool table_border_is_more_eyecatching(const struct border *a,
* if they've come from a computed style. */
assert(a->unit != CSS_UNIT_EM && a->unit != CSS_UNIT_EX);
assert(b->unit != CSS_UNIT_EM && b->unit != CSS_UNIT_EX);
awidth = nscss_len2px(a->width, a->unit, NULL);
bwidth = nscss_len2px(b->width, b->unit, NULL);
awidth = nscss_len2px(len_ctx, a->width, a->unit, NULL);
bwidth = nscss_len2px(len_ctx, b->width, b->unit, NULL);
if (awidth < bwidth)
return true;
@ -811,14 +874,18 @@ bool table_border_is_more_eyecatching(const struct border *a,
/**
* Process a table
*
* \param table Table to process
* \param a Current border style for cell
* \param a_src Source of \a a
* \param len_ctx Length conversion context
* \param table Table to process
* \param a Current border style for cell
* \param a_src Source of \a a
*
* \post \a a will be updated with most eyecatching style
* \post \a a_src will be updated also
*/
void table_cell_top_process_table(struct box *table, struct border *a,
void table_cell_top_process_table(
const nscss_len_ctx *len_ctx,
struct box *table,
struct border *a,
box_type *a_src)
{
struct border b;
@ -828,11 +895,11 @@ void table_cell_top_process_table(struct box *table, struct border *a,
b.style = css_computed_border_top_style(table->style);
b.color = css_computed_border_top_color(table->style, &b.c);
css_computed_border_top_width(table->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, table->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, table->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE;
if (table_border_is_more_eyecatching(a, *a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx, a, *a_src, &b, b_src)) {
*a = b;
*a_src = b_src;
}
@ -841,17 +908,22 @@ void table_cell_top_process_table(struct box *table, struct border *a,
/**
* Process a group
*
* \param cell Cell being considered
* \param group Group to process
* \param a Current border style for cell
* \param a_src Source of \a a
* \param len_ctx Length conversion context
* \param cell Cell being considered
* \param group Group to process
* \param a Current border style for cell
* \param a_src Source of \a a
* \return true if group has non-empty rows, false otherwise
*
* \post \a a will be updated with most eyecatching style
* \post \a a_src will be updated also
*/
bool table_cell_top_process_group(struct box *cell, struct box *group,
struct border *a, box_type *a_src)
bool table_cell_top_process_group(
const nscss_len_ctx *len_ctx,
struct box *cell,
struct box *group,
struct border *a,
box_type *a_src)
{
struct border b;
box_type b_src;
@ -860,11 +932,11 @@ bool table_cell_top_process_group(struct box *cell, struct box *group,
b.style = css_computed_border_bottom_style(group->style);
b.color = css_computed_border_bottom_color(group->style, &b.c);
css_computed_border_bottom_width(group->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, group->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, group->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_ROW_GROUP;
if (table_border_is_more_eyecatching(a, *a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx, a, *a_src, &b, b_src)) {
*a = b;
*a_src = b_src;
}
@ -873,7 +945,7 @@ bool table_cell_top_process_group(struct box *cell, struct box *group,
/* Process rows in group, starting with last */
struct box *row = group->last;
while (table_cell_top_process_row(cell, row,
while (table_cell_top_process_row(len_ctx, cell, row,
a, a_src) == false) {
if (row->prev == NULL) {
return false;
@ -886,11 +958,12 @@ bool table_cell_top_process_group(struct box *cell, struct box *group,
b.style = css_computed_border_top_style(group->style);
b.color = css_computed_border_top_color(group->style, &b.c);
css_computed_border_top_width(group->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, group->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, group->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_ROW_GROUP;
if (table_border_is_more_eyecatching(a, *a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
a, *a_src, &b, b_src)) {
*a = b;
*a_src = b_src;
}
@ -904,17 +977,22 @@ bool table_cell_top_process_group(struct box *cell, struct box *group,
/**
* Process a row
*
* \param cell Cell being considered
* \param row Row to process
* \param a Current border style for cell
* \param a_src Source of \a a
* \param len_ctx Length conversion context
* \param cell Cell being considered
* \param row Row to process
* \param a Current border style for cell
* \param a_src Source of \a a
* \return true if row has cells, false otherwise
*
* \post \a a will be updated with most eyecatching style
* \post \a a_src will be updated also
*/
bool table_cell_top_process_row(struct box *cell, struct box *row,
struct border *a, box_type *a_src)
bool table_cell_top_process_row(
const nscss_len_ctx *len_ctx,
struct box *cell,
struct box *row,
struct border *a,
box_type *a_src)
{
struct border b;
box_type b_src;
@ -923,11 +1001,11 @@ bool table_cell_top_process_row(struct box *cell, struct box *row,
b.style = css_computed_border_bottom_style(row->style);
b.color = css_computed_border_bottom_color(row->style, &b.c);
css_computed_border_bottom_width(row->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, row->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, row->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_ROW;
if (table_border_is_more_eyecatching(a, *a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx, a, *a_src, &b, b_src)) {
*a = b;
*a_src = b_src;
}
@ -937,11 +1015,12 @@ bool table_cell_top_process_row(struct box *cell, struct box *row,
b.style = css_computed_border_top_style(row->style);
b.color = css_computed_border_top_color(row->style, &b.c);
css_computed_border_top_width(row->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, row->style);
b.width = nscss_len2px(len_ctx, b.width, b.unit, row->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_ROW;
if (table_border_is_more_eyecatching(a, *a_src, &b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
a, *a_src, &b, b_src)) {
*a = b;
*a_src = b_src;
}
@ -975,13 +1054,13 @@ bool table_cell_top_process_row(struct box *cell, struct box *row,
c->style, &b.c);
css_computed_border_bottom_width(c->style,
&b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit,
c->style);
b.width = nscss_len2px(len_ctx,
b.width, b.unit, c->style);
b.unit = CSS_UNIT_PX;
b_src = BOX_TABLE_CELL;
if (table_border_is_more_eyecatching(a, *a_src,
&b, b_src)) {
if (table_border_is_more_eyecatching(len_ctx,
a, *a_src, &b, b_src)) {
*a = b;
*a_src = b_src;
}

View File

@ -28,7 +28,11 @@
struct box;
bool table_calculate_column_types(struct box *table);
void table_used_border_for_cell(struct box *cell);
bool table_calculate_column_types(
const nscss_len_ctx *len_ctx,
struct box *table);
void table_used_border_for_cell(
const nscss_len_ctx *len_ctx,
struct box *cell);
#endif

View File

@ -988,7 +988,7 @@ textplain_open(struct content *c,
text->bw = bw;
/* text selection */
selection_init(&text->sel, NULL);
selection_init(&text->sel, NULL, NULL);
}