From 7bd1fb50c6415a21fae22f7bd534894e02b512bf Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Mon, 1 Jan 2018 13:51:40 +0000 Subject: Utils: Filename: Squash warning: -Wformat-truncation= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to check the snprintf return value, or GCC7 whinges: warning: ‘snprintf’ output may be truncated before the last format character [-Wformat-truncation=] --- utils/filename.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/utils/filename.c b/utils/filename.c index 01a403fd9..f0e1bb0f5 100644 --- a/utils/filename.c +++ b/utils/filename.c @@ -272,15 +272,19 @@ bool filename_flush_directory(const char *folder, int depth) parent = opendir(folder); while ((entry = readdir(parent))) { - struct stat statbuf; + int written; + struct stat statbuf; /* Ignore '.' and '..' */ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; - snprintf(child, sizeof(child), "%s/%s", folder, entry->d_name); - child[sizeof(child) - 1] = '\0'; + written = snprintf(child, sizeof(child), "%s/%s", + folder, entry->d_name); + if (written == sizeof(child)) { + child[sizeof(child) - 1] = '\0'; + } if (stat(child, &statbuf) == -1) { NSLOG(netsurf, INFO, "Unable to stat %s: %s", child, @@ -383,16 +387,21 @@ bool filename_delete_recursive(char *folder) parent = opendir(folder); while ((entry = readdir(parent))) { + int written; + /* Ignore '.' and '..' */ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; - snprintf(child, sizeof(child), "%s/%s", folder, entry->d_name); - child[sizeof(child) - 1] = '\0'; + written = snprintf(child, sizeof(child), "%s/%s", + folder, entry->d_name); + if (written == sizeof(child)) { + child[sizeof(child) - 1] = '\0'; + } if (stat(child, &statbuf) == -1) { - NSLOG(netsurf, INFO, "Unable to stat %s: %s", child, + NSLOG(netsurf, INFO, "Unable to stat %s: %s", child, strerror(errno)); continue; } -- cgit v1.2.3 From d1c656b55f7c21b5fb96bf5e1bd8fedaa55c4fc2 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Tue, 2 Jan 2018 15:38:35 +0000 Subject: CSS: Add new libcss unit types to computed style dump. --- content/handlers/css/dump.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/content/handlers/css/dump.c b/content/handlers/css/dump.c index 529bd4a88..b12e1d9e8 100644 --- a/content/handlers/css/dump.c +++ b/content/handlers/css/dump.c @@ -113,6 +113,45 @@ static void dump_css_unit(FILE *stream, css_fixed val, css_unit unit) case CSS_UNIT_KHZ: fprintf(stream, "kHz"); break; + case CSS_UNIT_CAP: + fprintf(stream, "cap"); + break; + case CSS_UNIT_CH: + fprintf(stream, "ch"); + break; + case CSS_UNIT_IC: + fprintf(stream, "ic"); + break; + case CSS_UNIT_REM: + fprintf(stream, "rem"); + break; + case CSS_UNIT_LH: + fprintf(stream, "lh"); + break; + case CSS_UNIT_RLH: + fprintf(stream, "rlh"); + break; + case CSS_UNIT_VH: + fprintf(stream, "vh"); + break; + case CSS_UNIT_VW: + fprintf(stream, "vw"); + break; + case CSS_UNIT_VI: + fprintf(stream, "vi"); + break; + case CSS_UNIT_VB: + fprintf(stream, "vb"); + break; + case CSS_UNIT_VMIN: + fprintf(stream, "vmin"); + break; + case CSS_UNIT_VMAX: + fprintf(stream, "vmax"); + break; + case CSS_UNIT_Q: + fprintf(stream, "q"); + break; } } -- cgit v1.2.3 From 5776d3448c50d58af0eac8f3960200aa1b5fc1a0 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Wed, 3 Jan 2018 16:59:58 +0000 Subject: 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. --- content/handlers/css/select.c | 52 +++++++++++++++++++++--- content/handlers/css/select.h | 1 + render/box.h | 5 ++- render/box_construct.c | 23 ++++++++--- render/box_normalise.c | 94 +++++++++++++++++++++++++++++++------------ 5 files changed, 137 insertions(+), 38 deletions(-) diff --git a/content/handlers/css/select.c b/content/handlers/css/select.c index 328d6a711..ee79eb394 100644 --- a/content/handlers/css/select.c +++ b/content/handlers/css/select.c @@ -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; diff --git a/content/handlers/css/select.h b/content/handlers/css/select.h index abfb85814..9fa6d3a56 100644 --- a/content/handlers/css/select.h +++ b/content/handlers/css/select.h @@ -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; diff --git a/render/box.h b/render/box.h index 2800d4026..8208a6fd3 100644 --- a/render/box.h +++ b/render/box.h @@ -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 diff --git a/render/box_construct.c b/render/box_construct.c index 1982622f9..1aa99e2d1 100644 --- a/render/box_construct.c +++ b/render/box_construct.c @@ -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 */ diff --git a/render/box_normalise.c b/render/box_normalise.c index 9f78f75ac..9c0875b4e 100644 --- a/render/box_normalise.c +++ b/render/box_normalise.c @@ -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; -- cgit v1.2.3 From cf3eba081a048d413158350000352ff2b5e5f220 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Wed, 3 Jan 2018 21:18:41 +0000 Subject: Layout: No need to expose layout_minmax_table(). --- render/layout.c | 342 +++++++++++++++++++++++++++++--------------------------- render/layout.h | 10 -- 2 files changed, 175 insertions(+), 177 deletions(-) diff --git a/render/layout.c b/render/layout.c index 7ca688fab..fa49667ff 100644 --- a/render/layout.c +++ b/render/layout.c @@ -285,6 +285,181 @@ calculate_mbp_width(const css_computed_style *style, } +/** + * Calculate minimum and maximum width of a table. + * + * \param table box of type TABLE + * \param font_func Font functions + * \param content The HTML content being layed out. + * \post table->min_width and table->max_width filled in, + * 0 <= table->min_width <= table->max_width + */ +static void +layout_minmax_table(struct box *table, const struct gui_layout_table *font_func) +{ + unsigned int i, j; + int border_spacing_h = 0; + int table_min = 0, table_max = 0; + int extra_fixed = 0; + float extra_frac = 0; + struct column *col = table->col; + struct box *row_group, *row, *cell; + enum css_width_e wtype; + css_fixed value = 0; + css_unit unit = CSS_UNIT_PX; + + /* check if the widths have already been calculated */ + if (table->max_width != UNKNOWN_MAX_WIDTH) + return; + + /* start with 0 except for fixed-width columns */ + for (i = 0; i != table->columns; i++) { + if (col[i].type == COLUMN_WIDTH_FIXED) + col[i].min = col[i].max = col[i].width; + else + col[i].min = col[i].max = 0; + } + + /* border-spacing is used in the separated borders model */ + if (css_computed_border_collapse(table->style) == + CSS_BORDER_COLLAPSE_SEPARATE) { + css_fixed h = 0, v = 0; + css_unit hu = CSS_UNIT_PX, vu = CSS_UNIT_PX; + + css_computed_border_spacing(table->style, &h, &hu, &v, &vu); + + border_spacing_h = FIXTOINT(nscss_len2px(h, hu, table->style)); + } + + /* 1st pass: consider cells with colspan 1 only */ + for (row_group = table->children; row_group; row_group =row_group->next) + for (row = row_group->children; row; row = row->next) + for (cell = row->children; cell; cell = cell->next) { + assert(cell->type == BOX_TABLE_CELL); + assert(cell->style); + /** TODO: Handle colspan="0" correctly. + * It's currently converted to 1 in box normaisation */ + assert(cell->columns != 0); + + if (cell->columns != 1) + continue; + + layout_minmax_block(cell, font_func); + i = cell->start_column; + + if (col[i].positioned) + continue; + + /* update column min, max widths using cell widths */ + if (col[i].min < cell->min_width) + col[i].min = cell->min_width; + if (col[i].max < cell->max_width) + col[i].max = cell->max_width; + } + + /* 2nd pass: cells which span multiple columns */ + for (row_group = table->children; row_group; row_group =row_group->next) + for (row = row_group->children; row; row = row->next) + for (cell = row->children; cell; cell = cell->next) { + unsigned int flexible_columns = 0; + int min = 0, max = 0, fixed_width = 0, extra; + + if (cell->columns == 1) + continue; + + layout_minmax_block(cell, font_func); + i = cell->start_column; + + /* find min width so far of spanned columns, and count + * number of non-fixed spanned columns and total fixed width */ + for (j = 0; j != cell->columns; j++) { + min += col[i + j].min; + if (col[i + j].type == COLUMN_WIDTH_FIXED) + fixed_width += col[i + j].width; + else + flexible_columns++; + } + min += (cell->columns - 1) * border_spacing_h; + + /* distribute extra min to spanned columns */ + if (min < cell->min_width) { + if (flexible_columns == 0) { + extra = 1 + (cell->min_width - min) / + cell->columns; + for (j = 0; j != cell->columns; j++) { + col[i + j].min += extra; + if (col[i + j].max < col[i + j].min) + col[i + j].max = col[i + j].min; + } + } else { + extra = 1 + (cell->min_width - min) / + flexible_columns; + for (j = 0; j != cell->columns; j++) { + if (col[i + j].type != + COLUMN_WIDTH_FIXED) { + col[i + j].min += extra; + if (col[i + j].max < + col[i + j].min) + col[i + j].max = + col[i + j].min; + } + } + } + } + + /* find max width so far of spanned columns */ + for (j = 0; j != cell->columns; j++) + max += col[i + j].max; + max += (cell->columns - 1) * border_spacing_h; + + /* distribute extra max to spanned columns */ + if (max < cell->max_width && flexible_columns) { + extra = 1 + (cell->max_width - max) / flexible_columns; + for (j = 0; j != cell->columns; j++) + if (col[i + j].type != COLUMN_WIDTH_FIXED) + col[i + j].max += extra; + } + } + + for (i = 0; i != table->columns; i++) { + if (col[i].max < col[i].min) { + box_dump(stderr, table, 0, true); + assert(0); + } + table_min += col[i].min; + table_max += col[i].max; + } + + /* fixed width takes priority, unless it is too narrow */ + wtype = css_computed_width(table->style, &value, &unit); + if (wtype == CSS_WIDTH_SET && unit != CSS_UNIT_PCT) { + int width = FIXTOINT(nscss_len2px(value, unit, table->style)); + if (table_min < width) + table_min = width; + if (table_max < width) + table_max = width; + } + + /* add margins, border, padding to min, max widths */ + calculate_mbp_width(table->style, LEFT, true, true, true, + &extra_fixed, &extra_frac); + calculate_mbp_width(table->style, RIGHT, true, true, true, + &extra_fixed, &extra_frac); + if (extra_fixed < 0) + extra_fixed = 0; + if (extra_frac < 0) + extra_frac = 0; + if (1.0 <= extra_frac) + extra_frac = 0.9; + table->min_width = (table_min + extra_fixed) / (1.0 - extra_frac); + table->max_width = (table_max + extra_fixed) / (1.0 - extra_frac); + table->min_width += (table->columns + 1) * border_spacing_h; + table->max_width += (table->columns + 1) * border_spacing_h; + + assert(0 <= table->min_width && table->min_width <= table->max_width); +} + + /** * Calculate minimum and maximum width of a line. * @@ -4926,173 +5101,6 @@ bool layout_inline_container(struct box *inline_container, int width, } -/* exported function documented in render/layout.h */ -void -layout_minmax_table(struct box *table, const struct gui_layout_table *font_func) -{ - unsigned int i, j; - int border_spacing_h = 0; - int table_min = 0, table_max = 0; - int extra_fixed = 0; - float extra_frac = 0; - struct column *col = table->col; - struct box *row_group, *row, *cell; - enum css_width_e wtype; - css_fixed value = 0; - css_unit unit = CSS_UNIT_PX; - - /* check if the widths have already been calculated */ - if (table->max_width != UNKNOWN_MAX_WIDTH) - return; - - /* start with 0 except for fixed-width columns */ - for (i = 0; i != table->columns; i++) { - if (col[i].type == COLUMN_WIDTH_FIXED) - col[i].min = col[i].max = col[i].width; - else - col[i].min = col[i].max = 0; - } - - /* border-spacing is used in the separated borders model */ - if (css_computed_border_collapse(table->style) == - CSS_BORDER_COLLAPSE_SEPARATE) { - css_fixed h = 0, v = 0; - css_unit hu = CSS_UNIT_PX, vu = CSS_UNIT_PX; - - css_computed_border_spacing(table->style, &h, &hu, &v, &vu); - - border_spacing_h = FIXTOINT(nscss_len2px(h, hu, table->style)); - } - - /* 1st pass: consider cells with colspan 1 only */ - for (row_group = table->children; row_group; row_group =row_group->next) - for (row = row_group->children; row; row = row->next) - for (cell = row->children; cell; cell = cell->next) { - assert(cell->type == BOX_TABLE_CELL); - assert(cell->style); - /** TODO: Handle colspan="0" correctly. - * It's currently converted to 1 in box normaisation */ - assert(cell->columns != 0); - - if (cell->columns != 1) - continue; - - layout_minmax_block(cell, font_func); - i = cell->start_column; - - if (col[i].positioned) - continue; - - /* update column min, max widths using cell widths */ - if (col[i].min < cell->min_width) - col[i].min = cell->min_width; - if (col[i].max < cell->max_width) - col[i].max = cell->max_width; - } - - /* 2nd pass: cells which span multiple columns */ - for (row_group = table->children; row_group; row_group =row_group->next) - for (row = row_group->children; row; row = row->next) - for (cell = row->children; cell; cell = cell->next) { - unsigned int flexible_columns = 0; - int min = 0, max = 0, fixed_width = 0, extra; - - if (cell->columns == 1) - continue; - - layout_minmax_block(cell, font_func); - i = cell->start_column; - - /* find min width so far of spanned columns, and count - * number of non-fixed spanned columns and total fixed width */ - for (j = 0; j != cell->columns; j++) { - min += col[i + j].min; - if (col[i + j].type == COLUMN_WIDTH_FIXED) - fixed_width += col[i + j].width; - else - flexible_columns++; - } - min += (cell->columns - 1) * border_spacing_h; - - /* distribute extra min to spanned columns */ - if (min < cell->min_width) { - if (flexible_columns == 0) { - extra = 1 + (cell->min_width - min) / - cell->columns; - for (j = 0; j != cell->columns; j++) { - col[i + j].min += extra; - if (col[i + j].max < col[i + j].min) - col[i + j].max = col[i + j].min; - } - } else { - extra = 1 + (cell->min_width - min) / - flexible_columns; - for (j = 0; j != cell->columns; j++) { - if (col[i + j].type != - COLUMN_WIDTH_FIXED) { - col[i + j].min += extra; - if (col[i + j].max < - col[i + j].min) - col[i + j].max = - col[i + j].min; - } - } - } - } - - /* find max width so far of spanned columns */ - for (j = 0; j != cell->columns; j++) - max += col[i + j].max; - max += (cell->columns - 1) * border_spacing_h; - - /* distribute extra max to spanned columns */ - if (max < cell->max_width && flexible_columns) { - extra = 1 + (cell->max_width - max) / flexible_columns; - for (j = 0; j != cell->columns; j++) - if (col[i + j].type != COLUMN_WIDTH_FIXED) - col[i + j].max += extra; - } - } - - for (i = 0; i != table->columns; i++) { - if (col[i].max < col[i].min) { - box_dump(stderr, table, 0, true); - assert(0); - } - table_min += col[i].min; - table_max += col[i].max; - } - - /* fixed width takes priority, unless it is too narrow */ - wtype = css_computed_width(table->style, &value, &unit); - if (wtype == CSS_WIDTH_SET && unit != CSS_UNIT_PCT) { - int width = FIXTOINT(nscss_len2px(value, unit, table->style)); - if (table_min < width) - table_min = width; - if (table_max < width) - table_max = width; - } - - /* add margins, border, padding to min, max widths */ - calculate_mbp_width(table->style, LEFT, true, true, true, - &extra_fixed, &extra_frac); - calculate_mbp_width(table->style, RIGHT, true, true, true, - &extra_fixed, &extra_frac); - if (extra_fixed < 0) - extra_fixed = 0; - if (extra_frac < 0) - extra_frac = 0; - if (1.0 <= extra_frac) - extra_frac = 0.9; - table->min_width = (table_min + extra_fixed) / (1.0 - extra_frac); - table->max_width = (table_max + extra_fixed) / (1.0 - extra_frac); - table->min_width += (table->columns + 1) * border_spacing_h; - table->max_width += (table->columns + 1) * border_spacing_h; - - assert(0 <= table->min_width && table->min_width <= table->max_width); -} - - /** * Find a box's bounding box relative to itself, i.e. the box's border edge box * diff --git a/render/layout.h b/render/layout.h index 78a30028e..7a579ca22 100644 --- a/render/layout.h +++ b/render/layout.h @@ -63,14 +63,4 @@ bool layout_inline_container(struct box *box, int width, struct box *cont, int c */ void layout_calculate_descendant_bboxes(struct box *box); -/** - * Calculate minimum and maximum width of a table. - * - * \param table box of type TABLE - * \param font_func Font functions - * \post table->min_width and table->max_width filled in, - * 0 <= table->min_width <= table->max_width - */ -void layout_minmax_table(struct box *table, const struct gui_layout_table *font_func); - #endif -- cgit v1.2.3 From ae286be5a9a5c1150dfa7627f2b30a73238b506c Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Wed, 3 Jan 2018 22:15:25 +0000 Subject: Layout: No need to expose layout_inline_container(). --- render/layout.c | 4258 ++++++++++++++++++++++++++++--------------------------- render/layout.h | 13 - 2 files changed, 2134 insertions(+), 2137 deletions(-) diff --git a/render/layout.c b/render/layout.c index fa49667ff..b19d93f44 100644 --- a/render/layout.c +++ b/render/layout.c @@ -2634,493 +2634,340 @@ static bool layout_block_object(struct box *block) /** - * Layout a block formatting context. + * Insert a float into a container. * - * \param block BLOCK, INLINE_BLOCK, or TABLE_CELL to layout - * \param viewport_height Height of viewport in pixels or -ve if unknown - * \param content Memory pool for any new boxes - * \return true on success, false on memory exhaustion + * \param cont block formatting context block, used to contain float + * \param b box to add to float * - * This function carries out layout of a block and its children, as described - * in CSS 2.1 9.4.1. + * This sorts floats in order of descending bottom edges. */ -static bool -layout_block_context(struct box *block, - int viewport_height, - html_content *content) +static void add_float_to_container(struct box *cont, struct box *b) { - struct box *box; - int cx, cy; /**< current coordinates */ - int max_pos_margin = 0; - int max_neg_margin = 0; - int y = 0; - int lm, rm; - struct box *margin_collapse = NULL; - bool in_margin = false; - css_fixed gadget_size; - css_unit gadget_unit; /* Checkbox / radio buttons */ - - assert(block->type == BOX_BLOCK || - block->type == BOX_INLINE_BLOCK || - block->type == BOX_TABLE_CELL); - assert(block->width != UNKNOWN_WIDTH); - assert(block->width != AUTO); + struct box *box = cont->float_children; + int b_bottom = b->y + b->height; - block->float_children = NULL; - block->cached_place_below_level = 0; - block->clear_level = 0; + assert(b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT); - /* special case if the block contains an object */ - if (block->object) { - int temp_width = block->width; - if (!layout_block_object(block)) - return false; - layout_get_object_dimensions(block, &temp_width, - &block->height, INT_MIN, INT_MAX, - INT_MIN, INT_MAX); - return true; - } else if (block->flags & REPLACE_DIM) { - return true; + if (box == NULL) { + /* No other float children */ + b->next_float = NULL; + cont->float_children = b; + return; + } else if (b_bottom >= box->y + box->height) { + /* Goes at start of list */ + b->next_float = cont->float_children; + cont->float_children = b; + } else { + struct box *prev = NULL; + while (box != NULL && b_bottom < box->y + box->height) { + prev = box; + box = box->next_float; + } + if (prev != NULL) { + b->next_float = prev->next_float; + prev->next_float = b; + } } +} - /* special case if the block contains an radio button or checkbox */ - if (block->gadget && (block->gadget->type == GADGET_RADIO || - block->gadget->type == GADGET_CHECKBOX)) { - /* form checkbox or radio button - * if width or height is AUTO, set it to 1em */ - gadget_unit = CSS_UNIT_EM; - gadget_size = INTTOFIX(1); - if (block->height == AUTO) - block->height = FIXTOINT(nscss_len2px(gadget_size, - gadget_unit, block->style)); + +/** + * Split a text box. + * + * \param content memory pool for any new boxes + * \param fstyle style for text in text box + * \param split_box box with text to split + * \param new_length new length for text in split_box, after splitting + * \param new_width new width for text in split_box, after splitting + * \return true on success, false on memory exhaustion + * + * A new box is created and inserted into the box tree after split_box, + * containing the text after new_length excluding the initial space character. + */ +static bool +layout_text_box_split(html_content *content, + plot_font_style_t *fstyle, + struct box *split_box, + size_t new_length, + int new_width) +{ + int space_width = split_box->space; + struct box *c2; + const struct gui_layout_table *font_func = content->font_func; + bool space = (split_box->text[new_length] == ' '); + int used_length = new_length + (space ? 1 : 0); + + if ((space && space_width == 0) || space_width == UNKNOWN_WIDTH) { + /* We're need to add a space, and we don't know how big + * it's to be, OR we have a space of unknown width anyway; + * Calculate space width */ + font_func->width(fstyle, " ", 1, &space_width); } - box = block->children; - /* set current coordinates to top-left of the block */ - cx = 0; - y = cy = block->padding[TOP]; - if (box) - box->y = block->padding[TOP]; + if (split_box->space == UNKNOWN_WIDTH) + split_box->space = space_width; + if (!space) + space_width = 0; - /* Step through the descendants of the block in depth-first order, but - * not into the children of boxes which aren't blocks. For example, if - * the tree passed to this function looks like this (box->type shown): - * - * block -> BOX_BLOCK - * BOX_BLOCK * (1) - * BOX_INLINE_CONTAINER * (2) - * BOX_INLINE - * BOX_TEXT - * ... - * BOX_BLOCK * (3) - * BOX_TABLE * (4) - * BOX_TABLE_ROW - * BOX_TABLE_CELL - * ... - * BOX_TABLE_CELL - * ... - * BOX_BLOCK * (5) - * BOX_INLINE_CONTAINER * (6) - * BOX_TEXT - * ... - * then the while loop will visit each box marked with *, setting box - * to each in the order shown. */ - while (box) { - enum css_overflow_e overflow_x = CSS_OVERFLOW_VISIBLE; - enum css_overflow_e overflow_y = CSS_OVERFLOW_VISIBLE; + /* Create clone of split_box, c2 */ + c2 = talloc_memdup(content->bctx, split_box, sizeof *c2); + if (!c2) + return false; + c2->flags |= CLONE; - assert(box->type == BOX_BLOCK || box->type == BOX_TABLE || - box->type == BOX_INLINE_CONTAINER); + /* Set remaining text in c2 */ + c2->text += used_length; - /* Tables are laid out before being positioned, because the - * position depends on the width which is calculated in - * table layout. Blocks and inline containers are positioned - * before being laid out, because width is not dependent on - * content, and the position is required during layout for - * correct handling of floats. - */ + /* Set c2 according to the remaining text */ + c2->width -= new_width + space_width; + c2->flags &= ~MEASURED; /* width has been estimated */ + c2->length = split_box->length - used_length; - if (box->style && - (css_computed_position(box->style) == - CSS_POSITION_ABSOLUTE || - css_computed_position(box->style) == - CSS_POSITION_FIXED)) { - box->x = box->parent->padding[LEFT]; - /* absolute positioned; this element will establish - * its own block context when it gets laid out later, - * so no need to look at its children now. */ - goto advance_to_next_box; - } + /* Update split_box for its reduced text */ + split_box->width = new_width; + split_box->flags |= MEASURED; + split_box->length = new_length; + split_box->space = space_width; - /* If we don't know which box the current margin collapses - * through to, find out. Update the pos/neg margin values. */ - if (margin_collapse == NULL) { - margin_collapse = layout_next_margin_block(box, block, - viewport_height, - &max_pos_margin, &max_neg_margin); - /* We have a margin that has not yet been applied. */ - in_margin = true; - } + /* Insert c2 into box list */ + c2->next = split_box->next; + split_box->next = c2; + c2->prev = split_box; + if (c2->next) + c2->next->prev = c2; + else + c2->parent->last = c2; - /* Clearance. */ - y = 0; - if (box->style && css_computed_clear(box->style) != - CSS_CLEAR_NONE) - y = layout_clear(block->float_children, - css_computed_clear(box->style)); + NSLOG(layout, DEBUG, + "split_box %p len: %" PRIsizet " \"%.*s\"", + split_box, + split_box->length, + (int)split_box->length, + split_box->text); + NSLOG(layout, DEBUG, + " new_box %p len: %" PRIsizet " \"%.*s\"", + c2, + c2->length, + (int)c2->length, + c2->text); - /* Find box's overflow properties */ - if (box->style) { - overflow_x = css_computed_overflow_x(box->style); - overflow_y = css_computed_overflow_y(box->style); - } + return true; +} - /* Blocks establishing a block formatting context get minimum - * left and right margins to avoid any floats. */ - lm = rm = 0; - if (box->type == BOX_BLOCK || box->flags & IFRAME) { - if (!box->object && !(box->flags & IFRAME) && - !(box->flags & REPLACE_DIM) && - box->style && - (overflow_x != CSS_OVERFLOW_VISIBLE || - overflow_y != CSS_OVERFLOW_VISIBLE)) { - /* box establishes new block formatting context - * so available width may be diminished due to - * floats. */ - int x0, x1, top; - struct box *left, *right; - top = cy + max_pos_margin - max_neg_margin; - top = (top > y) ? top : y; - x0 = cx; - x1 = cx + box->parent->width - - box->parent->padding[LEFT] - - box->parent->padding[RIGHT]; - find_sides(block->float_children, top, top, - &x0, &x1, &left, &right); - /* calculate min required left & right margins - * needed to avoid floats */ - lm = x0 - cx; - rm = cx + box->parent->width - - box->parent->padding[LEFT] - - box->parent->padding[RIGHT] - - x1; - } - layout_block_find_dimensions(box->parent->width, - viewport_height, lm, rm, box); - if (box->type == BOX_BLOCK && !(box->flags & IFRAME)) { - layout_block_add_scrollbar(box, RIGHT); - layout_block_add_scrollbar(box, BOTTOM); - } - } else if (box->type == BOX_TABLE) { - if (box->style != NULL) { - enum css_width_e wtype; - css_fixed width = 0; - css_unit unit = CSS_UNIT_PX; +/** + * Compute dimensions of box, margins, paddings, and borders for a floating + * element using shrink-to-fit. Also used for inline-blocks. + * + * \param available_width Max width available in pixels + * \param style Box's style + * \param box Box for which to find dimensions + * Box margins, borders, paddings, width and + * height are updated. + */ +static void +layout_float_find_dimensions(int available_width, + const css_computed_style *style, + struct box *box) +{ + int width, height, max_width, min_width, max_height, min_height; + int *margin = box->margin; + int *padding = box->padding; + struct box_border *border = box->border; + enum css_overflow_e overflow_x = css_computed_overflow_x(style); + enum css_overflow_e overflow_y = css_computed_overflow_y(style); + int scrollbar_width_x = + (overflow_x == CSS_OVERFLOW_SCROLL || + overflow_x == CSS_OVERFLOW_AUTO) ? + SCROLLBAR_WIDTH : 0; + int scrollbar_width_y = + (overflow_y == CSS_OVERFLOW_SCROLL || + overflow_y == CSS_OVERFLOW_AUTO) ? + SCROLLBAR_WIDTH : 0; - wtype = css_computed_width(box->style, &width, - &unit); + layout_find_dimensions(available_width, -1, box, style, &width, &height, + &max_width, &min_width, &max_height, &min_height, + margin, padding, border); - if (wtype == CSS_WIDTH_AUTO) { - /* max available width may be - * diminished due to floats. */ - int x0, x1, top; - struct box *left, *right; - top = cy + max_pos_margin - - max_neg_margin; - top = (top > y) ? top : y; - x0 = cx; - x1 = cx + box->parent->width - - box->parent->padding[LEFT] - - box->parent->padding[RIGHT]; - find_sides(block->float_children, - top, top, &x0, &x1, - &left, &right); - /* calculate min required left & right - * margins needed to avoid floats */ - lm = x0 - cx; - rm = cx + box->parent->width - - box->parent->padding[LEFT] - - box->parent->padding[RIGHT] - - x1; - } - } - if (!layout_table(box, box->parent->width - lm - rm, - content)) - return false; - layout_solve_width(box, box->parent->width, box->width, - lm, rm, -1, -1); - } + if (margin[LEFT] == AUTO) + margin[LEFT] = 0; + if (margin[RIGHT] == AUTO) + margin[RIGHT] = 0; - /* Position box: horizontal. */ - box->x = box->parent->padding[LEFT] + box->margin[LEFT] + - box->border[LEFT].width; - cx += box->x; + if (box->gadget == NULL) { + padding[RIGHT] += scrollbar_width_y; + padding[BOTTOM] += scrollbar_width_x; + } - /* Position box: vertical. */ - if (box->border[TOP].width) { - box->y += box->border[TOP].width; - cy += box->border[TOP].width; - } + if (box->object && !(box->flags & REPLACE_DIM) && + content_get_type(box->object) != CONTENT_HTML) { + /* Floating replaced element, with intrinsic width or height. + * See 10.3.6 and 10.6.2 */ + layout_get_object_dimensions(box, &width, &height, + min_width, max_width, min_height, max_height); + } else if (box->gadget && (box->gadget->type == GADGET_TEXTBOX || + box->gadget->type == GADGET_PASSWORD || + box->gadget->type == GADGET_FILE || + box->gadget->type == GADGET_TEXTAREA)) { + css_fixed size = 0; + css_unit unit = CSS_UNIT_EM; - /* Vertical margin */ - if (((box->type == BOX_BLOCK && - (box->flags & HAS_HEIGHT)) || - box->type == BOX_TABLE || - (box->type == BOX_INLINE_CONTAINER && - box != box->parent->children) || - margin_collapse == box) && - in_margin == true) { - /* Margin goes above this box. */ - cy += max_pos_margin - max_neg_margin; - box->y += max_pos_margin - max_neg_margin; + /* Give sensible dimensions to gadgets, with auto width/height, + * that don't shrink to fit contained text. */ + assert(box->style); - /* Current margin has been applied. */ - in_margin = false; - max_pos_margin = max_neg_margin = 0; + if (box->gadget->type == GADGET_TEXTBOX || + box->gadget->type == GADGET_PASSWORD || + box->gadget->type == GADGET_FILE) { + if (width == AUTO) { + size = INTTOFIX(10); + width = FIXTOINT(nscss_len2px(size, unit, + box->style)); + } + if (box->gadget->type == GADGET_FILE && + height == AUTO) { + size = FLTTOFIX(1.5); + height = FIXTOINT(nscss_len2px(size, unit, + box->style)); + } } - - /* Handle clearance */ - if (box->type != BOX_INLINE_CONTAINER && - (y > 0) && (cy < y)) { - /* box clears something*/ - box->y += y - cy; - cy = y; + if (box->gadget->type == GADGET_TEXTAREA) { + if (width == AUTO) { + size = INTTOFIX(10); + width = FIXTOINT(nscss_len2px(size, unit, + box->style)); + } + if (height == AUTO) { + size = INTTOFIX(4); + height = FIXTOINT(nscss_len2px(size, unit, + box->style)); + } } + } else if (width == AUTO) { + /* CSS 2.1 section 10.3.5 */ + width = min(max(box->min_width, available_width), + box->max_width); - /* Unless the box has an overflow style of visible, the box - * establishes a new block context. */ - if (box->type == BOX_BLOCK && box->style && - (overflow_x != CSS_OVERFLOW_VISIBLE || - overflow_y != CSS_OVERFLOW_VISIBLE)) { + /* width includes margin, borders and padding */ + if (width == available_width) { + width -= box->margin[LEFT] + box->border[LEFT].width + + box->padding[LEFT] + + box->padding[RIGHT] + + box->border[RIGHT].width + + box->margin[RIGHT]; + } else { + /* width was obtained from a min_width or max_width + * value, so need to use the same method for calculating + * mbp as was used in layout_minmax_block() */ + int fixed = 0; + float frac = 0; + calculate_mbp_width(box->style, LEFT, true, true, true, + &fixed, &frac); + calculate_mbp_width(box->style, RIGHT, true, true, true, + &fixed, &frac); + if (fixed < 0) + fixed = 0; - layout_block_context(box, viewport_height, content); + width -= fixed; + } - cy += box->padding[TOP]; + if (max_width >= 0 && width > max_width) width = max_width; + if (min_width > 0 && width < min_width) width = min_width; - if (box->height == AUTO) { - box->height = 0; - layout_block_add_scrollbar(box, BOTTOM); - } + } else { + if (max_width >= 0 && width > max_width) width = max_width; + if (min_width > 0 && width < min_width) width = min_width; + width -= scrollbar_width_y; + } - cx -= box->x; - cy += box->height + box->padding[BOTTOM] + - box->border[BOTTOM].width; - y = box->y + box->padding[TOP] + box->height + - box->padding[BOTTOM] + - box->border[BOTTOM].width; + box->width = width; + box->height = height; - /* Skip children, because they are done in the new - * block context */ - goto advance_to_next_box; - } + if (margin[TOP] == AUTO) + margin[TOP] = 0; + if (margin[BOTTOM] == AUTO) + margin[BOTTOM] = 0; +} - NSLOG(layout, DEBUG, "box %p, cx %i, cy %i", box, cx, cy); - /* Layout (except tables). */ - if (box->object) { - if (!layout_block_object(box)) - return false; +/** + * Layout the contents of a float or inline block. + * + * \param b float or inline block box + * \param width available width + * \param content memory pool for any new boxes + * \return true on success, false on memory exhaustion + */ +static bool layout_float(struct box *b, int width, html_content *content) +{ + assert(b->type == BOX_TABLE || b->type == BOX_BLOCK || + b->type == BOX_INLINE_BLOCK); + layout_float_find_dimensions(width, b->style, b); + if (b->type == BOX_TABLE) { + if (!layout_table(b, width, content)) + return false; + if (b->margin[LEFT] == AUTO) + b->margin[LEFT] = 0; + if (b->margin[RIGHT] == AUTO) + b->margin[RIGHT] = 0; + if (b->margin[TOP] == AUTO) + b->margin[TOP] = 0; + if (b->margin[BOTTOM] == AUTO) + b->margin[BOTTOM] = 0; + } else + return layout_block_context(b, -1, content); + return true; +} - } else if (box->type == BOX_INLINE_CONTAINER) { - box->width = box->parent->width; - if (!layout_inline_container(box, box->width, block, - cx, cy, content)) - return false; - } else if (box->type == BOX_TABLE) { - /* Move down to avoid floats if necessary. */ - int x0, x1; - struct box *left, *right; - y = cy; - while (1) { - enum css_width_e wtype; - css_fixed width = 0; - css_unit unit = CSS_UNIT_PX; - - wtype = css_computed_width(box->style, - &width, &unit); - - x0 = cx; - x1 = cx + box->parent->width; - find_sides(block->float_children, y, - y + box->height, - &x0, &x1, &left, &right); - if (wtype == CSS_WIDTH_AUTO) - break; - if (box->width <= x1 - x0) - break; - if (!left && !right) - break; - else if (!left) - y = right->y + right->height + 1; - else if (!right) - y = left->y + left->height + 1; - else if (left->y + left->height < - right->y + right->height) - y = left->y + left->height + 1; - else - y = right->y + right->height + 1; - } - box->x += x0 - cx; - cx = x0; - box->y += y - cy; - cy = y; - } - - /* Advance to next box. */ - if (box->type == BOX_BLOCK && !box->object && !(box->iframe) && - box->children) { - /* Down into children. */ - - if (box == margin_collapse) { - /* Current margin collapsed though to this box. - * Unset margin_collapse. */ - margin_collapse = NULL; - } - - y = box->padding[TOP]; - box = box->children; - box->y = y; - cy += y; - continue; - } else if (box->type == BOX_BLOCK || box->object || - box->flags & IFRAME) - cy += box->padding[TOP]; - - if (box->type == BOX_BLOCK && box->height == AUTO) { - box->height = 0; - layout_block_add_scrollbar(box, BOTTOM); - } - - cy += box->height + box->padding[BOTTOM] + - box->border[BOTTOM].width; - cx -= box->x; - y = box->y + box->padding[TOP] + box->height + - box->padding[BOTTOM] + - box->border[BOTTOM].width; - - advance_to_next_box: - if (!box->next) { - /* No more siblings: - * up to first ancestor with a sibling. */ - - do { - if (box == margin_collapse) { - /* Current margin collapsed though to - * this box. Unset margin_collapse. */ - margin_collapse = NULL; - } - - /* Apply bottom margin */ - if (max_pos_margin < box->margin[BOTTOM]) - max_pos_margin = box->margin[BOTTOM]; - else if (max_neg_margin < -box->margin[BOTTOM]) - max_neg_margin = -box->margin[BOTTOM]; - - box = box->parent; - if (box == block) - break; - - /* Margin is invalidated if this is a box - * margins can't collapse through. */ - if (box->type == BOX_BLOCK && - box->flags & MAKE_HEIGHT) { - margin_collapse = NULL; - in_margin = false; - max_pos_margin = max_neg_margin = 0; - } - - if (box->height == AUTO) { - box->height = y - box->padding[TOP]; - - if (box->type == BOX_BLOCK) - layout_block_add_scrollbar(box, - BOTTOM); - } else - cy += box->height - - (y - box->padding[TOP]); - - /* Apply any min-height and max-height to - * boxes in normal flow */ - if (box->style && - css_computed_position(box->style) != - CSS_POSITION_ABSOLUTE && - layout_apply_minmax_height(box, - NULL)) { - /* Height altered */ - /* Set current cy */ - cy += box->height - - (y - box->padding[TOP]); - } - - cy += box->padding[BOTTOM] + - box->border[BOTTOM].width; - cx -= box->x; - y = box->y + box->padding[TOP] + box->height + - box->padding[BOTTOM] + - box->border[BOTTOM].width; +/** + * Position a float in the first available space. + * + * \param c float box to position + * \param width available width + * \param cx x coordinate relative to cont to place float right of + * \param y y coordinate relative to cont to place float below + * \param cont ancestor box which defines horizontal space, for floats + */ +static void +place_float_below(struct box *c, int width, int cx, int y, struct box *cont) +{ + int x0, x1, yy; + struct box *left; + struct box *right; - } while (box->next == NULL); - if (box == block) - break; - } + yy = y > cont->cached_place_below_level ? + y : cont->cached_place_below_level; - /* To next sibling. */ + NSLOG(layout, DEBUG, + "c %p, width %i, cx %i, y %i, cont %p", c, + width, cx, y, cont); - if (box == margin_collapse) { - /* Current margin collapsed though to this box. - * Unset margin_collapse. */ - margin_collapse = NULL; + do { + y = yy; + x0 = cx; + x1 = cx + width; + find_sides(cont->float_children, y, y + c->height, &x0, &x1, + &left, &right); + if (left != 0 && right != 0) { + yy = (left->y + left->height < + right->y + right->height ? + left->y + left->height : + right->y + right->height); + } else if (left == 0 && right != 0) { + yy = right->y + right->height; + } else if (left != 0 && right == 0) { + yy = left->y + left->height; } + } while ((left != 0 || right != 0) && (c->width > x1 - x0)); - if (max_pos_margin < box->margin[BOTTOM]) - max_pos_margin = box->margin[BOTTOM]; - else if (max_neg_margin < -box->margin[BOTTOM]) - max_neg_margin = -box->margin[BOTTOM]; - - box = box->next; - box->y = y; - } - - /* Account for bottom margin of last contained block */ - cy += max_pos_margin - max_neg_margin; - - /* Increase height to contain any floats inside (CSS 2.1 10.6.7). */ - for (box = block->float_children; box; box = box->next_float) { - y = box->y + box->height + box->padding[BOTTOM] + - box->border[BOTTOM].width + box->margin[BOTTOM]; - if (cy < y) - cy = y; - } - - if (block->height == AUTO) { - block->height = cy - block->padding[TOP]; - if (block->type == BOX_BLOCK) - layout_block_add_scrollbar(block, BOTTOM); - } - - if (block->style && css_computed_position(block->style) != - CSS_POSITION_ABSOLUTE) { - /* Block is in normal flow */ - layout_apply_minmax_height(block, NULL); - } - - if (block->gadget && - (block->gadget->type == GADGET_TEXTAREA || - block->gadget->type == GADGET_PASSWORD || - block->gadget->type == GADGET_TEXTBOX)) { - int ta_width = block->padding[LEFT] + block->width + - block->padding[RIGHT]; - int ta_height = block->padding[TOP] + block->height + - block->padding[BOTTOM]; - textarea_set_layout(block->gadget->data.text.ta, - ta_width, ta_height, - block->padding[TOP], block->padding[RIGHT], - block->padding[BOTTOM], block->padding[LEFT]); + if (c->type == BOX_FLOAT_LEFT) { + c->x = x0; + } else { + c->x = x1 - c->width; } - - return true; + c->y = y; + cont->cached_place_below_level = y; } @@ -3160,1944 +3007,2107 @@ static int line_height(const css_computed_style *style) /** - * Layout list markers. + * Position a line of boxes in inline formatting context. + * + * \param first box at start of line + * \param width available width on input, updated with actual width on output + * (may be incorrect if the line gets split?) + * \param y coordinate of top of line, updated on exit to bottom + * \param cx coordinate of left of line relative to cont + * \param cy coordinate of top of line relative to cont + * \param cont ancestor box which defines horizontal space, for floats + * \param indent apply any first-line indent + * \param has_text_children at least one TEXT in the inline_container + * \param next_box updated to first box for next line, or 0 at end + * \param content memory pool for any new boxes + * \return true on success, false on memory exhaustion */ -static void -layout_lists(struct box *box, - const struct gui_layout_table *font_func) +static bool +layout_line(struct box *first, + int *width, + int *y, + int cx, + int cy, + struct box *cont, + bool indent, + bool has_text_children, + html_content *content, + struct box **next_box) { - struct box *child; - struct box *marker; - plot_font_style_t fstyle; - - for (child = box->children; child; child = child->next) { - if (child->list_marker) { - marker = child->list_marker; - if (marker->object) { - marker->width = - content_get_width(marker->object); - marker->x = -marker->width; - marker->height = - content_get_height(marker->object); - marker->y = (line_height(marker->style) - - marker->height) / 2; - } else if (marker->text) { - if (marker->width == UNKNOWN_WIDTH) { - font_plot_style_from_css(marker->style, - &fstyle); - font_func->width(&fstyle, - marker->text, - marker->length, - &marker->width); - marker->flags |= MEASURED; - } - marker->x = -marker->width; - marker->y = 0; - marker->height = line_height(marker->style); - } else { - marker->x = 0; - marker->y = 0; - marker->width = 0; - marker->height = 0; - } - /* Gap between marker and content */ - marker->x -= 4; - } - layout_lists(child, font_func); - } -} + int height, used_height; + int x0 = 0; + int x1 = *width; + int x, h, x_previous; + int fy = cy; + struct box *left; + struct box *right; + struct box *b; + struct box *split_box = 0; + struct box *d; + struct box *br_box = 0; + bool move_y = false; + bool place_below = false; + int space_before = 0, space_after = 0; + unsigned int inline_count = 0; + unsigned int i; + const struct gui_layout_table *font_func = content->font_func; + plot_font_style_t fstyle; + NSLOG(layout, DEBUG, + "first %p, first->text '%.*s', width %i, y %i, cx %i, cy %i", + first, + (int)first->length, + first->text, + *width, + *y, + cx, + cy); -/** - * Compute box offsets for a relatively or absolutely positioned box with - * respect to a box. - * - * \param box box to compute offsets for - * \param containing_block box to compute percentages with respect to - * \param top updated to top offset, or AUTO - * \param right updated to right offset, or AUTO - * \param bottom updated to bottom offset, or AUTO - * \param left updated to left offset, or AUTO - * - * See CSS 2.1 9.3.2. containing_block must have width and height. - */ -static void -layout_compute_offsets(struct box *box, - struct box *containing_block, - int *top, - int *right, - int *bottom, - int *left) -{ - uint32_t type; - css_fixed value = 0; - css_unit unit = CSS_UNIT_PX; + /* find sides at top of line */ + x0 += cx; + x1 += cx; + find_sides(cont->float_children, cy, cy, &x0, &x1, &left, &right); + x0 -= cx; + x1 -= cx; - assert(containing_block->width != UNKNOWN_WIDTH && - containing_block->width != AUTO && - containing_block->height != AUTO); + if (indent) + x0 += layout_text_indent(first->parent->parent->style, *width); - /* left */ - type = css_computed_left(box->style, &value, &unit); - if (type == CSS_LEFT_SET) { - if (unit == CSS_UNIT_PCT) { - *left = FPCT_OF_INT_TOINT(value, - containing_block->width); - } else { - *left = FIXTOINT(nscss_len2px(value, unit, box->style)); - } - } else { - *left = AUTO; - } + if (x1 < x0) + x1 = x0; - /* right */ - type = css_computed_right(box->style, &value, &unit); - if (type == CSS_RIGHT_SET) { - if (unit == CSS_UNIT_PCT) { - *right = FPCT_OF_INT_TOINT(value, - containing_block->width); - } else { - *right = FIXTOINT(nscss_len2px(value, unit, - box->style)); - } - } else { - *right = AUTO; - } + /* get minimum line height from containing block. + * this is the line-height if there are text children and also in the + * case of an initially empty text input */ + if (has_text_children || first->parent->parent->gadget) + used_height = height = + line_height(first->parent->parent->style); + else + /* inline containers with no text are usually for layout and + * look better with no minimum line-height */ + used_height = height = 0; - /* top */ - type = css_computed_top(box->style, &value, &unit); - if (type == CSS_TOP_SET) { - if (unit == CSS_UNIT_PCT) { - *top = FPCT_OF_INT_TOINT(value, - containing_block->height); - } else { - *top = FIXTOINT(nscss_len2px(value, unit, box->style)); - } - } else { - *top = AUTO; - } + /* pass 1: find height of line assuming sides at top of line: loop + * body executed at least once + * keep in sync with the loop in layout_minmax_line() */ - /* bottom */ - type = css_computed_bottom(box->style, &value, &unit); - if (type == CSS_BOTTOM_SET) { - if (unit == CSS_UNIT_PCT) { - *bottom = FPCT_OF_INT_TOINT(value, - containing_block->height); - } else { - *bottom = FIXTOINT(nscss_len2px(value, unit, - box->style)); - } - } else { - *bottom = AUTO; - } -} + NSLOG(layout, DEBUG, "x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0); -/** - * Layout and position an absolutely positioned box. - * - * \param box absolute box to layout and position - * \param containing_block containing block - * \param cx position of box relative to containing_block - * \param cy position of box relative to containing_block - * \param content memory pool for any new boxes - * \return true on success, false on memory exhaustion - */ -static bool -layout_absolute(struct box *box, - struct box *containing_block, - int cx, int cy, - html_content *content) -{ - int static_left, static_top; /* static position */ - int top, right, bottom, left; - int width, height, max_width, min_width; - int *margin = box->margin; - int *padding = box->padding; - struct box_border *border = box->border; - int available_width = containing_block->width; - int space; + for (x = 0, b = first; x <= x1 - x0 && b != 0; b = b->next) { + int min_width, max_width, min_height, max_height; - assert(box->type == BOX_BLOCK || box->type == BOX_TABLE || - box->type == BOX_INLINE_BLOCK); + assert(b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK || + b->type == BOX_FLOAT_LEFT || + b->type == BOX_FLOAT_RIGHT || + b->type == BOX_BR || b->type == BOX_TEXT || + b->type == BOX_INLINE_END); - /* The static position is where the box would be if it was not - * absolutely positioned. The x and y are filled in by - * layout_block_context(). */ - static_left = cx + box->x; - static_top = cy + box->y; - if (containing_block->type == BOX_BLOCK || - containing_block->type == BOX_INLINE_BLOCK || - containing_block->type == BOX_TABLE_CELL) { - /* Block level container => temporarily increase containing - * block dimensions to include padding (we restore this - * again at the end) */ - containing_block->width += containing_block->padding[LEFT] + - containing_block->padding[RIGHT]; - containing_block->height += containing_block->padding[TOP] + - containing_block->padding[BOTTOM]; - } else { - /** \todo inline containers */ - } + NSLOG(layout, DEBUG, "pass 1: b %p, x %i", b, x); - layout_compute_offsets(box, containing_block, - &top, &right, &bottom, &left); - /* Pass containing block into layout_find_dimensions via the float - * containing block box member. This is unused for absolutely positioned - * boxes because a box can't be floated and absolutely positioned. */ - box->float_container = containing_block; - layout_find_dimensions(available_width, -1, box, box->style, - &width, &height, &max_width, &min_width, - 0, 0, margin, padding, border); - box->float_container = NULL; + if (b->type == BOX_BR) + break; - /* 10.3.7 */ - NSLOG(layout, DEBUG, - "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", - left, margin[LEFT], border[LEFT].width, padding[LEFT], width, - padding[RIGHT], border[RIGHT].width, margin[RIGHT], right, - containing_block->width); + if (b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT) + continue; + if (b->type == BOX_INLINE_BLOCK && + (css_computed_position(b->style) == + CSS_POSITION_ABSOLUTE || + css_computed_position(b->style) == + CSS_POSITION_FIXED)) + continue; + assert(b->style != NULL); + font_plot_style_from_css(b->style, &fstyle); - if (left == AUTO && width == AUTO && right == AUTO) { - if (margin[LEFT] == AUTO) - margin[LEFT] = 0; - if (margin[RIGHT] == AUTO) - margin[RIGHT] = 0; - left = static_left; + x += space_after; - width = min(max(box->min_width, available_width), - box->max_width); - width -= box->margin[LEFT] + box->border[LEFT].width + - box->padding[LEFT] + box->padding[RIGHT] + - box->border[RIGHT].width + box->margin[RIGHT]; - - /* Adjust for {min|max}-width */ - if (max_width >= 0 && width > max_width) width = max_width; - if (width < min_width) width = min_width; - - right = containing_block->width - - left - - margin[LEFT] - border[LEFT].width - padding[LEFT] - - width - - padding[RIGHT] - border[RIGHT].width - margin[RIGHT]; - } else if (left != AUTO && width != AUTO && right != AUTO) { - - /* Adjust for {min|max}-width */ - if (max_width >= 0 && width > max_width) width = max_width; - if (min_width > 0 && width < min_width) width = min_width; + if (b->type == BOX_INLINE_BLOCK) { + if (b->max_width != UNKNOWN_WIDTH) + if (!layout_float(b, *width, content)) + return false; + h = b->border[TOP].width + b->padding[TOP] + b->height + + b->padding[BOTTOM] + + b->border[BOTTOM].width; + if (height < h) + height = h; + x += b->margin[LEFT] + b->border[LEFT].width + + b->padding[LEFT] + b->width + + b->padding[RIGHT] + + b->border[RIGHT].width + + b->margin[RIGHT]; + space_after = 0; + continue; + } - if (margin[LEFT] == AUTO && margin[RIGHT] == AUTO) { - space = containing_block->width - - left - border[LEFT].width - - padding[LEFT] - width - padding[RIGHT] - - border[RIGHT].width - right; - if (space < 0) { - margin[LEFT] = 0; - margin[RIGHT] = space; + if (b->type == BOX_INLINE) { + /* calculate borders, margins, and padding */ + layout_find_dimensions(*width, -1, b, b->style, 0, 0, + 0, 0, 0, 0, b->margin, b->padding, + b->border); + for (i = 0; i != 4; i++) + if (b->margin[i] == AUTO) + b->margin[i] = 0; + x += b->margin[LEFT] + b->border[LEFT].width + + b->padding[LEFT]; + if (b->inline_end) { + b->inline_end->margin[RIGHT] = b->margin[RIGHT]; + b->inline_end->padding[RIGHT] = + b->padding[RIGHT]; + b->inline_end->border[RIGHT] = + b->border[RIGHT]; } else { - margin[LEFT] = margin[RIGHT] = space / 2; + x += b->padding[RIGHT] + + b->border[RIGHT].width + + b->margin[RIGHT]; } - } else if (margin[LEFT] == AUTO) { - margin[LEFT] = containing_block->width - - left - border[LEFT].width - - padding[LEFT] - width - padding[RIGHT] - - border[RIGHT].width - margin[RIGHT] - - right; - } else if (margin[RIGHT] == AUTO) { - margin[RIGHT] = containing_block->width - - left - margin[LEFT] - - border[LEFT].width - - padding[LEFT] - width - padding[RIGHT] - - border[RIGHT].width - right; - } else { - right = containing_block->width - - left - margin[LEFT] - - border[LEFT].width - - padding[LEFT] - width - padding[RIGHT] - - border[RIGHT].width - margin[RIGHT]; + } else if (b->type == BOX_INLINE_END) { + b->width = 0; + if (b->space == UNKNOWN_WIDTH) { + font_func->width(&fstyle, " ", 1, &b->space); + /** \todo handle errors */ + } + space_after = b->space; + + x += b->padding[RIGHT] + b->border[RIGHT].width + + b->margin[RIGHT]; + continue; } - } else { - if (margin[LEFT] == AUTO) - margin[LEFT] = 0; - if (margin[RIGHT] == AUTO) - margin[RIGHT] = 0; - if (left == AUTO && width == AUTO && right != AUTO) { - available_width -= right; + if (!b->object && !(b->flags & IFRAME) && !b->gadget && + !(b->flags & REPLACE_DIM)) { + /* inline non-replaced, 10.3.1 and 10.6.1 */ + b->height = line_height(b->style ? b->style : + b->parent->parent->style); + if (height < b->height) + height = b->height; - width = min(max(box->min_width, available_width), - box->max_width); - width -= box->margin[LEFT] + box->border[LEFT].width + - box->padding[LEFT] + box->padding[RIGHT] + - box->border[RIGHT].width + box->margin[RIGHT]; + if (!b->text) { + b->width = 0; + space_after = 0; + continue; + } - /* Adjust for {min|max}-width */ - if (max_width >= 0 && width > max_width) - width = max_width; - if (width < min_width) - width = min_width; + if (b->width == UNKNOWN_WIDTH) { + /** \todo handle errors */ - left = containing_block->width - - margin[LEFT] - border[LEFT].width - - padding[LEFT] - width - padding[RIGHT] - - border[RIGHT].width - margin[RIGHT] - - right; - } else if (left == AUTO && width != AUTO && right == AUTO) { + /* If it's a select element, we must use the + * width of the widest option text */ + if (b->parent->parent->gadget && + b->parent->parent->gadget->type + == GADGET_SELECT) { + int opt_maxwidth = 0; + struct form_option *o; - /* Adjust for {min|max}-width */ - if (max_width >= 0 && width > max_width) - width = max_width; - if (min_width > 0 && width < min_width) - width = min_width; + for (o = b->parent->parent->gadget-> + data.select.items; o; + o = o->next) { + int opt_width; + font_func->width(&fstyle, + o->text, + strlen(o->text), + &opt_width); - left = static_left; - right = containing_block->width - - left - margin[LEFT] - - border[LEFT].width - - padding[LEFT] - width - padding[RIGHT] - - border[RIGHT].width - margin[RIGHT]; - } else if (left != AUTO && width == AUTO && right == AUTO) { - available_width -= left; + if (opt_maxwidth < opt_width) + opt_maxwidth =opt_width; + } + b->width = opt_maxwidth; + if (nsoption_bool(core_select_menu)) + b->width += SCROLLBAR_WIDTH; + } else { + font_func->width(&fstyle, b->text, + b->length, &b->width); + b->flags |= MEASURED; + } + } - width = min(max(box->min_width, available_width), - box->max_width); - width -= box->margin[LEFT] + box->border[LEFT].width + - box->padding[LEFT] + box->padding[RIGHT] + - box->border[RIGHT].width + box->margin[RIGHT]; + /* If the current text has not been measured (i.e. its + * width was estimated after splitting), and it fits on + * the line, measure it properly, so next box is placed + * correctly. */ + if (b->text && (x + b->width < x1 - x0) && + !(b->flags & MEASURED) && + b->next) { + font_func->width(&fstyle, b->text, + b->length, &b->width); + b->flags |= MEASURED; + } - /* Adjust for {min|max}-width */ - if (max_width >= 0 && width > max_width) - width = max_width; - if (width < min_width) - width = min_width; + x += b->width; + if (b->space == UNKNOWN_WIDTH) { + font_func->width(&fstyle, " ", 1, &b->space); + /** \todo handle errors */ + } + space_after = b->space; + continue; + } - right = containing_block->width - - left - margin[LEFT] - - border[LEFT].width - - padding[LEFT] - width - padding[RIGHT] - - border[RIGHT].width - margin[RIGHT]; - } else if (left == AUTO && width != AUTO && right != AUTO) { + space_after = 0; - /* Adjust for {min|max}-width */ - if (max_width >= 0 && width > max_width) - width = max_width; - if (width < min_width) - width = min_width; + /* inline replaced, 10.3.2 and 10.6.2 */ + assert(b->style); - left = containing_block->width - - margin[LEFT] - border[LEFT].width - - padding[LEFT] - width - padding[RIGHT] - - border[RIGHT].width - margin[RIGHT] - - right; - } else if (left != AUTO && width == AUTO && right != AUTO) { - width = containing_block->width - - left - margin[LEFT] - - border[LEFT].width - - padding[LEFT] - padding[RIGHT] - - border[RIGHT].width - margin[RIGHT] - - right; + layout_find_dimensions(*width, -1, b, b->style, + &b->width, &b->height, &max_width, &min_width, + &max_height, &min_height, NULL, NULL, NULL); - /* Adjust for {min|max}-width */ - if (max_width >= 0 && width > max_width) - width = max_width; - if (width < min_width) - width = min_width; + if (b->object && !(b->flags & REPLACE_DIM)) { + layout_get_object_dimensions(b, &b->width, &b->height, + min_width, max_width, + min_height, max_height); + } else if (b->flags & IFRAME) { + /* TODO: should we look at the content dimensions? */ + if (b->width == AUTO) + b->width = 400; + if (b->height == AUTO) + b->height = 300; - } else if (left != AUTO && width != AUTO && right == AUTO) { + /* We reformat the iframe browser window to new + * dimensions in pass 2 */ + } else { + /* form control with no object */ + if (b->width == AUTO) + b->width = FIXTOINT(nscss_len2px(INTTOFIX(1), + CSS_UNIT_EM, b->style)); + if (b->height == AUTO) + b->height = FIXTOINT(nscss_len2px(INTTOFIX(1), + CSS_UNIT_EM, b->style)); + } - /* Adjust for {min|max}-width */ - if (max_width >= 0 && width > max_width) - width = max_width; - if (width < min_width) - width = min_width; + /* Reformat object to new box size */ + if (b->object && content_get_type(b->object) == CONTENT_HTML && + b->width != + content_get_available_width(b->object)) { + css_fixed value = 0; + css_unit unit = CSS_UNIT_PX; + enum css_height_e htype = css_computed_height(b->style, + &value, &unit); - right = containing_block->width - - left - margin[LEFT] - - border[LEFT].width - - padding[LEFT] - width - padding[RIGHT] - - border[RIGHT].width - margin[RIGHT]; + content_reformat(b->object, false, b->width, b->height); + + if (htype == CSS_HEIGHT_AUTO) + b->height = content_get_height(b->object); } - } - NSLOG(layout, DEBUG, - "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", - left, margin[LEFT], border[LEFT].width, padding[LEFT], width, - padding[RIGHT], border[RIGHT].width, margin[RIGHT], right, - containing_block->width); + if (height < b->height) + height = b->height; - box->x = left + margin[LEFT] + border[LEFT].width - cx; - if (containing_block->type == BOX_BLOCK || - containing_block->type == BOX_INLINE_BLOCK || - containing_block->type == BOX_TABLE_CELL) { - /* Block-level ancestor => reset container's width */ - containing_block->width -= containing_block->padding[LEFT] + - containing_block->padding[RIGHT]; - } else { - /** \todo inline ancestors */ + x += b->width; } - box->width = width; - box->height = height; - if (box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK || - box->object || box->flags & IFRAME) { - if (!layout_block_context(box, -1, content)) - return false; - } else if (box->type == BOX_TABLE) { - /* layout_table also expects the containing block to be - * stored in the float_container field */ - box->float_container = containing_block; - /* \todo layout_table considers margins etc. again */ - if (!layout_table(box, width, content)) - return false; - box->float_container = NULL; - layout_solve_width(box, box->parent->width, box->width, 0, 0, - -1, -1); - } + /* find new sides using this height */ + x0 = cx; + x1 = cx + *width; + find_sides(cont->float_children, cy, cy + height, &x0, &x1, + &left, &right); + x0 -= cx; + x1 -= cx; - /* 10.6.4 */ - NSLOG(layout, DEBUG, - "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", - top, margin[TOP], border[TOP].width, padding[TOP], height, - padding[BOTTOM], border[BOTTOM].width, margin[BOTTOM], bottom, - containing_block->height); + if (indent) + x0 += layout_text_indent(first->parent->parent->style, *width); - if (top == AUTO && height == AUTO && bottom == AUTO) { - top = static_top; - height = box->height; - if (margin[TOP] == AUTO) - margin[TOP] = 0; - if (margin[BOTTOM] == AUTO) - margin[BOTTOM] = 0; - bottom = containing_block->height - - top - margin[TOP] - border[TOP].width - - padding[TOP] - height - padding[BOTTOM] - - border[BOTTOM].width - margin[BOTTOM]; - } else if (top != AUTO && height != AUTO && bottom != AUTO) { - if (margin[TOP] == AUTO && margin[BOTTOM] == AUTO) { - space = containing_block->height - - top - border[TOP].width - padding[TOP] - - height - padding[BOTTOM] - - border[BOTTOM].width - bottom; - margin[TOP] = margin[BOTTOM] = space / 2; - } else if (margin[TOP] == AUTO) { - margin[TOP] = containing_block->height - - top - border[TOP].width - padding[TOP] - - height - padding[BOTTOM] - - border[BOTTOM].width - margin[BOTTOM] - - bottom; - } else if (margin[BOTTOM] == AUTO) { - margin[BOTTOM] = containing_block->height - - top - margin[TOP] - border[TOP].width - - padding[TOP] - height - - padding[BOTTOM] - border[BOTTOM].width - - bottom; - } else { - bottom = containing_block->height - - top - margin[TOP] - border[TOP].width - - padding[TOP] - height - - padding[BOTTOM] - border[BOTTOM].width - - margin[BOTTOM]; - } - } else { - if (margin[TOP] == AUTO) - margin[TOP] = 0; - if (margin[BOTTOM] == AUTO) - margin[BOTTOM] = 0; - if (top == AUTO && height == AUTO && bottom != AUTO) { - height = box->height; - top = containing_block->height - - margin[TOP] - border[TOP].width - - padding[TOP] - height - - padding[BOTTOM] - border[BOTTOM].width - - margin[BOTTOM] - bottom; - } else if (top == AUTO && height != AUTO && bottom == AUTO) { - top = static_top; - bottom = containing_block->height - - top - margin[TOP] - border[TOP].width - - padding[TOP] - height - - padding[BOTTOM] - border[BOTTOM].width - - margin[BOTTOM]; - } else if (top != AUTO && height == AUTO && bottom == AUTO) { - height = box->height; - bottom = containing_block->height - - top - margin[TOP] - border[TOP].width - - padding[TOP] - height - - padding[BOTTOM] - border[BOTTOM].width - - margin[BOTTOM]; - } else if (top == AUTO && height != AUTO && bottom != AUTO) { - top = containing_block->height - - margin[TOP] - border[TOP].width - - padding[TOP] - height - - padding[BOTTOM] - border[BOTTOM].width - - margin[BOTTOM] - bottom; - } else if (top != AUTO && height == AUTO && bottom != AUTO) { - height = containing_block->height - - top - margin[TOP] - border[TOP].width - - padding[TOP] - padding[BOTTOM] - - border[BOTTOM].width - margin[BOTTOM] - - bottom; - } else if (top != AUTO && height != AUTO && bottom == AUTO) { - bottom = containing_block->height - - top - margin[TOP] - border[TOP].width - - padding[TOP] - height - - padding[BOTTOM] - border[BOTTOM].width - - margin[BOTTOM]; - } - } + if (x1 < x0) + x1 = x0; - NSLOG(layout, DEBUG, - "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", - top, margin[TOP], border[TOP].width, padding[TOP], height, - padding[BOTTOM], border[BOTTOM].width, margin[BOTTOM], bottom, - containing_block->height); + space_after = space_before = 0; - box->y = top + margin[TOP] + border[TOP].width - cy; - if (containing_block->type == BOX_BLOCK || - containing_block->type == BOX_INLINE_BLOCK || - containing_block->type == BOX_TABLE_CELL) { - /* Block-level ancestor => reset container's height */ - containing_block->height -= containing_block->padding[TOP] + - containing_block->padding[BOTTOM]; - } else { - /** \todo Inline ancestors */ - } - box->height = height; - layout_apply_minmax_height(box, containing_block); + /* pass 2: place boxes in line: loop body executed at least once */ - return true; -} + NSLOG(layout, DEBUG, "x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0); + for (x = x_previous = 0, b = first; x <= x1 - x0 && b; b = b->next) { -/** - * Recursively layout and position absolutely positioned boxes. - * - * \param box tree of boxes to layout - * \param containing_block current containing block - * \param cx position of box relative to containing_block - * \param cy position of box relative to containing_block - * \param content memory pool for any new boxes - * \return true on success, false on memory exhaustion - */ -static bool -layout_position_absolute(struct box *box, - struct box *containing_block, - int cx, int cy, - html_content *content) -{ - struct box *c; + NSLOG(layout, DEBUG, "pass 2: b %p, x %i", b, x); - for (c = box->children; c; c = c->next) { - if ((c->type == BOX_BLOCK || c->type == BOX_TABLE || - c->type == BOX_INLINE_BLOCK) && - (css_computed_position(c->style) == + if (b->type == BOX_INLINE_BLOCK && + (css_computed_position(b->style) == CSS_POSITION_ABSOLUTE || - css_computed_position(c->style) == + css_computed_position(b->style) == CSS_POSITION_FIXED)) { - if (!layout_absolute(c, containing_block, - cx, cy, content)) - return false; - if (!layout_position_absolute(c, c, 0, 0, content)) - return false; - } else if (c->style && css_computed_position(c->style) == - CSS_POSITION_RELATIVE) { - if (!layout_position_absolute(c, c, 0, 0, content)) - return false; - } else { - int px, py; - if (c->style && (css_computed_float(c->style) == - CSS_FLOAT_LEFT || - css_computed_float(c->style) == - CSS_FLOAT_RIGHT)) { - /* Float x/y coords are relative to nearest - * ansestor with float_children, rather than - * relative to parent. Need to get x/y relative - * to parent */ - struct box *p; - px = c->x; - py = c->y; - for (p = box->parent; p && !p->float_children; - p = p->parent) { - px -= p->x; - py -= p->y; - } - } else { - /* Not a float, so box x/y coords are relative - * to parent */ - px = c->x; - py = c->y; - } - if (!layout_position_absolute(c, containing_block, - cx + px, cy + py, content)) - return false; - } - } + b->x = x + space_after; - return true; -} + } else if (b->type == BOX_INLINE || + b->type == BOX_INLINE_BLOCK || + b->type == BOX_TEXT || + b->type == BOX_INLINE_END) { + assert(b->width != UNKNOWN_WIDTH); + x_previous = x; + x += space_after; + b->x = x; -/** - * Compute a box's relative offset as per CSS 2.1 9.4.3 - * - * \param box Box to compute relative offsets for. - * \param x Receives relative offset in x. - * \param y Receives relative offset in y. - */ -static void layout_compute_relative_offset(struct box *box, int *x, int *y) -{ - int left, right, top, bottom; - struct box *containing_block; - - assert(box && box->parent && box->style && - css_computed_position(box->style) == - CSS_POSITION_RELATIVE); - - if (box->float_container && - (css_computed_float(box->style) == CSS_FLOAT_LEFT || - css_computed_float(box->style) == CSS_FLOAT_RIGHT)) { - containing_block = box->float_container; - } else { - containing_block = box->parent; - } + if ((b->type == BOX_INLINE && !b->inline_end) || + b->type == BOX_INLINE_BLOCK) { + b->x += b->margin[LEFT] + b->border[LEFT].width; + x = b->x + b->padding[LEFT] + b->width + + b->padding[RIGHT] + + b->border[RIGHT].width + + b->margin[RIGHT]; + } else if (b->type == BOX_INLINE) { + b->x += b->margin[LEFT] + b->border[LEFT].width; + x = b->x + b->padding[LEFT] + b->width; + } else if (b->type == BOX_INLINE_END) { + b->height = b->inline_end->height; + x += b->padding[RIGHT] + + b->border[RIGHT].width + + b->margin[RIGHT]; + } else { + x += b->width; + } - layout_compute_offsets(box, containing_block, - &top, &right, &bottom, &left); + space_before = space_after; + if (b->object || b->flags & REPLACE_DIM || + b->flags & IFRAME) + space_after = 0; + else if (b->text || b->type == BOX_INLINE_END) { + if (b->space == UNKNOWN_WIDTH) { + font_plot_style_from_css(b->style, + &fstyle); + /** \todo handle errors */ + font_func->width(&fstyle, " ", 1, + &b->space); + } + space_after = b->space; + } else { + space_after = 0; + } + split_box = b; + move_y = true; + inline_count++; + } else if (b->type == BOX_BR) { + b->x = x; + b->width = 0; + br_box = b; + b = b->next; + split_box = 0; + move_y = true; + break; - if (left == AUTO && right == AUTO) - left = right = 0; - else if (left == AUTO) - /* left is auto => computed = -right */ - left = -right; - else if (right == AUTO) - /* right is auto => computed = -left */ - right = -left; - else { - /* over constrained => examine direction property - * of containing block */ - if (containing_block->style && - css_computed_direction( - containing_block->style) == - CSS_DIRECTION_RTL) { - /* right wins */ - left = -right; } else { - /* assume LTR in all other cases */ - right = -left; - } - } + /* float */ + NSLOG(layout, DEBUG, "float %p", b); - assert(left == -right); + d = b->children; + d->float_children = 0; + d->cached_place_below_level = 0; + b->float_container = d->float_container = cont; - if (top == AUTO && bottom == AUTO) { - top = bottom = 0; - } else if (top == AUTO) { - top = -bottom; - } else { - /* bottom is AUTO, or neither are AUTO */ - bottom = -top; - } + if (!layout_float(d, *width, content)) + return false; - NSLOG(layout, DEBUG, "left %i, right %i, top %i, bottom %i", left, - right, top, bottom); + NSLOG(layout, DEBUG, + "%p : %d %d", + d, + d->margin[TOP], + d->border[TOP].width); - *x = left; - *y = top; -} + d->x = d->margin[LEFT] + d->border[LEFT].width; + d->y = d->margin[TOP] + d->border[TOP].width; + b->width = d->margin[LEFT] + d->border[LEFT].width + + d->padding[LEFT] + d->width + + d->padding[RIGHT] + + d->border[RIGHT].width + + d->margin[RIGHT]; + b->height = d->margin[TOP] + d->border[TOP].width + + d->padding[TOP] + d->height + + d->padding[BOTTOM] + + d->border[BOTTOM].width + + d->margin[BOTTOM]; + if (b->width > (x1 - x0) - x) + place_below = true; + if (d->style && (css_computed_clear(d->style) == + CSS_CLEAR_NONE || + (css_computed_clear(d->style) == + CSS_CLEAR_LEFT && left == 0) || + (css_computed_clear(d->style) == + CSS_CLEAR_RIGHT && + right == 0) || + (css_computed_clear(d->style) == + CSS_CLEAR_BOTH && + left == 0 && right == 0)) && + (!place_below || + (left == 0 && right == 0 && x == 0)) && + cy >= cont->clear_level && + cy >= cont->cached_place_below_level) { + /* + not cleared or, + * cleared and there are no floats to clear + * + fits without needing to be placed below or, + * this line is empty with no floats + * + current y, cy, is below the clear level + * + * Float affects current line */ + if (b->type == BOX_FLOAT_LEFT) { + b->x = cx + x0; + if (b->width > 0) + x0 += b->width; + left = b; + } else { + b->x = cx + x1 - b->width; + if (b->width > 0) + x1 -= b->width; + right = b; + } + b->y = cy; + } else { + /* cleared or doesn't fit on line */ + /* place below into next available space */ + int fcy = (cy > cont->clear_level) ? cy : + cont->clear_level; + fcy = (fcy > cont->cached_place_below_level) ? + fcy : + cont->cached_place_below_level; + fy = (fy > fcy) ? fy : fcy; + fy = (fy == cy) ? fy + height : fy; -/** - * Adjust positions of relatively positioned boxes. - * - * \param root box to adjust the position of - * \param fp box which forms the block formatting context for children of - * "root" which are floats - * \param fx x offset due to intervening relatively positioned boxes - * between current box, "root", and the block formatting context - * box, "fp", for float children of "root" - * \param fy y offset due to intervening relatively positioned boxes - * between current box, "root", and the block formatting context - * box, "fp", for float children of "root" - */ -static void -layout_position_relative(struct box *root, struct box *fp, int fx, int fy) -{ - struct box *box; /* for children of "root" */ - struct box *fn; /* for block formatting context box for children of - * "box" */ - struct box *fc; /* for float children of the block formatting context, - * "fp" */ - int x, y; /* for the offsets resulting from any relative - * positioning on the current block */ - int fnx, fny; /* for affsets which apply to flat children of "box" */ + place_float_below(b, *width, cx, fy, cont); + fy = b->y; + if (d->style && ( + (css_computed_clear(d->style) == + CSS_CLEAR_LEFT && left != 0) || + (css_computed_clear(d->style) == + CSS_CLEAR_RIGHT && + right != 0) || + (css_computed_clear(d->style) == + CSS_CLEAR_BOTH && + (left != 0 || right != 0)))) { + /* to be cleared below existing + * floats */ + if (b->type == BOX_FLOAT_LEFT) + b->x = cx; + else + b->x = cx + *width - b->width; - /**\todo ensure containing box is large enough after moving boxes */ + fcy = layout_clear(cont->float_children, + css_computed_clear(d->style)); + if (fcy > cont->clear_level) + cont->clear_level = fcy; + if (b->y < fcy) + b->y = fcy; + } + if (b->type == BOX_FLOAT_LEFT) + left = b; + else + right = b; + } + add_float_to_container(cont, b); - assert(root); + split_box = 0; + } + } - /* Normal children */ - for (box = root->children; box; box = box->next) { + if (x1 - x0 < x && split_box) { + /* the last box went over the end */ + size_t split = 0; + int w; + bool no_wrap = css_computed_white_space( + split_box->style) == CSS_WHITE_SPACE_NOWRAP || + css_computed_white_space( + split_box->style) == CSS_WHITE_SPACE_PRE; - if (box->type == BOX_TEXT) - continue; + x = x_previous; - /* If relatively positioned, get offsets */ - if (box->style && css_computed_position(box->style) == - CSS_POSITION_RELATIVE) - layout_compute_relative_offset(box, &x, &y); - else - x = y = 0; + if (!no_wrap && + (split_box->type == BOX_INLINE || + split_box->type == BOX_TEXT) && + !split_box->object && + !(split_box->flags & REPLACE_DIM) && + !(split_box->flags & IFRAME) && + !split_box->gadget && split_box->text) { - /* Adjust float coordinates. - * (note float x and y are relative to their block formatting - * context box and not their parent) */ - if (box->style && (css_computed_float(box->style) == - CSS_FLOAT_LEFT || - css_computed_float(box->style) == - CSS_FLOAT_RIGHT) && - (fx != 0 || fy != 0)) { - /* box is a float and there is a float offset to - * apply */ - for (fc = fp->float_children; fc; fc = fc->next_float) { - if (box == fc->children) { - /* Box is floated in the block - * formatting context block, fp. - * Apply float offsets. */ - box->x += fx; - box->y += fy; - fx = fy = 0; - } - } + font_plot_style_from_css(split_box->style, &fstyle); + /** \todo handle errors */ + font_func->split(&fstyle, + split_box->text, + split_box->length, + x1 - x0 - x - space_before, + &split, + &w); } - if (box->float_children) { - fn = box; - fnx = fny = 0; - } else { - fn = fp; - fnx = fx + x; - fny = fy + y; - } + /* split == 0 implies that text can't be split */ - /* recurse first */ - layout_position_relative(box, fn, fnx, fny); + if (split == 0) + w = split_box->width; - /* Ignore things we're not interested in. */ - if (!box->style || (box->style && - css_computed_position(box->style) != - CSS_POSITION_RELATIVE)) - continue; - box->x += x; - box->y += y; + NSLOG(layout, DEBUG, + "splitting: split_box %p \"%.*s\", spilt %zu, w %i, " + "left %p, right %p, inline_count %u", + split_box, + (int)split_box->length, + split_box->text, + split, + w, + left, + right, + inline_count); - /* Handle INLINEs - their "children" are in fact - * the sibling boxes between the INLINE and - * INLINE_END boxes */ - if (box->type == BOX_INLINE && box->inline_end) { - struct box *b; - for (b = box->next; b && b != box->inline_end; - b = b->next) { - b->x += x; - b->y += y; + if ((split == 0 || x1 - x0 <= x + space_before + w) && + !left && !right && inline_count == 1) { + /* first word of box doesn't fit, but no floats and + * first box on line so force in */ + if (split == 0 || split == split_box->length) { + /* only one word in this box, or not text + * or white-space:nowrap */ + b = split_box->next; + } else { + /* cut off first word for this line */ + if (!layout_text_box_split(content, &fstyle, + split_box, split, w)) + return false; + b = split_box->next; } - } - } -} + x += space_before + w; + NSLOG(layout, DEBUG, "forcing"); -/* exported function documented in render/layout.h */ -bool layout_document(html_content *content, int width, int height) -{ - bool ret; - struct box *doc = content->layout; - const struct gui_layout_table *font_func = content->font_func; + } else if ((split == 0 || x1 - x0 <= x + space_before + w) && + inline_count == 1) { + /* first word of first box doesn't fit, but a float is + * taking some of the width so move below it */ + assert(left || right); + used_height = 0; + if (left) { - layout_minmax_block(doc, font_func); + NSLOG(layout, DEBUG, + "cy %i, left->y %i, left->height %i", + cy, + left->y, + left->height); - layout_block_find_dimensions(width, height, 0, 0, doc); - doc->x = doc->margin[LEFT] + doc->border[LEFT].width; - doc->y = doc->margin[TOP] + doc->border[TOP].width; - width -= doc->margin[LEFT] + doc->border[LEFT].width + - doc->padding[LEFT] + doc->padding[RIGHT] + - doc->border[RIGHT].width + doc->margin[RIGHT]; - if (width < 0) { - width = 0; - } - doc->width = width; + used_height = left->y + left->height - cy + 1; - ret = layout_block_context(doc, height, content); + NSLOG(layout, DEBUG, "used_height %i", + used_height); - /* make and fill available height */ - if (doc->y + doc->padding[TOP] + doc->height + doc->padding[BOTTOM] + - doc->border[BOTTOM].width + doc->margin[BOTTOM] < - height) { - doc->height = height - (doc->y + doc->padding[TOP] + - doc->padding[BOTTOM] + - doc->border[BOTTOM].width + - doc->margin[BOTTOM]); - if (doc->children) - doc->children->height = doc->height - - (doc->children->margin[TOP] + - doc->children->border[TOP].width + - doc->children->padding[TOP] + - doc->children->padding[BOTTOM] + - doc->children->border[BOTTOM].width + - doc->children->margin[BOTTOM]); - } + } + if (right && used_height < + right->y + right->height - cy + 1) + used_height = right->y + right->height - cy + 1; - layout_lists(doc, font_func); - layout_position_absolute(doc, doc, 0, 0, content); - layout_position_relative(doc, doc, 0, 0); + if (used_height < 0) + used_height = 0; - layout_calculate_descendant_bboxes(doc); + b = split_box; - return ret; -} + NSLOG(layout, DEBUG, "moving below float"); + } else if (split == 0 || x1 - x0 <= x + space_before + w) { + /* first word of box doesn't fit so leave box for next + * line */ + b = split_box; -/** - * Insert a float into a container. - * - * \param cont block formatting context block, used to contain float - * \param b box to add to float - * - * This sorts floats in order of descending bottom edges. - */ -static void add_float_to_container(struct box *cont, struct box *b) -{ - struct box *box = cont->float_children; - int b_bottom = b->y + b->height; + NSLOG(layout, DEBUG, "leaving for next line"); - assert(b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT); + } else { + /* fit as many words as possible */ + assert(split != 0); - if (box == NULL) { - /* No other float children */ - b->next_float = NULL; - cont->float_children = b; - return; - } else if (b_bottom >= box->y + box->height) { - /* Goes at start of list */ - b->next_float = cont->float_children; - cont->float_children = b; - } else { - struct box *prev = NULL; - while (box != NULL && b_bottom < box->y + box->height) { - prev = box; - box = box->next_float; - } - if (prev != NULL) { - b->next_float = prev->next_float; - prev->next_float = b; - } - } -} + NSLOG(layout, DEBUG, "'%.*s' %i %zu %i", + (int)split_box->length, split_box->text, + x1 - x0, split, w); + if (split != split_box->length) { + if (!layout_text_box_split(content, &fstyle, + split_box, split, w)) + return false; + b = split_box->next; + } + x += space_before + w; -/** - * Split a text box. - * - * \param content memory pool for any new boxes - * \param fstyle style for text in text box - * \param split_box box with text to split - * \param new_length new length for text in split_box, after splitting - * \param new_width new width for text in split_box, after splitting - * \return true on success, false on memory exhaustion - * - * A new box is created and inserted into the box tree after split_box, - * containing the text after new_length excluding the initial space character. - */ -static bool -layout_text_box_split(html_content *content, - plot_font_style_t *fstyle, - struct box *split_box, - size_t new_length, - int new_width) -{ - int space_width = split_box->space; - struct box *c2; - const struct gui_layout_table *font_func = content->font_func; - bool space = (split_box->text[new_length] == ' '); - int used_length = new_length + (space ? 1 : 0); + NSLOG(layout, DEBUG, "fitting words"); - if ((space && space_width == 0) || space_width == UNKNOWN_WIDTH) { - /* We're need to add a space, and we don't know how big - * it's to be, OR we have a space of unknown width anyway; - * Calculate space width */ - font_func->width(fstyle, " ", 1, &space_width); + } + move_y = true; } - if (split_box->space == UNKNOWN_WIDTH) - split_box->space = space_width; - if (!space) - space_width = 0; - - /* Create clone of split_box, c2 */ - c2 = talloc_memdup(content->bctx, split_box, sizeof *c2); - if (!c2) - return false; - c2->flags |= CLONE; - - /* Set remaining text in c2 */ - c2->text += used_length; - - /* Set c2 according to the remaining text */ - c2->width -= new_width + space_width; - c2->flags &= ~MEASURED; /* width has been estimated */ - c2->length = split_box->length - used_length; - - /* Update split_box for its reduced text */ - split_box->width = new_width; - split_box->flags |= MEASURED; - split_box->length = new_length; - split_box->space = space_width; + /* set positions */ + switch (css_computed_text_align(first->parent->parent->style)) { + case CSS_TEXT_ALIGN_RIGHT: + case CSS_TEXT_ALIGN_LIBCSS_RIGHT: + x0 = x1 - x; + break; + case CSS_TEXT_ALIGN_CENTER: + case CSS_TEXT_ALIGN_LIBCSS_CENTER: + x0 = (x0 + (x1 - x)) / 2; + break; + case CSS_TEXT_ALIGN_LEFT: + case CSS_TEXT_ALIGN_LIBCSS_LEFT: + case CSS_TEXT_ALIGN_JUSTIFY: + /* leave on left */ + break; + case CSS_TEXT_ALIGN_DEFAULT: + /* None; consider text direction */ + switch (css_computed_direction(first->parent->parent->style)) { + case CSS_DIRECTION_LTR: + /* leave on left */ + break; + case CSS_DIRECTION_RTL: + x0 = x1 - x; + break; + } + break; + } - /* Insert c2 into box list */ - c2->next = split_box->next; - split_box->next = c2; - c2->prev = split_box; - if (c2->next) - c2->next->prev = c2; - else - c2->parent->last = c2; + for (d = first; d != b; d = d->next) { + d->flags &= ~NEW_LINE; - NSLOG(layout, DEBUG, - "split_box %p len: %" PRIsizet " \"%.*s\"", - split_box, - split_box->length, - (int)split_box->length, - split_box->text); - NSLOG(layout, DEBUG, - " new_box %p len: %" PRIsizet " \"%.*s\"", - c2, - c2->length, - (int)c2->length, - c2->text); + if (d->type == BOX_INLINE_BLOCK && + (css_computed_position(d->style) == + CSS_POSITION_ABSOLUTE || + css_computed_position(d->style) == + CSS_POSITION_FIXED)) { + /* positioned inline-blocks: + * set static position (x,y) only, rest of positioning + * is handled later */ + d->x += x0; + d->y = *y; + continue; + } else if ((d->type == BOX_INLINE && + ((d->object || d->gadget) == false) && + !(d->flags & IFRAME) && + !(d->flags & REPLACE_DIM)) || + d->type == BOX_BR || + d->type == BOX_TEXT || + d->type == BOX_INLINE_END) { + /* regular (non-replaced) inlines */ + d->x += x0; + d->y = *y - d->padding[TOP]; + + if (d->type == BOX_TEXT && d->height > used_height) { + /* text */ + used_height = d->height; + } + } else if ((d->type == BOX_INLINE) || + d->type == BOX_INLINE_BLOCK) { + /* replaced inlines and inline-blocks */ + d->x += x0; + d->y = *y + d->border[TOP].width + d->margin[TOP]; + h = d->margin[TOP] + d->border[TOP].width + + d->padding[TOP] + d->height + + d->padding[BOTTOM] + + d->border[BOTTOM].width + + d->margin[BOTTOM]; + if (used_height < h) + used_height = h; + } + } + + first->flags |= NEW_LINE; + + assert(b != first || (move_y && 0 < used_height && (left || right))); + + /* handle vertical-align by adjusting box y values */ + /** \todo proper vertical alignment handling */ + for (d = first; d != b; d = d->next) { + if ((d->type == BOX_INLINE && d->inline_end) || + d->type == BOX_BR || + d->type == BOX_TEXT || + d->type == BOX_INLINE_END) { + css_fixed value = 0; + css_unit unit = CSS_UNIT_PX; + switch (css_computed_vertical_align(d->style, &value, + &unit)) { + case CSS_VERTICAL_ALIGN_SUPER: + case CSS_VERTICAL_ALIGN_TOP: + case CSS_VERTICAL_ALIGN_TEXT_TOP: + /* already at top */ + break; + case CSS_VERTICAL_ALIGN_SUB: + case CSS_VERTICAL_ALIGN_BOTTOM: + case CSS_VERTICAL_ALIGN_TEXT_BOTTOM: + d->y += used_height - d->height; + break; + default: + case CSS_VERTICAL_ALIGN_BASELINE: + d->y += 0.75 * (used_height - d->height); + break; + } + } + } + + /* handle clearance for br */ + if (br_box && css_computed_clear(br_box->style) != CSS_CLEAR_NONE) { + int clear_y = layout_clear(cont->float_children, + css_computed_clear(br_box->style)); + if (used_height < clear_y - cy) + used_height = clear_y - cy; + } + if (move_y) + *y += used_height; + *next_box = b; + *width = x; /* return actual width */ return true; } /** - * Compute dimensions of box, margins, paddings, and borders for a floating - * element using shrink-to-fit. Also used for inline-blocks. + * Layout lines of text or inline boxes with floats. * - * \param available_width Max width available in pixels - * \param style Box's style - * \param box Box for which to find dimensions - * Box margins, borders, paddings, width and - * height are updated. + * \param box inline container box + * \param width horizontal space available + * \param cont ancestor box which defines horizontal space, for floats + * \param cx box position relative to cont + * \param cy box position relative to cont + * \param content memory pool for any new boxes + * \return true on success, false on memory exhaustion */ -static void -layout_float_find_dimensions(int available_width, - const css_computed_style *style, - struct box *box) +static bool layout_inline_container(struct box *inline_container, int width, + struct box *cont, int cx, int cy, html_content *content) { - int width, height, max_width, min_width, max_height, min_height; - int *margin = box->margin; - int *padding = box->padding; - struct box_border *border = box->border; - enum css_overflow_e overflow_x = css_computed_overflow_x(style); - enum css_overflow_e overflow_y = css_computed_overflow_y(style); - int scrollbar_width_x = - (overflow_x == CSS_OVERFLOW_SCROLL || - overflow_x == CSS_OVERFLOW_AUTO) ? - SCROLLBAR_WIDTH : 0; - int scrollbar_width_y = - (overflow_y == CSS_OVERFLOW_SCROLL || - overflow_y == CSS_OVERFLOW_AUTO) ? - SCROLLBAR_WIDTH : 0; + bool first_line = true; + bool has_text_children; + struct box *c, *next; + int y = 0; + int curwidth,maxwidth = width; - layout_find_dimensions(available_width, -1, box, style, &width, &height, - &max_width, &min_width, &max_height, &min_height, - margin, padding, border); + assert(inline_container->type == BOX_INLINE_CONTAINER); - if (margin[LEFT] == AUTO) - margin[LEFT] = 0; - if (margin[RIGHT] == AUTO) - margin[RIGHT] = 0; + NSLOG(layout, DEBUG, + "inline_container %p, width %i, cont %p, cx %i, cy %i", + inline_container, + width, + cont, + cx, + cy); - if (box->gadget == NULL) { - padding[RIGHT] += scrollbar_width_y; - padding[BOTTOM] += scrollbar_width_x; - } - if (box->object && !(box->flags & REPLACE_DIM) && - content_get_type(box->object) != CONTENT_HTML) { - /* Floating replaced element, with intrinsic width or height. - * See 10.3.6 and 10.6.2 */ - layout_get_object_dimensions(box, &width, &height, - min_width, max_width, min_height, max_height); - } else if (box->gadget && (box->gadget->type == GADGET_TEXTBOX || - box->gadget->type == GADGET_PASSWORD || - box->gadget->type == GADGET_FILE || - box->gadget->type == GADGET_TEXTAREA)) { - css_fixed size = 0; - css_unit unit = CSS_UNIT_EM; + has_text_children = false; + for (c = inline_container->children; c; c = c->next) { + bool is_pre = false; - /* Give sensible dimensions to gadgets, with auto width/height, - * that don't shrink to fit contained text. */ - assert(box->style); + if (c->style) { + enum css_white_space_e whitespace; - if (box->gadget->type == GADGET_TEXTBOX || - box->gadget->type == GADGET_PASSWORD || - box->gadget->type == GADGET_FILE) { - if (width == AUTO) { - size = INTTOFIX(10); - width = FIXTOINT(nscss_len2px(size, unit, - box->style)); - } - if (box->gadget->type == GADGET_FILE && - height == AUTO) { - size = FLTTOFIX(1.5); - height = FIXTOINT(nscss_len2px(size, unit, - box->style)); - } - } - if (box->gadget->type == GADGET_TEXTAREA) { - if (width == AUTO) { - size = INTTOFIX(10); - width = FIXTOINT(nscss_len2px(size, unit, - box->style)); - } - if (height == AUTO) { - size = INTTOFIX(4); - height = FIXTOINT(nscss_len2px(size, unit, - box->style)); - } + whitespace = css_computed_white_space(c->style); + + is_pre = (whitespace == CSS_WHITE_SPACE_PRE || + whitespace == CSS_WHITE_SPACE_PRE_LINE || + whitespace == CSS_WHITE_SPACE_PRE_WRAP); } - } else if (width == AUTO) { - /* CSS 2.1 section 10.3.5 */ - width = min(max(box->min_width, available_width), - box->max_width); - /* width includes margin, borders and padding */ - if (width == available_width) { - width -= box->margin[LEFT] + box->border[LEFT].width + - box->padding[LEFT] + - box->padding[RIGHT] + - box->border[RIGHT].width + - box->margin[RIGHT]; - } else { - /* width was obtained from a min_width or max_width - * value, so need to use the same method for calculating - * mbp as was used in layout_minmax_block() */ - int fixed = 0; - float frac = 0; - calculate_mbp_width(box->style, LEFT, true, true, true, - &fixed, &frac); - calculate_mbp_width(box->style, RIGHT, true, true, true, - &fixed, &frac); - if (fixed < 0) - fixed = 0; + if ((!c->object && !(c->flags & REPLACE_DIM) && + !(c->flags & IFRAME) && + c->text && (c->length || is_pre)) || + c->type == BOX_BR) + has_text_children = true; + } - width -= fixed; - } + /** \todo fix wrapping so that a box with horizontal scrollbar will + * shrink back to 'width' if no word is wider than 'width' (Or just set + * curwidth = width and have the multiword lines wrap to the min width) + */ + for (c = inline_container->children; c; ) { - if (max_width >= 0 && width > max_width) width = max_width; - if (min_width > 0 && width < min_width) width = min_width; + NSLOG(layout, DEBUG, "c %p", c); - } else { - if (max_width >= 0 && width > max_width) width = max_width; - if (min_width > 0 && width < min_width) width = min_width; - width -= scrollbar_width_y; + curwidth = inline_container->width; + if (!layout_line(c, &curwidth, &y, cx, cy + y, cont, first_line, + has_text_children, content, &next)) + return false; + maxwidth = max(maxwidth,curwidth); + c = next; + first_line = false; } - box->width = width; - box->height = height; + inline_container->width = maxwidth; + inline_container->height = y; - if (margin[TOP] == AUTO) - margin[TOP] = 0; - if (margin[BOTTOM] == AUTO) - margin[BOTTOM] = 0; + return true; } /** - * Layout the contents of a float or inline block. + * Layout a block formatting context. * - * \param b float or inline block box - * \param width available width - * \param content memory pool for any new boxes + * \param block BLOCK, INLINE_BLOCK, or TABLE_CELL to layout + * \param viewport_height Height of viewport in pixels or -ve if unknown + * \param content Memory pool for any new boxes * \return true on success, false on memory exhaustion - */ -static bool layout_float(struct box *b, int width, html_content *content) -{ - assert(b->type == BOX_TABLE || b->type == BOX_BLOCK || - b->type == BOX_INLINE_BLOCK); - layout_float_find_dimensions(width, b->style, b); - if (b->type == BOX_TABLE) { - if (!layout_table(b, width, content)) - return false; - if (b->margin[LEFT] == AUTO) - b->margin[LEFT] = 0; - if (b->margin[RIGHT] == AUTO) - b->margin[RIGHT] = 0; - if (b->margin[TOP] == AUTO) - b->margin[TOP] = 0; - if (b->margin[BOTTOM] == AUTO) - b->margin[BOTTOM] = 0; - } else - return layout_block_context(b, -1, content); - return true; -} - - -/** - * Position a float in the first available space. * - * \param c float box to position - * \param width available width - * \param cx x coordinate relative to cont to place float right of - * \param y y coordinate relative to cont to place float below - * \param cont ancestor box which defines horizontal space, for floats + * This function carries out layout of a block and its children, as described + * in CSS 2.1 9.4.1. */ -static void -place_float_below(struct box *c, int width, int cx, int y, struct box *cont) +static bool +layout_block_context(struct box *block, + int viewport_height, + html_content *content) { - int x0, x1, yy; - struct box *left; - struct box *right; - - yy = y > cont->cached_place_below_level ? - y : cont->cached_place_below_level; + struct box *box; + int cx, cy; /**< current coordinates */ + int max_pos_margin = 0; + int max_neg_margin = 0; + int y = 0; + int lm, rm; + struct box *margin_collapse = NULL; + bool in_margin = false; + css_fixed gadget_size; + css_unit gadget_unit; /* Checkbox / radio buttons */ - NSLOG(layout, DEBUG, - "c %p, width %i, cx %i, y %i, cont %p", c, - width, cx, y, cont); + assert(block->type == BOX_BLOCK || + block->type == BOX_INLINE_BLOCK || + block->type == BOX_TABLE_CELL); + assert(block->width != UNKNOWN_WIDTH); + assert(block->width != AUTO); - do { - y = yy; - x0 = cx; - x1 = cx + width; - find_sides(cont->float_children, y, y + c->height, &x0, &x1, - &left, &right); - if (left != 0 && right != 0) { - yy = (left->y + left->height < - right->y + right->height ? - left->y + left->height : - right->y + right->height); - } else if (left == 0 && right != 0) { - yy = right->y + right->height; - } else if (left != 0 && right == 0) { - yy = left->y + left->height; - } - } while ((left != 0 || right != 0) && (c->width > x1 - x0)); + block->float_children = NULL; + block->cached_place_below_level = 0; + block->clear_level = 0; - if (c->type == BOX_FLOAT_LEFT) { - c->x = x0; - } else { - c->x = x1 - c->width; + /* special case if the block contains an object */ + if (block->object) { + int temp_width = block->width; + if (!layout_block_object(block)) + return false; + layout_get_object_dimensions(block, &temp_width, + &block->height, INT_MIN, INT_MAX, + INT_MIN, INT_MAX); + return true; + } else if (block->flags & REPLACE_DIM) { + return true; } - c->y = y; - cont->cached_place_below_level = y; -} + /* special case if the block contains an radio button or checkbox */ + if (block->gadget && (block->gadget->type == GADGET_RADIO || + block->gadget->type == GADGET_CHECKBOX)) { + /* form checkbox or radio button + * if width or height is AUTO, set it to 1em */ + gadget_unit = CSS_UNIT_EM; + gadget_size = INTTOFIX(1); + if (block->height == AUTO) + block->height = FIXTOINT(nscss_len2px(gadget_size, + gadget_unit, block->style)); + } -/** - * Position a line of boxes in inline formatting context. - * - * \param first box at start of line - * \param width available width on input, updated with actual width on output - * (may be incorrect if the line gets split?) - * \param y coordinate of top of line, updated on exit to bottom - * \param cx coordinate of left of line relative to cont - * \param cy coordinate of top of line relative to cont - * \param cont ancestor box which defines horizontal space, for floats - * \param indent apply any first-line indent - * \param has_text_children at least one TEXT in the inline_container - * \param next_box updated to first box for next line, or 0 at end - * \param content memory pool for any new boxes - * \return true on success, false on memory exhaustion - */ -static bool -layout_line(struct box *first, - int *width, - int *y, - int cx, - int cy, - struct box *cont, - bool indent, - bool has_text_children, - html_content *content, - struct box **next_box) -{ - int height, used_height; - int x0 = 0; - int x1 = *width; - int x, h, x_previous; - int fy = cy; - struct box *left; - struct box *right; - struct box *b; - struct box *split_box = 0; - struct box *d; - struct box *br_box = 0; - bool move_y = false; - bool place_below = false; - int space_before = 0, space_after = 0; - unsigned int inline_count = 0; - unsigned int i; - const struct gui_layout_table *font_func = content->font_func; - plot_font_style_t fstyle; + box = block->children; + /* set current coordinates to top-left of the block */ + cx = 0; + y = cy = block->padding[TOP]; + if (box) + box->y = block->padding[TOP]; - NSLOG(layout, DEBUG, - "first %p, first->text '%.*s', width %i, y %i, cx %i, cy %i", - first, - (int)first->length, - first->text, - *width, - *y, - cx, - cy); + /* Step through the descendants of the block in depth-first order, but + * not into the children of boxes which aren't blocks. For example, if + * the tree passed to this function looks like this (box->type shown): + * + * block -> BOX_BLOCK + * BOX_BLOCK * (1) + * BOX_INLINE_CONTAINER * (2) + * BOX_INLINE + * BOX_TEXT + * ... + * BOX_BLOCK * (3) + * BOX_TABLE * (4) + * BOX_TABLE_ROW + * BOX_TABLE_CELL + * ... + * BOX_TABLE_CELL + * ... + * BOX_BLOCK * (5) + * BOX_INLINE_CONTAINER * (6) + * BOX_TEXT + * ... + * then the while loop will visit each box marked with *, setting box + * to each in the order shown. */ + while (box) { + enum css_overflow_e overflow_x = CSS_OVERFLOW_VISIBLE; + enum css_overflow_e overflow_y = CSS_OVERFLOW_VISIBLE; - /* find sides at top of line */ - x0 += cx; - x1 += cx; - find_sides(cont->float_children, cy, cy, &x0, &x1, &left, &right); - x0 -= cx; - x1 -= cx; + assert(box->type == BOX_BLOCK || box->type == BOX_TABLE || + box->type == BOX_INLINE_CONTAINER); - if (indent) - x0 += layout_text_indent(first->parent->parent->style, *width); + /* Tables are laid out before being positioned, because the + * position depends on the width which is calculated in + * table layout. Blocks and inline containers are positioned + * before being laid out, because width is not dependent on + * content, and the position is required during layout for + * correct handling of floats. + */ - if (x1 < x0) - x1 = x0; + if (box->style && + (css_computed_position(box->style) == + CSS_POSITION_ABSOLUTE || + css_computed_position(box->style) == + CSS_POSITION_FIXED)) { + box->x = box->parent->padding[LEFT]; + /* absolute positioned; this element will establish + * its own block context when it gets laid out later, + * so no need to look at its children now. */ + goto advance_to_next_box; + } - /* get minimum line height from containing block. - * this is the line-height if there are text children and also in the - * case of an initially empty text input */ - if (has_text_children || first->parent->parent->gadget) - used_height = height = - line_height(first->parent->parent->style); - else - /* inline containers with no text are usually for layout and - * look better with no minimum line-height */ - used_height = height = 0; + /* If we don't know which box the current margin collapses + * through to, find out. Update the pos/neg margin values. */ + if (margin_collapse == NULL) { + margin_collapse = layout_next_margin_block(box, block, + viewport_height, + &max_pos_margin, &max_neg_margin); + /* We have a margin that has not yet been applied. */ + in_margin = true; + } - /* pass 1: find height of line assuming sides at top of line: loop - * body executed at least once - * keep in sync with the loop in layout_minmax_line() */ + /* Clearance. */ + y = 0; + if (box->style && css_computed_clear(box->style) != + CSS_CLEAR_NONE) + y = layout_clear(block->float_children, + css_computed_clear(box->style)); - NSLOG(layout, DEBUG, "x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0); + /* Find box's overflow properties */ + if (box->style) { + overflow_x = css_computed_overflow_x(box->style); + overflow_y = css_computed_overflow_y(box->style); + } + /* Blocks establishing a block formatting context get minimum + * left and right margins to avoid any floats. */ + lm = rm = 0; - for (x = 0, b = first; x <= x1 - x0 && b != 0; b = b->next) { - int min_width, max_width, min_height, max_height; + if (box->type == BOX_BLOCK || box->flags & IFRAME) { + if (!box->object && !(box->flags & IFRAME) && + !(box->flags & REPLACE_DIM) && + box->style && + (overflow_x != CSS_OVERFLOW_VISIBLE || + overflow_y != CSS_OVERFLOW_VISIBLE)) { + /* box establishes new block formatting context + * so available width may be diminished due to + * floats. */ + int x0, x1, top; + struct box *left, *right; + top = cy + max_pos_margin - max_neg_margin; + top = (top > y) ? top : y; + x0 = cx; + x1 = cx + box->parent->width - + box->parent->padding[LEFT] - + box->parent->padding[RIGHT]; + find_sides(block->float_children, top, top, + &x0, &x1, &left, &right); + /* calculate min required left & right margins + * needed to avoid floats */ + lm = x0 - cx; + rm = cx + box->parent->width - + box->parent->padding[LEFT] - + box->parent->padding[RIGHT] - + x1; + } + layout_block_find_dimensions(box->parent->width, + viewport_height, lm, rm, box); + if (box->type == BOX_BLOCK && !(box->flags & IFRAME)) { + layout_block_add_scrollbar(box, RIGHT); + layout_block_add_scrollbar(box, BOTTOM); + } + } else if (box->type == BOX_TABLE) { + if (box->style != NULL) { + enum css_width_e wtype; + css_fixed width = 0; + css_unit unit = CSS_UNIT_PX; - assert(b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK || - b->type == BOX_FLOAT_LEFT || - b->type == BOX_FLOAT_RIGHT || - b->type == BOX_BR || b->type == BOX_TEXT || - b->type == BOX_INLINE_END); + wtype = css_computed_width(box->style, &width, + &unit); + + if (wtype == CSS_WIDTH_AUTO) { + /* max available width may be + * diminished due to floats. */ + int x0, x1, top; + struct box *left, *right; + top = cy + max_pos_margin - + max_neg_margin; + top = (top > y) ? top : y; + x0 = cx; + x1 = cx + box->parent->width - + box->parent->padding[LEFT] - + box->parent->padding[RIGHT]; + find_sides(block->float_children, + top, top, &x0, &x1, + &left, &right); + /* calculate min required left & right + * margins needed to avoid floats */ + lm = x0 - cx; + rm = cx + box->parent->width - + box->parent->padding[LEFT] - + box->parent->padding[RIGHT] - + x1; + } + } + if (!layout_table(box, box->parent->width - lm - rm, + content)) + return false; + layout_solve_width(box, box->parent->width, box->width, + lm, rm, -1, -1); + } + /* Position box: horizontal. */ + box->x = box->parent->padding[LEFT] + box->margin[LEFT] + + box->border[LEFT].width; + cx += box->x; - NSLOG(layout, DEBUG, "pass 1: b %p, x %i", b, x); + /* Position box: vertical. */ + if (box->border[TOP].width) { + box->y += box->border[TOP].width; + cy += box->border[TOP].width; + } + /* Vertical margin */ + if (((box->type == BOX_BLOCK && + (box->flags & HAS_HEIGHT)) || + box->type == BOX_TABLE || + (box->type == BOX_INLINE_CONTAINER && + box != box->parent->children) || + margin_collapse == box) && + in_margin == true) { + /* Margin goes above this box. */ + cy += max_pos_margin - max_neg_margin; + box->y += max_pos_margin - max_neg_margin; - if (b->type == BOX_BR) - break; + /* Current margin has been applied. */ + in_margin = false; + max_pos_margin = max_neg_margin = 0; + } - if (b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT) - continue; - if (b->type == BOX_INLINE_BLOCK && - (css_computed_position(b->style) == - CSS_POSITION_ABSOLUTE || - css_computed_position(b->style) == - CSS_POSITION_FIXED)) - continue; + /* Handle clearance */ + if (box->type != BOX_INLINE_CONTAINER && + (y > 0) && (cy < y)) { + /* box clears something*/ + box->y += y - cy; + cy = y; + } - assert(b->style != NULL); - font_plot_style_from_css(b->style, &fstyle); + /* Unless the box has an overflow style of visible, the box + * establishes a new block context. */ + if (box->type == BOX_BLOCK && box->style && + (overflow_x != CSS_OVERFLOW_VISIBLE || + overflow_y != CSS_OVERFLOW_VISIBLE)) { - x += space_after; + layout_block_context(box, viewport_height, content); - if (b->type == BOX_INLINE_BLOCK) { - if (b->max_width != UNKNOWN_WIDTH) - if (!layout_float(b, *width, content)) - return false; - h = b->border[TOP].width + b->padding[TOP] + b->height + - b->padding[BOTTOM] + - b->border[BOTTOM].width; - if (height < h) - height = h; - x += b->margin[LEFT] + b->border[LEFT].width + - b->padding[LEFT] + b->width + - b->padding[RIGHT] + - b->border[RIGHT].width + - b->margin[RIGHT]; - space_after = 0; - continue; - } + cy += box->padding[TOP]; - if (b->type == BOX_INLINE) { - /* calculate borders, margins, and padding */ - layout_find_dimensions(*width, -1, b, b->style, 0, 0, - 0, 0, 0, 0, b->margin, b->padding, - b->border); - for (i = 0; i != 4; i++) - if (b->margin[i] == AUTO) - b->margin[i] = 0; - x += b->margin[LEFT] + b->border[LEFT].width + - b->padding[LEFT]; - if (b->inline_end) { - b->inline_end->margin[RIGHT] = b->margin[RIGHT]; - b->inline_end->padding[RIGHT] = - b->padding[RIGHT]; - b->inline_end->border[RIGHT] = - b->border[RIGHT]; - } else { - x += b->padding[RIGHT] + - b->border[RIGHT].width + - b->margin[RIGHT]; - } - } else if (b->type == BOX_INLINE_END) { - b->width = 0; - if (b->space == UNKNOWN_WIDTH) { - font_func->width(&fstyle, " ", 1, &b->space); - /** \todo handle errors */ + if (box->height == AUTO) { + box->height = 0; + layout_block_add_scrollbar(box, BOTTOM); } - space_after = b->space; - x += b->padding[RIGHT] + b->border[RIGHT].width + - b->margin[RIGHT]; - continue; + cx -= box->x; + cy += box->height + box->padding[BOTTOM] + + box->border[BOTTOM].width; + y = box->y + box->padding[TOP] + box->height + + box->padding[BOTTOM] + + box->border[BOTTOM].width; + + /* Skip children, because they are done in the new + * block context */ + goto advance_to_next_box; } - if (!b->object && !(b->flags & IFRAME) && !b->gadget && - !(b->flags & REPLACE_DIM)) { - /* inline non-replaced, 10.3.1 and 10.6.1 */ - b->height = line_height(b->style ? b->style : - b->parent->parent->style); - if (height < b->height) - height = b->height; + NSLOG(layout, DEBUG, "box %p, cx %i, cy %i", box, cx, cy); - if (!b->text) { - b->width = 0; - space_after = 0; - continue; - } + /* Layout (except tables). */ + if (box->object) { + if (!layout_block_object(box)) + return false; - if (b->width == UNKNOWN_WIDTH) { - /** \todo handle errors */ + } else if (box->type == BOX_INLINE_CONTAINER) { + box->width = box->parent->width; + if (!layout_inline_container(box, box->width, block, + cx, cy, content)) + return false; - /* If it's a select element, we must use the - * width of the widest option text */ - if (b->parent->parent->gadget && - b->parent->parent->gadget->type - == GADGET_SELECT) { - int opt_maxwidth = 0; - struct form_option *o; + } else if (box->type == BOX_TABLE) { + /* Move down to avoid floats if necessary. */ + int x0, x1; + struct box *left, *right; + y = cy; + while (1) { + enum css_width_e wtype; + css_fixed width = 0; + css_unit unit = CSS_UNIT_PX; - for (o = b->parent->parent->gadget-> - data.select.items; o; - o = o->next) { - int opt_width; - font_func->width(&fstyle, - o->text, - strlen(o->text), - &opt_width); + wtype = css_computed_width(box->style, + &width, &unit); - if (opt_maxwidth < opt_width) - opt_maxwidth =opt_width; - } - b->width = opt_maxwidth; - if (nsoption_bool(core_select_menu)) - b->width += SCROLLBAR_WIDTH; - } else { - font_func->width(&fstyle, b->text, - b->length, &b->width); - b->flags |= MEASURED; - } + x0 = cx; + x1 = cx + box->parent->width; + find_sides(block->float_children, y, + y + box->height, + &x0, &x1, &left, &right); + if (wtype == CSS_WIDTH_AUTO) + break; + if (box->width <= x1 - x0) + break; + if (!left && !right) + break; + else if (!left) + y = right->y + right->height + 1; + else if (!right) + y = left->y + left->height + 1; + else if (left->y + left->height < + right->y + right->height) + y = left->y + left->height + 1; + else + y = right->y + right->height + 1; } + box->x += x0 - cx; + cx = x0; + box->y += y - cy; + cy = y; + } - /* If the current text has not been measured (i.e. its - * width was estimated after splitting), and it fits on - * the line, measure it properly, so next box is placed - * correctly. */ - if (b->text && (x + b->width < x1 - x0) && - !(b->flags & MEASURED) && - b->next) { - font_func->width(&fstyle, b->text, - b->length, &b->width); - b->flags |= MEASURED; - } + /* Advance to next box. */ + if (box->type == BOX_BLOCK && !box->object && !(box->iframe) && + box->children) { + /* Down into children. */ - x += b->width; - if (b->space == UNKNOWN_WIDTH) { - font_func->width(&fstyle, " ", 1, &b->space); - /** \todo handle errors */ + if (box == margin_collapse) { + /* Current margin collapsed though to this box. + * Unset margin_collapse. */ + margin_collapse = NULL; } - space_after = b->space; + + y = box->padding[TOP]; + box = box->children; + box->y = y; + cy += y; continue; + } else if (box->type == BOX_BLOCK || box->object || + box->flags & IFRAME) + cy += box->padding[TOP]; + + if (box->type == BOX_BLOCK && box->height == AUTO) { + box->height = 0; + layout_block_add_scrollbar(box, BOTTOM); } - space_after = 0; + cy += box->height + box->padding[BOTTOM] + + box->border[BOTTOM].width; + cx -= box->x; + y = box->y + box->padding[TOP] + box->height + + box->padding[BOTTOM] + + box->border[BOTTOM].width; - /* inline replaced, 10.3.2 and 10.6.2 */ - assert(b->style); + advance_to_next_box: + if (!box->next) { + /* No more siblings: + * up to first ancestor with a sibling. */ - layout_find_dimensions(*width, -1, b, b->style, - &b->width, &b->height, &max_width, &min_width, - &max_height, &min_height, NULL, NULL, NULL); + do { + if (box == margin_collapse) { + /* Current margin collapsed though to + * this box. Unset margin_collapse. */ + margin_collapse = NULL; + } - if (b->object && !(b->flags & REPLACE_DIM)) { - layout_get_object_dimensions(b, &b->width, &b->height, - min_width, max_width, - min_height, max_height); - } else if (b->flags & IFRAME) { - /* TODO: should we look at the content dimensions? */ - if (b->width == AUTO) - b->width = 400; - if (b->height == AUTO) - b->height = 300; + /* Apply bottom margin */ + if (max_pos_margin < box->margin[BOTTOM]) + max_pos_margin = box->margin[BOTTOM]; + else if (max_neg_margin < -box->margin[BOTTOM]) + max_neg_margin = -box->margin[BOTTOM]; - /* We reformat the iframe browser window to new - * dimensions in pass 2 */ - } else { - /* form control with no object */ - if (b->width == AUTO) - b->width = FIXTOINT(nscss_len2px(INTTOFIX(1), - CSS_UNIT_EM, b->style)); - if (b->height == AUTO) - b->height = FIXTOINT(nscss_len2px(INTTOFIX(1), - CSS_UNIT_EM, b->style)); - } + box = box->parent; + if (box == block) + break; - /* Reformat object to new box size */ - if (b->object && content_get_type(b->object) == CONTENT_HTML && - b->width != - content_get_available_width(b->object)) { - css_fixed value = 0; - css_unit unit = CSS_UNIT_PX; - enum css_height_e htype = css_computed_height(b->style, - &value, &unit); + /* Margin is invalidated if this is a box + * margins can't collapse through. */ + if (box->type == BOX_BLOCK && + box->flags & MAKE_HEIGHT) { + margin_collapse = NULL; + in_margin = false; + max_pos_margin = max_neg_margin = 0; + } - content_reformat(b->object, false, b->width, b->height); + if (box->height == AUTO) { + box->height = y - box->padding[TOP]; - if (htype == CSS_HEIGHT_AUTO) - b->height = content_get_height(b->object); - } + if (box->type == BOX_BLOCK) + layout_block_add_scrollbar(box, + BOTTOM); + } else + cy += box->height - + (y - box->padding[TOP]); - if (height < b->height) - height = b->height; + /* Apply any min-height and max-height to + * boxes in normal flow */ + if (box->style && + css_computed_position(box->style) != + CSS_POSITION_ABSOLUTE && + layout_apply_minmax_height(box, + NULL)) { + /* Height altered */ + /* Set current cy */ + cy += box->height - + (y - box->padding[TOP]); + } - x += b->width; - } + cy += box->padding[BOTTOM] + + box->border[BOTTOM].width; + cx -= box->x; + y = box->y + box->padding[TOP] + box->height + + box->padding[BOTTOM] + + box->border[BOTTOM].width; - /* find new sides using this height */ - x0 = cx; - x1 = cx + *width; - find_sides(cont->float_children, cy, cy + height, &x0, &x1, - &left, &right); - x0 -= cx; - x1 -= cx; + } while (box->next == NULL); + if (box == block) + break; + } - if (indent) - x0 += layout_text_indent(first->parent->parent->style, *width); + /* To next sibling. */ - if (x1 < x0) - x1 = x0; + if (box == margin_collapse) { + /* Current margin collapsed though to this box. + * Unset margin_collapse. */ + margin_collapse = NULL; + } - space_after = space_before = 0; + if (max_pos_margin < box->margin[BOTTOM]) + max_pos_margin = box->margin[BOTTOM]; + else if (max_neg_margin < -box->margin[BOTTOM]) + max_neg_margin = -box->margin[BOTTOM]; - /* pass 2: place boxes in line: loop body executed at least once */ + box = box->next; + box->y = y; + } - NSLOG(layout, DEBUG, "x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0); + /* Account for bottom margin of last contained block */ + cy += max_pos_margin - max_neg_margin; - for (x = x_previous = 0, b = first; x <= x1 - x0 && b; b = b->next) { + /* Increase height to contain any floats inside (CSS 2.1 10.6.7). */ + for (box = block->float_children; box; box = box->next_float) { + y = box->y + box->height + box->padding[BOTTOM] + + box->border[BOTTOM].width + box->margin[BOTTOM]; + if (cy < y) + cy = y; + } - NSLOG(layout, DEBUG, "pass 2: b %p, x %i", b, x); + if (block->height == AUTO) { + block->height = cy - block->padding[TOP]; + if (block->type == BOX_BLOCK) + layout_block_add_scrollbar(block, BOTTOM); + } - if (b->type == BOX_INLINE_BLOCK && - (css_computed_position(b->style) == - CSS_POSITION_ABSOLUTE || - css_computed_position(b->style) == - CSS_POSITION_FIXED)) { - b->x = x + space_after; + if (block->style && css_computed_position(block->style) != + CSS_POSITION_ABSOLUTE) { + /* Block is in normal flow */ + layout_apply_minmax_height(block, NULL); + } - } else if (b->type == BOX_INLINE || - b->type == BOX_INLINE_BLOCK || - b->type == BOX_TEXT || - b->type == BOX_INLINE_END) { - assert(b->width != UNKNOWN_WIDTH); + if (block->gadget && + (block->gadget->type == GADGET_TEXTAREA || + block->gadget->type == GADGET_PASSWORD || + block->gadget->type == GADGET_TEXTBOX)) { + int ta_width = block->padding[LEFT] + block->width + + block->padding[RIGHT]; + int ta_height = block->padding[TOP] + block->height + + block->padding[BOTTOM]; + textarea_set_layout(block->gadget->data.text.ta, + ta_width, ta_height, + block->padding[TOP], block->padding[RIGHT], + block->padding[BOTTOM], block->padding[LEFT]); + } - x_previous = x; - x += space_after; - b->x = x; + return true; +} - if ((b->type == BOX_INLINE && !b->inline_end) || - b->type == BOX_INLINE_BLOCK) { - b->x += b->margin[LEFT] + b->border[LEFT].width; - x = b->x + b->padding[LEFT] + b->width + - b->padding[RIGHT] + - b->border[RIGHT].width + - b->margin[RIGHT]; - } else if (b->type == BOX_INLINE) { - b->x += b->margin[LEFT] + b->border[LEFT].width; - x = b->x + b->padding[LEFT] + b->width; - } else if (b->type == BOX_INLINE_END) { - b->height = b->inline_end->height; - x += b->padding[RIGHT] + - b->border[RIGHT].width + - b->margin[RIGHT]; - } else { - x += b->width; - } - space_before = space_after; - if (b->object || b->flags & REPLACE_DIM || - b->flags & IFRAME) - space_after = 0; - else if (b->text || b->type == BOX_INLINE_END) { - if (b->space == UNKNOWN_WIDTH) { - font_plot_style_from_css(b->style, +/** + * Layout list markers. + */ +static void +layout_lists(struct box *box, + const struct gui_layout_table *font_func) +{ + struct box *child; + struct box *marker; + plot_font_style_t fstyle; + + for (child = box->children; child; child = child->next) { + if (child->list_marker) { + marker = child->list_marker; + if (marker->object) { + marker->width = + content_get_width(marker->object); + marker->x = -marker->width; + marker->height = + content_get_height(marker->object); + marker->y = (line_height(marker->style) - + marker->height) / 2; + } else if (marker->text) { + if (marker->width == UNKNOWN_WIDTH) { + font_plot_style_from_css(marker->style, &fstyle); - /** \todo handle errors */ - font_func->width(&fstyle, " ", 1, - &b->space); + font_func->width(&fstyle, + marker->text, + marker->length, + &marker->width); + marker->flags |= MEASURED; } - space_after = b->space; + marker->x = -marker->width; + marker->y = 0; + marker->height = line_height(marker->style); } else { - space_after = 0; + marker->x = 0; + marker->y = 0; + marker->width = 0; + marker->height = 0; } - split_box = b; - move_y = true; - inline_count++; - } else if (b->type == BOX_BR) { - b->x = x; - b->width = 0; - br_box = b; - b = b->next; - split_box = 0; - move_y = true; - break; + /* Gap between marker and content */ + marker->x -= 4; + } + layout_lists(child, font_func); + } +} + + +/** + * Compute box offsets for a relatively or absolutely positioned box with + * respect to a box. + * + * \param box box to compute offsets for + * \param containing_block box to compute percentages with respect to + * \param top updated to top offset, or AUTO + * \param right updated to right offset, or AUTO + * \param bottom updated to bottom offset, or AUTO + * \param left updated to left offset, or AUTO + * + * See CSS 2.1 9.3.2. containing_block must have width and height. + */ +static void +layout_compute_offsets(struct box *box, + struct box *containing_block, + int *top, + int *right, + int *bottom, + int *left) +{ + uint32_t type; + css_fixed value = 0; + css_unit unit = CSS_UNIT_PX; + + assert(containing_block->width != UNKNOWN_WIDTH && + containing_block->width != AUTO && + containing_block->height != AUTO); + /* left */ + type = css_computed_left(box->style, &value, &unit); + if (type == CSS_LEFT_SET) { + if (unit == CSS_UNIT_PCT) { + *left = FPCT_OF_INT_TOINT(value, + containing_block->width); } else { - /* float */ - NSLOG(layout, DEBUG, "float %p", b); + *left = FIXTOINT(nscss_len2px(value, unit, box->style)); + } + } else { + *left = AUTO; + } - d = b->children; - d->float_children = 0; - d->cached_place_below_level = 0; - b->float_container = d->float_container = cont; + /* right */ + type = css_computed_right(box->style, &value, &unit); + if (type == CSS_RIGHT_SET) { + if (unit == CSS_UNIT_PCT) { + *right = FPCT_OF_INT_TOINT(value, + containing_block->width); + } else { + *right = FIXTOINT(nscss_len2px(value, unit, + box->style)); + } + } else { + *right = AUTO; + } - if (!layout_float(d, *width, content)) - return false; + /* top */ + type = css_computed_top(box->style, &value, &unit); + if (type == CSS_TOP_SET) { + if (unit == CSS_UNIT_PCT) { + *top = FPCT_OF_INT_TOINT(value, + containing_block->height); + } else { + *top = FIXTOINT(nscss_len2px(value, unit, box->style)); + } + } else { + *top = AUTO; + } - NSLOG(layout, DEBUG, - "%p : %d %d", - d, - d->margin[TOP], - d->border[TOP].width); + /* bottom */ + type = css_computed_bottom(box->style, &value, &unit); + if (type == CSS_BOTTOM_SET) { + if (unit == CSS_UNIT_PCT) { + *bottom = FPCT_OF_INT_TOINT(value, + containing_block->height); + } else { + *bottom = FIXTOINT(nscss_len2px(value, unit, + box->style)); + } + } else { + *bottom = AUTO; + } +} - d->x = d->margin[LEFT] + d->border[LEFT].width; - d->y = d->margin[TOP] + d->border[TOP].width; - b->width = d->margin[LEFT] + d->border[LEFT].width + - d->padding[LEFT] + d->width + - d->padding[RIGHT] + - d->border[RIGHT].width + - d->margin[RIGHT]; - b->height = d->margin[TOP] + d->border[TOP].width + - d->padding[TOP] + d->height + - d->padding[BOTTOM] + - d->border[BOTTOM].width + - d->margin[BOTTOM]; - if (b->width > (x1 - x0) - x) - place_below = true; - if (d->style && (css_computed_clear(d->style) == - CSS_CLEAR_NONE || - (css_computed_clear(d->style) == - CSS_CLEAR_LEFT && left == 0) || - (css_computed_clear(d->style) == - CSS_CLEAR_RIGHT && - right == 0) || - (css_computed_clear(d->style) == - CSS_CLEAR_BOTH && - left == 0 && right == 0)) && - (!place_below || - (left == 0 && right == 0 && x == 0)) && - cy >= cont->clear_level && - cy >= cont->cached_place_below_level) { - /* + not cleared or, - * cleared and there are no floats to clear - * + fits without needing to be placed below or, - * this line is empty with no floats - * + current y, cy, is below the clear level - * - * Float affects current line */ - if (b->type == BOX_FLOAT_LEFT) { - b->x = cx + x0; - if (b->width > 0) - x0 += b->width; - left = b; - } else { - b->x = cx + x1 - b->width; - if (b->width > 0) - x1 -= b->width; - right = b; - } - b->y = cy; - } else { - /* cleared or doesn't fit on line */ - /* place below into next available space */ - int fcy = (cy > cont->clear_level) ? cy : - cont->clear_level; - fcy = (fcy > cont->cached_place_below_level) ? - fcy : - cont->cached_place_below_level; - fy = (fy > fcy) ? fy : fcy; - fy = (fy == cy) ? fy + height : fy; +/** + * Layout and position an absolutely positioned box. + * + * \param box absolute box to layout and position + * \param containing_block containing block + * \param cx position of box relative to containing_block + * \param cy position of box relative to containing_block + * \param content memory pool for any new boxes + * \return true on success, false on memory exhaustion + */ +static bool +layout_absolute(struct box *box, + struct box *containing_block, + int cx, int cy, + html_content *content) +{ + int static_left, static_top; /* static position */ + int top, right, bottom, left; + int width, height, max_width, min_width; + int *margin = box->margin; + int *padding = box->padding; + struct box_border *border = box->border; + int available_width = containing_block->width; + int space; - place_float_below(b, *width, cx, fy, cont); - fy = b->y; - if (d->style && ( - (css_computed_clear(d->style) == - CSS_CLEAR_LEFT && left != 0) || - (css_computed_clear(d->style) == - CSS_CLEAR_RIGHT && - right != 0) || - (css_computed_clear(d->style) == - CSS_CLEAR_BOTH && - (left != 0 || right != 0)))) { - /* to be cleared below existing - * floats */ - if (b->type == BOX_FLOAT_LEFT) - b->x = cx; - else - b->x = cx + *width - b->width; + assert(box->type == BOX_BLOCK || box->type == BOX_TABLE || + box->type == BOX_INLINE_BLOCK); - fcy = layout_clear(cont->float_children, - css_computed_clear(d->style)); - if (fcy > cont->clear_level) - cont->clear_level = fcy; - if (b->y < fcy) - b->y = fcy; - } - if (b->type == BOX_FLOAT_LEFT) - left = b; - else - right = b; + /* The static position is where the box would be if it was not + * absolutely positioned. The x and y are filled in by + * layout_block_context(). */ + static_left = cx + box->x; + static_top = cy + box->y; + + if (containing_block->type == BOX_BLOCK || + containing_block->type == BOX_INLINE_BLOCK || + containing_block->type == BOX_TABLE_CELL) { + /* Block level container => temporarily increase containing + * block dimensions to include padding (we restore this + * again at the end) */ + containing_block->width += containing_block->padding[LEFT] + + containing_block->padding[RIGHT]; + containing_block->height += containing_block->padding[TOP] + + containing_block->padding[BOTTOM]; + } else { + /** \todo inline containers */ + } + + layout_compute_offsets(box, containing_block, + &top, &right, &bottom, &left); + + /* Pass containing block into layout_find_dimensions via the float + * containing block box member. This is unused for absolutely positioned + * boxes because a box can't be floated and absolutely positioned. */ + box->float_container = containing_block; + layout_find_dimensions(available_width, -1, box, box->style, + &width, &height, &max_width, &min_width, + 0, 0, margin, padding, border); + box->float_container = NULL; + + /* 10.3.7 */ + NSLOG(layout, DEBUG, + "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", + left, margin[LEFT], border[LEFT].width, padding[LEFT], width, + padding[RIGHT], border[RIGHT].width, margin[RIGHT], right, + containing_block->width); + + + if (left == AUTO && width == AUTO && right == AUTO) { + if (margin[LEFT] == AUTO) + margin[LEFT] = 0; + if (margin[RIGHT] == AUTO) + margin[RIGHT] = 0; + left = static_left; + + width = min(max(box->min_width, available_width), + box->max_width); + width -= box->margin[LEFT] + box->border[LEFT].width + + box->padding[LEFT] + box->padding[RIGHT] + + box->border[RIGHT].width + box->margin[RIGHT]; + + /* Adjust for {min|max}-width */ + if (max_width >= 0 && width > max_width) width = max_width; + if (width < min_width) width = min_width; + + right = containing_block->width - + left - + margin[LEFT] - border[LEFT].width - padding[LEFT] - + width - + padding[RIGHT] - border[RIGHT].width - margin[RIGHT]; + } else if (left != AUTO && width != AUTO && right != AUTO) { + + /* Adjust for {min|max}-width */ + if (max_width >= 0 && width > max_width) width = max_width; + if (min_width > 0 && width < min_width) width = min_width; + + if (margin[LEFT] == AUTO && margin[RIGHT] == AUTO) { + space = containing_block->width - + left - border[LEFT].width - + padding[LEFT] - width - padding[RIGHT] - + border[RIGHT].width - right; + if (space < 0) { + margin[LEFT] = 0; + margin[RIGHT] = space; + } else { + margin[LEFT] = margin[RIGHT] = space / 2; } - add_float_to_container(cont, b); + } else if (margin[LEFT] == AUTO) { + margin[LEFT] = containing_block->width - + left - border[LEFT].width - + padding[LEFT] - width - padding[RIGHT] - + border[RIGHT].width - margin[RIGHT] - + right; + } else if (margin[RIGHT] == AUTO) { + margin[RIGHT] = containing_block->width - + left - margin[LEFT] - + border[LEFT].width - + padding[LEFT] - width - padding[RIGHT] - + border[RIGHT].width - right; + } else { + right = containing_block->width - + left - margin[LEFT] - + border[LEFT].width - + padding[LEFT] - width - padding[RIGHT] - + border[RIGHT].width - margin[RIGHT]; + } + } else { + if (margin[LEFT] == AUTO) + margin[LEFT] = 0; + if (margin[RIGHT] == AUTO) + margin[RIGHT] = 0; - split_box = 0; + if (left == AUTO && width == AUTO && right != AUTO) { + available_width -= right; + + width = min(max(box->min_width, available_width), + box->max_width); + width -= box->margin[LEFT] + box->border[LEFT].width + + box->padding[LEFT] + box->padding[RIGHT] + + box->border[RIGHT].width + box->margin[RIGHT]; + + /* Adjust for {min|max}-width */ + if (max_width >= 0 && width > max_width) + width = max_width; + if (width < min_width) + width = min_width; + + left = containing_block->width - + margin[LEFT] - border[LEFT].width - + padding[LEFT] - width - padding[RIGHT] - + border[RIGHT].width - margin[RIGHT] - + right; + } else if (left == AUTO && width != AUTO && right == AUTO) { + + /* Adjust for {min|max}-width */ + if (max_width >= 0 && width > max_width) + width = max_width; + if (min_width > 0 && width < min_width) + width = min_width; + + left = static_left; + right = containing_block->width - + left - margin[LEFT] - + border[LEFT].width - + padding[LEFT] - width - padding[RIGHT] - + border[RIGHT].width - margin[RIGHT]; + } else if (left != AUTO && width == AUTO && right == AUTO) { + available_width -= left; + + width = min(max(box->min_width, available_width), + box->max_width); + width -= box->margin[LEFT] + box->border[LEFT].width + + box->padding[LEFT] + box->padding[RIGHT] + + box->border[RIGHT].width + box->margin[RIGHT]; + + /* Adjust for {min|max}-width */ + if (max_width >= 0 && width > max_width) + width = max_width; + if (width < min_width) + width = min_width; + + right = containing_block->width - + left - margin[LEFT] - + border[LEFT].width - + padding[LEFT] - width - padding[RIGHT] - + border[RIGHT].width - margin[RIGHT]; + } else if (left == AUTO && width != AUTO && right != AUTO) { + + /* Adjust for {min|max}-width */ + if (max_width >= 0 && width > max_width) + width = max_width; + if (width < min_width) + width = min_width; + + left = containing_block->width - + margin[LEFT] - border[LEFT].width - + padding[LEFT] - width - padding[RIGHT] - + border[RIGHT].width - margin[RIGHT] - + right; + } else if (left != AUTO && width == AUTO && right != AUTO) { + width = containing_block->width - + left - margin[LEFT] - + border[LEFT].width - + padding[LEFT] - padding[RIGHT] - + border[RIGHT].width - margin[RIGHT] - + right; + + /* Adjust for {min|max}-width */ + if (max_width >= 0 && width > max_width) + width = max_width; + if (width < min_width) + width = min_width; + + } else if (left != AUTO && width != AUTO && right == AUTO) { + + /* Adjust for {min|max}-width */ + if (max_width >= 0 && width > max_width) + width = max_width; + if (width < min_width) + width = min_width; + + right = containing_block->width - + left - margin[LEFT] - + border[LEFT].width - + padding[LEFT] - width - padding[RIGHT] - + border[RIGHT].width - margin[RIGHT]; } } - if (x1 - x0 < x && split_box) { - /* the last box went over the end */ - size_t split = 0; - int w; - bool no_wrap = css_computed_white_space( - split_box->style) == CSS_WHITE_SPACE_NOWRAP || - css_computed_white_space( - split_box->style) == CSS_WHITE_SPACE_PRE; + NSLOG(layout, DEBUG, + "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", + left, margin[LEFT], border[LEFT].width, padding[LEFT], width, + padding[RIGHT], border[RIGHT].width, margin[RIGHT], right, + containing_block->width); - x = x_previous; + box->x = left + margin[LEFT] + border[LEFT].width - cx; + if (containing_block->type == BOX_BLOCK || + containing_block->type == BOX_INLINE_BLOCK || + containing_block->type == BOX_TABLE_CELL) { + /* Block-level ancestor => reset container's width */ + containing_block->width -= containing_block->padding[LEFT] + + containing_block->padding[RIGHT]; + } else { + /** \todo inline ancestors */ + } + box->width = width; + box->height = height; - if (!no_wrap && - (split_box->type == BOX_INLINE || - split_box->type == BOX_TEXT) && - !split_box->object && - !(split_box->flags & REPLACE_DIM) && - !(split_box->flags & IFRAME) && - !split_box->gadget && split_box->text) { + if (box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK || + box->object || box->flags & IFRAME) { + if (!layout_block_context(box, -1, content)) + return false; + } else if (box->type == BOX_TABLE) { + /* layout_table also expects the containing block to be + * stored in the float_container field */ + box->float_container = containing_block; + /* \todo layout_table considers margins etc. again */ + if (!layout_table(box, width, content)) + return false; + box->float_container = NULL; + layout_solve_width(box, box->parent->width, box->width, 0, 0, + -1, -1); + } - font_plot_style_from_css(split_box->style, &fstyle); - /** \todo handle errors */ - font_func->split(&fstyle, - split_box->text, - split_box->length, - x1 - x0 - x - space_before, - &split, - &w); + /* 10.6.4 */ + NSLOG(layout, DEBUG, + "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", + top, margin[TOP], border[TOP].width, padding[TOP], height, + padding[BOTTOM], border[BOTTOM].width, margin[BOTTOM], bottom, + containing_block->height); + + if (top == AUTO && height == AUTO && bottom == AUTO) { + top = static_top; + height = box->height; + if (margin[TOP] == AUTO) + margin[TOP] = 0; + if (margin[BOTTOM] == AUTO) + margin[BOTTOM] = 0; + bottom = containing_block->height - + top - margin[TOP] - border[TOP].width - + padding[TOP] - height - padding[BOTTOM] - + border[BOTTOM].width - margin[BOTTOM]; + } else if (top != AUTO && height != AUTO && bottom != AUTO) { + if (margin[TOP] == AUTO && margin[BOTTOM] == AUTO) { + space = containing_block->height - + top - border[TOP].width - padding[TOP] - + height - padding[BOTTOM] - + border[BOTTOM].width - bottom; + margin[TOP] = margin[BOTTOM] = space / 2; + } else if (margin[TOP] == AUTO) { + margin[TOP] = containing_block->height - + top - border[TOP].width - padding[TOP] - + height - padding[BOTTOM] - + border[BOTTOM].width - margin[BOTTOM] - + bottom; + } else if (margin[BOTTOM] == AUTO) { + margin[BOTTOM] = containing_block->height - + top - margin[TOP] - border[TOP].width - + padding[TOP] - height - + padding[BOTTOM] - border[BOTTOM].width - + bottom; + } else { + bottom = containing_block->height - + top - margin[TOP] - border[TOP].width - + padding[TOP] - height - + padding[BOTTOM] - border[BOTTOM].width - + margin[BOTTOM]; + } + } else { + if (margin[TOP] == AUTO) + margin[TOP] = 0; + if (margin[BOTTOM] == AUTO) + margin[BOTTOM] = 0; + if (top == AUTO && height == AUTO && bottom != AUTO) { + height = box->height; + top = containing_block->height - + margin[TOP] - border[TOP].width - + padding[TOP] - height - + padding[BOTTOM] - border[BOTTOM].width - + margin[BOTTOM] - bottom; + } else if (top == AUTO && height != AUTO && bottom == AUTO) { + top = static_top; + bottom = containing_block->height - + top - margin[TOP] - border[TOP].width - + padding[TOP] - height - + padding[BOTTOM] - border[BOTTOM].width - + margin[BOTTOM]; + } else if (top != AUTO && height == AUTO && bottom == AUTO) { + height = box->height; + bottom = containing_block->height - + top - margin[TOP] - border[TOP].width - + padding[TOP] - height - + padding[BOTTOM] - border[BOTTOM].width - + margin[BOTTOM]; + } else if (top == AUTO && height != AUTO && bottom != AUTO) { + top = containing_block->height - + margin[TOP] - border[TOP].width - + padding[TOP] - height - + padding[BOTTOM] - border[BOTTOM].width - + margin[BOTTOM] - bottom; + } else if (top != AUTO && height == AUTO && bottom != AUTO) { + height = containing_block->height - + top - margin[TOP] - border[TOP].width - + padding[TOP] - padding[BOTTOM] - + border[BOTTOM].width - margin[BOTTOM] - + bottom; + } else if (top != AUTO && height != AUTO && bottom == AUTO) { + bottom = containing_block->height - + top - margin[TOP] - border[TOP].width - + padding[TOP] - height - + padding[BOTTOM] - border[BOTTOM].width - + margin[BOTTOM]; } + } - /* split == 0 implies that text can't be split */ - - if (split == 0) - w = split_box->width; - - - NSLOG(layout, DEBUG, - "splitting: split_box %p \"%.*s\", spilt %zu, w %i, " - "left %p, right %p, inline_count %u", - split_box, - (int)split_box->length, - split_box->text, - split, - w, - left, - right, - inline_count); - - if ((split == 0 || x1 - x0 <= x + space_before + w) && - !left && !right && inline_count == 1) { - /* first word of box doesn't fit, but no floats and - * first box on line so force in */ - if (split == 0 || split == split_box->length) { - /* only one word in this box, or not text - * or white-space:nowrap */ - b = split_box->next; - } else { - /* cut off first word for this line */ - if (!layout_text_box_split(content, &fstyle, - split_box, split, w)) - return false; - b = split_box->next; - } - x += space_before + w; - - NSLOG(layout, DEBUG, "forcing"); - - } else if ((split == 0 || x1 - x0 <= x + space_before + w) && - inline_count == 1) { - /* first word of first box doesn't fit, but a float is - * taking some of the width so move below it */ - assert(left || right); - used_height = 0; - if (left) { - - NSLOG(layout, DEBUG, - "cy %i, left->y %i, left->height %i", - cy, - left->y, - left->height); - - used_height = left->y + left->height - cy + 1; - - NSLOG(layout, DEBUG, "used_height %i", - used_height); - - } - if (right && used_height < - right->y + right->height - cy + 1) - used_height = right->y + right->height - cy + 1; - - if (used_height < 0) - used_height = 0; + NSLOG(layout, DEBUG, + "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", + top, margin[TOP], border[TOP].width, padding[TOP], height, + padding[BOTTOM], border[BOTTOM].width, margin[BOTTOM], bottom, + containing_block->height); - b = split_box; + box->y = top + margin[TOP] + border[TOP].width - cy; + if (containing_block->type == BOX_BLOCK || + containing_block->type == BOX_INLINE_BLOCK || + containing_block->type == BOX_TABLE_CELL) { + /* Block-level ancestor => reset container's height */ + containing_block->height -= containing_block->padding[TOP] + + containing_block->padding[BOTTOM]; + } else { + /** \todo Inline ancestors */ + } + box->height = height; + layout_apply_minmax_height(box, containing_block); - NSLOG(layout, DEBUG, "moving below float"); + return true; +} - } else if (split == 0 || x1 - x0 <= x + space_before + w) { - /* first word of box doesn't fit so leave box for next - * line */ - b = split_box; - NSLOG(layout, DEBUG, "leaving for next line"); +/** + * Recursively layout and position absolutely positioned boxes. + * + * \param box tree of boxes to layout + * \param containing_block current containing block + * \param cx position of box relative to containing_block + * \param cy position of box relative to containing_block + * \param content memory pool for any new boxes + * \return true on success, false on memory exhaustion + */ +static bool +layout_position_absolute(struct box *box, + struct box *containing_block, + int cx, int cy, + html_content *content) +{ + struct box *c; + for (c = box->children; c; c = c->next) { + if ((c->type == BOX_BLOCK || c->type == BOX_TABLE || + c->type == BOX_INLINE_BLOCK) && + (css_computed_position(c->style) == + CSS_POSITION_ABSOLUTE || + css_computed_position(c->style) == + CSS_POSITION_FIXED)) { + if (!layout_absolute(c, containing_block, + cx, cy, content)) + return false; + if (!layout_position_absolute(c, c, 0, 0, content)) + return false; + } else if (c->style && css_computed_position(c->style) == + CSS_POSITION_RELATIVE) { + if (!layout_position_absolute(c, c, 0, 0, content)) + return false; } else { - /* fit as many words as possible */ - assert(split != 0); - - NSLOG(layout, DEBUG, "'%.*s' %i %zu %i", - (int)split_box->length, split_box->text, - x1 - x0, split, w); - - if (split != split_box->length) { - if (!layout_text_box_split(content, &fstyle, - split_box, split, w)) - return false; - b = split_box->next; + int px, py; + if (c->style && (css_computed_float(c->style) == + CSS_FLOAT_LEFT || + css_computed_float(c->style) == + CSS_FLOAT_RIGHT)) { + /* Float x/y coords are relative to nearest + * ansestor with float_children, rather than + * relative to parent. Need to get x/y relative + * to parent */ + struct box *p; + px = c->x; + py = c->y; + for (p = box->parent; p && !p->float_children; + p = p->parent) { + px -= p->x; + py -= p->y; + } + } else { + /* Not a float, so box x/y coords are relative + * to parent */ + px = c->x; + py = c->y; } - x += space_before + w; - - NSLOG(layout, DEBUG, "fitting words"); - + if (!layout_position_absolute(c, containing_block, + cx + px, cy + py, content)) + return false; } - move_y = true; } - /* set positions */ - switch (css_computed_text_align(first->parent->parent->style)) { - case CSS_TEXT_ALIGN_RIGHT: - case CSS_TEXT_ALIGN_LIBCSS_RIGHT: - x0 = x1 - x; - break; - case CSS_TEXT_ALIGN_CENTER: - case CSS_TEXT_ALIGN_LIBCSS_CENTER: - x0 = (x0 + (x1 - x)) / 2; - break; - case CSS_TEXT_ALIGN_LEFT: - case CSS_TEXT_ALIGN_LIBCSS_LEFT: - case CSS_TEXT_ALIGN_JUSTIFY: - /* leave on left */ - break; - case CSS_TEXT_ALIGN_DEFAULT: - /* None; consider text direction */ - switch (css_computed_direction(first->parent->parent->style)) { - case CSS_DIRECTION_LTR: - /* leave on left */ - break; - case CSS_DIRECTION_RTL: - x0 = x1 - x; - break; - } - break; - } + return true; +} - for (d = first; d != b; d = d->next) { - d->flags &= ~NEW_LINE; - if (d->type == BOX_INLINE_BLOCK && - (css_computed_position(d->style) == - CSS_POSITION_ABSOLUTE || - css_computed_position(d->style) == - CSS_POSITION_FIXED)) { - /* positioned inline-blocks: - * set static position (x,y) only, rest of positioning - * is handled later */ - d->x += x0; - d->y = *y; - continue; - } else if ((d->type == BOX_INLINE && - ((d->object || d->gadget) == false) && - !(d->flags & IFRAME) && - !(d->flags & REPLACE_DIM)) || - d->type == BOX_BR || - d->type == BOX_TEXT || - d->type == BOX_INLINE_END) { - /* regular (non-replaced) inlines */ - d->x += x0; - d->y = *y - d->padding[TOP]; +/** + * Compute a box's relative offset as per CSS 2.1 9.4.3 + * + * \param box Box to compute relative offsets for. + * \param x Receives relative offset in x. + * \param y Receives relative offset in y. + */ +static void layout_compute_relative_offset(struct box *box, int *x, int *y) +{ + int left, right, top, bottom; + struct box *containing_block; - if (d->type == BOX_TEXT && d->height > used_height) { - /* text */ - used_height = d->height; - } - } else if ((d->type == BOX_INLINE) || - d->type == BOX_INLINE_BLOCK) { - /* replaced inlines and inline-blocks */ - d->x += x0; - d->y = *y + d->border[TOP].width + d->margin[TOP]; - h = d->margin[TOP] + d->border[TOP].width + - d->padding[TOP] + d->height + - d->padding[BOTTOM] + - d->border[BOTTOM].width + - d->margin[BOTTOM]; - if (used_height < h) - used_height = h; - } + assert(box && box->parent && box->style && + css_computed_position(box->style) == + CSS_POSITION_RELATIVE); + + if (box->float_container && + (css_computed_float(box->style) == CSS_FLOAT_LEFT || + css_computed_float(box->style) == CSS_FLOAT_RIGHT)) { + containing_block = box->float_container; + } else { + containing_block = box->parent; } - first->flags |= NEW_LINE; - - assert(b != first || (move_y && 0 < used_height && (left || right))); + layout_compute_offsets(box, containing_block, + &top, &right, &bottom, &left); - /* handle vertical-align by adjusting box y values */ - /** \todo proper vertical alignment handling */ - for (d = first; d != b; d = d->next) { - if ((d->type == BOX_INLINE && d->inline_end) || - d->type == BOX_BR || - d->type == BOX_TEXT || - d->type == BOX_INLINE_END) { - css_fixed value = 0; - css_unit unit = CSS_UNIT_PX; - switch (css_computed_vertical_align(d->style, &value, - &unit)) { - case CSS_VERTICAL_ALIGN_SUPER: - case CSS_VERTICAL_ALIGN_TOP: - case CSS_VERTICAL_ALIGN_TEXT_TOP: - /* already at top */ - break; - case CSS_VERTICAL_ALIGN_SUB: - case CSS_VERTICAL_ALIGN_BOTTOM: - case CSS_VERTICAL_ALIGN_TEXT_BOTTOM: - d->y += used_height - d->height; - break; - default: - case CSS_VERTICAL_ALIGN_BASELINE: - d->y += 0.75 * (used_height - d->height); - break; - } + if (left == AUTO && right == AUTO) + left = right = 0; + else if (left == AUTO) + /* left is auto => computed = -right */ + left = -right; + else if (right == AUTO) + /* right is auto => computed = -left */ + right = -left; + else { + /* over constrained => examine direction property + * of containing block */ + if (containing_block->style && + css_computed_direction( + containing_block->style) == + CSS_DIRECTION_RTL) { + /* right wins */ + left = -right; + } else { + /* assume LTR in all other cases */ + right = -left; } } - /* handle clearance for br */ - if (br_box && css_computed_clear(br_box->style) != CSS_CLEAR_NONE) { - int clear_y = layout_clear(cont->float_children, - css_computed_clear(br_box->style)); - if (used_height < clear_y - cy) - used_height = clear_y - cy; + assert(left == -right); + + if (top == AUTO && bottom == AUTO) { + top = bottom = 0; + } else if (top == AUTO) { + top = -bottom; + } else { + /* bottom is AUTO, or neither are AUTO */ + bottom = -top; } - if (move_y) - *y += used_height; - *next_box = b; - *width = x; /* return actual width */ - return true; + NSLOG(layout, DEBUG, "left %i, right %i, top %i, bottom %i", left, + right, top, bottom); + + *x = left; + *y = top; } -/* exported function documented in render/layout.h */ -bool layout_inline_container(struct box *inline_container, int width, - struct box *cont, int cx, int cy, html_content *content) +/** + * Adjust positions of relatively positioned boxes. + * + * \param root box to adjust the position of + * \param fp box which forms the block formatting context for children of + * "root" which are floats + * \param fx x offset due to intervening relatively positioned boxes + * between current box, "root", and the block formatting context + * box, "fp", for float children of "root" + * \param fy y offset due to intervening relatively positioned boxes + * between current box, "root", and the block formatting context + * box, "fp", for float children of "root" + */ +static void +layout_position_relative(struct box *root, struct box *fp, int fx, int fy) { - bool first_line = true; - bool has_text_children; - struct box *c, *next; - int y = 0; - int curwidth,maxwidth = width; + struct box *box; /* for children of "root" */ + struct box *fn; /* for block formatting context box for children of + * "box" */ + struct box *fc; /* for float children of the block formatting context, + * "fp" */ + int x, y; /* for the offsets resulting from any relative + * positioning on the current block */ + int fnx, fny; /* for affsets which apply to flat children of "box" */ - assert(inline_container->type == BOX_INLINE_CONTAINER); + /**\todo ensure containing box is large enough after moving boxes */ - NSLOG(layout, DEBUG, - "inline_container %p, width %i, cont %p, cx %i, cy %i", - inline_container, - width, - cont, - cx, - cy); + assert(root); + /* Normal children */ + for (box = root->children; box; box = box->next) { - has_text_children = false; - for (c = inline_container->children; c; c = c->next) { - bool is_pre = false; + if (box->type == BOX_TEXT) + continue; - if (c->style) { - enum css_white_space_e whitespace; + /* If relatively positioned, get offsets */ + if (box->style && css_computed_position(box->style) == + CSS_POSITION_RELATIVE) + layout_compute_relative_offset(box, &x, &y); + else + x = y = 0; - whitespace = css_computed_white_space(c->style); + /* Adjust float coordinates. + * (note float x and y are relative to their block formatting + * context box and not their parent) */ + if (box->style && (css_computed_float(box->style) == + CSS_FLOAT_LEFT || + css_computed_float(box->style) == + CSS_FLOAT_RIGHT) && + (fx != 0 || fy != 0)) { + /* box is a float and there is a float offset to + * apply */ + for (fc = fp->float_children; fc; fc = fc->next_float) { + if (box == fc->children) { + /* Box is floated in the block + * formatting context block, fp. + * Apply float offsets. */ + box->x += fx; + box->y += fy; + fx = fy = 0; + } + } + } - is_pre = (whitespace == CSS_WHITE_SPACE_PRE || - whitespace == CSS_WHITE_SPACE_PRE_LINE || - whitespace == CSS_WHITE_SPACE_PRE_WRAP); + if (box->float_children) { + fn = box; + fnx = fny = 0; + } else { + fn = fp; + fnx = fx + x; + fny = fy + y; } - if ((!c->object && !(c->flags & REPLACE_DIM) && - !(c->flags & IFRAME) && - c->text && (c->length || is_pre)) || - c->type == BOX_BR) - has_text_children = true; + /* recurse first */ + layout_position_relative(box, fn, fnx, fny); + + /* Ignore things we're not interested in. */ + if (!box->style || (box->style && + css_computed_position(box->style) != + CSS_POSITION_RELATIVE)) + continue; + + box->x += x; + box->y += y; + + /* Handle INLINEs - their "children" are in fact + * the sibling boxes between the INLINE and + * INLINE_END boxes */ + if (box->type == BOX_INLINE && box->inline_end) { + struct box *b; + for (b = box->next; b && b != box->inline_end; + b = b->next) { + b->x += x; + b->y += y; + } + } } +} - /** \todo fix wrapping so that a box with horizontal scrollbar will - * shrink back to 'width' if no word is wider than 'width' (Or just set - * curwidth = width and have the multiword lines wrap to the min width) - */ - for (c = inline_container->children; c; ) { - NSLOG(layout, DEBUG, "c %p", c); +/* exported function documented in render/layout.h */ +bool layout_document(html_content *content, int width, int height) +{ + bool ret; + struct box *doc = content->layout; + const struct gui_layout_table *font_func = content->font_func; - curwidth = inline_container->width; - if (!layout_line(c, &curwidth, &y, cx, cy + y, cont, first_line, - has_text_children, content, &next)) - return false; - maxwidth = max(maxwidth,curwidth); - c = next; - first_line = false; + layout_minmax_block(doc, font_func); + + layout_block_find_dimensions(width, height, 0, 0, doc); + doc->x = doc->margin[LEFT] + doc->border[LEFT].width; + doc->y = doc->margin[TOP] + doc->border[TOP].width; + width -= doc->margin[LEFT] + doc->border[LEFT].width + + doc->padding[LEFT] + doc->padding[RIGHT] + + doc->border[RIGHT].width + doc->margin[RIGHT]; + if (width < 0) { + width = 0; } + doc->width = width; - inline_container->width = maxwidth; - inline_container->height = y; + ret = layout_block_context(doc, height, content); - return true; + /* make and fill available height */ + if (doc->y + doc->padding[TOP] + doc->height + doc->padding[BOTTOM] + + doc->border[BOTTOM].width + doc->margin[BOTTOM] < + height) { + doc->height = height - (doc->y + doc->padding[TOP] + + doc->padding[BOTTOM] + + doc->border[BOTTOM].width + + doc->margin[BOTTOM]); + if (doc->children) + doc->children->height = doc->height - + (doc->children->margin[TOP] + + doc->children->border[TOP].width + + doc->children->padding[TOP] + + doc->children->padding[BOTTOM] + + doc->children->border[BOTTOM].width + + doc->children->margin[BOTTOM]); + } + + layout_lists(doc, font_func); + layout_position_absolute(doc, doc, 0, 0, content); + layout_position_relative(doc, doc, 0, 0); + + layout_calculate_descendant_bboxes(doc); + + return ret; } diff --git a/render/layout.h b/render/layout.h index 7a579ca22..0aa0da3e9 100644 --- a/render/layout.h +++ b/render/layout.h @@ -42,19 +42,6 @@ struct gui_layout_table; */ bool layout_document(struct html_content *content, int width, int height); -/** - * Layout lines of text or inline boxes with floats. - * - * \param box inline container box - * \param width horizontal space available - * \param cont ancestor box which defines horizontal space, for floats - * \param cx box position relative to cont - * \param cy box position relative to cont - * \param content memory pool for any new boxes - * \return true on success, false on memory exhaustion - */ -bool layout_inline_container(struct box *box, int width, struct box *cont, int cx, int cy, struct html_content *content); - /** * Recursively calculate the descendant_[xy][01] values for a laid-out box tree * and inform iframe browser windows of their size and position. -- cgit v1.2.3 From a67973f312b7cba8a6d56f9841a542a731a9ddb4 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Wed, 3 Jan 2018 22:18:12 +0000 Subject: Layout: No need to expose layout_calculate_descendant_bboxes(). --- render/layout.c | 109 +++++++++++++++++++++++++++++--------------------------- render/layout.h | 8 ----- 2 files changed, 57 insertions(+), 60 deletions(-) diff --git a/render/layout.c b/render/layout.c index b19d93f44..83dbc536d 100644 --- a/render/layout.c +++ b/render/layout.c @@ -5061,56 +5061,6 @@ layout_position_relative(struct box *root, struct box *fp, int fx, int fy) } -/* exported function documented in render/layout.h */ -bool layout_document(html_content *content, int width, int height) -{ - bool ret; - struct box *doc = content->layout; - const struct gui_layout_table *font_func = content->font_func; - - layout_minmax_block(doc, font_func); - - layout_block_find_dimensions(width, height, 0, 0, doc); - doc->x = doc->margin[LEFT] + doc->border[LEFT].width; - doc->y = doc->margin[TOP] + doc->border[TOP].width; - width -= doc->margin[LEFT] + doc->border[LEFT].width + - doc->padding[LEFT] + doc->padding[RIGHT] + - doc->border[RIGHT].width + doc->margin[RIGHT]; - if (width < 0) { - width = 0; - } - doc->width = width; - - ret = layout_block_context(doc, height, content); - - /* make and fill available height */ - if (doc->y + doc->padding[TOP] + doc->height + doc->padding[BOTTOM] + - doc->border[BOTTOM].width + doc->margin[BOTTOM] < - height) { - doc->height = height - (doc->y + doc->padding[TOP] + - doc->padding[BOTTOM] + - doc->border[BOTTOM].width + - doc->margin[BOTTOM]); - if (doc->children) - doc->children->height = doc->height - - (doc->children->margin[TOP] + - doc->children->border[TOP].width + - doc->children->padding[TOP] + - doc->children->padding[BOTTOM] + - doc->children->border[BOTTOM].width + - doc->children->margin[BOTTOM]); - } - - layout_lists(doc, font_func); - layout_position_absolute(doc, doc, 0, 0, content); - layout_position_relative(doc, doc, 0, 0); - - layout_calculate_descendant_bboxes(doc); - - return ret; -} - - /** * Find a box's bounding box relative to itself, i.e. the box's border edge box * @@ -5215,8 +5165,13 @@ layout_update_descendant_bbox(struct box *box, } -/* exported function documented in render/layout.h */ -void layout_calculate_descendant_bboxes(struct box *box) +/** + * Recursively calculate the descendant_[xy][01] values for a laid-out box tree + * and inform iframe browser windows of their size and position. + * + * \param box tree of boxes to update + */ +static void layout_calculate_descendant_bboxes(struct box *box) { struct box *child; @@ -5303,3 +5258,53 @@ void layout_calculate_descendant_bboxes(struct box *box) layout_update_descendant_bbox(box, child, 0, 0); } } + + +/* exported function documented in render/layout.h */ +bool layout_document(html_content *content, int width, int height) +{ + bool ret; + struct box *doc = content->layout; + const struct gui_layout_table *font_func = content->font_func; + + layout_minmax_block(doc, font_func); + + layout_block_find_dimensions(width, height, 0, 0, doc); + doc->x = doc->margin[LEFT] + doc->border[LEFT].width; + doc->y = doc->margin[TOP] + doc->border[TOP].width; + width -= doc->margin[LEFT] + doc->border[LEFT].width + + doc->padding[LEFT] + doc->padding[RIGHT] + + doc->border[RIGHT].width + doc->margin[RIGHT]; + if (width < 0) { + width = 0; + } + doc->width = width; + + ret = layout_block_context(doc, height, content); + + /* make and fill available height */ + if (doc->y + doc->padding[TOP] + doc->height + doc->padding[BOTTOM] + + doc->border[BOTTOM].width + doc->margin[BOTTOM] < + height) { + doc->height = height - (doc->y + doc->padding[TOP] + + doc->padding[BOTTOM] + + doc->border[BOTTOM].width + + doc->margin[BOTTOM]); + if (doc->children) + doc->children->height = doc->height - + (doc->children->margin[TOP] + + doc->children->border[TOP].width + + doc->children->padding[TOP] + + doc->children->padding[BOTTOM] + + doc->children->border[BOTTOM].width + + doc->children->margin[BOTTOM]); + } + + layout_lists(doc, font_func); + layout_position_absolute(doc, doc, 0, 0, content); + layout_position_relative(doc, doc, 0, 0); + + layout_calculate_descendant_bboxes(doc); + + return ret; +} diff --git a/render/layout.h b/render/layout.h index 0aa0da3e9..cd5ddd77f 100644 --- a/render/layout.h +++ b/render/layout.h @@ -42,12 +42,4 @@ struct gui_layout_table; */ bool layout_document(struct html_content *content, int width, int height); -/** - * Recursively calculate the descendant_[xy][01] values for a laid-out box tree - * and inform iframe browser windows of their size and position. - * - * \param box tree of boxes to update - */ -void layout_calculate_descendant_bboxes(struct box *box); - #endif -- cgit v1.2.3 From 6be6fa1b2197ffe6e511c5eff9abe14d883f8478 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Wed, 3 Jan 2018 23:58:18 +0000 Subject: CSS utils: Handle new units in length conversion routines. This causes a ripple effect of all the callsites needing information they didn't have. --- content/handlers/css/utils.c | 144 ++++++++++- content/handlers/css/utils.h | 46 +++- desktop/print.c | 37 +-- desktop/selection.c | 67 ++++-- desktop/selection.h | 7 +- desktop/textarea.c | 46 +++- desktop/textarea.h | 8 +- render/box.c | 41 ++-- render/box.h | 6 +- render/box_normalise.c | 3 - render/box_textarea.c | 11 +- render/font.c | 8 +- render/font.h | 11 +- render/form.c | 3 +- render/html.c | 15 +- render/html_interaction.c | 12 +- render/html_internal.h | 4 + render/html_object.c | 6 +- render/html_redraw.c | 41 ++-- render/layout.c | 562 +++++++++++++++++++++++++++---------------- render/search.c | 5 +- render/table.c | 319 +++++++++++++++--------- render/table.h | 8 +- render/textplain.c | 2 +- 24 files changed, 956 insertions(+), 456 deletions(-) diff --git a/content/handlers/css/utils.c b/content/handlers/css/utils.c index 5c7cbd9a7..8fe157bd2 100644 --- a/content/handlers/css/utils.c +++ b/content/handlers/css/utils.c @@ -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 = 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; diff --git a/content/handlers/css/utils.h b/content/handlers/css/utils.h index 21cb4973b..c8f4c82f4 100644 --- a/content/handlers/css/utils.h +++ b/content/handlers/css/utils.h @@ -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); /** diff --git a/desktop/print.c b/desktop/print.c index 54cc5451a..5c0333a96 100644 --- a/desktop/print.c +++ b/desktop/print.c @@ -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; diff --git a/desktop/selection.c b/desktop/selection.c index 7506af0ef..5cb43b8c3 100644 --- a/desktop/selection.c +++ b/desktop/selection.c @@ -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 */ diff --git a/desktop/selection.h b/desktop/selection.h index e2bc3b31d..2f3f6dcfe 100644 --- a/desktop/selection.h +++ b/desktop/selection.h @@ -25,6 +25,7 @@ #include #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); */ diff --git a/desktop/textarea.c b/desktop/textarea.c index 149ca26b1..3fd4c9804 100644 --- a/desktop/textarea.c +++ b/desktop/textarea.c @@ -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) { diff --git a/desktop/textarea.h b/desktop/textarea.h index b386e50e8..82e0de95b 100644 --- a/desktop/textarea.h +++ b/desktop/textarea.h @@ -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); /** diff --git a/render/box.c b/render/box.c index 8b9c89ee6..c97e8982b 100644 --- a/render/box.c +++ b/render/box.c @@ -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); diff --git a/render/box.h b/render/box.h index 8208a6fd3..1af0a8b73 100644 --- a/render/box.h +++ b/render/box.h @@ -91,6 +91,8 @@ #include #include +#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); diff --git a/render/box_normalise.c b/render/box_normalise.c index 9c0875b4e..8da245754 100644 --- a/render/box_normalise.c +++ b/render/box_normalise.c @@ -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 diff --git a/render/box_textarea.c b/render/box_textarea.c index 3b1e7750c..a60984235 100644 --- a/render/box_textarea.c +++ b/render/box_textarea.c @@ -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; diff --git a/render/font.c b/render/font.c index 94ef877c7..a769b476f 100644 --- a/render/font.c +++ b/render/font.c @@ -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 */ diff --git a/render/font.h b/render/font.h index fba368a97..52f5a62c2 100644 --- a/render/font.h +++ b/render/font.h @@ -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 diff --git a/render/form.c b/render/form.c index 904272d3a..432002564 100644 --- a/render/form.c +++ b/render/form.c @@ -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; diff --git a/render/html.c b/render/html.c index 3cfc5e236..b7d7aa313 100644 --- a/render/html.c +++ b/render/html.c @@ -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) == diff --git a/render/html_interaction.c b/render/html_interaction.c index 30adaa080..2d14ed2ae 100644 --- a/render/html_interaction.c +++ b/render/html_interaction.c @@ -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, diff --git a/render/html_internal.h b/render/html_internal.h index 2f84cf869..66ecb2b36 100644 --- a/render/html_internal.h +++ b/render/html_internal.h @@ -26,6 +26,7 @@ #include +#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; diff --git a/render/html_object.c b/render/html_object.c index e98bdba0b..fb9e7b090 100644 --- a/render/html_object.c +++ b/render/html_object.c @@ -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)); } diff --git a/render/html_redraw.c b/render/html_redraw.c index 2f8730634..9a97e5ec5 100644 --- a/render/html_redraw.c +++ b/render/html_redraw.c @@ -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, - ¤t_background_color, bg_box, ctx)) + ¤t_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, - ¤t_background_color, ctx)) + ¤t_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, ¤t_background_color, ctx)) + first, true, ¤t_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 && diff --git a/render/layout.c b/render/layout.c index 83dbc536d..15eb1e846 100644 --- a/render/layout.c +++ b/render/layout.c @@ -69,8 +69,14 @@ #define FPCT_OF_INT_TOINT(a, b) (FIXTOINT(FDIV((a * b), F_100))) /* forward declaration to break cycles */ -static bool layout_block_context(struct box *block, int viewport_height, html_content *content); -static void layout_minmax_block(struct box *block, const struct gui_layout_table *font_func); +static bool layout_block_context( + struct box *block, + int viewport_height, + html_content *content); +static void layout_minmax_block( + struct box *block, + const struct gui_layout_table *font_func, + const html_content *content); /** @@ -179,7 +185,9 @@ layout_get_object_dimensions(struct box *box, * \param width width of containing block * \return length of indent */ -static int layout_text_indent(const css_computed_style *style, int width) +static int layout_text_indent( + const nscss_len_ctx *len_ctx, + const css_computed_style *style, int width) { css_fixed value = 0; css_unit unit = CSS_UNIT_PX; @@ -189,7 +197,7 @@ static int layout_text_indent(const css_computed_style *style, int width) if (unit == CSS_UNIT_PCT) { return FPCT_OF_INT_TOINT(value, width); } else { - return FIXTOINT(nscss_len2px(value, unit, style)); + return FIXTOINT(nscss_len2px(len_ctx, value, unit, style)); } } @@ -197,6 +205,7 @@ static int layout_text_indent(const css_computed_style *style, int width) /** * Determine width of margin, borders, and padding on one side of a box. * + * \param len_ctx CSS length conversion context for document * \param style style to measure * \param side side of box to measure * \param margin whether margin width is required @@ -206,7 +215,8 @@ static int layout_text_indent(const css_computed_style *style, int width) * \param frac increased by sum of fractional margin and padding */ static void -calculate_mbp_width(const css_computed_style *style, +calculate_mbp_width(const nscss_len_ctx *len_ctx, + const css_computed_style *style, unsigned int side, bool margin, bool border, @@ -217,19 +227,19 @@ calculate_mbp_width(const css_computed_style *style, typedef uint8_t (*len_func)(const css_computed_style *style, css_fixed *length, css_unit *unit); - static len_func margin_funcs[4] = { + static const len_func margin_funcs[4] = { css_computed_margin_top, css_computed_margin_right, css_computed_margin_bottom, css_computed_margin_left }; - static len_func padding_funcs[4] = { + static const len_func padding_funcs[4] = { css_computed_padding_top, css_computed_padding_right, css_computed_padding_bottom, css_computed_padding_left }; - static struct { + static const struct { len_func width; uint8_t (*style)(const css_computed_style *style); } border_funcs[4] = { @@ -257,8 +267,8 @@ calculate_mbp_width(const css_computed_style *style, if (unit == CSS_UNIT_PCT) { *frac += FIXTOINT(FDIV(value, F_100)); } else { - *fixed += FIXTOINT(nscss_len2px(value, unit, - style)); + *fixed += FIXTOINT(nscss_len2px(len_ctx, + value, unit, style)); } } } @@ -269,7 +279,8 @@ calculate_mbp_width(const css_computed_style *style, CSS_BORDER_STYLE_NONE) { border_funcs[side].width(style, &value, &unit); - *fixed += FIXTOINT(nscss_len2px(value, unit, style)); + *fixed += FIXTOINT(nscss_len2px(len_ctx, + value, unit, style)); } } @@ -279,7 +290,8 @@ calculate_mbp_width(const css_computed_style *style, if (unit == CSS_UNIT_PCT) { *frac += FIXTOINT(FDIV(value, F_100)); } else { - *fixed += FIXTOINT(nscss_len2px(value, unit, style)); + *fixed += FIXTOINT(nscss_len2px(len_ctx, + value, unit, style)); } } } @@ -290,19 +302,20 @@ calculate_mbp_width(const css_computed_style *style, * * \param table box of type TABLE * \param font_func Font functions - * \param content The HTML content being layed out. + * \param content The HTML content we are laying out. * \post table->min_width and table->max_width filled in, * 0 <= table->min_width <= table->max_width */ -static void -layout_minmax_table(struct box *table, const struct gui_layout_table *font_func) +static void layout_minmax_table(struct box *table, + const struct gui_layout_table *font_func, + const html_content *content) { unsigned int i, j; int border_spacing_h = 0; int table_min = 0, table_max = 0; int extra_fixed = 0; float extra_frac = 0; - struct column *col = table->col; + struct column *col; struct box *row_group, *row, *cell; enum css_width_e wtype; css_fixed value = 0; @@ -312,6 +325,13 @@ layout_minmax_table(struct box *table, const struct gui_layout_table *font_func) if (table->max_width != UNKNOWN_MAX_WIDTH) return; + if (table_calculate_column_types(&content->len_ctx, table) == false) { + NSLOG(netsurf, WARNING, + "Could not establish table column types."); + return; + } + col = table->col; + /* start with 0 except for fixed-width columns */ for (i = 0; i != table->columns; i++) { if (col[i].type == COLUMN_WIDTH_FIXED) @@ -328,7 +348,8 @@ layout_minmax_table(struct box *table, const struct gui_layout_table *font_func) css_computed_border_spacing(table->style, &h, &hu, &v, &vu); - border_spacing_h = FIXTOINT(nscss_len2px(h, hu, table->style)); + border_spacing_h = FIXTOINT(nscss_len2px(&content->len_ctx, + h, hu, table->style)); } /* 1st pass: consider cells with colspan 1 only */ @@ -344,7 +365,7 @@ layout_minmax_table(struct box *table, const struct gui_layout_table *font_func) if (cell->columns != 1) continue; - layout_minmax_block(cell, font_func); + layout_minmax_block(cell, font_func, content); i = cell->start_column; if (col[i].positioned) @@ -367,7 +388,7 @@ layout_minmax_table(struct box *table, const struct gui_layout_table *font_func) if (cell->columns == 1) continue; - layout_minmax_block(cell, font_func); + layout_minmax_block(cell, font_func, content); i = cell->start_column; /* find min width so far of spanned columns, and count @@ -433,7 +454,8 @@ layout_minmax_table(struct box *table, const struct gui_layout_table *font_func) /* fixed width takes priority, unless it is too narrow */ wtype = css_computed_width(table->style, &value, &unit); if (wtype == CSS_WIDTH_SET && unit != CSS_UNIT_PCT) { - int width = FIXTOINT(nscss_len2px(value, unit, table->style)); + int width = FIXTOINT(nscss_len2px(&content->len_ctx, + value, unit, table->style)); if (table_min < width) table_min = width; if (table_max < width) @@ -441,9 +463,11 @@ layout_minmax_table(struct box *table, const struct gui_layout_table *font_func) } /* add margins, border, padding to min, max widths */ - calculate_mbp_width(table->style, LEFT, true, true, true, + calculate_mbp_width(&content->len_ctx, + table->style, LEFT, true, true, true, &extra_fixed, &extra_frac); - calculate_mbp_width(table->style, RIGHT, true, true, true, + calculate_mbp_width(&content->len_ctx, + table->style, RIGHT, true, true, true, &extra_fixed, &extra_frac); if (extra_fixed < 0) extra_fixed = 0; @@ -478,7 +502,8 @@ layout_minmax_line(struct box *first, int *line_max, bool first_line, bool *line_has_height, - const struct gui_layout_table *font_func) + const struct gui_layout_table *font_func, + const html_content *content) { int min = 0, max = 0, width, height, fixed; float frac; @@ -524,9 +549,11 @@ layout_minmax_line(struct box *first, if (b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT) { assert(b->children); if (b->children->type == BOX_BLOCK) - layout_minmax_block(b->children, font_func); + layout_minmax_block(b->children, font_func, + content); else - layout_minmax_table(b->children, font_func); + layout_minmax_table(b->children, font_func, + content); b->min_width = b->children->min_width; b->max_width = b->children->max_width; if (min < b->min_width) @@ -536,7 +563,7 @@ layout_minmax_line(struct box *first, } if (b->type == BOX_INLINE_BLOCK) { - layout_minmax_block(b, font_func); + layout_minmax_block(b, font_func, content); if (min < b->min_width) min = b->min_width; max += b->max_width; @@ -547,16 +574,18 @@ layout_minmax_line(struct box *first, } assert(b->style); - font_plot_style_from_css(b->style, &fstyle); + font_plot_style_from_css(&content->len_ctx, b->style, &fstyle); if (b->type == BOX_INLINE && !b->object && !(b->flags & REPLACE_DIM) && !(b->flags & IFRAME)) { fixed = frac = 0; - calculate_mbp_width(b->style, LEFT, true, true, true, + calculate_mbp_width(&content->len_ctx, + b->style, LEFT, true, true, true, &fixed, &frac); if (!b->inline_end) - calculate_mbp_width(b->style, RIGHT, + calculate_mbp_width(&content->len_ctx, + b->style, RIGHT, true, true, true, &fixed, &frac); if (0 < fixed) @@ -565,7 +594,8 @@ layout_minmax_line(struct box *first, /* \todo update min width, consider fractional extra */ } else if (b->type == BOX_INLINE_END) { fixed = frac = 0; - calculate_mbp_width(b->inline_end->style, RIGHT, + calculate_mbp_width(&content->len_ctx, + b->inline_end->style, RIGHT, true, true, true, &fixed, &frac); if (0 < fixed) @@ -686,15 +716,17 @@ layout_minmax_line(struct box *first, width = AUTO; } else { - width = FIXTOINT(nscss_len2px(value, unit, - b->style)); + width = FIXTOINT(nscss_len2px(&content->len_ctx, + value, unit, b->style)); if (bs == CSS_BOX_SIZING_BORDER_BOX) { fixed = frac = 0; - calculate_mbp_width(block->style, LEFT, + calculate_mbp_width(&content->len_ctx, + block->style, LEFT, false, true, true, &fixed, &frac); - calculate_mbp_width(block->style, RIGHT, + calculate_mbp_width(&content->len_ctx, + block->style, RIGHT, false, true, true, &fixed, &frac); if (width < fixed) { @@ -711,7 +743,8 @@ layout_minmax_line(struct box *first, /* height */ htype = css_computed_height(b->style, &value, &unit); if (htype == CSS_HEIGHT_SET) { - height = FIXTOINT(nscss_len2px(value, unit, b->style)); + height = FIXTOINT(nscss_len2px(&content->len_ctx, + value, unit, b->style)); } else { height = AUTO; } @@ -727,17 +760,21 @@ layout_minmax_line(struct box *first, fixed = frac = 0; if (bs == CSS_BOX_SIZING_BORDER_BOX) { - calculate_mbp_width(b->style, LEFT, + calculate_mbp_width(&content->len_ctx, + b->style, LEFT, true, false, false, &fixed, &frac); - calculate_mbp_width(b->style, RIGHT, + calculate_mbp_width(&content->len_ctx, + b->style, RIGHT, true, false, false, &fixed, &frac); } else { - calculate_mbp_width(b->style, LEFT, + calculate_mbp_width(&content->len_ctx, + b->style, LEFT, true, true, true, &fixed, &frac); - calculate_mbp_width(b->style, RIGHT, + calculate_mbp_width(&content->len_ctx, + b->style, RIGHT, true, true, true, &fixed, &frac); } @@ -750,17 +787,21 @@ layout_minmax_line(struct box *first, fixed = frac = 0; if (bs == CSS_BOX_SIZING_BORDER_BOX) { - calculate_mbp_width(b->style, LEFT, + calculate_mbp_width(&content->len_ctx, + b->style, LEFT, true, false, false, &fixed, &frac); - calculate_mbp_width(b->style, RIGHT, + calculate_mbp_width(&content->len_ctx, + b->style, RIGHT, true, false, false, &fixed, &frac); } else { - calculate_mbp_width(b->style, LEFT, + calculate_mbp_width(&content->len_ctx, + b->style, LEFT, true, true, true, &fixed, &frac); - calculate_mbp_width(b->style, RIGHT, + calculate_mbp_width(&content->len_ctx, + b->style, RIGHT, true, true, true, &fixed, &frac); } @@ -771,8 +812,10 @@ layout_minmax_line(struct box *first, } else { /* form control with no object */ if (width == AUTO) - width = FIXTOINT(nscss_len2px(INTTOFIX(1), - CSS_UNIT_EM, b->style)); + width = FIXTOINT(nscss_len2px( + &content->len_ctx, + INTTOFIX(1), CSS_UNIT_EM, + b->style)); } if (min < width) @@ -785,7 +828,7 @@ layout_minmax_line(struct box *first, if (first_line) { /* todo: handle percentage values properly */ /* todo: handle text-indent interaction with floats */ - int text_indent = layout_text_indent( + int text_indent = layout_text_indent(&content->len_ctx, first->parent->parent->style, 100); min = (min + text_indent < 0) ? 0 : min + text_indent; max = (max + text_indent < 0) ? 0 : max + text_indent; @@ -815,7 +858,8 @@ layout_minmax_line(struct box *first, static void layout_minmax_inline_container(struct box *inline_container, bool *has_height, - const struct gui_layout_table *font_func) + const struct gui_layout_table *font_func, + const html_content *content) { struct box *child; int line_min = 0, line_max = 0; @@ -833,7 +877,8 @@ layout_minmax_inline_container(struct box *inline_container, for (child = inline_container->children; child; ) { child = layout_minmax_line(child, &line_min, &line_max, - first_line, &line_has_height, font_func); + first_line, &line_has_height, font_func, + content); if (min < line_min) min = line_min; if (max < line_max) @@ -856,11 +901,14 @@ layout_minmax_inline_container(struct box *inline_container, * * \param block box of type BLOCK, INLINE_BLOCK, or TABLE_CELL * \param font_func font functions + * \param content The HTML content being layed out. * \post block->min_width and block->max_width filled in, * 0 <= block->min_width <= block->max_width */ -static void -layout_minmax_block(struct box *block, const struct gui_layout_table *font_func) +static void layout_minmax_block( + struct box *block, + const struct gui_layout_table *font_func, + const html_content *content) { struct box *child; int min = 0, max = 0; @@ -913,7 +961,8 @@ layout_minmax_block(struct box *block, const struct gui_layout_table *font_func) css_fixed size = INTTOFIX(10); css_unit unit = CSS_UNIT_EM; - min = max = FIXTOINT(nscss_len2px(size, unit, block->style)); + min = max = FIXTOINT(nscss_len2px(&content->len_ctx, + size, unit, block->style)); block->flags |= HAS_HEIGHT; } @@ -926,7 +975,8 @@ layout_minmax_block(struct box *block, const struct gui_layout_table *font_func) /* form checkbox or radio button * if width is AUTO, set it to 1em */ - min = max = FIXTOINT(nscss_len2px(size, unit, block->style)); + min = max = FIXTOINT(nscss_len2px(&content->len_ctx, + size, unit, block->style)); block->flags |= HAS_HEIGHT; } @@ -934,7 +984,7 @@ layout_minmax_block(struct box *block, const struct gui_layout_table *font_func) if (block->object) { if (content_get_type(block->object) == CONTENT_HTML) { layout_minmax_block(html_get_box_tree(block->object), - font_func); + font_func, content); min = html_get_box_tree(block->object)->min_width; max = html_get_box_tree(block->object)->max_width; } else { @@ -951,7 +1001,8 @@ layout_minmax_block(struct box *block, const struct gui_layout_table *font_func) for (child = block->children; child; child = child->next) { switch (child->type) { case BOX_BLOCK: - layout_minmax_block(child, font_func); + layout_minmax_block(child, font_func, + content); if (child->flags & HAS_HEIGHT) child_has_height = true; break; @@ -960,7 +1011,8 @@ layout_minmax_block(struct box *block, const struct gui_layout_table *font_func) child->flags |= NEED_MIN; layout_minmax_inline_container(child, - &child_has_height, font_func); + &child_has_height, font_func, + content); if (child_has_height && child == child->parent->children) { @@ -968,7 +1020,8 @@ layout_minmax_block(struct box *block, const struct gui_layout_table *font_func) } break; case BOX_TABLE: - layout_minmax_table(child, font_func); + layout_minmax_table(child, font_func, + content); /* todo: fix for zero height tables */ child_has_height = true; child->flags |= MAKE_HEIGHT; @@ -1006,14 +1059,17 @@ layout_minmax_block(struct box *block, const struct gui_layout_table *font_func) /* fixed width takes priority */ if (block->type != BOX_TABLE_CELL && wtype == CSS_WIDTH_SET && wunit != CSS_UNIT_PCT) { - min = max = FIXTOINT(nscss_len2px(width, wunit, block->style)); + min = max = FIXTOINT(nscss_len2px(&content->len_ctx, + width, wunit, block->style)); if (bs == CSS_BOX_SIZING_BORDER_BOX) { int border_box_fixed = 0; float border_box_frac = 0; - calculate_mbp_width(block->style, LEFT, + calculate_mbp_width(&content->len_ctx, + block->style, LEFT, false, true, true, &border_box_fixed, &border_box_frac); - calculate_mbp_width(block->style, RIGHT, + calculate_mbp_width(&content->len_ctx, + block->style, RIGHT, false, true, true, &border_box_fixed, &border_box_frac); if (min < border_box_fixed) { @@ -1033,14 +1089,18 @@ layout_minmax_block(struct box *block, const struct gui_layout_table *font_func) * and paddings are wrong. */ if (bs == CSS_BOX_SIZING_BORDER_BOX && wtype == CSS_WIDTH_SET) { /* Border and padding included in width, so just get margin */ - calculate_mbp_width(block->style, LEFT, true, false, false, + calculate_mbp_width(&content->len_ctx, + block->style, LEFT, true, false, false, &extra_fixed, &extra_frac); - calculate_mbp_width(block->style, RIGHT, true, false, false, + calculate_mbp_width(&content->len_ctx, + block->style, RIGHT, true, false, false, &extra_fixed, &extra_frac); } else { - calculate_mbp_width(block->style, LEFT, true, true, true, + calculate_mbp_width(&content->len_ctx, + block->style, LEFT, true, true, true, &extra_fixed, &extra_frac); - calculate_mbp_width(block->style, RIGHT, true, true, true, + calculate_mbp_width(&content->len_ctx, + block->style, RIGHT, true, true, true, &extra_fixed, &extra_frac); } if (extra_fixed < 0) @@ -1070,6 +1130,7 @@ layout_minmax_block(struct box *block, const struct gui_layout_table *font_func) * * This turns the specified dimension into a content-box dimension. * + * \param len_ctx Length conversion context * \param box gadget to adjust dimensions of * \param available_width width of containing block * \param setwidth set true if the dimension to be tweaked is a width, @@ -1079,6 +1140,7 @@ layout_minmax_block(struct box *block, const struct gui_layout_table *font_func) * gadget properties. */ static void layout_handle_box_sizing( + const nscss_len_ctx *len_ctx, struct box *box, int available_width, bool setwidth, @@ -1095,9 +1157,11 @@ static void layout_handle_box_sizing( int fixed = 0; float frac = 0; - calculate_mbp_width(box->style, setwidth ? LEFT : TOP, + calculate_mbp_width(len_ctx, box->style, + setwidth ? LEFT : TOP, false, true, true, &fixed, &frac); - calculate_mbp_width(box->style, setwidth ? RIGHT : BOTTOM, + calculate_mbp_width(len_ctx, box->style, + setwidth ? RIGHT : BOTTOM, false, true, true, &fixed, &frac); orig -= frac * available_width + fixed; *dimension = orig > 0 ? orig : 0; @@ -1108,6 +1172,7 @@ static void layout_handle_box_sizing( /** * Calculate width, height, and thickness of margins, paddings, and borders. * + * \param len_ctx Length conversion context * \param available_width width of containing block * \param viewport_height height of viewport in pixels or -ve if unknown * \param box current box @@ -1124,7 +1189,8 @@ static void layout_handle_box_sizing( * \param border filled with border widths, may be NULL */ static void -layout_find_dimensions(int available_width, +layout_find_dimensions(const nscss_len_ctx *len_ctx, + int available_width, int viewport_height, struct box *box, const css_computed_style *style, @@ -1153,15 +1219,15 @@ layout_find_dimensions(int available_width, *width = FPCT_OF_INT_TOINT( value, available_width); } else { - *width = FIXTOINT(nscss_len2px(value, unit, - style)); + *width = FIXTOINT(nscss_len2px(len_ctx, + value, unit, style)); } } else { *width = AUTO; } if (*width != AUTO) { - layout_handle_box_sizing(box, available_width, + layout_handle_box_sizing(len_ctx, box, available_width, true, width); } } @@ -1241,15 +1307,15 @@ layout_find_dimensions(int available_width, *height = AUTO; } } else { - *height = FIXTOINT(nscss_len2px(value, unit, - style)); + *height = FIXTOINT(nscss_len2px(len_ctx, + value, unit, style)); } } else { *height = AUTO; } if (*height != AUTO) { - layout_handle_box_sizing(box, available_width, + layout_handle_box_sizing(len_ctx, box, available_width, false, height); } } @@ -1266,8 +1332,8 @@ layout_find_dimensions(int available_width, *max_width = FPCT_OF_INT_TOINT(value, available_width); } else { - *max_width = FIXTOINT(nscss_len2px(value, unit, - style)); + *max_width = FIXTOINT(nscss_len2px(len_ctx, + value, unit, style)); } } else { /* Inadmissible */ @@ -1275,7 +1341,7 @@ layout_find_dimensions(int available_width, } if (*max_width != -1) { - layout_handle_box_sizing(box, available_width, + layout_handle_box_sizing(len_ctx, box, available_width, true, max_width); } } @@ -1292,8 +1358,8 @@ layout_find_dimensions(int available_width, *min_width = FPCT_OF_INT_TOINT(value, available_width); } else { - *min_width = FIXTOINT(nscss_len2px(value, unit, - style)); + *min_width = FIXTOINT(nscss_len2px(len_ctx, + value, unit, style)); } } else { /* Inadmissible */ @@ -1301,7 +1367,7 @@ layout_find_dimensions(int available_width, } if (*min_width != 0) { - layout_handle_box_sizing(box, available_width, + layout_handle_box_sizing(len_ctx, box, available_width, true, min_width); } } @@ -1318,8 +1384,8 @@ layout_find_dimensions(int available_width, /* TODO: handle percentage */ *max_height = -1; } else { - *max_height = FIXTOINT(nscss_len2px(value, unit, - style)); + *max_height = FIXTOINT(nscss_len2px(len_ctx, + value, unit, style)); } } else { /* Inadmissible */ @@ -1339,8 +1405,8 @@ layout_find_dimensions(int available_width, /* TODO: handle percentage */ *min_height = 0; } else { - *min_height = FIXTOINT(nscss_len2px(value, unit, - style)); + *min_height = FIXTOINT(nscss_len2px(len_ctx, + value, unit, style)); } } else { /* Inadmissible */ @@ -1378,8 +1444,9 @@ layout_find_dimensions(int available_width, margin[i] = FPCT_OF_INT_TOINT(value, available_width); } else { - margin[i] = FIXTOINT(nscss_len2px(value, - unit, style)); + margin[i] = FIXTOINT(nscss_len2px( + len_ctx, + value, unit, style)); } } else { margin[i] = AUTO; @@ -1411,8 +1478,8 @@ layout_find_dimensions(int available_width, padding[i] = FPCT_OF_INT_TOINT(value, available_width); } else { - padding[i] = FIXTOINT(nscss_len2px(value, unit, - style)); + padding[i] = FIXTOINT(nscss_len2px(len_ctx, + value, unit, style)); } } @@ -1459,8 +1526,8 @@ layout_find_dimensions(int available_width, /* spec unclear: following Mozilla */ border[i].width = 0; else - border[i].width = FIXTOINT(nscss_len2px(value, - unit, style)); + border[i].width = FIXTOINT(nscss_len2px(len_ctx, + value, unit, style)); /* Special case for border-collapse: make all borders * on table/table-row-group/table-row zero width. */ @@ -1478,6 +1545,7 @@ layout_find_dimensions(int available_width, /** * Find next block that current margin collapses to. * + * \param len_ctx Length conversion context * \param box box to start tree-order search from (top margin is included) * \param block box responsible for current block fromatting context * \param viewport_height height of viewport in px @@ -1486,7 +1554,8 @@ layout_find_dimensions(int available_width, * \return next box that current margin collapses to, or NULL if none. */ static struct box* -layout_next_margin_block(struct box *box, +layout_next_margin_block(const nscss_len_ctx *len_ctx, + struct box *box, struct box *block, int viewport_height, int *max_pos_margin, @@ -1505,7 +1574,8 @@ layout_next_margin_block(struct box *box, /* Get margins */ if (box->style) { - layout_find_dimensions(box->parent->width, + layout_find_dimensions(len_ctx, + box->parent->width, viewport_height, box, box->style, NULL, NULL, NULL, NULL, @@ -1579,7 +1649,8 @@ layout_next_margin_block(struct box *box, /* Get margins */ if (box->style) { - layout_find_dimensions(box->parent->width, + layout_find_dimensions(len_ctx, + box->parent->width, viewport_height, box, box->style, NULL, NULL, NULL, NULL, @@ -1815,6 +1886,7 @@ layout_solve_width(struct box *box, * Compute dimensions of box, margins, paddings, and borders for a block-level * element. * + * \param len_ctx Length conversion context * \param available_width Max width available in pixels * \param viewport_height Height of viewport in pixels or -ve if unknown * \param lm min left margin required to avoid floats in px. @@ -1827,7 +1899,8 @@ layout_solve_width(struct box *box, * See CSS 2.1 10.3.3, 10.3.4, 10.6.2, and 10.6.3. */ static void -layout_block_find_dimensions(int available_width, +layout_block_find_dimensions(const nscss_len_ctx *len_ctx, + int available_width, int viewport_height, int lm, int rm, @@ -1840,8 +1913,8 @@ layout_block_find_dimensions(int available_width, struct box_border *border = box->border; const css_computed_style *style = box->style; - layout_find_dimensions(available_width, viewport_height, box, style, - &width, &height, &max_width, &min_width, + layout_find_dimensions(len_ctx, available_width, viewport_height, box, + style, &width, &height, &max_width, &min_width, &max_height, &min_height, margin, padding, border); if (box->object && !(box->flags & REPLACE_DIM) && @@ -1994,8 +2067,9 @@ static bool layout_table(struct box *table, int available_width, memcpy(col, table->col, sizeof(col[0]) * columns); /* find margins, paddings, and borders for table and cells */ - layout_find_dimensions(available_width, -1, table, style, 0, 0, 0, 0, - 0, 0, table->margin, table->padding, table->border); + layout_find_dimensions(&content->len_ctx, available_width, -1, table, + style, 0, 0, 0, 0, 0, 0, table->margin, table->padding, + table->border); for (row_group = table->children; row_group; row_group = row_group->next) { for (row = row_group->children; row; row = row->next) { @@ -2004,9 +2078,11 @@ static bool layout_table(struct box *table, int available_width, enum css_overflow_e overflow_y; assert(c->style); - table_used_border_for_cell(c); - layout_find_dimensions(available_width, -1, - c, c->style, 0, 0, 0, 0, 0, 0, + table_used_border_for_cell( + &content->len_ctx, c); + layout_find_dimensions(&content->len_ctx, + available_width, -1, c, + c->style, 0, 0, 0, 0, 0, 0, 0, c->padding, c->border); overflow_x = css_computed_overflow_x(c->style); @@ -2034,8 +2110,10 @@ static bool layout_table(struct box *table, int available_width, css_computed_border_spacing(style, &h, &hu, &v, &vu); - border_spacing_h = FIXTOINT(nscss_len2px(h, hu, style)); - border_spacing_v = FIXTOINT(nscss_len2px(v, vu, style)); + border_spacing_h = FIXTOINT(nscss_len2px(&content->len_ctx, + h, hu, style)); + border_spacing_v = FIXTOINT(nscss_len2px(&content->len_ctx, + v, vu, style)); } /* find specified table width, or available width if auto-width */ @@ -2045,7 +2123,8 @@ static bool layout_table(struct box *table, int available_width, table_width = FPCT_OF_INT_TOINT(value, available_width); } else { table_width = - FIXTOINT(nscss_len2px(value, unit, style)); + FIXTOINT(nscss_len2px(&content->len_ctx, + value, unit, style)); } /* specified width includes border */ @@ -2123,7 +2202,8 @@ static bool layout_table(struct box *table, int available_width, } else { /* This is the minimum height for the table * (see 17.5.3) */ - min_height = FIXTOINT(nscss_len2px(value, unit, style)); + min_height = FIXTOINT(nscss_len2px(&content->len_ctx, + value, unit, style)); } } @@ -2313,8 +2393,9 @@ static bool layout_table(struct box *table, int available_width, htype = css_computed_height(row->style, &value, &unit); if (htype == CSS_HEIGHT_SET && unit != CSS_UNIT_PCT) { - row_height = FIXTOINT(nscss_len2px(value, unit, - row->style)); + row_height = FIXTOINT(nscss_len2px( + &content->len_ctx, + value, unit, row->style)); } for (c = row->children; c; c = c->next) { assert(c->style); @@ -2351,8 +2432,9 @@ static bool layout_table(struct box *table, int available_width, /* some sites use height="1" or similar * to attempt to make cells as small as * possible, so treat it as a minimum */ - int h = FIXTOINT(nscss_len2px(value, - unit, c->style)); + int h = FIXTOINT(nscss_len2px( + &content->len_ctx, + value, unit, c->style)); if (c->height < h) c->height = h; } @@ -2496,12 +2578,16 @@ static bool layout_table(struct box *table, int available_width, /** * Manimpulate box height according to CSS min-height and max-height properties * + * \param len_ctx CSS length conversion context for document. * \param box block to modify with any min-height or max-height * \param container containing block for absolutely positioned elements, or * NULL for non absolutely positioned elements. * \return whether the height has been changed */ -static bool layout_apply_minmax_height(struct box *box, struct box *container) +static bool layout_apply_minmax_height( + const nscss_len_ctx *len_ctx, + struct box *box, + struct box *container) { int h; struct box *containing_block = NULL; @@ -2560,8 +2646,8 @@ static bool layout_apply_minmax_height(struct box *box, struct box *container) } } } else { - h = FIXTOINT(nscss_len2px(value, unit, - box->style)); + h = FIXTOINT(nscss_len2px(len_ctx, + value, unit, box->style)); if (h < box->height) { box->height = h; updated = true; @@ -2590,8 +2676,8 @@ static bool layout_apply_minmax_height(struct box *box, struct box *container) } } } else { - h = FIXTOINT(nscss_len2px(value, unit, - box->style)); + h = FIXTOINT(nscss_len2px(len_ctx, + value, unit, box->style)); if (h > box->height) { box->height = h; updated = true; @@ -2759,6 +2845,7 @@ layout_text_box_split(html_content *content, * Compute dimensions of box, margins, paddings, and borders for a floating * element using shrink-to-fit. Also used for inline-blocks. * + * \param len_ctx CSS length conversion context for document. * \param available_width Max width available in pixels * \param style Box's style * \param box Box for which to find dimensions @@ -2766,9 +2853,11 @@ layout_text_box_split(html_content *content, * height are updated. */ static void -layout_float_find_dimensions(int available_width, - const css_computed_style *style, - struct box *box) +layout_float_find_dimensions( + const nscss_len_ctx *len_ctx, + int available_width, + const css_computed_style *style, + struct box *box) { int width, height, max_width, min_width, max_height, min_height; int *margin = box->margin; @@ -2785,9 +2874,9 @@ layout_float_find_dimensions(int available_width, overflow_y == CSS_OVERFLOW_AUTO) ? SCROLLBAR_WIDTH : 0; - layout_find_dimensions(available_width, -1, box, style, &width, &height, - &max_width, &min_width, &max_height, &min_height, - margin, padding, border); + layout_find_dimensions(len_ctx, available_width, -1, box, style, + &width, &height, &max_width, &min_width, + &max_height, &min_height, margin, padding, border); if (margin[LEFT] == AUTO) margin[LEFT] = 0; @@ -2821,26 +2910,26 @@ layout_float_find_dimensions(int available_width, box->gadget->type == GADGET_FILE) { if (width == AUTO) { size = INTTOFIX(10); - width = FIXTOINT(nscss_len2px(size, unit, - box->style)); + width = FIXTOINT(nscss_len2px(len_ctx, + size, unit, box->style)); } if (box->gadget->type == GADGET_FILE && height == AUTO) { size = FLTTOFIX(1.5); - height = FIXTOINT(nscss_len2px(size, unit, - box->style)); + height = FIXTOINT(nscss_len2px(len_ctx, + size, unit, box->style)); } } if (box->gadget->type == GADGET_TEXTAREA) { if (width == AUTO) { size = INTTOFIX(10); - width = FIXTOINT(nscss_len2px(size, unit, - box->style)); + width = FIXTOINT(nscss_len2px(len_ctx, + size, unit, box->style)); } if (height == AUTO) { size = INTTOFIX(4); - height = FIXTOINT(nscss_len2px(size, unit, - box->style)); + height = FIXTOINT(nscss_len2px(len_ctx, + size, unit, box->style)); } } } else if (width == AUTO) { @@ -2861,10 +2950,10 @@ layout_float_find_dimensions(int available_width, * mbp as was used in layout_minmax_block() */ int fixed = 0; float frac = 0; - calculate_mbp_width(box->style, LEFT, true, true, true, - &fixed, &frac); - calculate_mbp_width(box->style, RIGHT, true, true, true, - &fixed, &frac); + calculate_mbp_width(len_ctx, box->style, LEFT, + true, true, true, &fixed, &frac); + calculate_mbp_width(len_ctx, box->style, RIGHT, + true, true, true, &fixed, &frac); if (fixed < 0) fixed = 0; @@ -2902,7 +2991,7 @@ static bool layout_float(struct box *b, int width, html_content *content) { assert(b->type == BOX_TABLE || b->type == BOX_BLOCK || b->type == BOX_INLINE_BLOCK); - layout_float_find_dimensions(width, b->style, b); + layout_float_find_dimensions(&content->len_ctx, width, b->style, b); if (b->type == BOX_TABLE) { if (!layout_table(b, width, content)) return false; @@ -2974,7 +3063,9 @@ place_float_below(struct box *c, int width, int cx, int y, struct box *cont) /** * Calculate line height from a style. */ -static int line_height(const css_computed_style *style) +static int line_height( + const nscss_len_ctx *len_ctx, + const css_computed_style *style) { enum css_line_height_e lhtype; css_fixed lhvalue = 0; @@ -2992,14 +3083,16 @@ static int line_height(const css_computed_style *style) if (lhtype == CSS_LINE_HEIGHT_NUMBER || lhunit == CSS_UNIT_PCT) { - line_height = nscss_len2px(lhvalue, CSS_UNIT_EM, style); + line_height = nscss_len2px(len_ctx, + lhvalue, CSS_UNIT_EM, style); if (lhtype != CSS_LINE_HEIGHT_NUMBER) line_height = FDIV(line_height, F_100); } else { assert(lhunit != CSS_UNIT_PCT); - line_height = nscss_len2px(lhvalue, lhunit, style); + line_height = nscss_len2px(len_ctx, + lhvalue, lhunit, style); } return FIXTOINT(line_height); @@ -3071,7 +3164,8 @@ layout_line(struct box *first, x1 -= cx; if (indent) - x0 += layout_text_indent(first->parent->parent->style, *width); + x0 += layout_text_indent(&content->len_ctx, + first->parent->parent->style, *width); if (x1 < x0) x1 = x0; @@ -3080,8 +3174,8 @@ layout_line(struct box *first, * this is the line-height if there are text children and also in the * case of an initially empty text input */ if (has_text_children || first->parent->parent->gadget) - used_height = height = - line_height(first->parent->parent->style); + used_height = height = line_height(&content->len_ctx, + first->parent->parent->style); else /* inline containers with no text are usually for layout and * look better with no minimum line-height */ @@ -3120,7 +3214,7 @@ layout_line(struct box *first, continue; assert(b->style != NULL); - font_plot_style_from_css(b->style, &fstyle); + font_plot_style_from_css(&content->len_ctx, b->style, &fstyle); x += space_after; @@ -3144,9 +3238,9 @@ layout_line(struct box *first, if (b->type == BOX_INLINE) { /* calculate borders, margins, and padding */ - layout_find_dimensions(*width, -1, b, b->style, 0, 0, - 0, 0, 0, 0, b->margin, b->padding, - b->border); + layout_find_dimensions(&content->len_ctx, + *width, -1, b, b->style, 0, 0, 0, 0, + 0, 0, b->margin, b->padding, b->border); for (i = 0; i != 4; i++) if (b->margin[i] == AUTO) b->margin[i] = 0; @@ -3179,7 +3273,8 @@ layout_line(struct box *first, if (!b->object && !(b->flags & IFRAME) && !b->gadget && !(b->flags & REPLACE_DIM)) { /* inline non-replaced, 10.3.1 and 10.6.1 */ - b->height = line_height(b->style ? b->style : + b->height = line_height(&content->len_ctx, + b->style ? b->style : b->parent->parent->style); if (height < b->height) height = b->height; @@ -3249,9 +3344,12 @@ layout_line(struct box *first, /* inline replaced, 10.3.2 and 10.6.2 */ assert(b->style); - layout_find_dimensions(*width, -1, b, b->style, - &b->width, &b->height, &max_width, &min_width, - &max_height, &min_height, NULL, NULL, NULL); + layout_find_dimensions(&content->len_ctx, + *width, -1, b, b->style, + &b->width, &b->height, + &max_width, &min_width, + &max_height, &min_height, + NULL, NULL, NULL); if (b->object && !(b->flags & REPLACE_DIM)) { layout_get_object_dimensions(b, &b->width, &b->height, @@ -3269,10 +3367,12 @@ layout_line(struct box *first, } else { /* form control with no object */ if (b->width == AUTO) - b->width = FIXTOINT(nscss_len2px(INTTOFIX(1), + b->width = FIXTOINT(nscss_len2px( + &content->len_ctx, INTTOFIX(1), CSS_UNIT_EM, b->style)); if (b->height == AUTO) - b->height = FIXTOINT(nscss_len2px(INTTOFIX(1), + b->height = FIXTOINT(nscss_len2px( + &content->len_ctx, INTTOFIX(1), CSS_UNIT_EM, b->style)); } @@ -3306,7 +3406,8 @@ layout_line(struct box *first, x1 -= cx; if (indent) - x0 += layout_text_indent(first->parent->parent->style, *width); + x0 += layout_text_indent(&content->len_ctx, + first->parent->parent->style, *width); if (x1 < x0) x1 = x0; @@ -3363,8 +3464,9 @@ layout_line(struct box *first, space_after = 0; else if (b->text || b->type == BOX_INLINE_END) { if (b->space == UNKNOWN_WIDTH) { - font_plot_style_from_css(b->style, - &fstyle); + font_plot_style_from_css( + &content->len_ctx, + b->style, &fstyle); /** \todo handle errors */ font_func->width(&fstyle, " ", 1, &b->space); @@ -3517,7 +3619,8 @@ layout_line(struct box *first, !(split_box->flags & IFRAME) && !split_box->gadget && split_box->text) { - font_plot_style_from_css(split_box->style, &fstyle); + font_plot_style_from_css(&content->len_ctx, + split_box->style, &fstyle); /** \todo handle errors */ font_func->split(&fstyle, split_box->text, @@ -3879,7 +3982,8 @@ layout_block_context(struct box *block, gadget_unit = CSS_UNIT_EM; gadget_size = INTTOFIX(1); if (block->height == AUTO) - block->height = FIXTOINT(nscss_len2px(gadget_size, + block->height = FIXTOINT(nscss_len2px( + &content->len_ctx, gadget_size, gadget_unit, block->style)); } @@ -3943,7 +4047,8 @@ layout_block_context(struct box *block, /* If we don't know which box the current margin collapses * through to, find out. Update the pos/neg margin values. */ if (margin_collapse == NULL) { - margin_collapse = layout_next_margin_block(box, block, + margin_collapse = layout_next_margin_block( + &content->len_ctx, box, block, viewport_height, &max_pos_margin, &max_neg_margin); /* We have a margin that has not yet been applied. */ @@ -3994,7 +4099,8 @@ layout_block_context(struct box *block, box->parent->padding[RIGHT] - x1; } - layout_block_find_dimensions(box->parent->width, + layout_block_find_dimensions(&content->len_ctx, + box->parent->width, viewport_height, lm, rm, box); if (box->type == BOX_BLOCK && !(box->flags & IFRAME)) { layout_block_add_scrollbar(box, RIGHT); @@ -4234,8 +4340,9 @@ layout_block_context(struct box *block, if (box->style && css_computed_position(box->style) != CSS_POSITION_ABSOLUTE && - layout_apply_minmax_height(box, - NULL)) { + layout_apply_minmax_height( + &content->len_ctx, + box, NULL)) { /* Height altered */ /* Set current cy */ cy += box->height - @@ -4291,19 +4398,23 @@ layout_block_context(struct box *block, if (block->style && css_computed_position(block->style) != CSS_POSITION_ABSOLUTE) { /* Block is in normal flow */ - layout_apply_minmax_height(block, NULL); + layout_apply_minmax_height(&content->len_ctx, block, NULL); } if (block->gadget && (block->gadget->type == GADGET_TEXTAREA || block->gadget->type == GADGET_PASSWORD || block->gadget->type == GADGET_TEXTBOX)) { + plot_font_style_t fstyle; int ta_width = block->padding[LEFT] + block->width + block->padding[RIGHT]; int ta_height = block->padding[TOP] + block->height + block->padding[BOTTOM]; + font_plot_style_from_css(&content->len_ctx, + block->style, &fstyle); + fstyle.background = NS_TRANSPARENT; textarea_set_layout(block->gadget->data.text.ta, - ta_width, ta_height, + &fstyle, ta_width, ta_height, block->padding[TOP], block->padding[RIGHT], block->padding[BOTTOM], block->padding[LEFT]); } @@ -4317,7 +4428,8 @@ layout_block_context(struct box *block, */ static void layout_lists(struct box *box, - const struct gui_layout_table *font_func) + const struct gui_layout_table *font_func, + const nscss_len_ctx *len_ctx) { struct box *child; struct box *marker; @@ -4332,12 +4444,13 @@ layout_lists(struct box *box, marker->x = -marker->width; marker->height = content_get_height(marker->object); - marker->y = (line_height(marker->style) - + marker->y = (line_height(len_ctx, + marker->style) - marker->height) / 2; } else if (marker->text) { if (marker->width == UNKNOWN_WIDTH) { - font_plot_style_from_css(marker->style, - &fstyle); + font_plot_style_from_css(len_ctx, + marker->style, &fstyle); font_func->width(&fstyle, marker->text, marker->length, @@ -4346,7 +4459,8 @@ layout_lists(struct box *box, } marker->x = -marker->width; marker->y = 0; - marker->height = line_height(marker->style); + marker->height = line_height(len_ctx, + marker->style); } else { marker->x = 0; marker->y = 0; @@ -4356,7 +4470,7 @@ layout_lists(struct box *box, /* Gap between marker and content */ marker->x -= 4; } - layout_lists(child, font_func); + layout_lists(child, font_func, len_ctx); } } @@ -4365,6 +4479,7 @@ layout_lists(struct box *box, * Compute box offsets for a relatively or absolutely positioned box with * respect to a box. * + * \param len_ctx Length conversion context * \param box box to compute offsets for * \param containing_block box to compute percentages with respect to * \param top updated to top offset, or AUTO @@ -4375,7 +4490,8 @@ layout_lists(struct box *box, * See CSS 2.1 9.3.2. containing_block must have width and height. */ static void -layout_compute_offsets(struct box *box, +layout_compute_offsets(const nscss_len_ctx *len_ctx, + struct box *box, struct box *containing_block, int *top, int *right, @@ -4397,7 +4513,8 @@ layout_compute_offsets(struct box *box, *left = FPCT_OF_INT_TOINT(value, containing_block->width); } else { - *left = FIXTOINT(nscss_len2px(value, unit, box->style)); + *left = FIXTOINT(nscss_len2px(len_ctx, + value, unit, box->style)); } } else { *left = AUTO; @@ -4410,8 +4527,8 @@ layout_compute_offsets(struct box *box, *right = FPCT_OF_INT_TOINT(value, containing_block->width); } else { - *right = FIXTOINT(nscss_len2px(value, unit, - box->style)); + *right = FIXTOINT(nscss_len2px(len_ctx, + value, unit, box->style)); } } else { *right = AUTO; @@ -4424,7 +4541,8 @@ layout_compute_offsets(struct box *box, *top = FPCT_OF_INT_TOINT(value, containing_block->height); } else { - *top = FIXTOINT(nscss_len2px(value, unit, box->style)); + *top = FIXTOINT(nscss_len2px(len_ctx, + value, unit, box->style)); } } else { *top = AUTO; @@ -4437,8 +4555,8 @@ layout_compute_offsets(struct box *box, *bottom = FPCT_OF_INT_TOINT(value, containing_block->height); } else { - *bottom = FIXTOINT(nscss_len2px(value, unit, - box->style)); + *bottom = FIXTOINT(nscss_len2px(len_ctx, + value, unit, box->style)); } } else { *bottom = AUTO; @@ -4494,16 +4612,17 @@ layout_absolute(struct box *box, /** \todo inline containers */ } - layout_compute_offsets(box, containing_block, + layout_compute_offsets(&content->len_ctx, box, containing_block, &top, &right, &bottom, &left); /* Pass containing block into layout_find_dimensions via the float * containing block box member. This is unused for absolutely positioned * boxes because a box can't be floated and absolutely positioned. */ box->float_container = containing_block; - layout_find_dimensions(available_width, -1, box, box->style, - &width, &height, &max_width, &min_width, - 0, 0, margin, padding, border); + layout_find_dimensions(&content->len_ctx, available_width, -1, + box, box->style, &width, &height, + &max_width, &min_width, 0, 0, + margin, padding, border); box->float_container = NULL; /* 10.3.7 */ @@ -4818,7 +4937,7 @@ layout_absolute(struct box *box, /** \todo Inline ancestors */ } box->height = height; - layout_apply_minmax_height(box, containing_block); + layout_apply_minmax_height(&content->len_ctx, box, containing_block); return true; } @@ -4895,11 +5014,16 @@ layout_position_absolute(struct box *box, /** * Compute a box's relative offset as per CSS 2.1 9.4.3 * + * \param len_ctx Length conversion context * \param box Box to compute relative offsets for. * \param x Receives relative offset in x. * \param y Receives relative offset in y. */ -static void layout_compute_relative_offset(struct box *box, int *x, int *y) +static void layout_compute_relative_offset( + const nscss_len_ctx *len_ctx, + struct box *box, + int *x, + int *y) { int left, right, top, bottom; struct box *containing_block; @@ -4916,7 +5040,7 @@ static void layout_compute_relative_offset(struct box *box, int *x, int *y) containing_block = box->parent; } - layout_compute_offsets(box, containing_block, + layout_compute_offsets(len_ctx, box, containing_block, &top, &right, &bottom, &left); if (left == AUTO && right == AUTO) @@ -4964,6 +5088,7 @@ static void layout_compute_relative_offset(struct box *box, int *x, int *y) /** * Adjust positions of relatively positioned boxes. * + * \param len_ctx Length conversion context * \param root box to adjust the position of * \param fp box which forms the block formatting context for children of * "root" which are floats @@ -4975,7 +5100,12 @@ static void layout_compute_relative_offset(struct box *box, int *x, int *y) * box, "fp", for float children of "root" */ static void -layout_position_relative(struct box *root, struct box *fp, int fx, int fy) +layout_position_relative( + const nscss_len_ctx *len_ctx, + struct box *root, + struct box *fp, + int fx, + int fy) { struct box *box; /* for children of "root" */ struct box *fn; /* for block formatting context box for children of @@ -4999,7 +5129,8 @@ layout_position_relative(struct box *root, struct box *fp, int fx, int fy) /* If relatively positioned, get offsets */ if (box->style && css_computed_position(box->style) == CSS_POSITION_RELATIVE) - layout_compute_relative_offset(box, &x, &y); + layout_compute_relative_offset( + len_ctx, box, &x, &y); else x = y = 0; @@ -5035,7 +5166,7 @@ layout_position_relative(struct box *root, struct box *fp, int fx, int fy) } /* recurse first */ - layout_position_relative(box, fn, fnx, fny); + layout_position_relative(len_ctx, box, fn, fnx, fny); /* Ignore things we're not interested in. */ if (!box->style || (box->style && @@ -5064,6 +5195,7 @@ layout_position_relative(struct box *root, struct box *fp, int fx, int fy) /** * Find a box's bounding box relative to itself, i.e. the box's border edge box * + * \param len_ctx Length conversion context * \param box box find bounding box of * \param desc_x0 updated to left of box's bbox * \param desc_y0 updated to top of box's bbox @@ -5071,9 +5203,11 @@ layout_position_relative(struct box *root, struct box *fp, int fx, int fy) * \param desc_y1 updated to bottom of box's bbox */ static void -layout_get_box_bbox(struct box *box, - int *desc_x0, int *desc_y0, - int *desc_x1, int *desc_y1) +layout_get_box_bbox( + const nscss_len_ctx *len_ctx, + struct box *box, + int *desc_x0, int *desc_y0, + int *desc_x1, int *desc_y1) { *desc_x0 = -box->border[LEFT].width; *desc_y0 = -box->border[TOP].width; @@ -5093,7 +5227,8 @@ layout_get_box_bbox(struct box *box, int text_height; css_computed_font_size(box->style, &font_size, &font_unit); - text_height = nscss_len2px(font_size, font_unit, box->style); + text_height = nscss_len2px(len_ctx, font_size, font_unit, + box->style); text_height = FIXTOINT(text_height * 3 / 4); *desc_y0 = (*desc_y0 < -text_height) ? *desc_y0 : -text_height; } @@ -5103,16 +5238,19 @@ layout_get_box_bbox(struct box *box, /** * Apply changes to box descendant_[xy][01] values due to given child. * - * \param box box to update - * \param child a box, which may affect box's descendant bbox - * \param off_x offset to apply to child->x coord to treat as child of box - * \param off_y offset to apply to child->y coord to treat as child of box + * \param len_ctx Length conversion context + * \param box box to update + * \param child a box, which may affect box's descendant bbox + * \param off_x offset to apply to child->x coord to treat as child of box + * \param off_y offset to apply to child->y coord to treat as child of box */ static void -layout_update_descendant_bbox(struct box *box, - struct box *child, - int off_x, - int off_y) +layout_update_descendant_bbox( + const nscss_len_ctx *len_ctx, + struct box *box, + struct box *child, + int off_x, + int off_y) { int child_desc_x0, child_desc_y0, child_desc_x1, child_desc_y1; @@ -5132,7 +5270,8 @@ layout_update_descendant_bbox(struct box *box, } /* Get child's border edge */ - layout_get_box_bbox(child, &child_desc_x0, &child_desc_y0, + layout_get_box_bbox(len_ctx, child, + &child_desc_x0, &child_desc_y0, &child_desc_x1, &child_desc_y1); if (overflow_x == CSS_OVERFLOW_VISIBLE && @@ -5169,9 +5308,12 @@ layout_update_descendant_bbox(struct box *box, * Recursively calculate the descendant_[xy][01] values for a laid-out box tree * and inform iframe browser windows of their size and position. * - * \param box tree of boxes to update + * \param len_ctx Length conversion context + * \param box tree of boxes to update */ -static void layout_calculate_descendant_bboxes(struct box *box) +static void layout_calculate_descendant_bboxes( + const nscss_len_ctx *len_ctx, + struct box *box) { struct box *child; @@ -5180,7 +5322,8 @@ static void layout_calculate_descendant_bboxes(struct box *box) /* assert((box->width >= 0) && (box->height >= 0)); */ /* Initialise box's descendant box to border edge box */ - layout_get_box_bbox(box, &box->descendant_x0, &box->descendant_y0, + layout_get_box_bbox(len_ctx, box, + &box->descendant_x0, &box->descendant_y0, &box->descendant_x1, &box->descendant_y1); /* Extend it to contain HTML contents if box is replaced */ @@ -5213,7 +5356,7 @@ static void layout_calculate_descendant_bboxes(struct box *box) child->type == BOX_FLOAT_RIGHT) continue; - layout_update_descendant_bbox(box, child, + layout_update_descendant_bbox(len_ctx, box, child, box->x, box->y); if (child == box->inline_end) @@ -5231,7 +5374,7 @@ static void layout_calculate_descendant_bboxes(struct box *box) child->type == BOX_FLOAT_RIGHT) continue; - layout_calculate_descendant_bboxes(child); + layout_calculate_descendant_bboxes(len_ctx, child); if (box->style && css_computed_overflow_x(box->style) == CSS_OVERFLOW_HIDDEN && @@ -5239,23 +5382,23 @@ static void layout_calculate_descendant_bboxes(struct box *box) CSS_OVERFLOW_HIDDEN) continue; - layout_update_descendant_bbox(box, child, 0, 0); + layout_update_descendant_bbox(len_ctx, box, child, 0, 0); } for (child = box->float_children; child; child = child->next_float) { assert(child->type == BOX_FLOAT_LEFT || child->type == BOX_FLOAT_RIGHT); - layout_calculate_descendant_bboxes(child); + layout_calculate_descendant_bboxes(len_ctx, child); - layout_update_descendant_bbox(box, child, 0, 0); + layout_update_descendant_bbox(len_ctx, box, child, 0, 0); } if (box->list_marker) { child = box->list_marker; - layout_calculate_descendant_bboxes(child); + layout_calculate_descendant_bboxes(len_ctx, child); - layout_update_descendant_bbox(box, child, 0, 0); + layout_update_descendant_bbox(len_ctx, box, child, 0, 0); } } @@ -5267,9 +5410,10 @@ bool layout_document(html_content *content, int width, int height) struct box *doc = content->layout; const struct gui_layout_table *font_func = content->font_func; - layout_minmax_block(doc, font_func); + layout_minmax_block(doc, font_func, content); - layout_block_find_dimensions(width, height, 0, 0, doc); + layout_block_find_dimensions(&content->len_ctx, + width, height, 0, 0, doc); doc->x = doc->margin[LEFT] + doc->border[LEFT].width; doc->y = doc->margin[TOP] + doc->border[TOP].width; width -= doc->margin[LEFT] + doc->border[LEFT].width + @@ -5300,11 +5444,11 @@ bool layout_document(html_content *content, int width, int height) doc->children->margin[BOTTOM]); } - layout_lists(doc, font_func); + layout_lists(doc, font_func, &content->len_ctx); layout_position_absolute(doc, doc, 0, 0, content); - layout_position_relative(doc, doc, 0, 0); + layout_position_relative(&content->len_ctx, doc, doc, 0, 0); - layout_calculate_descendant_bboxes(doc); + layout_calculate_descendant_bboxes(&content->len_ctx, doc); return ret; } diff --git a/render/search.c b/render/search.c index 8f21d8758..ca9520165 100644 --- a/render/search.c +++ b/render/search.c @@ -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); diff --git a/render/table.c b/render/table.c index c41b9130e..08a2e805c 100644 --- a/render/table.c +++ b/render/table.c @@ -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; } diff --git a/render/table.h b/render/table.h index ecd3043b5..2eeffe699 100644 --- a/render/table.h +++ b/render/table.h @@ -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 diff --git a/render/textplain.c b/render/textplain.c index ab2d55955..0036eb5c0 100644 --- a/render/textplain.c +++ b/render/textplain.c @@ -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); } -- cgit v1.2.3 From 128753cdcf0719b1afc919cb841fbc22bb9715aa Mon Sep 17 00:00:00 2001 From: Chris Young Date: Sun, 7 Jan 2018 15:16:44 +0000 Subject: Update certificate bundle --- !NetSurf/Resources/ca-bundle | 1093 ++++++++++++++++-------------------------- 1 file changed, 423 insertions(+), 670 deletions(-) diff --git a/!NetSurf/Resources/ca-bundle b/!NetSurf/Resources/ca-bundle index 76adf8346..39ba33683 100644 --- a/!NetSurf/Resources/ca-bundle +++ b/!NetSurf/Resources/ca-bundle @@ -1,20 +1,20 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Wed Jan 20 04:12:04 2016 +## Certificate data from Mozilla as of: Wed Sep 20 03:12:05 2017 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates ## file (certdata.txt). This file can be found in the mozilla source tree: -## http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt +## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt ## ## It contains the certificates in PEM format and therefore ## can be directly used with curl / libcurl / php_curl, or with ## an Apache+mod_ssl webserver for SSL client authentication. ## Just configure this file as the SSLCACertificateFile. ## -## Conversion done with mk-ca-bundle.pl version 1.25. -## SHA1: 0ab47e2f41518f8d223eab517cb799e5b071231e +## Conversion done with mk-ca-bundle.pl version 1.27. +## SHA256: 2b2dbe5244e0047e088c597998883a913f6c5fffd1cb5c0fe5a368c8466cb2ec ## @@ -130,30 +130,6 @@ Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- -AddTrust Low-Value Services Root -================================ ------BEGIN CERTIFICATE----- -MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU -cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw -CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO -ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6 -54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr -oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1 -Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui -GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w -HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD -AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT -RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw -HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt -ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph -iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY -eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr -mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj -ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= ------END CERTIFICATE----- - AddTrust External Root ====================== -----BEGIN CERTIFICATE----- @@ -178,54 +154,6 @@ e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= -----END CERTIFICATE----- -AddTrust Public Services Root -============================= ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU -cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ -BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l -dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu -nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i -d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG -Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw -HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G -A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux -FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G -A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4 -JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL -+YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao -GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9 -Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H -EufOX1362KqxMy3ZdvJOOjMMK7MtkAY= ------END CERTIFICATE----- - -AddTrust Qualified Certificates Root -==================================== ------BEGIN CERTIFICATE----- -MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU -cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx -CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ -IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx -64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3 -KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o -L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR -wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU -MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE -BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y -azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD -ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG -GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X -dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze -RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB -iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE= ------END CERTIFICATE----- - Entrust Root Certification Authority ==================================== -----BEGIN CERTIFICATE----- @@ -252,27 +180,6 @@ W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- -RSA Security 2048 v3 -==================== ------BEGIN CERTIFICATE----- -MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK -ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy -MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb -BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7 -Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb -WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH -KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP -+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/ -MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E -FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY -v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj -0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj -VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395 -nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA -pKnXwiJPZ9d37CAFYd4= ------END CERTIFICATE----- - GeoTrust Global CA ================== -----BEGIN CERTIFICATE----- @@ -294,27 +201,6 @@ XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm Mw== -----END CERTIFICATE----- -GeoTrust Global CA 2 -==================== ------BEGIN CERTIFICATE----- -MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN -R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw -MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j -LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/ -NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k -LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA -Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b -HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH -K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7 -srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh -ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL -OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC -x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF -H4z1Ir+rzoPz4iIprn2DQKi6bA== ------END CERTIFICATE----- - GeoTrust Universal CA ===================== -----BEGIN CERTIFICATE----- @@ -440,56 +326,6 @@ Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z 12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== -----END CERTIFICATE----- -Comodo Secure Services root -=========================== ------BEGIN CERTIFICATE----- -MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg -TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw -MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu -Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi -BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP -9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc -rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC -oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V -p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E -FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w -gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj -YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm -aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm -4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj -Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL -DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw -pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H -RR3B7Hzs/Sk= ------END CERTIFICATE----- - -Comodo Trusted Services root -============================ ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg -TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw -MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h -bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw -IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7 -3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y -/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6 -juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS -ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud -DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp -ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl -cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw -uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 -pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA -BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l -R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O -9y5Xt5hwXsjEeLBi ------END CERTIFICATE----- - QuoVadis Root CA ================ -----BEGIN CERTIFICATE----- @@ -629,54 +465,6 @@ EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH llpwrN9M -----END CERTIFICATE----- -Staat der Nederlanden Root CA -============================= ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE -ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g -Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w -HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh -bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt -vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P -jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca -C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth -vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6 -22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV -HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v -dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN -BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR -EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw -MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y -nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR -iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== ------END CERTIFICATE----- - -UTN USERFirst Hardware Root CA -============================== ------BEGIN CERTIFICATE----- -MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd -BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx -OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0 -eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz -ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI -wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd -tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8 -i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf -Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw -gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF -lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF -UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF -BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM -//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW -XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2 -lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn -iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67 -nfhmqA== ------END CERTIFICATE----- - Camerfirma Chambers of Commerce Root ==================================== -----BEGIN CERTIFICATE----- @@ -731,41 +519,6 @@ IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== -----END CERTIFICATE----- -NetLock Notary (Class A) Root -============================= ------BEGIN CERTIFICATE----- -MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI -EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 -dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j -ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX -DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH -EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD -VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz -cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM -D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ -z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC -/tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7 -tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6 -4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG -A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC -Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv -bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu -IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn -LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0 -ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz -IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh -IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu -b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh -bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg -Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp -bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5 -ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP -ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB -CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr -KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM -8CgHrTwXZoi1/baI ------END CERTIFICATE----- - XRamp Global CA Root ==================== -----BEGIN CERTIFICATE----- @@ -909,38 +662,6 @@ CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy +fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS -----END CERTIFICATE----- -Swisscom Root CA 1 -================== ------BEGIN CERTIFICATE----- -MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG -EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy -dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4 -MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln -aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC -IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM -MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF -NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe -AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC -b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn -7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN -cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp -WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5 -haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY -MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw -HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j -BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9 -MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn -jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ -MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H -VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl -vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl -OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3 -1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq -nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy -x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW -NY6E0F/6MBr1mmz0DlP5OlvRHA== ------END CERTIFICATE----- - DigiCert Assured ID Root CA =========================== -----BEGIN CERTIFICATE----- @@ -1298,33 +1019,6 @@ wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey -----END CERTIFICATE----- -WellsSecure Public Root Certificate Authority -============================================= ------BEGIN CERTIFICATE----- -MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM -F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw -NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN -MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl -bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD -VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1 -iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13 -i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8 -bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB -K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB -AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu -cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm -lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB -i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww -GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg -Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI -K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0 -bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj -qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es -E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ -tylv2G0xffX8oRAHh84vWdw+WNs= ------END CERTIFICATE----- - COMODO ECC Certification Authority ================================== -----BEGIN CERTIFICATE----- @@ -1342,30 +1036,6 @@ FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= -----END CERTIFICATE----- -IGC/A -===== ------BEGIN CERTIFICATE----- -MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD -VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE -Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy -MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI -EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT -STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2 -TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW -So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy -HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd -frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ -tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB -egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC -iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK -q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q -MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg -Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI -lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF -0mBWWg== ------END CERTIFICATE----- - Security Communication EV RootCA1 ================================= -----BEGIN CERTIFICATE----- @@ -1410,46 +1080,6 @@ hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= -----END CERTIFICATE----- -Microsec e-Szigno Root CA -========================= ------BEGIN CERTIFICATE----- -MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE -BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL -EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0 -MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz -dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT -GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG -d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N -oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc -QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ -PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb -MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG -IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD -VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3 -LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A -dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn -AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA -4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg -AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA -egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6 -Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO -PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv -c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h -cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw -IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT -WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV -MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER -MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp -Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal -HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT -nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE -aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a -86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK -yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB -S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= ------END CERTIFICATE----- - Certigna ======== -----BEGIN CERTIFICATE----- @@ -1575,58 +1205,6 @@ LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= -----END CERTIFICATE----- -Buypass Class 2 CA 1 -==================== ------BEGIN CERTIFICATE----- -MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2 -MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh -c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M -cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83 -0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4 -0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R -uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P -AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV -1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt -7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2 -fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w -wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho ------END CERTIFICATE----- - -EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 -========================================================================== ------BEGIN CERTIFICATE----- -MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNVBAMML0VCRyBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMTcwNQYDVQQKDC5FQkcg -QmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXptZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAe -Fw0wNjA4MTcwMDIxMDlaFw0xNjA4MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25p -ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2lt -IFRla25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h4fuXd7hxlugTlkaDT7by -X3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAktiHq6yOU/im/+4mRDGSaBUorzAzu8T2b -gmmkTPiab+ci2hC6X5L8GCcKqKpE+i4stPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfr -eYteIAbTdgtsApWjluTLdlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZ -TqNGFav4c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8UmTDGy -Y5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z+kI2sSXFCjEmN1Zn -uqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0OLna9XvNRiYuoP1Vzv9s6xiQFlpJI -qkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMWOeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vm -ExH8nYQKE3vwO9D8owrXieqWfo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0 -Nokb+Clsi7n2l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB -/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgwFoAU587GT/wW -Z5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+8ygjdsZs93/mQJ7ANtyVDR2t -FcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgm -zJNSroIBk5DKd8pNSe/iWtkqvTDOTLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64k -XPBfrAowzIpAoHMEwfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqT -bCmYIai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJnxk1Gj7sU -RT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4QDgZxGhBM/nV+/x5XOULK -1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9qKd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt -2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11thie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQ -Y9iJSrSq3RZj9W6+YKH47ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9 -AahH3eU7QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT ------END CERTIFICATE----- - certSIGN ROOT CA ================ -----BEGIN CERTIFICATE----- @@ -1647,49 +1225,6 @@ vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD -----END CERTIFICATE----- -CNNIC ROOT -========== ------BEGIN CERTIFICATE----- -MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE -ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw -OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD -o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz -VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT -VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or -czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK -y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC -wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S -lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5 -Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM -O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8 -BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2 -G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m -mxE= ------END CERTIFICATE----- - -ApplicationCA - Japanese Government -=================================== ------BEGIN CERTIFICATE----- -MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT -SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw -MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl -cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4 -fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN -wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE -jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu -nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU -WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV -BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD -vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs -o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g -/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD -io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW -dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL -rosot4LKGAfmt1t06SAZf7IbiVQ= ------END CERTIFICATE----- - GeoTrust Primary Certification Authority - G3 ============================================= -----BEGIN CERTIFICATE----- @@ -1821,7 +1356,7 @@ AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== -----END CERTIFICATE----- NetLock Arany (Class Gold) Főtanúsítvány -============================================ +======================================== -----BEGIN CERTIFICATE----- MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 @@ -1876,58 +1411,6 @@ IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm 66+KAQ== -----END CERTIFICATE----- -CA Disig -======== ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK -QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw -MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz -bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm -GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD -Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo -hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt -ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w -gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P -AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz -aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff -ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa -BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t -WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3 -mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ -CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K -ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA -4Z7CRneC9VkGjCFMhwnN5ag= ------END CERTIFICATE----- - -Juur-SK -======= ------BEGIN CERTIFICATE----- -MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA -c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw -DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG -SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy -aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf -TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC -+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw -UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa -Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF -MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD -HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh -AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA -cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr -AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw -cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE -FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G -A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo -ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL -abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678 -IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh -Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2 -yyqcjg== ------END CERTIFICATE----- - Hongkong Post Root CA 1 ======================= -----BEGIN CERTIFICATE----- @@ -2361,7 +1844,7 @@ Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -----END CERTIFICATE----- Certinomis - Autorité Racine -============================= +============================ -----BEGIN CERTIFICATE----- MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg @@ -2391,41 +1874,6 @@ wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/ vgt2Fl43N+bYdJeimUV5 -----END CERTIFICATE----- -Root CA Generalitat Valenciana -============================== ------BEGIN CERTIFICATE----- -MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE -ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290 -IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3 -WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE -CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2 -F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B -ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ -D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte -JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB -AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n -dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB -ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl -AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA -YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy -AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA -aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt -AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA -YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu -AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA -OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0 -dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV -BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G -A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S -b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh -TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz -Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63 -NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH -iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt -+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= ------END CERTIFICATE----- - TWCA Root Certification Authority ================================= -----BEGIN CERTIFICATE----- @@ -2871,93 +2319,6 @@ poLWccret9W6aAjtmcz9opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3Y eMLEYC/HYvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km -----END CERTIFICATE----- -China Internet Network Information Center EV Certificates Root -============================================================== ------BEGIN CERTIFICATE----- -MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCQ04xMjAwBgNV -BAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyMUcwRQYDVQQDDD5D -aGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMg -Um9vdDAeFw0xMDA4MzEwNzExMjVaFw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAG -A1UECgwpQ2hpbmEgSW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMM -PkNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRpZmljYXRl -cyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z7r07eKpkQ0H1UN+U8i6y -jUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV -98YPjUesWgbdYavi7NifFy2cyjw1l1VxzUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2H -klY0bBoQCxfVWhyXWIQ8hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23 -KzhmBsUs4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54ugQEC -7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oYNJKiyoOCWTAPBgNV -HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfHJLOcfA22KlT5uqGDSSosqD -glkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd5 -0XPFtQO3WKwMVC/GVhMPMdoG52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM -7+czV0I664zBechNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws -ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrIzo9uoV1/A3U0 -5K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATywy39FCqQmbkHzJ8= ------END CERTIFICATE----- - -Swisscom Root CA 2 -================== ------BEGIN CERTIFICATE----- -MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQG -EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy -dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2 -MjUwNzM4MTRaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln -aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIIC -IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvErjw0DzpPM -LgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r0rk0X2s682Q2zsKwzxNo -ysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJ -wDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVPACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpH -Wrumnf2U5NGKpV+GY3aFy6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1a -SgJA/MTAtukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL6yxS -NLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0uPoTXGiTOmekl9Ab -mbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrALacywlKinh/LTSlDcX3KwFnUey7QY -Ypqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velhk6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3 -qPyZ7iVNTA6z00yPhOgpD/0QVAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw -HQYDVR0hBBYwFDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O -BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqhb97iEoHF8Twu -MA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4RfbgZPnm3qKhyN2abGu2sEzsO -v2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ -82YqZh6NM4OKb3xuqFp1mrjX2lhIREeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLz -o9v/tdhZsnPdTSpxsrpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcs -a0vvaGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciATwoCqISxx -OQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99nBjx8Oto0QuFmtEYE3saW -mA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5Wt6NlUe07qxS/TFED6F+KBZvuim6c779o -+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TC -rvJcwhbtkj6EPnNgiLx29CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX -5OfNeOI5wSsSnqaeG8XmDtkx2Q== ------END CERTIFICATE----- - -Swisscom Root EV CA 2 -===================== ------BEGIN CERTIFICATE----- -MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAwZzELMAkGA1UE -BhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdpdGFsIENlcnRpZmljYXRlIFNl -cnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcN -MzEwNjI1MDg0NTA4WjBnMQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsT -HERpZ2l0YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYg -Q0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7BxUglgRCgz -o3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD1ycfMQ4jFrclyxy0uYAy -Xhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPHoCE2G3pXKSinLr9xJZDzRINpUKTk4Rti -GZQJo/PDvO/0vezbE53PnUgJUmfANykRHvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8Li -qG12W0OfvrSdsyaGOx9/5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaH -Za0zKcQvidm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHLOdAG -alNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaCNYGu+HuB5ur+rPQa -m3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f46Fq9mDU5zXNysRojddxyNMkM3Ox -bPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCBUWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDi -xzgHcgplwLa7JSnaFp6LNYth7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/ -BAQDAgGGMB0GA1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED -MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWBbj2ITY1x0kbB -bkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6xXCX5145v9Ydkn+0UjrgEjihL -j6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98TPLr+flaYC/NUn81ETm484T4VvwYmneTwkLbU -wp4wLh/vx3rEUMfqe9pQy3omywC0Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7 -XwgiG/W9mR4U9s70WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH -59yLGn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm7JFe3VE/ -23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4Snr8PyQUQ3nqjsTzyP6Wq -J3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VNvBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyA -HmBR3NdUIR7KYndP+tiPsys6DXhyyWhBWkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/gi -uMod89a2GQ+fYWVq6nTIfI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuW -l8PVP3wbI+2ksx0WckNLIOFZfsLorSa/ovc= ------END CERTIFICATE----- - CA Disig Root R1 ================ -----BEGIN CERTIFICATE----- @@ -3756,7 +3117,7 @@ ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su -----END CERTIFICATE----- TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 -========================================================= +==================================================== -----BEGIN CERTIFICATE----- MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN BgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp @@ -3779,30 +3140,6 @@ lpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8 B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU= -----END CERTIFICATE----- -TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6 -========================================================= ------BEGIN CERTIFICATE----- -MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQGEwJUUjEPMA0G -A1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls -acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5 -MDQxMFoXDTIzMTIxNjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBL -BgNVBAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSf -aSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2VydGlm -aWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCdsGjW6L0UlqMACprx9MfMkU1xeHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a -2uqsxgbPJQ1BgfbBOCK9+bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EED -wnS3/faAz1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0pu5Fb -HH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6plVxiSvgNZ1GpryHV -+DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMBAAGjQjBAMB0GA1UdDgQWBBTdVRcT -9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG -9w0BAQsFAAOCAQEAb1gNl0OqFlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3R -fdCaqaXKGDsCQC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy -o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKIDgI6tflEATseW -hvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm9ocJV612ph1jmv3XZch4gyt1 -O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsGtAuYSyher4hYyw== ------END CERTIFICATE----- - Certinomis - Root CA ==================== -----BEGIN CERTIFICATE----- @@ -3891,3 +3228,419 @@ MluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0 Daupn75OcsqF1NnstTJFGG+rrQIwfcf3aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYu a/GRspBl9JrmkO5K -----END CERTIFICATE----- + +SZAFIR ROOT CA2 +=============== +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG +A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV +BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ +BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD +VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q +qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK +DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE +2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ +ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi +ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC +AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5 +O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67 +oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul +4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6 ++/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +Certum Trusted Network CA 2 +=========================== +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE +BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1 +bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y +ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ +TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB +IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9 +7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o +CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b +Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p +uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130 +GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ +9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB +Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye +hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM +BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI +hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW +Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA +L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo +clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM +pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb +w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo +J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm +ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX +is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7 +zAYspsbiDrW5viSP +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2015 +======================================================= +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT +BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0 +aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx +MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg +QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV +BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw +MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv +bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh +iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+ +6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd +FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr +i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F +GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2 +fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu +iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI +hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+ +D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM +d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y +d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn +82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb +davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F +Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt +J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa +JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q +p/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions ECC RootCA 2015 +=========================================================== +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0 +aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u +cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw +MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj +IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD +VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290 +Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP +dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK +Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA +GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn +dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +Certplus Root CA G1 +=================== +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUAMD4xCzAJBgNV +BAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTAe +Fw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhD +ZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHN +r49aiZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt6kuJPKNx +Qv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP0FG7Yn2ksYyy/yARujVj +BYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTv +LRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDEEW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2 +z4QTd28n6v+WZxcIbekN1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc +4nBvCGrch2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCTmehd +4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV4EJQeIQEQWGw9CEj +jy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPOWftwenMGE9nTdDckQQoRb5fc5+R+ +ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0G +A1UdDgQWBBSowcCbkahDFXxdBie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHY +lwuBsTANBgkqhkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh +66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7/SMNkPX0XtPG +YX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BSS7CTKtQ+FjPlnsZlFT5kOwQ/ +2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F +6ALEUz65noe8zDUa3qHpimOHZR4RKttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilX +CNQ314cnrUlZp5GrRHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWe +tUNy6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEVV/xuZDDC +VRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5g4VCXA9DO2pJNdWY9BW/ ++mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl++O/QmueD6i9a5jc2NvLi6Td11n0bt3+ +qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo= +-----END CERTIFICATE----- + +Certplus Root CA G2 +=================== +-----BEGIN CERTIFICATE----- +MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4xCzAJBgNVBAYT +AkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjAeFw0x +NDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0 +cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IA +BM0PW1aC3/BFGtat93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uN +Am8xIk0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMB8GA1Ud +IwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqGSM49BAMDA2gAMGUCMHD+sAvZ94OX7PNV +HdTcswYO/jOYnYs5kGuUIe22113WTNchp+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjl +vPl5adytRSv3tjFzzAalU5ORGpOucGpnutee5WEaXw== +-----END CERTIFICATE----- + +OpenTrust Root CA G1 +==================== +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcx +MB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM +CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7fa +Yp6bwiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX/uMftk87 +ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR077F9jAHiOH3BX2pfJLKO +YheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGPuY4zbGneWK2gDqdkVBFpRGZPTBKnjix9 +xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLxp2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO +9z0M+Yo0FMT7MzUj8czxKselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq +3ywgsNw2TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+WG+Oi +n6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPwvFEVVJSmdz7QdFG9 +URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYYEQRVzXR7z2FwefR7LFxckvzluFqr +TJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUl0YhVyE12jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/Px +N3DlCPaTKbYwDQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E +PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kfgLMtMrpkZ2Cv +uVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbSFXJfLkur1J1juONI5f6ELlgK +n0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLh +X4SPgPL0DTatdrOjteFkdjpY3H1PXlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80 +nR14SohWZ25g/4/Ii+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcm +GS3tTAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L9109S5zvE/ +bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/KyPu1svf0OnWZzsD2097+o +4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJAwSQiumPv+i2tCqjI40cHLI5kqiPAlxA +OXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj1oxx +-----END CERTIFICATE----- + +OpenTrust Root CA G2 +==================== +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUAMEAxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcy +MB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM +CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+ +Ntmh/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78eCbY2albz +4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/61UWY0jUJ9gNDlP7ZvyCV +eYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fEFY8ElggGQgT4hNYdvJGmQr5J1WqIP7wt +UdGejeBSzFfdNTVY27SPJIjki9/ca1TSgSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz +3GIZ38i1MH/1PCZ1Eb3XG7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj +3CzMpSZyYhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaHvGOz +9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4t/bQWVyJ98LVtZR0 +0dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/gh7PU3+06yzbXfZqfUAkBXKJOAGT +y3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUajn6QiL35okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59 +M4PLuG53hq8wDQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz +Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0nXGEL8pZ0keI +mUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qTRmTFAHneIWv2V6CG1wZy7HBG +S4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpTwm+bREx50B1ws9efAvSyB7DH5fitIw6mVskp +EndI2S9G/Tvw/HRwkqWOOAgfZDC2t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ +6e18CL13zSdkzJTaTkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97kr +gCf2o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU3jg9CcCo +SmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eAiN1nE28daCSLT7d0geX0 +YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14fWKGVyasvc0rQLW6aWQ9VGHgtPFGml4vm +u7JwqkwR3v98KzfUetF3NI/n+UL3PIEMS1IK +-----END CERTIFICATE----- + +OpenTrust Root CA G3 +==================== +-----BEGIN CERTIFICATE----- +MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEczMB4X +DTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9w +ZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAARK7liuTcpm3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5B +ta1doYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAf +BgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAKBggqhkjOPQQDAwNpADBmAjEAj6jcnboM +BBf6Fek9LykBl7+BFjNAk2z8+e2AcG+qj9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta +3U1fJAuwACEl74+nBCZx4nxp5V2a+EEfOzmTk51V6s2N8fvB +-----END CERTIFICATE----- + +ISRG Root X1 +============ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE +BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD +EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG +EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT +DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r +Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1 +3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K +b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN +Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ +4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf +1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu +hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH +usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r +OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G +A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY +9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV +0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt +hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw +TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx +e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA +JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD +YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n +JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ +m+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +AC RAIZ FNMT-RCM +================ +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT +AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw +MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD +TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf +qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr +btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL +j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou +08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw +WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT +tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ +47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC +ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa +i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o +dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s +D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ +j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT +Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW ++YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7 +Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d +8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm +5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG +rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +Amazon Root CA 1 +================ +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1 +MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH +FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ +gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t +dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce +VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3 +DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM +CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy +8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa +2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2 +xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +Amazon Root CA 2 +================ +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1 +MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4 +kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp +N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9 +AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd +fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx +kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS +btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0 +Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN +c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+ +3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw +DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA +A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE +YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW +xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ +gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW +aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV +Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3 +KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi +JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw= +-----END CERTIFICATE----- + +Amazon Root CA 3 +================ +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB +f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr +Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43 +rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc +eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +Amazon Root CA 4 +================ +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN +/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri +83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA +MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1 +AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +LuxTrust Global Root 2 +====================== +-----BEGIN CERTIFICATE----- +MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQELBQAwRjELMAkG +A1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNVBAMMFkx1eFRydXN0IEdsb2Jh +bCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUwMzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEW +MBQGA1UECgwNTHV4VHJ1c3QgUy5BLjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wm +Kb3FibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTemhfY7RBi2 +xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1EMShduxq3sVs35a0VkBC +wGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsnXpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm +1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkm +FRseTJIpgp7VkoGSQXAZ96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niF +wpN6cj5mj5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4gDEa/ +a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+8kPREd8vZS9kzl8U +ubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2jX5t/Lax5Gw5CMZdjpPuKadUiDTSQ +MC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmHhFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB +/zBCBgNVHSAEOzA5MDcGByuBKwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5 +Lmx1eHRydXN0Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT ++Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQELBQADggIBAGoZ +FO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9BzZAcg4atmpZ1gDlaCDdLnIN +H2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTOjFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW +7MM3LGVYvlcAGvI1+ut7MV3CwRI9loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIu +ZY+kt9J/Z93I055cqqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWA +VWe+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/JEAdemrR +TxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKrezrnK+T+Tb/mjuuqlPpmt +/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQfLSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc +7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31I +iyBMz2TWuJdGsE7RKlY6oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr +-----END CERTIFICATE----- + +TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 +============================================= +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT +D0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr +IEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g +TWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp +ZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD +VQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt +c2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth +bXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11 +IFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8 +6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc +wv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0 +3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9 +WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU +ZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ +KoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc +lNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R +e37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j +q5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- -- cgit v1.2.3 From c03405b3b3b28942d50f672e897be5cfc0f6c540 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Fri, 12 Jan 2018 17:55:01 +0000 Subject: Layout: Reduce code duplication in handling of box side properties. --- render/layout.c | 148 +++++++++++++++++++++----------------------------------- 1 file changed, 56 insertions(+), 92 deletions(-) diff --git a/render/layout.c b/render/layout.c index 15eb1e846..f6b774a6e 100644 --- a/render/layout.c +++ b/render/layout.c @@ -68,6 +68,55 @@ /* Fixed point percentage (a) of an integer (b), to an integer */ #define FPCT_OF_INT_TOINT(a, b) (FIXTOINT(FDIV((a * b), F_100))) +typedef uint8_t (*css_len_func)( + const css_computed_style *style, + css_fixed *length, css_unit *unit); +typedef uint8_t (*css_border_style_func)( + const css_computed_style *style); +typedef uint8_t (*css_border_color_func)( + const css_computed_style *style, + css_color *color); + +/** Array of per-side access functions for computed style margins. */ +static const css_len_func margin_funcs[4] = { + [TOP] = css_computed_margin_top, + [RIGHT] = css_computed_margin_right, + [BOTTOM] = css_computed_margin_bottom, + [LEFT] = css_computed_margin_left, +}; + +/** Array of per-side access functions for computed style paddings. */ +static const css_len_func padding_funcs[4] = { + [TOP] = css_computed_padding_top, + [RIGHT] = css_computed_padding_right, + [BOTTOM] = css_computed_padding_bottom, + [LEFT] = css_computed_padding_left, +}; + +/** Array of per-side access functions for computed style border_widths. */ +static const css_len_func border_width_funcs[4] = { + [TOP] = css_computed_border_top_width, + [RIGHT] = css_computed_border_right_width, + [BOTTOM] = css_computed_border_bottom_width, + [LEFT] = css_computed_border_left_width, +}; + +/** Array of per-side access functions for computed style border styles. */ +static const css_border_style_func border_style_funcs[4] = { + [TOP] = css_computed_border_top_style, + [RIGHT] = css_computed_border_right_style, + [BOTTOM] = css_computed_border_bottom_style, + [LEFT] = css_computed_border_left_style, +}; + +/** Array of per-side access functions for computed style border colors. */ +static const css_border_color_func border_color_funcs[4] = { + [TOP] = css_computed_border_top_color, + [RIGHT] = css_computed_border_right_color, + [BOTTOM] = css_computed_border_bottom_color, + [LEFT] = css_computed_border_left_color, +}; + /* forward declaration to break cycles */ static bool layout_block_context( struct box *block, @@ -224,35 +273,6 @@ calculate_mbp_width(const nscss_len_ctx *len_ctx, int *fixed, float *frac) { - typedef uint8_t (*len_func)(const css_computed_style *style, - css_fixed *length, css_unit *unit); - - static const len_func margin_funcs[4] = { - css_computed_margin_top, - css_computed_margin_right, - css_computed_margin_bottom, - css_computed_margin_left - }; - static const len_func padding_funcs[4] = { - css_computed_padding_top, - css_computed_padding_right, - css_computed_padding_bottom, - css_computed_padding_left - }; - static const struct { - len_func width; - uint8_t (*style)(const css_computed_style *style); - } border_funcs[4] = { - { css_computed_border_top_width, - css_computed_border_top_style }, - { css_computed_border_right_width, - css_computed_border_right_style }, - { css_computed_border_bottom_width, - css_computed_border_bottom_style }, - { css_computed_border_left_width, - css_computed_border_left_style } - }; - css_fixed value = 0; css_unit unit = CSS_UNIT_PX; @@ -275,9 +295,9 @@ calculate_mbp_width(const nscss_len_ctx *len_ctx, /* border */ if (border) { - if (border_funcs[side].style(style) != + if (border_style_funcs[side](style) != CSS_BORDER_STYLE_NONE) { - border_funcs[side].width(style, &value, &unit); + border_width_funcs[side](style, &value, &unit); *fixed += FIXTOINT(nscss_len2px(len_ctx, value, unit, style)); @@ -1420,24 +1440,7 @@ layout_find_dimensions(const nscss_len_ctx *len_ctx, css_fixed value = 0; css_unit unit = CSS_UNIT_PX; - switch (i) { - case TOP: - type = css_computed_margin_top(style, - &value, &unit); - break; - case RIGHT: - type = css_computed_margin_right(style, - &value, &unit); - break; - case BOTTOM: - type = css_computed_margin_bottom(style, - &value, &unit); - break; - case LEFT: - type = css_computed_margin_left(style, - &value, &unit); - break; - } + type = margin_funcs[i](style, &value, &unit); if (type == CSS_MARGIN_SET) { if (unit == CSS_UNIT_PCT) { @@ -1457,22 +1460,7 @@ layout_find_dimensions(const nscss_len_ctx *len_ctx, css_fixed value = 0; css_unit unit = CSS_UNIT_PX; - switch (i) { - case TOP: - css_computed_padding_top(style, &value, &unit); - break; - case RIGHT: - css_computed_padding_right(style, &value, - &unit); - break; - case BOTTOM: - css_computed_padding_bottom(style, &value, - &unit); - break; - case LEFT: - css_computed_padding_left(style, &value, &unit); - break; - } + padding_funcs[i](style, &value, &unit); if (unit == CSS_UNIT_PCT) { padding[i] = FPCT_OF_INT_TOINT(value, @@ -1490,33 +1478,9 @@ layout_find_dimensions(const nscss_len_ctx *len_ctx, css_fixed value = 0; css_unit unit = CSS_UNIT_PX; - switch (i) { - case TOP: - css_computed_border_top_width(style, &value, - &unit); - bstyle = css_computed_border_top_style(style); - css_computed_border_top_color(style, &color); - break; - case RIGHT: - css_computed_border_right_width(style, &value, - &unit); - bstyle = css_computed_border_right_style(style); - css_computed_border_right_color(style, &color); - break; - case BOTTOM: - css_computed_border_bottom_width(style, &value, - &unit); - bstyle = css_computed_border_bottom_style( - style); - css_computed_border_bottom_color(style, &color); - break; - case LEFT: - css_computed_border_left_width(style, &value, - &unit); - bstyle = css_computed_border_left_style(style); - css_computed_border_left_color(style, &color); - break; - } + border_width_funcs[i](style, &value, &unit); + bstyle = border_style_funcs[i](style); + border_color_funcs[i](style, &color); border[i].style = bstyle; border[i].c = color; -- cgit v1.2.3