@@ -44,6 +44,7 @@ This file is part of the iText (R) project.
4444package com .itextpdf .layout .renderer ;
4545
4646import com .itextpdf .io .LogMessageConstant ;
47+ import com .itextpdf .io .util .MessageFormatUtil ;
4748import com .itextpdf .kernel .geom .Rectangle ;
4849import com .itextpdf .layout .layout .LayoutArea ;
4950import com .itextpdf .layout .layout .LayoutContext ;
@@ -57,7 +58,6 @@ This file is part of the iText (R) project.
5758import org .slf4j .Logger ;
5859import org .slf4j .LoggerFactory ;
5960
60- import com .itextpdf .io .util .MessageFormatUtil ;
6161import java .util .ArrayList ;
6262import java .util .List ;
6363
@@ -72,6 +72,7 @@ public abstract class RootRenderer extends AbstractRenderer {
7272 private MarginsCollapseHandler marginsCollapseHandler ;
7373 private LayoutArea initialCurrentArea ;
7474 private List <Rectangle > floatRendererAreas ;
75+ private List <IRenderer > waitingNextPageRenderers = new ArrayList <>();
7576
7677 public void addChild (IRenderer renderer ) {
7778 // 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) {
99100 }
100101
101102 // Static layout
102- for (int i = 0 ; currentArea != null && i < addedRenderers .size (); i ++) {
103+ for (int i = 0 ; currentArea != null && i < addedRenderers .size (); i ++) {
103104 renderer = addedRenderers .get (i );
104105
105106 processWaitingKeepWithNextElement (renderer );
@@ -113,11 +114,15 @@ public void addChild(IRenderer renderer) {
113114 if (marginsCollapsingEnabled && currentArea != null && renderer != null ) {
114115 childMarginsInfo = marginsCollapseHandler .startChildMarginsHandling (renderer , currentArea .getBBox ());
115116 }
117+ boolean rendererIsFloat = FloatingHelper .isRendererFloating (renderer );
116118 while (currentArea != null && renderer != null && (result = renderer .setParent (this ).layout (
117119 new LayoutContext (currentArea .clone (), childMarginsInfo , floatRendererAreas )))
118120 .getStatus () != LayoutResult .FULL ) {
119121 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 ) {
121126 ((ImageRenderer ) result .getOverflowRenderer ()).autoScale (currentArea );
122127 } else {
123128 processRenderer (result .getSplitRenderer (), resultRenderers );
@@ -131,13 +136,18 @@ public void addChild(IRenderer renderer) {
131136 }
132137 } else if (result .getStatus () == LayoutResult .NOTHING ) {
133138 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+ }
135144 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 , "" ));
136150 }
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 , "" ));
141151 } else {
142152 if (currentArea .isEmptyArea () && result .getAreaBreak () == null ) {
143153 if (Boolean .TRUE .equals (result .getOverflowRenderer ().getModelElement ().<Boolean >getProperty (Property .KEEP_TOGETHER ))) {
@@ -172,11 +182,16 @@ public void addChild(IRenderer renderer) {
172182 currentPageNumber = nextStoredArea .getPageNumber ();
173183 nextStoredArea = null ;
174184 } else {
185+ if (rendererIsFloat ) {
186+ waitingNextPageRenderers .add (result .getOverflowRenderer ());
187+ break ;
188+ }
175189 updateCurrentAndInitialArea (result );
176190 }
177191 }
178192 }
179193 }
194+
180195 renderer = result .getOverflowRenderer ();
181196
182197 if (marginsCollapsingEnabled ) {
@@ -260,6 +275,7 @@ public void flush() {
260275 * and when no consequent element has been added. This method addresses such situations.
261276 */
262277 public void close () {
278+ addAllWaitingNextPageRenderers ();
263279 if (keepWithNextHangingRenderer != null ) {
264280 keepWithNextHangingRenderer .setProperty (Property .KEEP_WITH_NEXT , false );
265281 IRenderer rendererToBeAdded = keepWithNextHangingRenderer ;
@@ -303,7 +319,7 @@ protected void shrinkCurrentAreaAndProcessRenderer(IRenderer renderer, List<IRen
303319 if (currentArea != null ) {
304320 float resultRendererHeight = result .getOccupiedArea ().getBBox ().getHeight ();
305321 currentArea .getBBox ().setHeight (currentArea .getBBox ().getHeight () - resultRendererHeight );
306- if (currentArea .isEmptyArea () && resultRendererHeight > 0 ) {
322+ if (currentArea .isEmptyArea () && ( resultRendererHeight > 0 || FloatingHelper . isRendererFloating ( renderer )) ) {
307323 currentArea .setEmptyArea (false );
308324 }
309325 processRenderer (renderer , resultRenderers );
@@ -402,5 +418,25 @@ private void updateCurrentAndInitialArea(LayoutResult overflowResult) {
402418 floatRendererAreas = new ArrayList <>();
403419 updateCurrentArea (overflowResult );
404420 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+ }
405441 }
406442}
0 commit comments