58void SymmetryXY(
Global& g) {
62 std::swap(b.min_size_x, b.min_size_y);
63 std::swap(b.flex_grow_x, b.flex_grow_y);
64 std::swap(b.flex_shrink_x, b.flex_shrink_y);
66 std::swap(b.dim_x, b.dim_y);
73 b.x = g.
size_x - b.x - b.dim_x;
80 b.y = g.
size_y - b.y - b.dim_y;
85 std::vector<Block*> blocks;
88void SetX(
Global& global, std::vector<Line> lines) {
89 for (
auto& line : lines) {
90 std::vector<box_helper::Element> elements;
91 for (
auto* block : line.blocks) {
93 element.
min_size = block->min_size_x;
100 elements.push_back(element);
108 for (
size_t i = 0; i < line.blocks.size(); ++i) {
109 line.blocks[i]->dim_x = elements[i].size;
110 line.blocks[i]->x = x;
111 x += elements[i].size;
118void SetY(
Global& g, std::vector<Line> lines) {
119 std::vector<box_helper::Element> elements;
120 for (
auto& line : lines) {
122 element.
flex_shrink = line.blocks.front()->flex_shrink_y;
123 element.
flex_grow = line.blocks.front()->flex_grow_y;
124 for (
auto* block : line.blocks) {
129 elements.push_back(element);
136 std::vector<int> ys(elements.size());
138 for (
size_t i = 0; i < elements.size(); ++i) {
140 y += elements[i].size;
143 int remaining_space = std::max(0, g.
size_y - y);
150 for (
size_t i = 0; i < ys.size(); ++i) {
151 ys[i] += remaining_space;
157 for (
size_t i = 0; i < ys.size(); ++i) {
158 ys[i] += remaining_space / 2;
164 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
165 const int shifted = remaining_space * (i + 0) / (i + 1);
167 const int consumed = remaining_space - shifted;
168 elements[i].size += consumed;
169 remaining_space -= consumed;
175 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 1; --i) {
176 ys[i] += remaining_space;
177 remaining_space = remaining_space * (i - 1) / i;
183 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
184 ys[i] += remaining_space * (2 * i + 1) / (2 * i + 2);
185 remaining_space = remaining_space * (2 * i) / (2 * i + 2);
191 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
192 ys[i] += remaining_space * (i + 1) / (i + 2);
193 remaining_space = remaining_space * (i + 1) / (i + 2);
200 for (
size_t i = 0; i < lines.size(); ++i) {
201 auto& element = elements[i];
202 for (
auto* block : lines[i].blocks) {
204 block->flex_grow_y != 0 ||
207 stretch ? element.size : std::min(element.size, block->min_size_y);
216 block->y = ys[i] + (element.size -
size) / 2;
222 block->y = ys[i] + element.size -
size;
229 block->dim_y = element.size;
237void JustifyContent(
Global& g, std::vector<Line> lines) {
238 for (
auto& line : lines) {
239 Block* last = line.blocks.back();
247 for (
auto* block : line.blocks) {
248 block->x += remaining_space;
254 for (
auto* block : line.blocks) {
255 block->x += remaining_space / 2;
261 for (
int i = (
int)line.blocks.size() - 1; i >= 1; --i) {
262 line.blocks[i]->x += remaining_space;
263 remaining_space = remaining_space * (i - 1) / i;
269 for (
int i = (
int)line.blocks.size() - 1; i >= 0; --i) {
270 line.blocks[i]->x += remaining_space * (2 * i + 1) / (2 * i + 2);
271 remaining_space = remaining_space * (2 * i) / (2 * i + 2);
277 for (
int i = (
int)line.blocks.size() - 1; i >= 0; --i) {
278 line.blocks[i]->x += remaining_space * (i + 1) / (i + 2);
279 remaining_space = remaining_space * (i + 1) / (i + 2);
290void Compute1(
Global& global);
291void Compute2(
Global& global);
292void Compute3(
Global& global);
294void Compute1(
Global& global) {
304void Compute2(
Global& global) {
314void Compute3(
Global& global) {
316 std::vector<Line> lines;
320 for (
auto& block : global.
blocks) {
323 if (x + block.min_size_x > global.
size_x) {
325 if (!line.blocks.empty()) {
326 lines.push_back(std::move(line));
331 block.line = (int)lines.size();
332 block.line_position = (int)line.blocks.size();
333 line.blocks.push_back(&block);
336 if (!line.blocks.empty()) {
337 lines.push_back(std::move(line));
343 JustifyContent(global, lines);