Skip to content

Commit

Permalink
vaev-layout: fragmenting tables
Browse files Browse the repository at this point in the history
  • Loading branch information
pauloamed committed Dec 12, 2024
1 parent 2bec2cb commit bcbff54
Show file tree
Hide file tree
Showing 5 changed files with 471 additions and 70 deletions.
5 changes: 4 additions & 1 deletion src/web/vaev-driver/print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,10 @@ Vec<Strong<Scene::Page>> print(Markup::Document const &dom, Print::Settings cons
Layout::build(computer, dom),
};

Layout::Breakpoint prevBreakpoint{.endIdx = 0}, currBreakpoint;
// ideally prev breakpoint would be an OPT here or a pointer for the first iteration, where it doesnt exist
Layout::Breakpoint currBreakpoint,
prevBreakpoint{.endIdx = 0, .advanceCase = Layout::Breakpoint::ADVANCE_CASE::ADVANCE_WITHOUT_CHILDREN};

auto rootFragment = Layout::Frag();
while (true) {
Layout::Resolver resolver{};
Expand Down
96 changes: 81 additions & 15 deletions src/web/vaev-layout/input_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ struct Breakpoint {
// attribution could should be encapsulated in this class, instead of exposed to code
usize appeal = 0;

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

enum struct ADVANCE_CASE {
NOT_ADVANCE, // keeping children
ADVANCE_WITH_CHILDREN,
ADVANCE_WITHOUT_CHILDREN
} advanceCase;

void overrideIfBetter(Breakpoint &&BPWithMoreContent) {
if (appeal == 0 and BPWithMoreContent.appeal == 0)
Expand All @@ -33,26 +39,57 @@ struct Breakpoint {
}

void repr(Io::Emit &e) const {
e("(end: {} appeal: {}", endIdx, appeal);
if (child.len() == 0)
e("(end: {} appeal: {} advance case: {}", endIdx, appeal, advanceCase);
if (children.len() == 0)
e("; no child)");
else
e("; child : {})", child[0]);
e("; children : {})", children);
}

static Breakpoint buildForced(usize endIdx) {
return Breakpoint{
.endIdx = endIdx,
// since this is a FORCED break, it will have maximum appeal
.appeal = Limits<usize>::MAX
.appeal = Limits<usize>::MAX,
.advanceCase = ADVANCE_CASE::ADVANCE_WITHOUT_CHILDREN,
};
}

// NOTE: a bit inconsistent with the rest of the API
void applyAvoid() {
appeal = min(appeal, AVOID_APPEAL);
}

static Breakpoint buildFromChild(Breakpoint &&childBreakpoint, usize endIdx, bool isAvoid) {
Breakpoint b{
.endIdx = endIdx,
.appeal = childBreakpoint.appeal,
.child = {std::move(childBreakpoint)}
.children = {std::move(childBreakpoint)},
.advanceCase = ADVANCE_CASE::NOT_ADVANCE,
};

if (isAvoid)
b.appeal = min(b.appeal, AVOID_APPEAL);

return b;
}

static Breakpoint buildFromChildren(Vec<Opt<Breakpoint>> childrenBreakpoints, usize endIdx, bool isAvoid, bool advance) {
usize appeal = Limits<usize>::MAX;
for (auto &breakpoint : childrenBreakpoints) {
if (not breakpoint)
continue;
appeal = min(appeal, breakpoint.unwrap().appeal);
}

if (appeal == Limits<usize>::MAX)
panic("");

Breakpoint b{
.endIdx = endIdx,
.appeal = appeal,
.children = {std::move(childrenBreakpoints)},
.advanceCase = advance ? ADVANCE_CASE::ADVANCE_WITH_CHILDREN : ADVANCE_CASE::NOT_ADVANCE
};

if (isAvoid)
Expand All @@ -64,7 +101,8 @@ struct Breakpoint {
static Breakpoint buildClassB(usize endIdx, bool isAvoid) {
Breakpoint b{
.endIdx = endIdx,
.appeal = isAvoid ? AVOID_APPEAL : CLASS_B_APPEAL
.appeal = isAvoid ? AVOID_APPEAL : CLASS_B_APPEAL,
.advanceCase = ADVANCE_CASE::ADVANCE_WITHOUT_CHILDREN
};

return b;
Expand All @@ -74,7 +112,8 @@ struct Breakpoint {
// this is a placeholder breakpoint and should be overriden
return {
.endIdx = 0,
.appeal = 0
.appeal = 0,
.advanceCase = ADVANCE_CASE::NOT_ADVANCE
};
}
};
Expand All @@ -87,23 +126,44 @@ struct BreakpointTraverser {
MutCursor<Breakpoint> curr = nullptr
) : prevIteration(prev), currIteration(curr) {}

BreakpointTraverser traverseInsideUsingIthChild(usize i) {
BreakpointTraverser deeperBPT;
if (prevIteration and prevIteration->child.len() > 0 and i + 1 == prevIteration->endIdx) {
deeperBPT.prevIteration = &prevIteration->child[0];
bool isDeactivated() {
return prevIteration == nullptr and currIteration == nullptr;
}

MutCursor<Breakpoint> traversePrev(usize i, usize j) {
if (prevIteration and prevIteration->children.len() > 0 and
(i + 1 == prevIteration->endIdx or
(prevIteration->advanceCase == Breakpoint::ADVANCE_CASE::ADVANCE_WITH_CHILDREN and i == prevIteration->endIdx)
)) {
if (prevIteration->children[j])
return &prevIteration->children[j].unwrap();
}
return nullptr;
}

if (currIteration and currIteration->child.len() > 0 and i + 1 == currIteration->endIdx) {
deeperBPT.currIteration = &currIteration->child[0];
MutCursor<Breakpoint> traverseCurr(usize i, usize j) {
if (currIteration and currIteration->children.len() > 0 and i + 1 == currIteration->endIdx) {
if (currIteration->children[j])
return &currIteration->children[j].unwrap();
}
return nullptr;
}

BreakpointTraverser traverseInsideUsingIthChildToJthParallelFlow(usize i, usize j) {
BreakpointTraverser deeperBPT;
deeperBPT.prevIteration = traversePrev(i, j);
deeperBPT.currIteration = traverseCurr(i, j);
return deeperBPT;
}

BreakpointTraverser traverseInsideUsingIthChild(usize i) {
return traverseInsideUsingIthChildToJthParallelFlow(i, 0);
}

Opt<usize> getStart() {
if (prevIteration == nullptr)
return NONE;
return prevIteration->endIdx - (prevIteration->child.len() ? 1 : 0);
return prevIteration->endIdx - (prevIteration->advanceCase == Breakpoint::ADVANCE_CASE::NOT_ADVANCE);
}

Opt<usize> getEnd() {
Expand Down Expand Up @@ -173,6 +233,12 @@ struct Input {
copy.breakpointTraverser = bpt;
return copy;
}

Input addPendingVerticalSize(Px newPendingVerticalSize) const {
auto copy = *this;
copy.pendingVerticalSizes += newPendingVerticalSize;
return copy;
}
};

struct Output {
Expand Down
10 changes: 6 additions & 4 deletions src/web/vaev-layout/layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Output _contentLayout(Tree &tree, Box &box, Input input, usize startAt, Opt<usiz
} else if (display == Display::GRID) {
return gridLayout(tree, box, input);
} else if (display == Display::TABLE_BOX) {
return tableLayout(tree, box, input);
return tableLayout(tree, box, input, startAt, stopAt);
} else if (display == Display::INTERNAL) {
return Output{};
} else {
Expand Down Expand Up @@ -190,7 +190,8 @@ void maybeSetMonolithicBreakpoint(FragmentationContext &fc, bool isMonolticDispl
// NOTE: wont abstract this since this is currently a workaround since we dont have fragmentation for table,flex
Breakpoint bottomOfContentBreakForTopMonolitic{
.endIdx = boxChildrenLen,
.appeal = 2
.appeal = 2,
.advanceCase = Breakpoint::ADVANCE_CASE::ADVANCE_WITHOUT_CHILDREN
};

outputBreakpoint = bottomOfContentBreakForTopMonolitic;
Expand Down Expand Up @@ -231,7 +232,6 @@ Output layout(Tree &tree, Box &box, Input input) {
if (tree.fc.isDiscoveryMode()) {
bool isMonolticDisplay =
box.style->display == Display::Inside::FLEX or
box.style->display == Display::Inside::TABLE or
box.style->display == Display::Inside::GRID;

if (isMonolticDisplay)
Expand All @@ -249,7 +249,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 (out.completelyLaidOut and not input.breakpointTraverser.prevIteration) {
size.height = input.knownSize.height.unwrapOr(size.height);
}

// TODO: Class C breakpoint

Expand Down
Loading

0 comments on commit bcbff54

Please sign in to comment.