Skip to content

Commit f9386ff

Browse files
author
Dmitry Radchuk
committed
Fix flex cross size calculations for blocks
DEVSIX-8985
1 parent 4099ad7 commit f9386ff

File tree

6 files changed

+132
-6
lines changed

6 files changed

+132
-6
lines changed

layout/src/main/java/com/itextpdf/layout/minmaxwidth/MinMaxWidthUtils.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,40 @@ public static boolean isEqual(double x, double y) {
5555
return Math.abs(x - y) < eps;
5656
}
5757

58+
/**
59+
* Default implementation for min max width calculation.
60+
*
61+
* @param renderer renderer to calculate min max width for
62+
*
63+
* @return {@link MinMaxWidth} instance
64+
*/
5865
public static MinMaxWidth countDefaultMinMaxWidth(IRenderer renderer) {
5966
LayoutResult result = renderer.layout(new LayoutContext(new LayoutArea(1, new Rectangle(getInfWidth(), getInfHeight()))));
6067
return result.getStatus() == LayoutResult.NOTHING ? new MinMaxWidth() :
6168
new MinMaxWidth(0, result.getOccupiedArea().getBBox().getWidth(), 0);
6269
}
63-
70+
71+
/**
72+
* Default implementation for min max width calculation.
73+
*
74+
* @param renderer renderer to calculate min max width for
75+
* @param areaMaxWidth max available area for layout
76+
*
77+
* @return {@link MinMaxWidth} instance
78+
*/
79+
public static MinMaxWidth countDefaultMinMaxWidth(IRenderer renderer, float areaMaxWidth) {
80+
LayoutResult result = renderer.layout(new LayoutContext(new LayoutArea(1, new Rectangle(areaMaxWidth, getInfHeight()))));
81+
return result.getStatus() == LayoutResult.NOTHING ? new MinMaxWidth() :
82+
new MinMaxWidth(0, result.getOccupiedArea().getBBox().getWidth(), 0);
83+
}
84+
85+
/**
86+
* Get sum of left and right borders for the element.
87+
*
88+
* @param element element to calculate borders width for
89+
*
90+
* @return sum of left and right borders as {@code float}
91+
*/
6492
public static float getBorderWidth(IPropertyContainer element) {
6593
Border rightBorder = element.<Border>getProperty(Property.BORDER_RIGHT);
6694
Border leftBorder = element.<Border>getProperty(Property.BORDER_LEFT);
@@ -69,7 +97,14 @@ public static float getBorderWidth(IPropertyContainer element) {
6997
float leftBorderWidth = leftBorder != null ? leftBorder.getWidth() : 0;
7098
return rightBorderWidth + leftBorderWidth;
7199
}
72-
100+
101+
/**
102+
* Get sum of left and right margins for the element.
103+
*
104+
* @param element element to calculate margins width for
105+
*
106+
* @return sum of left and right margins as {@code float}
107+
*/
73108
public static float getMarginsWidth(IPropertyContainer element) {
74109
UnitValue rightMargin = element.<UnitValue>getProperty(Property.MARGIN_RIGHT);
75110
if (null != rightMargin && !rightMargin.isPointValue()) {
@@ -89,7 +124,14 @@ public static float getMarginsWidth(IPropertyContainer element) {
89124

90125
return rightMarginWidth + leftMarginWidth;
91126
}
92-
127+
128+
/**
129+
* Get sum of left and right paddings for the element.
130+
*
131+
* @param element element to calculate paddings width for
132+
*
133+
* @return sum of left and right paddings as {@code float}
134+
*/
93135
public static float getPaddingWidth(IPropertyContainer element) {
94136
UnitValue rightPadding = element.<UnitValue>getProperty(Property.PADDING_RIGHT);
95137
if (null != rightPadding && !rightPadding.isPointValue()) {

layout/src/main/java/com/itextpdf/layout/renderer/AbstractRenderer.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2174,6 +2174,17 @@ public MinMaxWidth getMinMaxWidth() {
21742174
return MinMaxWidthUtils.countDefaultMinMaxWidth(this);
21752175
}
21762176

2177+
/**
2178+
* Calculates min and max width values for current renderer.
2179+
*
2180+
* @param areaMaxWidth max width of the area on which current renderer will be laid out
2181+
*
2182+
* @return instance of {@link MinMaxWidth}
2183+
*/
2184+
public MinMaxWidth getMinMaxWidth(Float areaMaxWidth) {
2185+
return areaMaxWidth == null ? getMinMaxWidth() : MinMaxWidthUtils.countDefaultMinMaxWidth(this, areaMaxWidth);
2186+
}
2187+
21772188
protected boolean setMinMaxWidthBasedOnFixedWidth(MinMaxWidth minMaxWidth) {
21782189
// retrieve returns max width, if there is no width.
21792190
if (hasAbsoluteUnitValue(Property.WIDTH)) {

layout/src/main/java/com/itextpdf/layout/renderer/BlockRenderer.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,10 +1076,31 @@ void fixOccupiedAreaIfOverflowedY(OverflowPropertyValue overflowY, Rectangle lay
10761076
*/
10771077
@Override
10781078
public MinMaxWidth getMinMaxWidth() {
1079+
return getMinMaxWidth(null);
1080+
}
1081+
1082+
/**
1083+
* {@inheritDoc}
1084+
*/
1085+
@Override
1086+
public MinMaxWidth getMinMaxWidth(Float parentBoxWidth) {
10791087
MinMaxWidth minMaxWidth = new MinMaxWidth(calculateAdditionalWidth(this));
10801088
if (!setMinMaxWidthBasedOnFixedWidth(minMaxWidth)) {
1081-
Float minWidth = hasAbsoluteUnitValue(Property.MIN_WIDTH) ? retrieveMinWidth(0) : null;
1082-
Float maxWidth = hasAbsoluteUnitValue(Property.MAX_WIDTH) ? retrieveMaxWidth(0) : null;
1089+
Float minWidth;
1090+
Float maxWidth;
1091+
if (parentBoxWidth == null) {
1092+
minWidth = hasAbsoluteUnitValue(Property.MIN_WIDTH) ? retrieveMinWidth(0) : null;
1093+
maxWidth = hasAbsoluteUnitValue(Property.MAX_WIDTH) ? retrieveMaxWidth(0) : null;
1094+
} else {
1095+
minWidth = retrieveMinWidth(parentBoxWidth);
1096+
if (minWidth == null) {
1097+
minWidth = retrieveUnitValue(parentBoxWidth, Property.WIDTH);
1098+
}
1099+
maxWidth = retrieveMaxWidth(parentBoxWidth);
1100+
if (maxWidth == null) {
1101+
maxWidth = retrieveUnitValue(parentBoxWidth, Property.WIDTH);
1102+
}
1103+
}
10831104
if (minWidth == null || maxWidth == null) {
10841105
AbstractWidthHandler handler = new MaxMaxWidthHandler(minMaxWidth);
10851106
int epsilonNum = 0;

layout/src/main/java/com/itextpdf/layout/renderer/FlexUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ private static void determineHypotheticalCrossSizeForFlexItem(FlexItemCalculatio
667667
info.hypotheticalCrossSize = ((FlexContainerRenderer) info.renderer)
668668
.getHypotheticalCrossSize(info.mainSize).floatValue();
669669
} else if (isColumnDirection) {
670-
MinMaxWidth minMaxWidth = info.renderer.getMinMaxWidth();
670+
MinMaxWidth minMaxWidth = info.renderer.getMinMaxWidth(crossSize);
671671
info.hypotheticalCrossSize = info.getInnerCrossSize(
672672
Math.max(Math.min(minMaxWidth.getMaxWidth(), crossSize), minMaxWidth.getMinWidth()));
673673
// Cache hypotheticalCrossSize for FlexContainerRenderer

layout/src/test/java/com/itextpdf/layout/renderer/BlockRendererTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ This file is part of the iText (R) project.
3838
import com.itextpdf.layout.font.FontProvider;
3939
import com.itextpdf.layout.layout.LayoutArea;
4040
import com.itextpdf.layout.layout.LayoutPosition;
41+
import com.itextpdf.layout.minmaxwidth.MinMaxWidth;
4142
import com.itextpdf.layout.properties.OverflowPropertyValue;
4243
import com.itextpdf.layout.properties.Property;
4344
import com.itextpdf.layout.properties.UnitValue;
@@ -56,6 +57,7 @@ This file is part of the iText (R) project.
5657
@Tag("IntegrationTest")
5758
public class BlockRendererTest extends ExtendedITextTest {
5859

60+
private static final float EPS = 0.001f;
5961
public static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/layout/BlockRendererTest/";
6062
public static final String DESTINATION_FOLDER = TestUtil.getOutputPath() + "/layout/BlockRendererTest/";
6163

@@ -83,6 +85,34 @@ public void applyMinHeightForSpecificDimensionsCausingFloatPrecisionErrorTest()
8385
Assertions.assertNull(renderer);
8486
}
8587

88+
@Test
89+
public void relativeWidthInMinMaxWidthCalculationsTest() {
90+
Div div = new Div();
91+
div.setWidth(UnitValue.createPercentValue(42.5F));
92+
BlockRenderer divRenderer = (BlockRenderer) div.getRenderer();
93+
MinMaxWidth minMaxWidth = divRenderer.getMinMaxWidth(200.0F);
94+
Assertions.assertEquals(85.0F, minMaxWidth.getMaxWidth(), EPS);
95+
}
96+
97+
@Test
98+
public void relativeMaxWidthInMinMaxWidthCalculationsTest() {
99+
Div div = new Div();
100+
div.setProperty(Property.MAX_WIDTH, UnitValue.createPercentValue(42.5F));
101+
BlockRenderer divRenderer = (BlockRenderer) div.getRenderer();
102+
MinMaxWidth minMaxWidth = divRenderer.getMinMaxWidth(200.0F);
103+
Assertions.assertEquals(85.0F, minMaxWidth.getMaxWidth(), EPS);
104+
}
105+
106+
@Test
107+
public void relativeMinWidthInMinMaxWidthCalculationsTest() {
108+
Div div = new Div();
109+
div.setProperty(Property.MIN_WIDTH, UnitValue.createPercentValue(42.5F));
110+
BlockRenderer divRenderer = (BlockRenderer) div.getRenderer();
111+
MinMaxWidth minMaxWidth = divRenderer.getMinMaxWidth(200.0F);
112+
Assertions.assertEquals(85.0F, minMaxWidth.getMinWidth(), EPS);
113+
Assertions.assertEquals(85.0F, minMaxWidth.getMaxWidth(), EPS);
114+
}
115+
86116
@Test
87117
@LogMessages(messages = {
88118
@LogMessage(messageTemplate = IoLogMessageConstant.OCCUPIED_AREA_HAS_NOT_BEEN_INITIALIZED, count = 2,

layout/src/test/java/com/itextpdf/layout/renderer/FlexUtilTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ This file is part of the iText (R) project.
2525
import com.itextpdf.io.font.constants.StandardFontFamilies;
2626
import com.itextpdf.io.font.constants.StandardFonts;
2727
import com.itextpdf.io.image.ImageDataFactory;
28+
import com.itextpdf.kernel.colors.ColorConstants;
2829
import com.itextpdf.kernel.geom.PageSize;
2930
import com.itextpdf.kernel.geom.Rectangle;
3031
import com.itextpdf.kernel.pdf.PdfDocument;
@@ -109,6 +110,27 @@ public void defaultTest01() {
109110
}
110111
}
111112

113+
@Test
114+
public void simpleColumnDirectionTest() {
115+
Rectangle bBox = new Rectangle(545, 842);
116+
DocumentRenderer documentRenderer = new DocumentRenderer(
117+
new Document(new PdfDocument(new PdfWriter(new ByteArrayOutputStream()))));
118+
119+
Div div = new Div();
120+
FlexContainerRenderer flexContainerRenderer = new FlexContainerRenderer(div);
121+
flexContainerRenderer.setParent(documentRenderer);
122+
div.setNextRenderer(flexContainerRenderer);
123+
div.addStyle(COLUMN_STYLE);
124+
Div childDiv = new Div().setBackgroundColor(ColorConstants.RED).setWidth(UnitValue.createPercentValue(75));
125+
div.add(childDiv);
126+
flexContainerRenderer.addChild(childDiv.createRendererSubTree().setParent(flexContainerRenderer));
127+
128+
List<List<FlexItemInfo>> rectangleTable =
129+
FlexUtil.calculateChildrenRectangles(bBox, (FlexContainerRenderer) div.getRenderer());
130+
131+
Assertions.assertEquals(75.0F, rectangleTable.get(0).get(0).getRectangle().getWidth(), EPS);
132+
}
133+
112134
@Test
113135
public void item1BasisGtWidthGrow0Shrink01Test01() {
114136
Rectangle bBox = new Rectangle(545, 842);

0 commit comments

Comments
 (0)