@@ -31,6 +31,7 @@ This file is part of the iText (R) project.
31
31
import com .itextpdf .layout .properties .ContinuousContainer ;
32
32
import com .itextpdf .layout .properties .GridFlow ;
33
33
import com .itextpdf .layout .properties .GridValue ;
34
+ import com .itextpdf .layout .properties .OverflowPropertyValue ;
34
35
import com .itextpdf .layout .properties .Property ;
35
36
import com .itextpdf .layout .properties .UnitValue ;
36
37
@@ -85,31 +86,15 @@ public LayoutResult layout(LayoutContext layoutContext) {
85
86
Grid grid = constructGrid (this , actualBBox );
86
87
GridLayoutResult layoutResult = layoutGrid (layoutContext , actualBBox , grid );
87
88
88
- //TODO DEVSIX-8329 improve nothing processing, consider checking for cause of nothing here?
89
- //TODO DEVSIX-8329 improve forced placement logic
90
- if (layoutResult .getOverflowRenderers ().isEmpty () && layoutResult .getSplitRenderers ().isEmpty ()) {
89
+ if (layoutResult .getOverflowRenderers ().isEmpty ()) {
91
90
this .occupiedArea = calculateContainerOccupiedArea (layoutContext , grid , true );
92
91
return new LayoutResult (LayoutResult .FULL , this .occupiedArea , null , null );
93
92
} else if (layoutResult .getSplitRenderers ().isEmpty ()) {
94
- if (Boolean .TRUE .equals (this .<Boolean >getProperty (Property .FORCED_PLACEMENT ))) {
95
- this .occupiedArea = calculateContainerOccupiedArea (layoutContext , grid , true );
96
- return new LayoutResult (LayoutResult .FULL , this .occupiedArea , this , null );
97
- }
98
93
IRenderer cause = this ;
99
94
if (!layoutResult .getCauseOfNothing ().isEmpty ()) {
100
95
cause = layoutResult .getCauseOfNothing ().get (0 );
101
96
}
102
97
return new LayoutResult (LayoutResult .NOTHING , null , null , this , cause );
103
- } else if (layoutResult .getOverflowRenderers ().isEmpty ()) {
104
- final ContinuousContainer continuousContainer = this .<ContinuousContainer >getProperty (
105
- Property .TREAT_AS_CONTINUOUS_CONTAINER_RESULT );
106
- if (continuousContainer != null ) {
107
- continuousContainer .reApplyProperties (this );
108
- }
109
- this .childRenderers .clear ();
110
- this .addAllChildRenderers (layoutResult .getSplitRenderers ());
111
- this .occupiedArea = calculateContainerOccupiedArea (layoutContext , grid , true );
112
- return new LayoutResult (LayoutResult .FULL , this .occupiedArea , this , null );
113
98
} else {
114
99
this .occupiedArea = calculateContainerOccupiedArea (layoutContext , grid , false );
115
100
return new LayoutResult (LayoutResult .PARTIAL , this .occupiedArea ,
@@ -118,6 +103,16 @@ public LayoutResult layout(LayoutContext layoutContext) {
118
103
}
119
104
}
120
105
106
+ /**
107
+ * {@inheritDoc}
108
+ */
109
+ @ Override
110
+ public void addChild (IRenderer renderer ) {
111
+ renderer .setProperty (Property .OVERFLOW_X , OverflowPropertyValue .VISIBLE );
112
+ renderer .setProperty (Property .OVERFLOW_Y , OverflowPropertyValue .VISIBLE );
113
+ super .addChild (renderer );
114
+ }
115
+
121
116
private AbstractRenderer createSplitRenderer (List <IRenderer > children ) {
122
117
AbstractRenderer splitRenderer = (AbstractRenderer ) getNextRenderer ();
123
118
splitRenderer .parent = parent ;
@@ -131,6 +126,7 @@ private AbstractRenderer createSplitRenderer(List<IRenderer> children) {
131
126
}
132
127
133
128
private AbstractRenderer createOverflowRenderer (List <IRenderer > children ) {
129
+ // TODO DEVSIX-8340 - We put the original amount of rows into overflow container.
134
130
GridContainerRenderer overflowRenderer = (GridContainerRenderer ) getNextRenderer ();
135
131
overflowRenderer .isFirstLayout = false ;
136
132
overflowRenderer .parent = parent ;
@@ -145,30 +141,39 @@ private AbstractRenderer createOverflowRenderer(List<IRenderer> children) {
145
141
private GridLayoutResult layoutGrid (LayoutContext layoutContext , Rectangle actualBBox , Grid grid ) {
146
142
GridLayoutResult layoutResult = new GridLayoutResult ();
147
143
ensureTemplateValuesFit (grid , actualBBox );
148
- //TODO DEVSIX-8329 improve forced placement logic, right now if we have a cell which could not be fitted on its
149
- // area or returns nothing as layout result RootRenderer sets FORCED_PLACEMENT on this class instance.
150
- // And basically every cell inherits this value and force placed, but we only need to force place cells
151
- // which were not fitted originally.
144
+
152
145
for (GridCell cell : grid .getUniqueGridCells (Grid .GridOrder .ROW )) {
153
- //If cell couldn't fit during cell layout area calculation than we need to put such cell straight to
154
- //nothing result list
155
- if (!cell .isValueFitOnCellArea ()) {
156
- layoutResult .getOverflowRenderers ().add (cell .getValue ());
157
- layoutResult .getCauseOfNothing ().add (cell .getValue ());
158
- continue ;
159
- }
160
- //Calculate cell layout context by getting actual x and y on parent layout area for it
146
+ // Calculate cell layout context by getting actual x and y on parent layout area for it
161
147
LayoutContext cellContext = getCellLayoutContext (layoutContext , actualBBox , cell );
162
- //We need to check for forced placement here, because otherwise we would infinitely return partial result.
163
- if (!Boolean .TRUE .equals (this .<Boolean >getProperty (Property .FORCED_PLACEMENT ))
164
- && !actualBBox .contains (cellContext .getArea ().getBBox ())) {
165
- layoutResult .getOverflowRenderers ().add (cell .getValue ());
166
- continue ;
167
- }
168
148
169
149
IRenderer cellToRender = cell .getValue ();
170
- cellToRender .setProperty (Property .FILL_AVAILABLE_AREA , true );
171
150
cellToRender .setProperty (Property .COLLAPSING_MARGINS , Boolean .FALSE );
151
+
152
+ // Now set the height for the individual items
153
+ // We know cell height upfront and this way we tell the element what it can occupy
154
+ Rectangle cellBBox = cellContext .getArea ().getBBox ();
155
+ if (!cellToRender .hasProperty (Property .HEIGHT )) {
156
+ final Rectangle rectangleWithoutBordersMarginsPaddings = cellBBox .clone ();
157
+ if (cellToRender instanceof AbstractRenderer ) {
158
+ final AbstractRenderer abstractCellRenderer = ((AbstractRenderer ) cellToRender );
159
+ // We subtract margins/borders/paddings because we should take into account that
160
+ // borders/paddings/margins should also fit into a cell.
161
+ if (AbstractRenderer .isBorderBoxSizing (cellToRender )) {
162
+ abstractCellRenderer .applyMargins (rectangleWithoutBordersMarginsPaddings , false );
163
+ } else {
164
+ abstractCellRenderer .applyMarginsBordersPaddings (rectangleWithoutBordersMarginsPaddings , false );
165
+ }
166
+ }
167
+
168
+ cellToRender .setProperty (Property .HEIGHT ,
169
+ UnitValue .createPointValue (rectangleWithoutBordersMarginsPaddings .getHeight ()));
170
+ }
171
+
172
+ // Adjust cell BBox to the remaining part of the layout bbox
173
+ // This way we can layout elements partially
174
+ cellBBox .setHeight (cellBBox .getTop () - actualBBox .getBottom ())
175
+ .setY (actualBBox .getY ());
176
+
172
177
LayoutResult cellResult = cellToRender .layout (cellContext );
173
178
174
179
if (cellResult .getStatus () == LayoutResult .NOTHING ) {
0 commit comments