Skip to content

Commit 0567773

Browse files
yulian-gaponenkoitext-teamcity
authored andcommitted
Fix issues with returned LayoutResult, split renderer children and RootRenderer float kids splitting
DEVSIX-1267 Autoported commit. Original commit hash: [8c807750e]
1 parent f41aba6 commit 0567773

File tree

4 files changed

+126
-107
lines changed

4 files changed

+126
-107
lines changed

itext/itext.layout/itext/layout/renderer/BlockRenderer.cs

Lines changed: 73 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ protected internal BlockRenderer(IElement modelElement)
6464

6565
public override LayoutResult Layout(LayoutContext layoutContext) {
6666
OverrideHeightProperties();
67+
IDictionary<int, IRenderer> waitingFloatsSplitRenderers = new LinkedDictionary<int, IRenderer>();
6768
IList<IRenderer> waitingOverflowFloatRenderers = new List<IRenderer>();
68-
IList<IRenderer> waitingSplitFloatRenderers = new List<IRenderer>();
6969
bool wasHeightClipped = false;
7070
int pageNumber = layoutContext.GetArea().GetPageNumber();
7171
bool isPositioned = IsPositioned();
@@ -137,19 +137,18 @@ public override LayoutResult Layout(LayoutContext layoutContext) {
137137
// the first renderer (one of childRenderers or their children) to produce LayoutResult.NOTHING
138138
IRenderer causeOfNothing = null;
139139
bool anythingPlaced = false;
140-
IList<IRenderer> ignoredChildRenderers = new List<IRenderer>();
141140
for (int childPos = 0; childPos < childRenderers.Count; childPos++) {
142141
IRenderer childRenderer = childRenderers[childPos];
143142
LayoutResult result;
144143
childRenderer.SetParent(this);
145144
MarginsCollapseInfo childMarginsInfo = null;
146-
if (!waitingOverflowFloatRenderers.IsEmpty() && FloatingHelper.IsFloatAffectedByClear(waitingOverflowFloatRenderers
147-
[waitingOverflowFloatRenderers.Count - 1].GetProperty<FloatPropertyValue?>(Property.FLOAT), childRenderer
148-
.GetProperty<ClearPropertyValue?>(Property.CLEAR))) {
149-
return SplitIfClearRendererIsPresentAfterFloatRendererWasSplitted(childPos, waitingSplitFloatRenderers, waitingOverflowFloatRenderers
145+
// TODO process correctly for floats with clear
146+
if (!waitingOverflowFloatRenderers.IsEmpty() && FloatingHelper.IsClearanceApplied(waitingOverflowFloatRenderers
147+
, childRenderer.GetProperty<ClearPropertyValue?>(Property.CLEAR))) {
148+
return SplitIfClearRendererIsPresentAfterFloatRendererWasSplit(childPos, waitingFloatsSplitRenderers, waitingOverflowFloatRenderers
150149
, blockMaxHeight, wasHeightClipped, marginsCollapseHandler, layoutContext.GetArea().GetBBox(), clearHeightCorrection
151150
, marginsCollapsingEnabled, isCellRenderer, paddings, borders, layoutContext.GetFloatRendererAreas(),
152-
causeOfNothing);
151+
causeOfNothing, layoutBox);
153152
}
154153
if (marginsCollapsingEnabled) {
155154
childMarginsInfo = marginsCollapseHandler.StartChildMarginsHandling(childRenderer, layoutBox);
@@ -210,18 +209,14 @@ public override LayoutResult Layout(LayoutContext layoutContext) {
210209
else {
211210
if (result.GetStatus() == LayoutResult.PARTIAL) {
212211
if (currentAreaPos + 1 == areas.Count) {
213-
AbstractRenderer[] splitAndOverflowRenderers = CreateSplitAndOverflowRenderers(childPos, ignoredChildRenderers
214-
, result, childRenderer, floatRendererAreas, layoutContext.GetArea().GetBBox(), clearHeightCorrection,
215-
marginsCollapsingEnabled, waitingSplitFloatRenderers, waitingOverflowFloatRenderers, LayoutResult.PARTIAL
216-
);
217-
AbstractRenderer splitRenderer = splitAndOverflowRenderers[0];
218-
splitRenderer.childRenderers.Add(result.GetSplitRenderer());
219-
FloatingHelper.AdjustResultOccupiedAreaForFloatAndClear(childRenderer, floatRendererAreas, parentBBox, clearHeightCorrection
220-
, marginsCollapsingEnabled);
221-
if (splitAndOverflowRenderers.Length == 1) {
222-
waitingSplitFloatRenderers = splitRenderer.childRenderers;
212+
AbstractRenderer[] splitAndOverflowRenderers = CreateSplitAndOverflowRenderers(childPos, waitingFloatsSplitRenderers
213+
, result, childRenderer, waitingOverflowFloatRenderers, LayoutResult.PARTIAL);
214+
if (splitAndOverflowRenderers == null) {
215+
waitingFloatsSplitRenderers.Put(childPos, result.GetSplitRenderer());
223216
break;
224217
}
218+
AbstractRenderer splitRenderer = splitAndOverflowRenderers[0];
219+
splitRenderer.childRenderers.Add(result.GetSplitRenderer());
225220
AbstractRenderer overflowRenderer = splitAndOverflowRenderers[1];
226221
overflowRenderer.DeleteOwnProperty(Property.FORCED_PLACEMENT);
227222
if (HasProperty(Property.MAX_HEIGHT)) {
@@ -244,14 +239,13 @@ public override LayoutResult Layout(LayoutContext layoutContext) {
244239
ApplyPaddings(occupiedArea.GetBBox(), paddings, true);
245240
ApplyBorderBox(occupiedArea.GetBBox(), borders, true);
246241
ApplyMargins(occupiedArea.GetBBox(), true);
242+
LayoutArea editedArea = FloatingHelper.AdjustResultOccupiedAreaForFloatAndClear(this, layoutContext.GetFloatRendererAreas
243+
(), layoutContext.GetArea().GetBBox(), clearHeightCorrection, marginsCollapsingEnabled);
247244
if (wasHeightClipped) {
248-
LayoutArea editedArea = FloatingHelper.AdjustResultOccupiedAreaForFloatAndClear(this, layoutContext.GetFloatRendererAreas
249-
(), layoutContext.GetArea().GetBBox(), clearHeightCorrection, marginsCollapsingEnabled);
250245
return new LayoutResult(LayoutResult.FULL, editedArea, splitRenderer, null);
251246
}
252247
else {
253-
return new LayoutResult(LayoutResult.PARTIAL, occupiedArea, splitRenderer, overflowRenderer, causeOfNothing
254-
);
248+
return new LayoutResult(LayoutResult.PARTIAL, editedArea, splitRenderer, overflowRenderer, causeOfNothing);
255249
}
256250
}
257251
else {
@@ -265,15 +259,13 @@ public override LayoutResult Layout(LayoutContext layoutContext) {
265259
if (result.GetStatus() == LayoutResult.NOTHING) {
266260
bool keepTogether = IsKeepTogether();
267261
int layoutResult = anythingPlaced && !keepTogether ? LayoutResult.PARTIAL : LayoutResult.NOTHING;
268-
AbstractRenderer[] splitAndOverflowRenderers = CreateSplitAndOverflowRenderers(childPos, ignoredChildRenderers
269-
, result, childRenderer, floatRendererAreas, layoutContext.GetArea().GetBBox(), clearHeightCorrection,
270-
marginsCollapsingEnabled, waitingSplitFloatRenderers, waitingOverflowFloatRenderers, layoutResult);
271-
AbstractRenderer splitRenderer = splitAndOverflowRenderers[0];
272-
waitingSplitFloatRenderers = splitRenderer.childRenderers;
273-
if (splitAndOverflowRenderers.Length == 1) {
274-
ignoredChildRenderers.Add(childRenderer);
262+
AbstractRenderer[] splitAndOverflowRenderers = CreateSplitAndOverflowRenderers(childPos, waitingFloatsSplitRenderers
263+
, result, childRenderer, waitingOverflowFloatRenderers, layoutResult);
264+
if (splitAndOverflowRenderers == null) {
265+
waitingFloatsSplitRenderers.Put(childPos, null);
275266
break;
276267
}
268+
AbstractRenderer splitRenderer = splitAndOverflowRenderers[0];
277269
AbstractRenderer overflowRenderer = splitAndOverflowRenderers[1];
278270
if (IsRelativePosition() && positionedRenderers.Count > 0) {
279271
overflowRenderer.positionedRenderers = new List<IRenderer>(positionedRenderers);
@@ -308,11 +300,15 @@ public override LayoutResult Layout(LayoutContext layoutContext) {
308300
ApplyBorderBox(occupiedArea.GetBBox(), borders, true);
309301
ApplyMargins(occupiedArea.GetBBox(), true);
310302
if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT)) || wasHeightClipped) {
311-
return new LayoutResult(LayoutResult.FULL, occupiedArea, splitRenderer, null, null);
303+
LayoutArea editedArea = FloatingHelper.AdjustResultOccupiedAreaForFloatAndClear(this, layoutContext.GetFloatRendererAreas
304+
(), layoutContext.GetArea().GetBBox(), clearHeightCorrection, marginsCollapsingEnabled);
305+
return new LayoutResult(LayoutResult.FULL, editedArea, splitRenderer, null, null);
312306
}
313307
else {
314308
if (layoutResult != LayoutResult.NOTHING) {
315-
return new LayoutResult(layoutResult, occupiedArea, splitRenderer, overflowRenderer, null).SetAreaBreak(result
309+
LayoutArea editedArea = FloatingHelper.AdjustResultOccupiedAreaForFloatAndClear(this, layoutContext.GetFloatRendererAreas
310+
(), layoutContext.GetArea().GetBBox(), clearHeightCorrection, marginsCollapsingEnabled);
311+
return new LayoutResult(layoutResult, editedArea, splitRenderer, overflowRenderer, null).SetAreaBreak(result
316312
.GetAreaBreak());
317313
}
318314
else {
@@ -335,8 +331,7 @@ public override LayoutResult Layout(LayoutContext layoutContext) {
335331
if (marginsCollapsingEnabled) {
336332
marginsCollapseHandler.EndChildMarginsHandling(layoutBox);
337333
}
338-
if (result.GetStatus() == LayoutResult.FULL && (waitingOverflowFloatRenderers.IsEmpty() || !FloatingHelper
339-
.IsRendererFloating(childRenderer))) {
334+
if (result.GetStatus() == LayoutResult.FULL) {
340335
layoutBox.SetHeight(result.GetOccupiedArea().GetBBox().GetY() - layoutBox.GetY());
341336
if (childRenderer.GetOccupiedArea() != null) {
342337
// Use occupied area's bbox width so that for absolutely positioned renderers we do not align using full width
@@ -423,25 +418,42 @@ public override LayoutResult Layout(LayoutContext layoutContext) {
423418
overflowRenderer_1 = CreateOverflowRenderer(LayoutResult.PARTIAL);
424419
overflowRenderer_1.GetChildRenderers().AddAll(waitingOverflowFloatRenderers);
425420
}
426-
IRenderer splitRenderer_1;
427-
if (!waitingSplitFloatRenderers.IsEmpty()) {
421+
AbstractRenderer splitRenderer_1 = this;
422+
if (!waitingFloatsSplitRenderers.IsEmpty()) {
428423
splitRenderer_1 = CreateSplitRenderer(LayoutResult.PARTIAL);
429-
splitRenderer_1.GetChildRenderers().AddAll(waitingSplitFloatRenderers);
424+
splitRenderer_1.childRenderers = new List<IRenderer>(childRenderers);
425+
ReplaceSplitRendererKidFloats(waitingFloatsSplitRenderers, splitRenderer_1);
430426
}
431-
else {
432-
splitRenderer_1 = this;
433-
}
434-
if (null == overflowRenderer_1) {
435-
LayoutArea editedArea = FloatingHelper.AdjustResultOccupiedAreaForFloatAndClear(this, layoutContext.GetFloatRendererAreas
436-
(), layoutContext.GetArea().GetBBox(), clearHeightCorrection, marginsCollapsingEnabled);
437-
return new LayoutResult(LayoutResult.FULL, editedArea, splitRenderer_1, null, causeOfNothing);
427+
LayoutArea editedArea_1 = FloatingHelper.AdjustResultOccupiedAreaForFloatAndClear(this, layoutContext.GetFloatRendererAreas
428+
(), layoutContext.GetArea().GetBBox(), clearHeightCorrection, marginsCollapsingEnabled);
429+
if (overflowRenderer_1 == null) {
430+
return new LayoutResult(LayoutResult.FULL, editedArea_1, splitRenderer_1, null, causeOfNothing);
438431
}
439432
else {
440-
return new LayoutResult(LayoutResult.PARTIAL, occupiedArea, splitRenderer_1, overflowRenderer_1, causeOfNothing
433+
// assert splitRenderer != this; // TODO review
434+
return new LayoutResult(LayoutResult.PARTIAL, editedArea_1, splitRenderer_1, overflowRenderer_1, causeOfNothing
441435
);
442436
}
443437
}
444438

439+
private void ReplaceSplitRendererKidFloats(IDictionary<int, IRenderer> waitingFloatsSplitRenderers, IRenderer
440+
splitRenderer) {
441+
foreach (KeyValuePair<int, IRenderer> waitingSplitRenderer in waitingFloatsSplitRenderers) {
442+
if (waitingSplitRenderer.Value != null) {
443+
splitRenderer.GetChildRenderers()[waitingSplitRenderer.Key] = waitingSplitRenderer.Value;
444+
}
445+
else {
446+
// splitRenderer.getChildRenderers().remove((int)waitingSplitRenderer.getKey());
447+
splitRenderer.GetChildRenderers()[(int)waitingSplitRenderer.Key] = null;
448+
}
449+
}
450+
for (int i = splitRenderer.GetChildRenderers().Count - 1; i >= 0; --i) {
451+
if (splitRenderer.GetChildRenderers()[i] == null) {
452+
splitRenderer.GetChildRenderers().JRemoveAt(i);
453+
}
454+
}
455+
}
456+
445457
protected internal virtual AbstractRenderer CreateSplitRenderer(int layoutResult) {
446458
AbstractRenderer splitRenderer = (AbstractRenderer)GetNextRenderer();
447459
splitRenderer.parent = parent;
@@ -752,18 +764,24 @@ internal virtual MinMaxWidth CorrectMinMaxWidth(MinMaxWidth minMaxWidth) {
752764
return minMaxWidth;
753765
}
754766

755-
private LayoutResult SplitIfClearRendererIsPresentAfterFloatRendererWasSplitted(int childPos, IList<IRenderer
756-
> waitingSplitRenderers, IList<IRenderer> waitingOverflowRenderers, float? blockMaxHeight, bool wasHeightClipped
757-
, MarginsCollapseHandler marginsCollapseHandler, Rectangle parentBBox, float clearHeightCorrection, bool
758-
marginsCollapsingEnabled, bool isCellRenderer, float[] paddings, Border[] borders, IList<Rectangle> floatRendererAreas
759-
, IRenderer causeOfNothing) {
767+
private LayoutResult SplitIfClearRendererIsPresentAfterFloatRendererWasSplit(int childPos, IDictionary<int
768+
, IRenderer> waitingFloatsSplitRenderers, IList<IRenderer> waitingFloatsOverflowRenderers, float? blockMaxHeight
769+
, bool wasHeightClipped, MarginsCollapseHandler marginsCollapseHandler, Rectangle parentBBox, float clearHeightCorrection
770+
, bool marginsCollapsingEnabled, bool isCellRenderer, float[] paddings, Border[] borders, IList<Rectangle
771+
> floatRendererAreas, IRenderer causeOfNothing, Rectangle layoutBox) {
772+
if (marginsCollapsingEnabled && !isCellRenderer) {
773+
marginsCollapseHandler.EndMarginsCollapse(layoutBox);
774+
}
760775
AbstractRenderer splitRenderer = CreateSplitRenderer(LayoutResult.PARTIAL);
776+
Rectangle splitRendererOccupiedArea = splitRenderer.GetOccupiedArea().GetBBox();
777+
splitRendererOccupiedArea.IncreaseHeight(splitRendererOccupiedArea.GetY() - layoutBox.GetY()).SetY(layoutBox
778+
.GetY());
761779
splitRenderer.childRenderers = new List<IRenderer>(childRenderers.SubList(0, childPos));
762-
splitRenderer.childRenderers = waitingSplitRenderers;
780+
ReplaceSplitRendererKidFloats(waitingFloatsSplitRenderers, splitRenderer);
763781
AbstractRenderer overflowRenderer = CreateOverflowRenderer(LayoutResult.PARTIAL);
764782
// Apply forced placement only on split renderer
765783
overflowRenderer.DeleteOwnProperty(Property.FORCED_PLACEMENT);
766-
overflowRenderer.childRenderers.AddAll(waitingOverflowRenderers);
784+
overflowRenderer.childRenderers.AddAll(waitingFloatsOverflowRenderers);
767785
overflowRenderer.childRenderers.AddAll(childRenderers.SubList(childPos, childRenderers.Count));
768786
if (HasProperty(Property.MAX_HEIGHT)) {
769787
overflowRenderer.SetProperty(Property.MAX_HEIGHT, RetrieveMaxHeight() - occupiedArea.GetBBox().GetHeight()
@@ -782,9 +800,6 @@ private LayoutResult SplitIfClearRendererIsPresentAfterFloatRendererWasSplitted(
782800
occupiedArea.GetBBox().MoveDown((float)blockMaxHeight - occupiedArea.GetBBox().GetHeight()).SetHeight((float
783801
)blockMaxHeight);
784802
}
785-
if (marginsCollapsingEnabled && !isCellRenderer) {
786-
marginsCollapseHandler.EndMarginsCollapse(occupiedArea.GetBBox());
787-
}
788803
ApplyPaddings(occupiedArea.GetBBox(), paddings, true);
789804
ApplyBorderBox(occupiedArea.GetBBox(), borders, true);
790805
ApplyMargins(occupiedArea.GetBBox(), true);
@@ -798,22 +813,18 @@ private LayoutResult SplitIfClearRendererIsPresentAfterFloatRendererWasSplitted(
798813
}
799814
}
800815

801-
private AbstractRenderer[] CreateSplitAndOverflowRenderers(int childPos, IList<IRenderer> ignoredChildRenderers
802-
, LayoutResult result, IRenderer childRenderer, IList<Rectangle> floatRendererAreas, Rectangle parentBBox
803-
, float clearHeightCorrection, bool marginsCollapsingEnabled, IList<IRenderer> waitingSplitFloatRenderers
804-
, IList<IRenderer> waitingOverflowFloatRenderers, int layoutStatus) {
816+
private AbstractRenderer[] CreateSplitAndOverflowRenderers(int childPos, IDictionary<int, IRenderer> waitingFloatsSplitRenderers
817+
, LayoutResult result, IRenderer childRenderer, IList<IRenderer> waitingOverflowFloatRenderers, int layoutStatus
818+
) {
805819
AbstractRenderer splitRenderer = CreateSplitRenderer(layoutStatus);
806820
splitRenderer.childRenderers = new List<IRenderer>(childRenderers.SubList(0, childPos));
807-
foreach (IRenderer ignoredRenderer in ignoredChildRenderers) {
808-
splitRenderer.childRenderers.Remove(ignoredRenderer);
809-
}
821+
ReplaceSplitRendererKidFloats(waitingFloatsSplitRenderers, splitRenderer);
810822
foreach (IRenderer renderer in splitRenderer.childRenderers) {
811823
renderer.SetParent(splitRenderer);
812824
}
813825
if (FloatingHelper.IsRendererFloating(childRenderer)) {
814-
// ignoredChildRenderers.add(childRenderer);
815826
waitingOverflowFloatRenderers.Add(result.GetOverflowRenderer());
816-
return new AbstractRenderer[] { splitRenderer };
827+
return null;
817828
}
818829
AbstractRenderer overflowRenderer = CreateOverflowRenderer(layoutStatus);
819830
overflowRenderer.childRenderers.AddAll(waitingOverflowFloatRenderers);

0 commit comments

Comments
 (0)