61void SymmetryXY(
Global& g) {
65 std::swap(b.min_size_x, b.min_size_y);
66 std::swap(b.flex_grow_x, b.flex_grow_y);
67 std::swap(b.flex_shrink_x, b.flex_shrink_y);
69 std::swap(b.dim_x, b.dim_y);
76 b.x = g.
size_x - b.x - b.dim_x;
83 b.y = g.
size_y - b.y - b.dim_y;
88 std::vector<Block*> blocks;
91void SetX(
Global& global, std::vector<Line> lines) {
92 for (
auto& line : lines) {
93 std::vector<box_helper::Element> elements;
94 elements.reserve(line.blocks.size());
95 for (
auto* block : line.blocks) {
97 element.
min_size = block->min_size_x;
104 elements.push_back(element);
112 for (
size_t i = 0; i < line.blocks.size(); ++i) {
113 line.blocks[i]->dim_x = elements[i].size;
114 line.blocks[i]->x = x;
115 x += elements[i].size;
122void SetY(
Global& g, std::vector<Line> lines) {
123 std::vector<box_helper::Element> elements;
124 elements.reserve(lines.size());
125 for (
auto& line : lines) {
127 element.
flex_shrink = line.blocks.front()->flex_shrink_y;
128 element.
flex_grow = line.blocks.front()->flex_grow_y;
129 for (
auto* block : line.blocks) {
134 elements.push_back(element);
141 std::vector<int> ys(elements.size());
143 for (
size_t i = 0; i < elements.size(); ++i) {
145 y += elements[i].size;
148 int remaining_space = std::max(0, g.
size_y - y);
155 for (
size_t i = 0; i < ys.size(); ++i) {
156 ys[i] += remaining_space;
162 for (
size_t i = 0; i < ys.size(); ++i) {
163 ys[i] += remaining_space / 2;
169 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
170 const int shifted = remaining_space * (i + 0) / (i + 1);
172 const int consumed = remaining_space - shifted;
173 elements[i].size += consumed;
174 remaining_space -= consumed;
180 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 1; --i) {
181 ys[i] += remaining_space;
182 remaining_space = remaining_space * (i - 1) / i;
188 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
189 ys[i] += remaining_space * (2 * i + 1) / (2 * i + 2);
190 remaining_space = remaining_space * (2 * i) / (2 * i + 2);
196 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
197 ys[i] += remaining_space * (i + 1) / (i + 2);
198 remaining_space = remaining_space * (i + 1) / (i + 2);
205 for (
size_t i = 0; i < lines.size(); ++i) {
206 auto& element = elements[i];
207 for (
auto* block : lines[i].blocks) {
209 block->flex_grow_y != 0 ||
212 stretch ? element.size : std::min(element.size, block->min_size_y);
221 block->y = ys[i] + (element.size -
size) / 2;
227 block->y = ys[i] + element.size -
size;
234 block->dim_y = element.size;
242void JustifyContent(
Global& g, std::vector<Line> lines) {
243 for (
auto& line : lines) {
244 Block* last = line.blocks.back();
252 for (
auto* block : line.blocks) {
253 block->x += remaining_space;
259 for (
auto* block : line.blocks) {
260 block->x += remaining_space / 2;
266 for (
int i = (
int)line.blocks.size() - 1; i >= 1; --i) {
267 line.blocks[i]->x += remaining_space;
268 remaining_space = remaining_space * (i - 1) / i;
274 for (
int i = (
int)line.blocks.size() - 1; i >= 0; --i) {
275 line.blocks[i]->x += remaining_space * (2 * i + 1) / (2 * i + 2);
276 remaining_space = remaining_space * (2 * i) / (2 * i + 2);
282 for (
int i = (
int)line.blocks.size() - 1; i >= 0; --i) {
283 line.blocks[i]->x += remaining_space * (i + 1) / (i + 2);
284 remaining_space = remaining_space * (i + 1) / (i + 2);
292void Compute1(
Global& global);
293void Compute2(
Global& global);
294void Compute3(
Global& global);
296void Compute1(
Global& global) {
306void Compute2(
Global& global) {
316void Compute3(
Global& global) {
318 std::vector<Line> lines;
322 line.blocks.reserve(global.
blocks.size());
323 for (
auto& block : global.
blocks) {
326 if (x + block.min_size_x > global.
size_x) {
328 if (!line.blocks.empty()) {
329 lines.push_back(std::move(line));
334 block.line = lines.size();
335 block.line_position = line.blocks.size();
336 line.blocks.push_back(&block);
339 if (!line.blocks.empty()) {
340 lines.push_back(std::move(line));
346 JustifyContent(global, lines);
void Compute(std::vector< Element > *elements, int target_size)
void Compute(Global &global)
std::vector< Block > blocks
Decorator size(WidthOrHeight, Constraint, int value)
Apply a constraint on the size of an element.
AlignContent align_content
@ Center
items are centered along the cross axis.
@ FlexStart
items are placed at the start of the cross axis.
@ FlexEnd
items are placed at the end of the cross axis.
@ SpaceBetween
items are evenly distributed in the cross axis.
@ Stretch
items are stretched to fill the cross axis.
@ Column
Flex items are laid out in a column.
@ Row
Flex items are laid out in a row.
@ RowInversed
Flex items are laid out in a row, but in reverse order.
@ NoWrap
Flex items will all try to fit onto one line.
@ Wrap
Flex items will wrap onto multiple lines.
@ Center
items are centered along the cross axis.
@ FlexStart
items are placed at the start of the cross axis.
@ FlexEnd
items are placed at the end of the cross axis.
@ Stretch
items are stretched to fill the cross axis.
JustifyContent justify_content
@ Center
Items are centered along the line.
@ FlexStart
Items are aligned to the start of flexbox's direction.
@ FlexEnd
Items are aligned to the end of flexbox's direction.
@ SpaceBetween
Items are evenly distributed in the line; first item is on the start.
@ Stretch
Items are stretched to fill the line.