Skip to content

Commit

Permalink
vaev-layout: fragmenting empty boxes based on their pixels
Browse files Browse the repository at this point in the history
  • Loading branch information
pauloamed committed Dec 12, 2024
1 parent bcbff54 commit a88ef68
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 12 deletions.
50 changes: 40 additions & 10 deletions src/web/vaev-layout/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,49 @@ Res<None, Output> processBreakpointsBeforeChild(usize endAt, Vec2Px currentSize,
Output fragmentEmptyBox(Tree &tree, Input input) {
// put this here instead of in layout.py since we want to know if its the empty box case
Vec2Px knownSize{input.knownSize.x.unwrapOr(0_px), input.knownSize.y.unwrapOr(0_px)};
if (tree.fc.acceptsFit(
input.position.y,
knownSize.y,
input.pendingVerticalSizes
)) {

if (not tree.fc.allowBreak())
return Output{
.size = knownSize,
.completelyLaidOut = true,
};

Px leftVerticalSpace = tree.fc.leftVerticalSpace(input.position.y, input.pendingVerticalSizes);
Px partialHeight = input.breakpointTraverser.getPartialHeight().unwrapOr(0_px);
Px remainingVerticalSize = knownSize.y - partialHeight;

if (tree.fc.isDiscoveryMode()) {
if (leftVerticalSpace == 0_px and knownSize.y > 0_px)
return Output{
.size = Vec2Px{0_px, 0_px},
.completelyLaidOut = false,
.breakpoint = Breakpoint::buildOverflow()
};

if (leftVerticalSpace < remainingVerticalSize) {
return Output{
.size = {knownSize.x, leftVerticalSpace},
.completelyLaidOut = false,
.breakpoint = Breakpoint::buildWithPartialHeight(partialHeight + leftVerticalSpace),
};
} else {
return Output{
.size = {knownSize.x, remainingVerticalSize},
.completelyLaidOut = true,
};
}
} else {
return Output{
.size = {},
.completelyLaidOut = false,
.breakpoint = Breakpoint::buildOverflow()
};
if (input.breakpointTraverser.currIteration and input.breakpointTraverser.getPartialHeight()) {
return Output{
.size = {knownSize.x, leftVerticalSpace},
.completelyLaidOut = false,
};
} else {
return Output{
.size = {knownSize.x, remainingVerticalSize},
.completelyLaidOut = true,
};
}
}
}

Expand Down Expand Up @@ -134,6 +162,8 @@ struct BlockFormatingContext {
}

Output run(Tree &tree, Box &box, Input input, usize startAt, Opt<usize> stopAt) {
// TODO: when the block's height is definite, it should reflect in the different fragments it belongs to

Px blockSize = 0_px;
Px inlineSize = input.knownSize.width.unwrapOr(0_px);

Expand Down
4 changes: 4 additions & 0 deletions src/web/vaev-layout/fragmentainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ struct FragmentationContext {
bool acceptsFit(Px verticalPosition, Px verticalSize, Px pendingVerticalSizes) {
return verticalPosition + verticalSize + pendingVerticalSizes <= defaultSize.y;
}

Px leftVerticalSpace(Px verticalPosition, Px pendingVerticalSizes) {
return defaultSize.y - verticalPosition - pendingVerticalSizes;
}
};

} // namespace Vaev::Layout
19 changes: 18 additions & 1 deletion src/web/vaev-layout/input_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ struct Breakpoint {
// attribution could should be encapsulated in this class, instead of exposed to code
usize appeal = 0;

Px partialHeight = {};

Vec<Opt<Breakpoint>> children = {};

enum struct ADVANCE_CASE {
Expand All @@ -39,7 +41,7 @@ struct Breakpoint {
}

void repr(Io::Emit &e) const {
e("(end: {} appeal: {} advance case: {}", endIdx, appeal, advanceCase);
e("(end: {} appeal: {} advance case: {} partial height: {}", endIdx, appeal, advanceCase, partialHeight);
if (children.len() == 0)
e("; no child)");
else
Expand Down Expand Up @@ -116,6 +118,15 @@ struct Breakpoint {
.advanceCase = ADVANCE_CASE::NOT_ADVANCE
};
}

static Breakpoint buildWithPartialHeight(Px partialHeight) {
return {
.endIdx = 0,
.appeal = 2,
.partialHeight = partialHeight,
.advanceCase = ADVANCE_CASE::NOT_ADVANCE
};
}
};

struct BreakpointTraverser {
Expand Down Expand Up @@ -171,6 +182,12 @@ struct BreakpointTraverser {
return NONE;
return currIteration->endIdx;
}

Opt<Px> getPartialHeight() {
if (prevIteration == nullptr)
return NONE;
return prevIteration->partialHeight == 0_px ? NONE : Opt<Px>{prevIteration->partialHeight};
}
};

/// Input to the layout algorithm.
Expand Down
4 changes: 3 additions & 1 deletion src/web/vaev-layout/layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,9 @@ Output layout(Tree &tree, Box &box, Input input) {

auto size = out.size;
size.width = input.knownSize.width.unwrapOr(size.width);
size.height = input.knownSize.height.unwrapOr(size.height);
if ((not tree.fc.allowBreak()) or (out.completelyLaidOut and not input.breakpointTraverser.prevIteration)) {
size.height = input.knownSize.height.unwrapOr(size.height);
}

size = size + padding.all() + borders.all();

Expand Down

0 comments on commit a88ef68

Please sign in to comment.