Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vaev-layout: Adapt Input API to fit box-sizing #23

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libs/karm-base/opt.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ struct [[nodiscard]] Opt {
}
}

always_inline constexpr auto map(auto f) -> Opt<decltype(f(unwrap()))> {
always_inline constexpr auto map(auto f) const -> Opt<decltype(f(unwrap()))> {
if (_present) {
return {f(unwrap())};
}
Expand Down
54 changes: 27 additions & 27 deletions src/web/vaev-driver/print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ static void _paintMargins(Style::PageComputedStyle& pageStyle, RectAu pageRect,
auto [_, topLeftMarginCornerFrag] = Layout::layoutCreateFragment(
topLeftMarginCornerTree,
{
.knownSize = topLeftMarginCornerRect.size().cast<Opt<Au>>(),
.position = topLeftMarginCornerRect.topStart(),
.availableSpace = topLeftMarginCornerRect.size(),
.knownBorderBoxSize = topLeftMarginCornerRect.size().cast<Opt<Au>>(),
.borderBoxPosition = topLeftMarginCornerRect.topStart(),
.borderBoxAvailableSpace = topLeftMarginCornerRect.size(),
.containingBlock = topLeftMarginCornerRect.size(),
}
);
Expand All @@ -49,9 +49,9 @@ static void _paintMargins(Style::PageComputedStyle& pageStyle, RectAu pageRect,
auto [_, topRightMarginCornerFrag] = Layout::layoutCreateFragment(
topRightMarginCornerTree,
{
.knownSize = topRightMarginCornerRect.size().cast<Opt<Au>>(),
.position = topRightMarginCornerRect.topStart(),
.availableSpace = topRightMarginCornerRect.size(),
.knownBorderBoxSize = topRightMarginCornerRect.size().cast<Opt<Au>>(),
.borderBoxPosition = topRightMarginCornerRect.topStart(),
.borderBoxAvailableSpace = topRightMarginCornerRect.size(),
.containingBlock = topRightMarginCornerRect.size(),
}
);
Expand All @@ -71,9 +71,9 @@ static void _paintMargins(Style::PageComputedStyle& pageStyle, RectAu pageRect,
auto [_, bottomLeftMarginCornerFrag] = Layout::layoutCreateFragment(
bottomLeftMarginCornerTree,
{
.knownSize = bottomLeftMarginCornerRect.size().cast<Opt<Au>>(),
.position = bottomLeftMarginCornerRect.topStart(),
.availableSpace = bottomLeftMarginCornerRect.size(),
.knownBorderBoxSize = bottomLeftMarginCornerRect.size().cast<Opt<Au>>(),
.borderBoxPosition = bottomLeftMarginCornerRect.topStart(),
.borderBoxAvailableSpace = bottomLeftMarginCornerRect.size(),
.containingBlock = bottomLeftMarginCornerRect.size(),
}
);
Expand All @@ -93,9 +93,9 @@ static void _paintMargins(Style::PageComputedStyle& pageStyle, RectAu pageRect,
auto [_, bottomRightMarginCornerFrag] = Layout::layoutCreateFragment(
bottomRightMarginCornerTree,
{
.knownSize = bottomRightMarginCornerRect.size().cast<Opt<Au>>(),
.position = bottomRightMarginCornerRect.topStart(),
.availableSpace = bottomRightMarginCornerRect.size(),
.knownBorderBoxSize = bottomRightMarginCornerRect.size().cast<Opt<Au>>(),
.borderBoxPosition = bottomRightMarginCornerRect.topStart(),
.borderBoxAvailableSpace = bottomRightMarginCornerRect.size(),
.containingBlock = bottomRightMarginCornerRect.size(),
}
);
Expand All @@ -121,9 +121,9 @@ static void _paintMargins(Style::PageComputedStyle& pageStyle, RectAu pageRect,
auto [_, topFrag] = Layout::layoutCreateFragment(
topTree,
{
.knownSize = topRect.size().cast<Opt<Au>>(),
.position = topRect.topStart(),
.availableSpace = topRect.size(),
.knownBorderBoxSize = topRect.size().cast<Opt<Au>>(),
.borderBoxPosition = topRect.topStart(),
.borderBoxAvailableSpace = topRect.size(),
.containingBlock = topRect.size(),
}
);
Expand All @@ -149,9 +149,9 @@ static void _paintMargins(Style::PageComputedStyle& pageStyle, RectAu pageRect,
auto [_, bottomFrag] = Layout::layoutCreateFragment(
bottomTree,
{
.knownSize = bottomRect.size().cast<Opt<Au>>(),
.position = bottomRect.topStart(),
.availableSpace = bottomRect.size(),
.knownBorderBoxSize = bottomRect.size().cast<Opt<Au>>(),
.borderBoxPosition = bottomRect.topStart(),
.borderBoxAvailableSpace = bottomRect.size(),
.containingBlock = bottomRect.size(),
}
);
Expand All @@ -177,9 +177,9 @@ static void _paintMargins(Style::PageComputedStyle& pageStyle, RectAu pageRect,
auto [_, leftFrag] = Layout::layoutCreateFragment(
leftTree,
{
.knownSize = leftRect.size().cast<Opt<Au>>(),
.position = leftRect.topStart(),
.availableSpace = leftRect.size(),
.knownBorderBoxSize = leftRect.size().cast<Opt<Au>>(),
.borderBoxPosition = leftRect.topStart(),
.borderBoxAvailableSpace = leftRect.size(),
.containingBlock = leftRect.size(),
}
);
Expand All @@ -206,9 +206,9 @@ static void _paintMargins(Style::PageComputedStyle& pageStyle, RectAu pageRect,
auto [_, rightFrag] = Layout::layoutCreateFragment(
rightTree,
{
.knownSize = rightRect.size().cast<Opt<Au>>(),
.position = rightRect.topStart(),
.availableSpace = rightRect.size(),
.knownBorderBoxSize = rightRect.size().cast<Opt<Au>>(),
.borderBoxPosition = rightRect.topStart(),
.borderBoxAvailableSpace = rightRect.size(),
.containingBlock = rightRect.size(),
}
);
Expand Down Expand Up @@ -336,9 +336,9 @@ Generator<Print::Page> print(Gc::Ref<Dom::Document> dom, Print::Settings const&
_paintMargins(*pageStyle, pageRect, pageContent, *pageStack);

Layout::Input pageLayoutInput{
.knownSize = {pageContent.width, NONE},
.position = pageContent.topStart(),
.availableSpace = pageContent.size(),
.knownBorderBoxSize = {pageContent.width, NONE},
.borderBoxPosition = pageContent.topStart(),
.borderBoxAvailableSpace = pageContent.size(),
.containingBlock = pageContent.size(),
};

Expand Down
4 changes: 2 additions & 2 deletions src/web/vaev-driver/render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ RenderResult render(Gc::Ref<Dom::Document> dom, Style::Media const& media, Layou
auto [outDiscovery, root] = Layout::layoutCreateFragment(
tree,
{
.knownSize = {viewport.small.width, NONE},
.availableSpace = {viewport.small.width, 0_au},
.knownBorderBoxSize = {viewport.small.width, NONE},
.borderBoxAvailableSpace = {viewport.small.width, 0_au},
.containingBlock = {viewport.small.width, viewport.small.height},
}
);
Expand Down
1 change: 1 addition & 0 deletions src/web/vaev-driver/res/html.css
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ dd {
/* https://html.spec.whatwg.org/multipage/rendering.html#tables-2 */

table {
box-sizing: border-box;
display: table;
}

Expand Down
64 changes: 51 additions & 13 deletions src/web/vaev-layout/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,13 @@ struct Input {
/// Parent fragment where the layout will be attached.
MutCursor<Frag> fragment = nullptr;
IntrinsicSize intrinsic = IntrinsicSize::AUTO;
Math::Vec2<Opt<Au>> knownSize = {};
Vec2Au position = {};
Vec2Au availableSpace = {};

InsetsAu computedBorders{}, computedPadding{};

Math::Vec2<Opt<Au>> knownBorderBoxSize = {};
Math::Vec2<Opt<Au>> knownContentBoxSize = {};
Vec2Au borderBoxPosition = {};
Vec2Au borderBoxAvailableSpace = {};
Vec2Au containingBlock = {};

BreakpointTraverser breakpointTraverser = {};
Expand All @@ -373,7 +377,41 @@ struct Input {

// TODO: instead of stringing this around, maybe change this (and check method of fragmentainer) to a
// "availableSpaceInFragmentainer" parameter
Au pendingVerticalSizes = {};
Au borderBoxPendingVerticalSizes = {};

Math::Vec2<Opt<Au>> contentBoxSize() const {
Math::Vec2<Opt<Au>> contentBoxSize;

if (not knownContentBoxSize.width) {
contentBoxSize.width = knownBorderBoxSize.width.map([=, this](auto s) {
return max(0_au, s - computedPadding.horizontal() - computedBorders.horizontal());
});
} else
contentBoxSize.width = knownContentBoxSize.width;

if (not knownContentBoxSize.height) {
contentBoxSize.height = knownBorderBoxSize.height.map([&](auto s) {
return max(0_au, s - computedPadding.vertical() - computedBorders.vertical());
});
} else
contentBoxSize.height = knownContentBoxSize.height;

return contentBoxSize;
}

Vec2Au contentBoxPosition() const {
return borderBoxPosition + computedBorders.topStart() + computedPadding.topStart();
}

Vec2Au contentBoxAvailableSpace() const {
return (borderBoxAvailableSpace - computedPadding.all() - computedBorders.all()).map([](auto x) {
return max(0_au, x);
});
}

Au contentBoxPendingVerticalSizes() const {
return borderBoxPendingVerticalSizes - computedPadding.bottom - computedBorders.bottom;
}

Input withFragment(MutCursor<Frag> f) const {
auto copy = *this;
Expand All @@ -387,25 +425,25 @@ struct Input {
return copy;
}

Input withKnownSize(Math::Vec2<Opt<Au>> size) const {
Input withKnownBorderBoxSize(Math::Vec2<Opt<Au>> size) const {
auto copy = *this;
copy.knownSize = size;
copy.knownBorderBoxSize = size;
return copy;
}

Input withPosition(Vec2Au pos) const {
Input withBorderBoxPosition(Vec2Au pos) const {
auto copy = *this;
copy.position = pos;
copy.borderBoxPosition = pos;
return copy;
}

Input withAvailableSpace(Vec2Au space) const {
Input withBorderBoxAvailableSpace(Vec2Au space) const {
auto copy = *this;
copy.availableSpace = space;
copy.borderBoxAvailableSpace = space;
return copy;
}

Input withContainingBlock(Vec2Au block) const {
Input withBorderBoxContainingBlock(Vec2Au block) const {
auto copy = *this;
copy.containingBlock = block;
return copy;
Expand All @@ -417,9 +455,9 @@ struct Input {
return copy;
}

Input addPendingVerticalSize(Au newPendingVerticalSize) const {
Input addBorderBoxPendingVerticalSize(Au newPendingVerticalSize) const {
auto copy = *this;
copy.pendingVerticalSizes += newPendingVerticalSize;
copy.borderBoxPendingVerticalSizes += newPendingVerticalSize;
return copy;
}
};
Expand Down
26 changes: 13 additions & 13 deletions src/web/vaev-layout/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ Res<None, Output> processBreakpointsBeforeChild(usize endAt, Vec2Au 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
Vec2Au knownSize{input.knownSize.x.unwrapOr(0_au), input.knownSize.y.unwrapOr(0_au)};
Vec2Au knownSize{input.contentBoxSize().x.unwrapOr(0_au), input.contentBoxSize().y.unwrapOr(0_au)};
if (tree.fc.isDiscoveryMode()) {
if (tree.fc.acceptsFit(
input.position.y,
input.contentBoxPosition().y,
knownSize.y,
input.pendingVerticalSizes
input.contentBoxPendingVerticalSizes()
)) {
return Output{
.size = knownSize,
Expand All @@ -106,7 +106,7 @@ Output fragmentEmptyBox(Tree& tree, Input input) {
} else {
// FIXME: we should be breaking empty boxes using pixels or percentages, this behaviour is not compliant
Au verticalSpaceLeft = tree.fc.leftVerticalSpace(
input.position.y, input.pendingVerticalSizes
input.contentBoxPosition().y, input.contentBoxPendingVerticalSizes()
);
return Output{
.size = {knownSize.x, min(knownSize.y, verticalSpaceLeft)},
Expand All @@ -124,7 +124,7 @@ struct BlockFormatingContext : public FormatingContext {
auto margin = computeMargins(
tree, c,
{
.containingBlock = {inlineSize, input.knownSize.y.unwrapOr(0_au)},
.containingBlock = {inlineSize, input.contentBoxSize().y.unwrapOr(0_au)},
}
);

Expand All @@ -144,15 +144,15 @@ struct BlockFormatingContext : public FormatingContext {

Output run(Tree& tree, Box& box, Input input, usize startAt, Opt<usize> stopAt) override {
Au blockSize = 0_au;
Au inlineSize = input.knownSize.width.unwrapOr(0_au);
Au inlineSize = input.contentBoxSize().width.unwrapOr(0_au);

if (box.children().len() == 0) {
return fragmentEmptyBox(tree, input);
}

// NOTE: Our parent has no clue about our width but wants us to commit,
// we need to compute it first
if (input.fragment and not input.knownSize.width)
if (input.fragment and not input.contentBoxSize().width)
inlineSize = run(tree, box, input.withFragment(nullptr), startAt, stopAt).width();

Breakpoint currentBreakpoint;
Expand Down Expand Up @@ -180,10 +180,10 @@ struct BlockFormatingContext : public FormatingContext {
Input childInput = {
.fragment = input.fragment,
.intrinsic = input.intrinsic,
.availableSpace = {input.availableSpace.x, 0_au},
.containingBlock = {inlineSize, input.knownSize.y.unwrapOr(0_au)},
.borderBoxAvailableSpace = {input.contentBoxAvailableSpace().x, 0_au},
.containingBlock = {inlineSize, input.contentBoxSize().y.unwrapOr(0_au)},
.breakpointTraverser = input.breakpointTraverser.traverseInsideUsingIthChild(i),
.pendingVerticalSizes = input.pendingVerticalSizes,
.borderBoxPendingVerticalSizes = input.contentBoxPendingVerticalSizes(),
};

auto margin = computeMargins(tree, c, childInput);
Expand All @@ -195,11 +195,11 @@ struct BlockFormatingContext : public FormatingContext {

if (c.style->position != Position::ABSOLUTE) {
blockSize += margin.top;
if (input.fragment or input.knownSize.x)
childInput.knownSize.width = childInlineSize;
if (input.fragment or input.contentBoxSize().x)
childInput.knownBorderBoxSize.width = childInlineSize;
}

childInput.position = input.position + Vec2Au{margin.start, blockSize};
childInput.borderBoxPosition = input.contentBoxPosition() + Vec2Au{margin.start, blockSize};

// HACK: Table Box mostly behaves like a block box, let's compute its capmin
// and avoid duplicating the layout code
Expand Down
Loading
Loading