Skip to content

Commit 90f44ff

Browse files
Implement float elements splitting
DEVSIX-1267
1 parent 5e52d4d commit 90f44ff

File tree

9 files changed

+185
-40
lines changed

9 files changed

+185
-40
lines changed

layout/src/main/java/com/itextpdf/layout/margincollapse/MarginsCollapseHandler.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@ public void endMarginsCollapse(Rectangle layoutBox) {
240240
boolean lastChildMarginJoinedToParent = prevChildMarginInfo != null && prevChildMarginInfo.isIgnoreOwnMarginBottom() && !lastKidCollapsedAfterHasClearanceApplied;
241241
if (lastChildMarginJoinedToParent) {
242242
ownCollapseAfter = prevChildMarginInfo.getOwnCollapseAfter();
243+
if (ownCollapseAfter == null) {
244+
ownCollapseAfter = new MarginsCollapse();
245+
}
243246
} else {
244247
ownCollapseAfter = new MarginsCollapse();
245248
}

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -538,23 +538,17 @@ public void drawBackground(DrawContext drawContext) {
538538
* @param drawContext the context (canvas, document, etc) of this drawing operation.
539539
*/
540540
public void drawChildren(DrawContext drawContext) {
541-
List<IRenderer> waitingRenderers = new ArrayList<>();
542541
for (IRenderer child : childRenderers) {
543542
if (FloatingHelper.isRendererFloating(child)) {
544543
RootRenderer rootRenderer = getRootRenderer();
545544
if (rootRenderer != null) {
546545
rootRenderer.waitingDrawingElements.add(child);
547546
child.setProperty(Property.FLOAT, null);
548-
} else {
549-
waitingRenderers.add(child);
550547
}
551548
} else {
552549
child.draw(drawContext);
553550
}
554551
}
555-
for (IRenderer waitingRenderer : waitingRenderers) {
556-
waitingRenderer.draw(drawContext);
557-
}
558552
}
559553

560554
/**

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

Lines changed: 116 additions & 29 deletions
Large diffs are not rendered by default.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
122122
applyBorderBox(layoutBox, borders, false);
123123

124124
if (isAbsolutePosition()) {
125+
// TODO applying it after floats processing here and everywhere. is it correct?
125126
applyAbsolutePosition(layoutBox);
126127
}
127128

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

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ This file is part of the iText (R) project.
5050
import com.itextpdf.layout.layout.*;
5151
import com.itextpdf.layout.margincollapse.MarginsCollapseHandler;
5252
import com.itextpdf.layout.minmaxwidth.MinMaxWidth;
53-
import com.itextpdf.layout.property.*;
53+
import com.itextpdf.layout.property.FloatPropertyValue;
54+
import com.itextpdf.layout.property.Leading;
55+
import com.itextpdf.layout.property.Property;
56+
import com.itextpdf.layout.property.TextAlignment;
5457
import org.slf4j.Logger;
5558
import org.slf4j.LoggerFactory;
5659

@@ -181,6 +184,38 @@ public LayoutResult layout(LayoutContext layoutContext) {
181184
float childBBoxWidth = layoutBox.getWidth() - lineIndent;
182185
Rectangle childLayoutBox = new Rectangle(layoutBox.getX() + lineIndent, layoutBox.getY(), childBBoxWidth, layoutBox.getHeight());
183186

187+
// if (childAffectedByFloat) {
188+
// currentRenderer.layout(new LayoutContext(new LayoutArea(pageNumber, childLayoutBox), layoutContext.getMarginsCollapseInfo(), floatRendererAreas));
189+
// float bottom = currentRenderer.getOccupiedArea().getBBox().getBottom();
190+
// float top = currentRenderer.getOccupiedArea().getBBox().getTop();
191+
// float left = currentRenderer.getOccupiedArea().getBBox().getLeft();
192+
// float right = currentRenderer.getOccupiedArea().getBBox().getRight();
193+
// boolean childLayoutBoxWasAdjusted;
194+
// float rightBorder = childLayoutBox.getRight();
195+
// float curRendWidth = currentRenderer.getOccupiedAreaBBox().getWidth();
196+
// do {
197+
// childLayoutBoxWasAdjusted = false;
198+
// for (Rectangle floatRendereArea : floatRendererAreas) {
199+
// if ((bottom > floatRendereArea.getBottom() && bottom < floatRendereArea.getTop()) || (top > floatRendereArea.getBottom() && top < floatRendereArea.getTop())) {
200+
// if ((left >= floatRendereArea.getLeft() && left < floatRendereArea.getRight()) ||
201+
// (right > floatRendereArea.getLeft() && right < floatRendereArea.getRight()) ||
202+
// (left > floatRendereArea.getLeft() && right < floatRendereArea.getRight())) {
203+
// childLayoutBox.setX(floatRendereArea.getRight());
204+
//
205+
//
206+
// if (childLayoutBox.getLeft() + curRendWidth > rightBorder) {
207+
// childLayoutBox.setWidth(rightBorder - childLayoutBox.getLeft());
208+
// } else {
209+
// childLayoutBox.setWidth(curRendWidth);
210+
// }
211+
// left = childLayoutBox.getLeft();
212+
// right = childLayoutBox.getRight();
213+
// childLayoutBoxWasAdjusted = true;
214+
// }
215+
// }
216+
// }
217+
// } while(childLayoutBoxWasAdjusted);
218+
// }
184219
LineLayoutResult result = ((LineRenderer) currentRenderer.setParent(this)).layout(new LayoutContext(
185220
new LayoutArea(pageNumber, childLayoutBox), null,
186221
floatRendererAreas));

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

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ This file is part of the iText (R) project.
5151
import com.itextpdf.layout.layout.LayoutResult;
5252
import com.itextpdf.layout.margincollapse.MarginsCollapseHandler;
5353
import com.itextpdf.layout.margincollapse.MarginsCollapseInfo;
54+
import com.itextpdf.layout.property.FloatPropertyValue;
5455
import com.itextpdf.layout.property.Property;
5556
import org.slf4j.Logger;
5657
import org.slf4j.LoggerFactory;
@@ -70,6 +71,7 @@ public abstract class RootRenderer extends AbstractRenderer {
7071
private MarginsCollapseHandler marginsCollapseHandler;
7172
private LayoutArea initialCurrentArea;
7273
private List<Rectangle> floatRendererAreas;
74+
private List<IRenderer> waitingRenderers = new ArrayList<>();
7375

7476
public void addChild(IRenderer renderer) {
7577
// Some positioned renderers might have been fetched from non-positioned child and added to this renderer,
@@ -78,6 +80,10 @@ public void addChild(IRenderer renderer) {
7880
int numberOfPositionedChildRenderers = positionedRenderers.size();
7981
super.addChild(renderer);
8082
List<IRenderer> addedRenderers = new ArrayList<>(1);
83+
if (currentArea != null && currentArea.getPageNumber() > 1) {
84+
addedRenderers.addAll(waitingRenderers);
85+
waitingRenderers.clear();
86+
}
8187
List<IRenderer> addedPositionedRenderers = new ArrayList<>(1);
8288
while (childRenderers.size() > numberOfChildRenderers) {
8389
addedRenderers.add(childRenderers.get(numberOfChildRenderers));
@@ -97,7 +103,7 @@ public void addChild(IRenderer renderer) {
97103
}
98104

99105
// Static layout
100-
for (int i = 0; currentArea != null && i < addedRenderers.size(); i++) {
106+
for (int i = 0, l = addedRenderers.size(); currentArea != null && i < l; i++) {
101107
renderer = addedRenderers.get(i);
102108

103109
processWaitingKeepWithNextElement(renderer);
@@ -111,11 +117,15 @@ public void addChild(IRenderer renderer) {
111117
if (marginsCollapsingEnabled && currentArea != null && renderer != null) {
112118
childMarginsInfo = marginsCollapseHandler.startChildMarginsHandling(renderer, currentArea.getBBox());
113119
}
120+
FloatPropertyValue floatPropertyValue = renderer.getProperty(Property.FLOAT);
121+
boolean rendererIsFloat = floatPropertyValue != null && !floatPropertyValue.equals(FloatPropertyValue.NONE);
114122
while (currentArea != null && renderer != null && (result = renderer.setParent(this).layout(
115123
new LayoutContext(currentArea.clone(), childMarginsInfo, floatRendererAreas)))
116124
.getStatus() != LayoutResult.FULL) {
117125
if (result.getStatus() == LayoutResult.PARTIAL) {
118-
if (result.getOverflowRenderer() instanceof ImageRenderer) {
126+
if (rendererIsFloat) {
127+
waitingRenderers.add(result.getOverflowRenderer());
128+
} else if (result.getOverflowRenderer() instanceof ImageRenderer) {
119129
((ImageRenderer) result.getOverflowRenderer()).autoScale(currentArea);
120130
} else {
121131
processRenderer(result.getSplitRenderer(), resultRenderers);
@@ -175,7 +185,18 @@ public void addChild(IRenderer renderer) {
175185
}
176186
}
177187
}
178-
renderer = result.getOverflowRenderer();
188+
if (rendererIsFloat && result.getStatus() != LayoutResult.NOTHING) {
189+
renderer = null;
190+
continue;
191+
}
192+
if (!waitingRenderers.isEmpty()) {
193+
renderer = waitingRenderers.remove(0);
194+
addedRenderers.addAll(waitingRenderers);
195+
addedRenderers.add(result.getOverflowRenderer());
196+
l+= waitingRenderers.size() + 1;
197+
} else {
198+
renderer = result.getOverflowRenderer();
199+
}
179200

180201
if (marginsCollapsingEnabled) {
181202
marginsCollapseHandler.endChildMarginsHandling(currentArea.getBBox());

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,8 @@ public LayoutResult layout(LayoutContext layoutContext) {
336336
// if this is the last renderer, we will use that information to enlarge rows proportionally
337337
List<Boolean> rowsHasCellWithSetHeight = new ArrayList<>();
338338

339+
List<Rectangle> childFloatRendererAreas = new ArrayList<>();
339340
for (row = 0; row < rows.size(); row++) {
340-
List<Rectangle> childFloatRendererAreas = new ArrayList<>();
341341
// if forced placement was earlier set, this means the element did not fit into the area, and in this case
342342
// we only want to place the first row in a forced way, not the next ones, otherwise they will be invisible
343343
if (row == 1 && Boolean.TRUE.equals(this.<Boolean>getProperty(Property.FORCED_PLACEMENT))) {

layout/src/test/java/com/itextpdf/layout/FloatTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ public void floatDivTest02() throws IOException, InterruptedException {
224224
@Test
225225
@Ignore("block level floating elements page-overflow and splitting not supported yet")
226226
public void floatDivTest03() throws IOException, InterruptedException {
227+
//
228+
// TODO probably we shouldn't review forced placement applying on floated elements
229+
// May be check if there are any floated elements already on page
230+
//
227231
String cmpFileName = sourceFolder + "cmp_floatDivTest03.pdf";
228232
String outFile = destinationFolder + "floatDivTest03.pdf";
229233

0 commit comments

Comments
 (0)