@@ -44,6 +44,7 @@ This file is part of the iText (R) project.
44
44
package com .itextpdf .layout .renderer ;
45
45
46
46
import com .itextpdf .io .LogMessageConstant ;
47
+ import com .itextpdf .io .util .MessageFormatUtil ;
47
48
import com .itextpdf .kernel .geom .Rectangle ;
48
49
import com .itextpdf .layout .layout .LayoutArea ;
49
50
import com .itextpdf .layout .layout .LayoutContext ;
@@ -57,7 +58,6 @@ This file is part of the iText (R) project.
57
58
import org .slf4j .Logger ;
58
59
import org .slf4j .LoggerFactory ;
59
60
60
- import com .itextpdf .io .util .MessageFormatUtil ;
61
61
import java .util .ArrayList ;
62
62
import java .util .List ;
63
63
@@ -72,6 +72,7 @@ public abstract class RootRenderer extends AbstractRenderer {
72
72
private MarginsCollapseHandler marginsCollapseHandler ;
73
73
private LayoutArea initialCurrentArea ;
74
74
private List <Rectangle > floatRendererAreas ;
75
+ private List <IRenderer > waitingNextPageRenderers = new ArrayList <>();
75
76
76
77
public void addChild (IRenderer renderer ) {
77
78
// Some positioned renderers might have been fetched from non-positioned child and added to this renderer,
@@ -99,7 +100,7 @@ public void addChild(IRenderer renderer) {
99
100
}
100
101
101
102
// Static layout
102
- for (int i = 0 ; currentArea != null && i < addedRenderers .size (); i ++) {
103
+ for (int i = 0 ; currentArea != null && i < addedRenderers .size (); i ++) {
103
104
renderer = addedRenderers .get (i );
104
105
105
106
processWaitingKeepWithNextElement (renderer );
@@ -113,11 +114,15 @@ public void addChild(IRenderer renderer) {
113
114
if (marginsCollapsingEnabled && currentArea != null && renderer != null ) {
114
115
childMarginsInfo = marginsCollapseHandler .startChildMarginsHandling (renderer , currentArea .getBBox ());
115
116
}
117
+ boolean rendererIsFloat = FloatingHelper .isRendererFloating (renderer );
116
118
while (currentArea != null && renderer != null && (result = renderer .setParent (this ).layout (
117
119
new LayoutContext (currentArea .clone (), childMarginsInfo , floatRendererAreas )))
118
120
.getStatus () != LayoutResult .FULL ) {
119
121
if (result .getStatus () == LayoutResult .PARTIAL ) {
120
- if (result .getOverflowRenderer () instanceof ImageRenderer ) {
122
+ if (rendererIsFloat ) {
123
+ waitingNextPageRenderers .add (result .getOverflowRenderer ());
124
+ break ;
125
+ } else if (result .getOverflowRenderer () instanceof ImageRenderer ) {
121
126
((ImageRenderer ) result .getOverflowRenderer ()).autoScale (currentArea );
122
127
} else {
123
128
processRenderer (result .getSplitRenderer (), resultRenderers );
@@ -131,13 +136,18 @@ public void addChild(IRenderer renderer) {
131
136
}
132
137
} else if (result .getStatus () == LayoutResult .NOTHING ) {
133
138
if (result .getOverflowRenderer () instanceof ImageRenderer ) {
134
- if (currentArea .getBBox ().getHeight () < ((ImageRenderer ) result .getOverflowRenderer ()).imageHeight && !currentArea .isEmptyArea ()) {
139
+ if (currentArea .getBBox ().getHeight () < ((ImageRenderer ) result .getOverflowRenderer ()).getOccupiedArea ().getBBox ().getHeight () && !currentArea .isEmptyArea ()) {
140
+ if (rendererIsFloat ) {
141
+ waitingNextPageRenderers .add (result .getOverflowRenderer ());
142
+ break ;
143
+ }
135
144
updateCurrentAndInitialArea (result );
145
+ } else {
146
+ ((ImageRenderer ) result .getOverflowRenderer ()).autoScale (currentArea );
147
+ result .getOverflowRenderer ().setProperty (Property .FORCED_PLACEMENT , true );
148
+ Logger logger = LoggerFactory .getLogger (RootRenderer .class );
149
+ logger .warn (MessageFormatUtil .format (LogMessageConstant .ELEMENT_DOES_NOT_FIT_AREA , "" ));
136
150
}
137
- ((ImageRenderer )result .getOverflowRenderer ()).autoScale (currentArea );
138
- result .getOverflowRenderer ().setProperty (Property .FORCED_PLACEMENT , true );
139
- Logger logger = LoggerFactory .getLogger (RootRenderer .class );
140
- logger .warn (MessageFormatUtil .format (LogMessageConstant .ELEMENT_DOES_NOT_FIT_AREA , "" ));
141
151
} else {
142
152
if (currentArea .isEmptyArea () && result .getAreaBreak () == null ) {
143
153
if (Boolean .TRUE .equals (result .getOverflowRenderer ().getModelElement ().<Boolean >getProperty (Property .KEEP_TOGETHER ))) {
@@ -172,11 +182,16 @@ public void addChild(IRenderer renderer) {
172
182
currentPageNumber = nextStoredArea .getPageNumber ();
173
183
nextStoredArea = null ;
174
184
} else {
185
+ if (rendererIsFloat ) {
186
+ waitingNextPageRenderers .add (result .getOverflowRenderer ());
187
+ break ;
188
+ }
175
189
updateCurrentAndInitialArea (result );
176
190
}
177
191
}
178
192
}
179
193
}
194
+
180
195
renderer = result .getOverflowRenderer ();
181
196
182
197
if (marginsCollapsingEnabled ) {
@@ -260,6 +275,7 @@ public void flush() {
260
275
* and when no consequent element has been added. This method addresses such situations.
261
276
*/
262
277
public void close () {
278
+ addAllWaitingNextPageRenderers ();
263
279
if (keepWithNextHangingRenderer != null ) {
264
280
keepWithNextHangingRenderer .setProperty (Property .KEEP_WITH_NEXT , false );
265
281
IRenderer rendererToBeAdded = keepWithNextHangingRenderer ;
@@ -303,7 +319,7 @@ protected void shrinkCurrentAreaAndProcessRenderer(IRenderer renderer, List<IRen
303
319
if (currentArea != null ) {
304
320
float resultRendererHeight = result .getOccupiedArea ().getBBox ().getHeight ();
305
321
currentArea .getBBox ().setHeight (currentArea .getBBox ().getHeight () - resultRendererHeight );
306
- if (currentArea .isEmptyArea () && resultRendererHeight > 0 ) {
322
+ if (currentArea .isEmptyArea () && ( resultRendererHeight > 0 || FloatingHelper . isRendererFloating ( renderer )) ) {
307
323
currentArea .setEmptyArea (false );
308
324
}
309
325
processRenderer (renderer , resultRenderers );
@@ -402,5 +418,25 @@ private void updateCurrentAndInitialArea(LayoutResult overflowResult) {
402
418
floatRendererAreas = new ArrayList <>();
403
419
updateCurrentArea (overflowResult );
404
420
initialCurrentArea = currentArea == null ? null : currentArea .clone ();
421
+ // TODO how bout currentArea == null ?
422
+ addWaitingNextPageRenderers ();
423
+ }
424
+
425
+ private void addAllWaitingNextPageRenderers () {
426
+ boolean marginsCollapsingEnabled = Boolean .TRUE .equals (getPropertyAsBoolean (Property .COLLAPSING_MARGINS ));
427
+ while (!waitingNextPageRenderers .isEmpty ()) {
428
+ if (marginsCollapsingEnabled ) {
429
+ marginsCollapseHandler = new MarginsCollapseHandler (this , null );
430
+ }
431
+ updateCurrentAndInitialArea (null );
432
+ }
433
+ }
434
+
435
+ private void addWaitingNextPageRenderers () {
436
+ List <IRenderer > waitingFloatRenderers = new ArrayList <>(waitingNextPageRenderers );
437
+ waitingNextPageRenderers .clear ();
438
+ for (IRenderer renderer : waitingFloatRenderers ) {
439
+ addChild (renderer );
440
+ }
405
441
}
406
442
}
0 commit comments