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);
71 for (
auto& l : g.
lines) {
73 std::swap(l.dim_x, l.dim_y);
80 b.x = g.
size_x - b.x - b.dim_x;
82 for (
auto& l : g.
lines) {
83 l.x = g.
size_x - l.x - l.dim_x;
90 b.y = g.
size_y - b.y - b.dim_y;
92 for (
auto& l : g.
lines) {
93 l.y = g.
size_y - l.y - l.dim_y;
98 for (
auto& line : global.
lines) {
99 std::vector<box_helper::Element> elements;
100 elements.reserve(line.blocks.size());
101 for (
auto* block : line.blocks) {
103 element.
min_size = block->min_size_x;
110 elements.push_back(element);
118 for (
size_t i = 0; i < line.blocks.size(); ++i) {
119 line.blocks[i]->x = x;
120 line.blocks[i]->dim_x = elements[i].size;
121 x += elements[i].size;
126 for (
auto& line : global.
lines) {
128 line.dim_x = global.
size_x;
134 std::vector<box_helper::Element> elements;
135 elements.reserve(g.
lines.size());
136 for (
auto& line : g.
lines) {
138 element.
flex_shrink = line.blocks.front()->flex_shrink_y;
139 element.
flex_grow = line.blocks.front()->flex_grow_y;
140 for (
auto* block : line.blocks) {
145 elements.push_back(element);
152 std::vector<int> ys(elements.size());
154 for (
size_t i = 0; i < elements.size(); ++i) {
156 y += elements[i].size;
159 int remaining_space = std::max(0, g.
size_y - y);
166 for (
size_t i = 0; i < ys.size(); ++i) {
167 ys[i] += remaining_space;
173 for (
size_t i = 0; i < ys.size(); ++i) {
174 ys[i] += remaining_space / 2;
180 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
181 const int shifted = remaining_space * (i + 0) / (i + 1);
183 const int consumed = remaining_space - shifted;
184 elements[i].size += consumed;
185 remaining_space -= consumed;
191 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 1; --i) {
192 ys[i] += remaining_space;
193 remaining_space = remaining_space * (i - 1) / i;
199 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
200 ys[i] += remaining_space * (2 * i + 1) / (2 * i + 2);
201 remaining_space = remaining_space * (2 * i) / (2 * i + 2);
207 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
208 ys[i] += remaining_space * (i + 1) / (i + 2);
209 remaining_space = remaining_space * (i + 1) / (i + 2);
216 for (
size_t i = 0; i < g.
lines.size(); ++i) {
217 auto& element = elements[i];
218 for (
auto* block : g.
lines[i].blocks) {
220 block->flex_grow_y != 0 ||
223 stretch ? element.size : std::min(element.size, block->min_size_y);
232 block->y = ys[i] + (element.size -
size) / 2;
238 block->y = ys[i] + element.size -
size;
245 block->dim_y = element.size;
253 for (
size_t i = 0; i < g.
lines.size(); ++i) {
254 g.
lines[i].y = ys[i];
255 g.
lines[i].dim_y = ys[i + 1] - ys[i];
259void JustifyContent(
Global& g) {
260 for (
auto& line : g.
lines) {
261 Block* last = line.blocks.back();
269 for (
auto* block : line.blocks) {
270 block->x += remaining_space;
276 for (
auto* block : line.blocks) {
277 block->x += remaining_space / 2;
283 for (
int i = (
int)line.blocks.size() - 1; i >= 1; --i) {
284 line.blocks[i]->x += remaining_space;
285 remaining_space = remaining_space * (i - 1) / i;
291 for (
int i = (
int)line.blocks.size() - 1; i >= 0; --i) {
292 line.blocks[i]->x += remaining_space * (2 * i + 1) / (2 * i + 2);
293 remaining_space = remaining_space * (2 * i) / (2 * i + 2);
299 for (
int i = (
int)line.blocks.size() - 1; i >= 0; --i) {
300 line.blocks[i]->x += remaining_space * (i + 1) / (i + 2);
301 remaining_space = remaining_space * (i + 1) / (i + 2);
309void Compute1(
Global& global);
310void Compute2(
Global& global);
311void Compute3(
Global& global);
313void Compute1(
Global& global) {
323void Compute2(
Global& global) {
333void Compute3(
Global& global) {
338 for (
auto& block : global.
blocks) {
341 if (x + block.min_size_x > global.
size_x) {
343 if (!line.
blocks.empty()) {
344 global.
lines.push_back(std::move(line));
349 block.line =
static_cast<int>(global.
lines.size());
350 block.line_position =
static_cast<int>(line.
blocks.size());
351 line.
blocks.push_back(&block);
354 if (!line.
blocks.empty()) {
355 global.
lines.push_back(std::move(line));
361 JustifyContent(global);