Skip to content

Commit 1dc93c7

Browse files
committed
Take epsilon into account while deciding whether a cell of a fixed height sgould be split.
Float are compared there without any epsilon value, which may cause issues because of float precision inaccuracy. DEVSIX-3848
1 parent 42962d3 commit 1dc93c7

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,10 @@ AbstractRenderer applyMinHeight(OverflowPropertyValue overflowY, Rectangle layou
820820
if (isFixedLayout()) {
821821
occupiedArea.getBBox().setY(blockBottom).setHeight((float) blockMinHeight);
822822
} else {
823-
if (isOverflowFit(overflowY) && blockBottom < layoutBox.getBottom()) {
823+
// Because of float precision inaccuracy, iText can incorrectly calculate that the block of fixed height
824+
// needs to be split. As a result, an empty block with a height equal to sum of paddings
825+
// may appear on the next area. To prevent such situations epsilon is used.
826+
if (isOverflowFit(overflowY) && blockBottom + EPS < layoutBox.getBottom()) {
824827
float hDelta = occupiedArea.getBBox().getBottom() - layoutBox.getBottom();
825828
occupiedArea.getBBox()
826829
.increaseHeight(hDelta)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.itextpdf.layout.renderer;
2+
3+
import com.itextpdf.kernel.geom.Rectangle;
4+
import com.itextpdf.layout.element.Div;
5+
import com.itextpdf.layout.layout.LayoutArea;
6+
import com.itextpdf.layout.property.OverflowPropertyValue;
7+
import com.itextpdf.layout.property.UnitValue;
8+
import com.itextpdf.test.ExtendedITextTest;
9+
import com.itextpdf.test.annotations.type.IntegrationTest;
10+
11+
import org.junit.Assert;
12+
import org.junit.Test;
13+
import org.junit.experimental.categories.Category;
14+
15+
@Category(IntegrationTest.class)
16+
public class BlockRendererTest extends ExtendedITextTest {
17+
18+
@Test
19+
public void applyMinHeightForSpecificDimensionsCausingFloatPrecisionError () {
20+
float divHeight = 42.55f;
21+
22+
Div div = new Div();
23+
div.setHeight(UnitValue.createPointValue(divHeight));
24+
25+
float occupiedHeight = 17.981995f;
26+
float leftHeight = 24.567993f;
27+
28+
Assert.assertTrue(occupiedHeight + leftHeight < divHeight);
29+
30+
BlockRenderer blockRenderer = (BlockRenderer) div.createRendererSubTree();
31+
blockRenderer.occupiedArea = new LayoutArea(1, new Rectangle(0, 267.9681f, 0, occupiedHeight));
32+
AbstractRenderer renderer = blockRenderer.applyMinHeight(OverflowPropertyValue.FIT,
33+
new Rectangle(0, 243.40012f, 0, leftHeight));
34+
Assert.assertNull(renderer);
35+
}
36+
}

0 commit comments

Comments
 (0)