Skip to content

Commit e2f29e5

Browse files
committed
Fix margin collapse in columncontainer
DEVSIX-7613
1 parent 4bd563b commit e2f29e5

File tree

5 files changed

+61
-45
lines changed

5 files changed

+61
-45
lines changed

layout/src/main/java/com/itextpdf/layout/properties/ContinuousContainer.java

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ This file is part of the iText (R) project.
2424

2525
import com.itextpdf.layout.IPropertyContainer;
2626
import com.itextpdf.layout.borders.Border;
27+
import com.itextpdf.layout.renderer.AbstractRenderer;
2728
import com.itextpdf.layout.renderer.BlockRenderer;
2829
import com.itextpdf.layout.renderer.IRenderer;
2930

@@ -34,16 +35,17 @@ This file is part of the iText (R) project.
3435
* THis is used for processing continuous container property.
3536
* This behavior is used when we want to simulate a continuous appearance over multiple pages.
3637
* This means that only for the first and last page the margins, paddings and borders are applied.
37-
* On the fist page the top properties are applied and on the last page the bottom properties are applied.
38+
* On the first page the top properties are applied and on the last page the bottom properties are applied.
3839
*/
3940
public final class ContinuousContainer {
4041

4142
/**
4243
* Properties needed to be removed/added for continuous container.
4344
*/
44-
static final int[] PROPERTIES_NEEDED_FOR_CONTINUOUS_CONTAINER = {Property.MARGIN_BOTTOM, Property.BORDER_BOTTOM,
45+
private static final int[] PROPERTIES_NEEDED_FOR_CONTINUOUS_CONTAINER = {Property.MARGIN_BOTTOM,
46+
Property.BORDER_BOTTOM,
4547
Property.PADDING_BOTTOM, Property.BORDER};
46-
final HashMap<Integer, Object> properties = new HashMap<>();
48+
private final HashMap<Integer, Object> properties = new HashMap<>();
4749

4850

4951
/**
@@ -63,24 +65,40 @@ private ContinuousContainer(IRenderer renderer) {
6365
* @param overFlowRenderer the renderer that is used to remove properties from.
6466
*/
6567
public static void clearPropertiesFromOverFlowRenderer(IPropertyContainer overFlowRenderer) {
66-
overFlowRenderer.setProperty(Property.PADDING_TOP, UnitValue.createPointValue(0));
67-
overFlowRenderer.setProperty(Property.MARGIN_TOP, UnitValue.createPointValue(0));
68-
overFlowRenderer.setProperty(Property.BORDER_TOP, null);
69-
68+
if (overFlowRenderer == null) {
69+
return;
70+
}
71+
if (Boolean.TRUE.equals(overFlowRenderer.<Boolean>getProperty(Property.TREAT_AS_CONTINUOUS_CONTAINER))) {
72+
overFlowRenderer.setProperty(Property.PADDING_TOP, UnitValue.createPointValue(0));
73+
overFlowRenderer.setProperty(Property.MARGIN_TOP, UnitValue.createPointValue(0));
74+
overFlowRenderer.setProperty(Property.BORDER_TOP, null);
75+
}
7076
}
7177

7278
/**
7379
* Sets up the needed values in the model element of the renderer.
7480
*
7581
* @param blockRenderer the renderer that is used to set up continuous container.
7682
*/
77-
public static void setupContinuousContainer(BlockRenderer blockRenderer) {
78-
if (!blockRenderer.hasProperty(Property.TREAT_AS_CONTINUOUS_CONTAINER_RESULT)) {
79-
final ContinuousContainer continuousContainer = new ContinuousContainer(blockRenderer);
80-
blockRenderer
81-
.setProperty(Property.TREAT_AS_CONTINUOUS_CONTAINER_RESULT, continuousContainer);
83+
public static void setupContinuousContainerIfNeeded(BlockRenderer blockRenderer) {
84+
if (Boolean.TRUE.equals(blockRenderer.<Boolean>getProperty(Property.TREAT_AS_CONTINUOUS_CONTAINER))) {
85+
if (!blockRenderer.hasProperty(Property.TREAT_AS_CONTINUOUS_CONTAINER_RESULT)) {
86+
final ContinuousContainer continuousContainer = new ContinuousContainer(blockRenderer);
87+
blockRenderer
88+
.setProperty(Property.TREAT_AS_CONTINUOUS_CONTAINER_RESULT, continuousContainer);
89+
}
90+
clearPropertiesFromSplitRenderer(blockRenderer);
8291
}
83-
clearProperties(blockRenderer);
92+
}
93+
94+
private static void clearPropertiesFromSplitRenderer(AbstractRenderer blockRenderer) {
95+
if (blockRenderer == null) {
96+
return;
97+
}
98+
blockRenderer.setProperty(Property.MARGIN_BOTTOM, UnitValue.createPointValue(0));
99+
blockRenderer.setProperty(Property.BORDER_BOTTOM, null);
100+
blockRenderer.setProperty(Property.PADDING_BOTTOM, UnitValue.createPointValue(0));
101+
84102
}
85103

86104
/**
@@ -98,10 +116,4 @@ public void reApplyProperties(BlockRenderer blockRenderer) {
98116
blockRenderer.setProperty(Property.BORDER_BOTTOM, allBorders);
99117
}
100118
}
101-
102-
private static void clearProperties(BlockRenderer blockRenderer) {
103-
blockRenderer.setProperty(Property.MARGIN_BOTTOM, UnitValue.createPointValue(0));
104-
blockRenderer.setProperty(Property.BORDER_BOTTOM, null);
105-
blockRenderer.setProperty(Property.PADDING_BOTTOM, UnitValue.createPointValue(0));
106-
}
107119
}

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

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ protected BlockRenderer(IElement modelElement) {
8282
@Override
8383
public LayoutResult layout(LayoutContext layoutContext) {
8484
this.isLastRendererForModelElement = true;
85-
8685
Map<Integer, IRenderer> waitingFloatsSplitRenderers = new LinkedHashMap<>();
8786
List<IRenderer> waitingOverflowFloatRenderers = new ArrayList<>();
8887
boolean floatOverflowedCompletely = false;
@@ -113,25 +112,26 @@ public LayoutResult layout(LayoutContext layoutContext) {
113112
blockWidth = RotationUtils.retrieveRotatedLayoutWidth(parentBBox.getWidth(), this);
114113
}
115114
boolean includeFloatsInOccupiedArea = BlockFormattingContextUtil.isRendererCreateBfc(this);
116-
float clearHeightCorrection = FloatingHelper.calculateClearHeightCorrection(this, floatRendererAreas, parentBBox);
117-
FloatingHelper.applyClearance(parentBBox, marginsCollapseHandler, clearHeightCorrection, FloatingHelper.isRendererFloating(this));
115+
float clearHeightCorrection = FloatingHelper.calculateClearHeightCorrection(this, floatRendererAreas,
116+
parentBBox);
117+
FloatingHelper.applyClearance(parentBBox, marginsCollapseHandler, clearHeightCorrection,
118+
FloatingHelper.isRendererFloating(this));
118119
if (FloatingHelper.isRendererFloating(this, floatPropertyValue)) {
119120
blockWidth = FloatingHelper.adjustFloatedBlockLayoutBox(this, parentBBox, blockWidth, floatRendererAreas,
120121
floatPropertyValue, overflowX);
121122
floatRendererAreas = new ArrayList<>();
122123
}
123124
boolean wasHeightDecreased = clearHeightCorrection > 0 &&
124125
(marginsCollapseHandler == null || FloatingHelper.isRendererFloating(this));
125-
float bfcHeightCorrection = FloatingHelper.adjustBlockFormattingContextLayoutBox(this, floatRendererAreas, parentBBox,
126+
float bfcHeightCorrection = FloatingHelper.adjustBlockFormattingContextLayoutBox(this, floatRendererAreas,
127+
parentBBox,
126128
blockWidth == null ? 0 : (float) blockWidth, wasHeightDecreased ? 0 : clearHeightCorrection);
127129
boolean isCellRenderer = this instanceof CellRenderer;
128130
if (marginsCollapsingEnabled) {
129131
marginsCollapseHandler.startMarginsCollapse(parentBBox);
130132
}
131133

132-
if (Boolean.TRUE.equals(this.<Boolean>getProperty(Property.TREAT_AS_CONTINUOUS_CONTAINER))) {
133-
ContinuousContainer.setupContinuousContainer(this);
134-
}
134+
ContinuousContainer.setupContinuousContainerIfNeeded(this);
135135

136136
Border[] borders = getBorders();
137137
UnitValue[] paddings = getPaddings();
@@ -440,7 +440,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
440440
}
441441
final ContinuousContainer continuousContainer = this.<ContinuousContainer>getProperty(
442442
Property.TREAT_AS_CONTINUOUS_CONTAINER_RESULT);
443-
if (continuousContainer != null) {
443+
if (continuousContainer != null && overflowRenderer == null) {
444444
continuousContainer.reApplyProperties(this);
445445
paddings = getPaddings();
446446
borders = getBorders();
@@ -469,14 +469,19 @@ public LayoutResult layout(LayoutContext layoutContext) {
469469

470470
FloatingHelper.removeFloatsAboveRendererBottom(floatRendererAreas, this);
471471

472+
ContinuousContainer.clearPropertiesFromOverFlowRenderer(overflowRenderer);
473+
472474
if (layoutResult != LayoutResult.NOTHING) {
473-
LayoutArea editedArea = FloatingHelper.adjustResultOccupiedAreaForFloatAndClear(this, layoutContext.getFloatRendererAreas(), layoutContext.getArea().getBBox(), clearHeightCorrection, bfcHeightCorrection, marginsCollapsingEnabled);
475+
LayoutArea editedArea = FloatingHelper.adjustResultOccupiedAreaForFloatAndClear(this,
476+
layoutContext.getFloatRendererAreas(), layoutContext.getArea().getBBox(), clearHeightCorrection,
477+
bfcHeightCorrection, marginsCollapsingEnabled);
474478
return new LayoutResult(layoutResult, editedArea, splitRenderer, overflowRenderer, causeOfNothing);
475479
} else {
476480
if (positionedRenderers.size() > 0) {
477481
overflowRenderer.positionedRenderers = new ArrayList<>(positionedRenderers);
478482
}
479483
floatRendererAreas.retainAll(nonChildFloatingRendererAreas);
484+
480485
return new LayoutResult(LayoutResult.NOTHING, null, null, overflowRenderer, causeOfNothing);
481486
}
482487
}
@@ -666,9 +671,7 @@ AbstractRenderer[] createSplitAndOverflowRenderers(int childPos, int layoutStatu
666671
}
667672
overflowRenderer.childRenderers.addAll(childRenderers.subList(childPos + 1, childRenderers.size()));
668673

669-
if (Boolean.TRUE.equals(this.<Boolean>getProperty(Property.TREAT_AS_CONTINUOUS_CONTAINER))) {
670-
ContinuousContainer.clearPropertiesFromOverFlowRenderer(overflowRenderer);
671-
}
674+
ContinuousContainer.clearPropertiesFromOverFlowRenderer(overflowRenderer);
672675

673676
if (childResult.getStatus() == LayoutResult.PARTIAL) {
674677
// Apply forced placement only on split renderer

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ private IRenderer layoutColumnsAndReturnOverflowRenderer(LayoutContext preLayout
180180

181181
LayoutContext columnContext = new LayoutContext(tempArea, preLayoutContext.getMarginsCollapseInfo(),
182182
preLayoutContext.getFloatRendererAreas(), preLayoutContext.isClippedHeight());
183-
183+
renderer.setProperty(Property.COLLAPSING_MARGINS, false);
184184
LayoutResult tempResultColumn = renderer.layout(columnContext);
185185
if (tempResultColumn.getSplitRenderer() == null) {
186186
container.add(renderer);

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

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,7 @@ protected LayoutResult directLayout(LayoutContext layoutContext) {
105105
marginsCollapseHandler = new MarginsCollapseHandler(this, layoutContext.getMarginsCollapseInfo());
106106
}
107107

108-
if (Boolean.TRUE.equals(this.<Boolean>getProperty(Property.TREAT_AS_CONTINUOUS_CONTAINER))) {
109-
ContinuousContainer.setupContinuousContainer(this);
110-
}
108+
ContinuousContainer.setupContinuousContainerIfNeeded(this);
111109

112110
OverflowPropertyValue overflowX = this.<OverflowPropertyValue>getProperty(Property.OVERFLOW_X);
113111

@@ -473,13 +471,14 @@ protected LayoutResult directLayout(LayoutContext layoutContext) {
473471
}
474472

475473
AbstractRenderer overflowRenderer = applyMinHeight(overflowY, layoutBox);
474+
476475
if (overflowRenderer != null && isKeepTogether()) {
477476
floatRendererAreas.retainAll(nonChildFloatingRendererAreas);
478477
return new LayoutResult(LayoutResult.NOTHING, null, null, this, this);
479478
}
480479
final ContinuousContainer continuousContainer = this.<ContinuousContainer>getProperty(
481480
Property.TREAT_AS_CONTINUOUS_CONTAINER_RESULT);
482-
if (continuousContainer != null) {
481+
if (continuousContainer != null && overflowRenderer == null) {
483482
continuousContainer.reApplyProperties(this);
484483
paddings = getPaddings();
485484
borders = getBorders();
@@ -496,7 +495,7 @@ protected LayoutResult directLayout(LayoutContext layoutContext) {
496495
if (rotation != null) {
497496
applyRotationLayout(layoutContext.getArea().getBBox().clone());
498497
if (isNotFittingLayoutArea(layoutContext.getArea())) {
499-
if(isNotFittingWidth(layoutContext.getArea()) && !isNotFittingHeight(layoutContext.getArea())) {
498+
if (isNotFittingWidth(layoutContext.getArea()) && !isNotFittingHeight(layoutContext.getArea())) {
500499
LoggerFactory.getLogger(getClass())
501500
.warn(MessageFormatUtil.format(LayoutLogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA,
502501
"It fits by height so it will be forced placed"));
@@ -510,13 +509,17 @@ protected LayoutResult directLayout(LayoutContext layoutContext) {
510509
applyVerticalAlignment();
511510

512511
FloatingHelper.removeFloatsAboveRendererBottom(floatRendererAreas, this);
513-
LayoutArea editedArea = FloatingHelper.adjustResultOccupiedAreaForFloatAndClear(this, layoutContext.getFloatRendererAreas(), layoutContext.getArea().getBBox(), clearHeightCorrection, marginsCollapsingEnabled);
514-
512+
LayoutArea editedArea = FloatingHelper.adjustResultOccupiedAreaForFloatAndClear(this,
513+
layoutContext.getFloatRendererAreas(), layoutContext.getArea().getBBox(), clearHeightCorrection,
514+
marginsCollapsingEnabled);
515515

516+
ContinuousContainer.clearPropertiesFromOverFlowRenderer(overflowRenderer);
516517
if (null == overflowRenderer) {
517-
return new MinMaxWidthLayoutResult(LayoutResult.FULL, editedArea, null, null, null).setMinMaxWidth(minMaxWidth);
518+
return new MinMaxWidthLayoutResult(LayoutResult.FULL, editedArea, null, null, null).setMinMaxWidth(
519+
minMaxWidth);
518520
} else {
519-
return new MinMaxWidthLayoutResult(LayoutResult.PARTIAL, editedArea, this, overflowRenderer, null).setMinMaxWidth(minMaxWidth);
521+
return new MinMaxWidthLayoutResult(LayoutResult.PARTIAL, editedArea, this, overflowRenderer,
522+
null).setMinMaxWidth(minMaxWidth);
520523
}
521524
}
522525

@@ -647,9 +650,7 @@ protected ParagraphRenderer createOverflowRenderer(IRenderer parent) {
647650
overflowRenderer.parent = parent;
648651
fixOverflowRenderer(overflowRenderer);
649652
overflowRenderer.addAllProperties(getOwnProperties());
650-
if (Boolean.TRUE.equals(this.<Boolean>getProperty(Property.TREAT_AS_CONTINUOUS_CONTAINER))) {
651-
ContinuousContainer.clearPropertiesFromOverFlowRenderer(overflowRenderer);
652-
}
653+
ContinuousContainer.clearPropertiesFromOverFlowRenderer(overflowRenderer);
653654
return overflowRenderer;
654655
}
655656

@@ -707,7 +708,7 @@ protected ParagraphRenderer[] split() {
707708

708709
ParagraphRenderer overflowRenderer = createOverflowRenderer(parent);
709710

710-
return new ParagraphRenderer[]{splitRenderer, overflowRenderer};
711+
return new ParagraphRenderer[] {splitRenderer, overflowRenderer};
711712
}
712713

713714
private void fixOverflowRenderer(ParagraphRenderer overflowRenderer) {

0 commit comments

Comments
 (0)