Add aspectRatio style property
Summary: Implement aspect ratio as part of Yoga. Aspect ratio allows users of the library to specify the size of the undefined dimension in terms of an aspect ratio. See test cases for examples. Reviewed By: gkassabli Differential Revision: D4211458 fbshipit-source-id: f8d0d318369c7b529ee29e61a52b17d0cf3b396d
This commit is contained in:
committed by
Facebook Github Bot
parent
b16c22a8f3
commit
55fc795686
@@ -85,6 +85,9 @@ typedef struct CSSStyle {
|
||||
float dimensions[2];
|
||||
float minDimensions[2];
|
||||
float maxDimensions[2];
|
||||
|
||||
// Yoga specific properties, not compatible with flexbox specification
|
||||
float aspectRatio;
|
||||
} CSSStyle;
|
||||
|
||||
typedef struct CSSNode {
|
||||
@@ -269,6 +272,8 @@ void CSSNodeInit(const CSSNodeRef node) {
|
||||
node->style.border[edge] = CSSUndefined;
|
||||
}
|
||||
|
||||
node->style.aspectRatio = CSSUndefined;
|
||||
|
||||
node->layout.dimensions[CSSDimensionWidth] = CSSUndefined;
|
||||
node->layout.dimensions[CSSDimensionHeight] = CSSUndefined;
|
||||
|
||||
@@ -459,6 +464,9 @@ CSS_NODE_STYLE_PROPERTY_IMPL(float, MinHeight, minHeight, minDimensions[CSSDimen
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MaxWidth, maxWidth, maxDimensions[CSSDimensionWidth]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MaxHeight, maxHeight, maxDimensions[CSSDimensionHeight]);
|
||||
|
||||
// Yoga specific properties, not compatible with flexbox specification
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, AspectRatio, aspectRatio, aspectRatio);
|
||||
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Left, position[CSSEdgeLeft]);
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Top, position[CSSEdgeTop]);
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Right, position[CSSEdgeRight]);
|
||||
@@ -1032,6 +1040,20 @@ static void computeChildFlexBasis(const CSSNodeRef node,
|
||||
childHeightMeasureMode = CSSMeasureModeExactly;
|
||||
}
|
||||
|
||||
if (!CSSValueIsUndefined(child->style.aspectRatio)) {
|
||||
if (!isMainAxisRow && childWidthMeasureMode == CSSMeasureModeExactly) {
|
||||
child->layout.computedFlexBasis =
|
||||
fmaxf(childWidth * child->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(child, CSSFlexDirectionColumn));
|
||||
return;
|
||||
} else if (isMainAxisRow && childHeightMeasureMode == CSSMeasureModeExactly) {
|
||||
child->layout.computedFlexBasis =
|
||||
fmaxf(childHeight * child->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(child, CSSFlexDirectionRow));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
constrainMaxSizeForMode(child->style.maxDimensions[CSSDimensionWidth],
|
||||
&childWidthMeasureMode,
|
||||
&childWidth);
|
||||
@@ -1108,6 +1130,20 @@ static void absoluteLayoutChild(const CSSNodeRef node,
|
||||
}
|
||||
}
|
||||
|
||||
// Exactly one dimension needs to be defined for us to be able to do aspect ratio
|
||||
// calculation. One dimension being the anchor and the other being flexible.
|
||||
if (CSSValueIsUndefined(childWidth) ^ CSSValueIsUndefined(childHeight)) {
|
||||
if (!CSSValueIsUndefined(child->style.aspectRatio)) {
|
||||
if (CSSValueIsUndefined(childWidth)) {
|
||||
childWidth = fmaxf(childHeight * child->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(child, CSSFlexDirectionColumn));
|
||||
} else if (CSSValueIsUndefined(childHeight)) {
|
||||
childHeight = fmaxf(childWidth * child->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(child, CSSFlexDirectionRow));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we're still missing one or the other dimension, measure the content.
|
||||
if (CSSValueIsUndefined(childWidth) || CSSValueIsUndefined(childHeight)) {
|
||||
childWidthMeasureMode =
|
||||
@@ -1774,6 +1810,19 @@ static void layoutNodeImpl(const CSSNodeRef node,
|
||||
}
|
||||
}
|
||||
|
||||
if (!CSSValueIsUndefined(currentRelativeChild->style.aspectRatio)) {
|
||||
if (isMainAxisRow && childHeightMeasureMode != CSSMeasureModeExactly) {
|
||||
childHeight =
|
||||
fmaxf(childWidth * currentRelativeChild->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(currentRelativeChild, CSSFlexDirectionColumn));
|
||||
childHeightMeasureMode = CSSMeasureModeExactly;
|
||||
} else if (!isMainAxisRow && childWidthMeasureMode != CSSMeasureModeExactly) {
|
||||
childWidth = fmaxf(childHeight * currentRelativeChild->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(currentRelativeChild, CSSFlexDirectionRow));
|
||||
childWidthMeasureMode = CSSMeasureModeExactly;
|
||||
}
|
||||
}
|
||||
|
||||
constrainMaxSizeForMode(currentRelativeChild->style.maxDimensions[CSSDimensionWidth],
|
||||
&childWidthMeasureMode,
|
||||
&childWidth);
|
||||
|
Reference in New Issue
Block a user