60void SymmetryXY(
Global& g) {
64 std::swap(b.min_size_x, b.min_size_y);
65 std::swap(b.flex_grow_x, b.flex_grow_y);
66 std::swap(b.flex_shrink_x, b.flex_shrink_y);
68 std::swap(b.dim_x, b.dim_y);
70 for (
auto& l : g.
lines) {
72 std::swap(l.dim_x, l.dim_y);
79 b.x = g.
size_x - b.x - b.dim_x;
81 for (
auto& l : g.
lines) {
82 l.x = g.
size_x - l.x - l.dim_x;
89 b.y = g.
size_y - b.y - b.dim_y;
91 for (
auto& l : g.
lines) {
92 l.y = g.
size_y - l.y - l.dim_y;
97 for (
auto& line : global.
lines) {
98 std::vector<box_helper::Element> elements;
99 elements.reserve(line.blocks.size());
100 for (
auto* block : line.blocks) {
102 element.
min_size = block->min_size_x;
109 elements.push_back(element);
117 for (
size_t i = 0; i < line.blocks.size(); ++i) {
118 line.blocks[i]->x = x;
119 line.blocks[i]->dim_x = elements[i].size;
120 x += elements[i].size;
125 for (
auto& line : global.
lines) {
127 line.dim_x = global.
size_x;
133 std::vector<box_helper::Element> elements;
134 elements.reserve(g.
lines.size());
135 for (
auto& line : g.
lines) {
137 element.
flex_shrink = line.blocks.front()->flex_shrink_y;
138 element.
flex_grow = line.blocks.front()->flex_grow_y;
139 for (
auto* block : line.blocks) {
144 elements.push_back(element);
151 std::vector<int> ys(elements.size());
153 for (
size_t i = 0; i < elements.size(); ++i) {
155 y += elements[i].size;
158 int remaining_space = std::max(0, g.
size_y - y);
165 for (
size_t i = 0; i < ys.size(); ++i) {
166 ys[i] += remaining_space;
172 for (
size_t i = 0; i < ys.size(); ++i) {
173 ys[i] += remaining_space / 2;
179 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
180 const int shifted = remaining_space * (i + 0) / (i + 1);
182 const int consumed = remaining_space - shifted;
183 elements[i].size += consumed;
184 remaining_space -= consumed;
190 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 1; --i) {
191 ys[i] += remaining_space;
192 remaining_space = remaining_space * (i - 1) / i;
198 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
199 ys[i] += remaining_space * (2 * i + 1) / (2 * i + 2);
200 remaining_space = remaining_space * (2 * i) / (2 * i + 2);
206 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
207 ys[i] += remaining_space * (i + 1) / (i + 2);
208 remaining_space = remaining_space * (i + 1) / (i + 2);
215 for (
size_t i = 0; i < g.
lines.size(); ++i) {
216 auto& element = elements[i];
217 for (
auto* block : g.
lines[i].blocks) {
219 block->flex_grow_y != 0 ||
222 stretch ? element.size : std::min(element.size, block->min_size_y);
231 block->y = ys[i] + (element.size -
size) / 2;
237 block->y = ys[i] + element.size -
size;
244 block->dim_y = element.size;
252 for (
size_t i = 0; i < g.
lines.size(); ++i) {
253 g.
lines[i].y = ys[i];
254 g.
lines[i].dim_y = ys[i + 1] - ys[i];
258void JustifyContent(
Global& g) {
259 for (
auto& line : g.
lines) {
260 Block* last = line.blocks.back();
268 for (
auto* block : line.blocks) {
269 block->x += remaining_space;
275 for (
auto* block : line.blocks) {
276 block->x += remaining_space / 2;
282 for (
int i = (
int)line.blocks.size() - 1; i >= 1; --i) {
283 line.blocks[i]->x += remaining_space;
284 remaining_space = remaining_space * (i - 1) / i;
290 for (
int i = (
int)line.blocks.size() - 1; i >= 0; --i) {
291 line.blocks[i]->x += remaining_space * (2 * i + 1) / (2 * i + 2);
292 remaining_space = remaining_space * (2 * i) / (2 * i + 2);
298 for (
int i = (
int)line.blocks.size() - 1; i >= 0; --i) {
299 line.blocks[i]->x += remaining_space * (i + 1) / (i + 2);
300 remaining_space = remaining_space * (i + 1) / (i + 2);
308void Compute1(
Global& global);
309void Compute2(
Global& global);
310void Compute3(
Global& global);
312void Compute1(
Global& global) {
322void Compute2(
Global& global) {
332void Compute3(
Global& global) {
337 for (
auto& block : global.
blocks) {
340 if (x + block.min_size_x > global.
size_x) {
342 if (!line.
blocks.empty()) {
343 global.
lines.push_back(std::move(line));
348 block.line =
static_cast<int>(global.
lines.size());
349 block.line_position =
static_cast<int>(line.
blocks.size());
350 line.
blocks.push_back(&block);
353 if (!line.
blocks.empty()) {
354 global.
lines.push_back(std::move(line));
360 JustifyContent(global);