diff options
author | Michael Drake <tlsa@netsurf-browser.org> | 2022-11-01 15:45:57 +0000 |
---|---|---|
committer | Michael Drake <mdrake.unique@gmail.com> | 2022-11-02 20:16:41 +0000 |
commit | 47482bd5391e15ab12293133feea9616b235b8b9 (patch) | |
tree | a6bd16d19b39b798723ccf82d10967122a93cb39 | |
parent | e9147bdeea34b862e029c4a500cd87049875df4b (diff) | |
download | netsurf-47482bd5391e15ab12293133feea9616b235b8b9.tar.gz netsurf-47482bd5391e15ab12293133feea9616b235b8b9.tar.bz2 |
html: layout: flex: Implement wrap-reverse
-rw-r--r-- | content/handlers/html/layout_flex.c | 73 |
1 files changed, 48 insertions, 25 deletions
diff --git a/content/handlers/html/layout_flex.c b/content/handlers/html/layout_flex.c index 1d7478e74..f0dfca833 100644 --- a/content/handlers/html/layout_flex.c +++ b/content/handlers/html/layout_flex.c @@ -70,6 +70,8 @@ struct flex_line_data { int main_size; int cross_size; + int pos; + size_t first; size_t count; size_t frozen; @@ -548,12 +550,10 @@ static inline void layout_flex__distribute_free_main( } } -static bool layout_flex__resolve_line_item_positions( +static bool layout_flex__place_line_items_main( struct flex_ctx *ctx, - struct flex_line_data *line, - int available_width) + struct flex_line_data *line) { - enum box_side cross_start = ctx->horizontal ? TOP : LEFT; enum box_side main_start = ctx->horizontal ? LEFT : TOP; size_t item_count = line->first + line->count; int main_pos = ctx->flex->padding[main_start]; @@ -561,32 +561,18 @@ static bool layout_flex__resolve_line_item_positions( for (size_t i = line->first; i < item_count; i++) { struct flex_item_data *item = &ctx->item.data[i]; struct box *b = item->box; - int *box_pos_cross; int *box_pos_main; if (ctx->horizontal) { - bool success; - b->width = item->target_main_size - lh__delta_outer_width(b); - success = layout_flex_item(ctx, item, b->width); - if (!success) { + if (!layout_flex_item(ctx, item, b->width)) { return false; } - - box_pos_main = &b->x; - box_pos_cross = &b->y; - } else { - box_pos_main = &b->y; - box_pos_cross = &b->x; } - *box_pos_cross = ctx->flex->padding[cross_start] + - ctx->cross_size + - lh__non_auto_margin(b, cross_start) + - b->border[cross_start].width; - + box_pos_main = ctx->horizontal ? &b->x : &b->y; *box_pos_main = main_pos + lh__non_auto_margin(b, main_start) + b->border[main_start].width; @@ -598,14 +584,14 @@ static bool layout_flex__resolve_line_item_positions( box_size_main = lh__box_size_main(ctx->horizontal, b); box_size_cross = lh__box_size_cross(ctx->horizontal, b); + main_pos += *box_size_main + lh__delta_outer_main( + ctx->flex, b); + cross_size = *box_size_cross + lh__delta_outer_cross( ctx->flex, b); if (line->cross_size < cross_size) { line->cross_size = cross_size; } - - main_pos += *box_size_main + lh__delta_outer_main( - ctx->flex, b); } } @@ -703,8 +689,7 @@ static bool layout_flex__resolve_line( } } - if (!layout_flex__resolve_line_item_positions(ctx, line, - available_width)) { + if (!layout_flex__place_line_items_main(ctx, line)) { return false; } @@ -745,6 +730,42 @@ static bool layout_flex__collect_items_into_lines( return true; } +static void layout_flex__place_line_items_cross(struct flex_ctx *ctx, + struct flex_line_data *line) +{ + enum box_side cross_start = ctx->horizontal ? TOP : LEFT; + size_t item_count = line->first + line->count; + + for (size_t i = line->first; i < item_count; i++) { + struct flex_item_data *item = &ctx->item.data[i]; + struct box *b = item->box; + int *box_pos_cross; + + box_pos_cross = ctx->horizontal ? &b->y : &b->x; + *box_pos_cross = ctx->flex->padding[cross_start] + line->pos + + lh__non_auto_margin(b, cross_start) + + b->border[cross_start].width; + } +} + +static void layout_flex__place_lines(struct flex_ctx *ctx) +{ + bool reversed = ctx->wrap == CSS_FLEX_WRAP_WRAP_REVERSE; + int line_pos = reversed ? ctx->cross_size : 0; + int post_multiplier = reversed ? 0 : 1; + int pre_multiplier = reversed ? -1 : 0; + + for (size_t i = 0; i < ctx->line.count; i++) { + struct flex_line_data *line = &ctx->line.data[i]; + + line_pos += pre_multiplier * line->cross_size; + line->pos = line_pos; + line_pos += post_multiplier * line->cross_size; + + layout_flex__place_line_items_cross(ctx, line); + } +} + /** * Layout a flex container. * @@ -785,6 +806,8 @@ bool layout_flex(struct box *flex, int available_width, goto cleanup; } + layout_flex__place_lines(ctx); + if (flex->height == AUTO) { flex->height = ctx->horizontal ? ctx->cross_size : |