Skip to content

Commit

Permalink
vaev-layout: fixes on flex basis and min preferred size computation f…
Browse files Browse the repository at this point in the history
…or flex
  • Loading branch information
pauloamed committed Nov 25, 2024
1 parent 6e1912f commit 70050f9
Showing 1 changed file with 71 additions and 48 deletions.
119 changes: 71 additions & 48 deletions src/vaev-layout/flex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,35 +241,37 @@ struct FlexItem {
);
}

// https://www.w3.org/TR/css-flexbox-1/#valdef-flex-basis-auto
void computeFlexBaseSize(Tree &tree, Px mainContainerSize) {
// TODO: check specs
if (flexItemProps.basis.type == FlexBasis::WIDTH) {
if (flexItemProps.basis.width.type == Width::Type::VALUE) {
flexBaseSize = resolve(
tree,
*box,
flexItemProps.basis.width.value,
mainContainerSize
);
} else if (flexItemProps.basis.width.type == Width::Type::AUTO) {
flexBaseSize = fa.mainAxis(speculativeSize);
}
}
// A NONE return here indicates a CONTENT case for the flex basis
auto getDefiniteFlexBasisSize = [](FlexProps &flexItemProps, FlexAxis &fa, Box *box) -> Opt<CalcValue<PercentOr<Length>>> {
if (flexItemProps.basis.type != FlexBasis::WIDTH)
return NONE;

if (flexItemProps.basis.type == FlexBasis::Type::CONTENT and
box->style->sizing->height.type == Size::Type::LENGTH /* and
intrinsic aspect ratio*/
) {
// TODO: placehold value, check specs
Px aspectRatio{1};
auto crossSize = resolve(tree, *box, box->style->sizing->height.value, 0_px);
flexBaseSize = (crossSize)*aspectRatio;
}
if (flexItemProps.basis.width.type == Width::Type::VALUE)
return flexItemProps.basis.width.value;

if (fa.mainAxis(box->style->sizing).type == Size::Type::AUTO)
return NONE;

if (false) {
// TODO: other flex base size cases
logWarn("not implemented flex base size case");
return fa.mainAxis(box->style->sizing).value;
};

if (auto flexBasisDefiniteSize = getDefiniteFlexBasisSize(flexItemProps, fa, box)) {
flexBaseSize = resolve(
tree,
*box,
flexBasisDefiniteSize.unwrap(),
mainContainerSize
);
return;
}

// TODO:
// https://www.w3.org/TR/css-flexbox-1/#algo-main-item
// - intrinsic aspect ratio case
// - what does it mean: "depends on its available space"?
flexBaseSize = fa.mainAxis(maxContentSize);
}

void computeHypotheticalMainSize(Tree &tree, Vec2Px containerSize) {
Expand All @@ -280,6 +282,43 @@ struct FlexItem {
);
}

// https://www.w3.org/TR/css-flexbox-1/#min-size-auto
Px getMinAutoPrefMainSize(Tree &tree, Vec2Px containerSize) const {

Opt<Px> definiteMaxMainSize;
auto maxMainSize = box->style->sizing->maxSize(fa.isRowOriented ? Axis::HORIZONTAL : Axis::VERTICAL);
if (maxMainSize.type == Size::Type::LENGTH) {
definiteMaxMainSize = resolve(
tree,
*box,
maxMainSize.value,
fa.mainAxis(containerSize)
);
}

Px contentSizeSuggestion = fa.mainAxis(minContentSize);
// TODO: clamped by cross size if there is an aspect ratio
if (definiteMaxMainSize)
contentSizeSuggestion = min(contentSizeSuggestion, definiteMaxMainSize.unwrap());

if (fa.mainAxis(box->style->sizing).type == Size::Type::LENGTH) {
Px specifiedSizeSuggestion = resolve(
tree,
*box,
fa.mainAxis(box->style->sizing).value,
fa.mainAxis(containerSize)
);

if (definiteMaxMainSize)
specifiedSizeSuggestion = min(specifiedSizeSuggestion, definiteMaxMainSize.unwrap());

return min(contentSizeSuggestion, specifiedSizeSuggestion);
// TODO: else if(aspect ratio)
} else {
return contentSizeSuggestion;
}
}

Px getMinMaxPrefferedSize(Tree &tree, bool isWidth, bool isMin, Vec2Px containerSize) const {
Size sizeToResolve;
if (isWidth and isMin)
Expand Down Expand Up @@ -308,27 +347,13 @@ struct FlexItem {
case Size::FIT_CONTENT:
logWarn("not implemented");
case Size::AUTO:
if (isMin) {
// https://www.w3.org/TR/css-flexbox-1/#min-size-auto
Size specifiedSizeToResolve{isWidth ? box->style->sizing->width : box->style->sizing->height};

if (specifiedSizeToResolve.type == Size::Type::LENGTH) {
auto resolvedSpecifiedSize = resolve(
tree,
*box,
specifiedSizeToResolve.value,
isWidth
? containerSize.x
: containerSize.y
);
return min(resolvedSpecifiedSize, isWidth ? minContentSize.x : minContentSize.y);
} else {
return isWidth ? minContentSize.x : minContentSize.y;
}

} else {
if (not isMin)
panic("AUTO is an invalid value for max-width");
}

// used cross min sizes are resolved to 0 whereas main sizes have specific method
return isWidth == fa.isRowOriented
? getMinAutoPrefMainSize(tree, containerSize)
: 0_px;
case Size::NONE:
if (isMin)
panic("NONE is an invalid value for min-width");
Expand Down Expand Up @@ -1043,8 +1068,6 @@ struct FlexFormatingContext {
.availableSpace = fa.extractMainAxisAndFillOther(i.usedSize, availableCrossSpace),
}
);

// COMO PODE EU TER UM HEIGHT PEQUENO AQUI??????????
}
}

Expand Down Expand Up @@ -1136,7 +1159,7 @@ struct FlexFormatingContext {
void _handleAlignContentStretch(Input input, Box &box) {
// FIXME: If the flex container has a definite cross size <=?=> f.style->sizing->height.type != Size::Type::AUTO
if (
(not(input.intrinsic == IntrinsicSize::MIN_CONTENT) and true) and
not(input.intrinsic == IntrinsicSize::MIN_CONTENT) and
(fa.crossAxis(box.style->sizing).type != Size::Type::AUTO or fa.crossAxis(input.knownSize)) and
box.style->aligns.alignContent == Style::Align::STRETCH
) {
Expand Down

0 comments on commit 70050f9

Please sign in to comment.