@@ -136,6 +136,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
136
136
UnitValue .createPointValue (rectangleWithoutBordersMarginsPaddings .getHeight ()));
137
137
}
138
138
}
139
+
139
140
final LayoutResult result = super .layout (layoutContext );
140
141
141
142
// We must set back widths of the children because multiple layouts are possible
@@ -195,17 +196,25 @@ AbstractRenderer[] createSplitAndOverflowRenderers(int childPos, int layoutStatu
195
196
List <IRenderer > waitingOverflowFloatRenderers ) {
196
197
final AbstractRenderer splitRenderer = createSplitRenderer (layoutStatus );
197
198
final AbstractRenderer overflowRenderer = createOverflowRenderer (layoutStatus );
199
+
198
200
final IRenderer childRenderer = getChildRenderers ().get (childPos );
199
201
final boolean forcedPlacement = Boolean .TRUE .equals (this .<Boolean >getProperty (Property .FORCED_PLACEMENT ));
200
202
boolean metChildRenderer = false ;
201
203
for (final List <FlexItemInfo > line : lines ) {
202
- metChildRenderer = metChildRenderer ||
203
- line .stream ().anyMatch (flexItem -> flexItem .getRenderer () == childRenderer );
204
- for (final FlexItemInfo itemInfo : line ) {
205
- if (metChildRenderer && !forcedPlacement ) {
206
- overflowRenderer .addChildRenderer (itemInfo .getRenderer ());
207
- } else {
208
- splitRenderer .addChildRenderer (itemInfo .getRenderer ());
204
+ final boolean isSplitLine = line .stream ().anyMatch (flexItem -> flexItem .getRenderer () == childRenderer );
205
+ metChildRenderer = metChildRenderer || isSplitLine ;
206
+
207
+ // If the renderer to split is in the current line
208
+ if (isSplitLine && !forcedPlacement && layoutStatus == LayoutResult .PARTIAL ) {
209
+ fillSplitOverflowRenderersForPartialResult (splitRenderer , overflowRenderer , line , childRenderer ,
210
+ childResult );
211
+ } else {
212
+ for (final FlexItemInfo itemInfo : line ) {
213
+ if (metChildRenderer && !forcedPlacement ) {
214
+ overflowRenderer .addChildRenderer (itemInfo .getRenderer ());
215
+ } else {
216
+ splitRenderer .addChildRenderer (itemInfo .getRenderer ());
217
+ }
209
218
}
210
219
}
211
220
}
@@ -224,22 +233,30 @@ LayoutResult processNotFullChildResult(LayoutContext layoutContext,
224
233
List <Rectangle > areas , int currentAreaPos , Rectangle layoutBox ,
225
234
Set <Rectangle > nonChildFloatingRendererAreas , IRenderer causeOfNothing ,
226
235
boolean anythingPlaced , int childPos , LayoutResult result ) {
227
-
228
236
final boolean keepTogether = isKeepTogether (causeOfNothing );
237
+ if (Boolean .TRUE .equals (getPropertyAsBoolean (Property .FORCED_PLACEMENT )) || wasHeightClipped ) {
238
+ final AbstractRenderer splitRenderer = keepTogether ? null : createSplitRenderer (result .getStatus ());
239
+ if (splitRenderer != null ) {
240
+ splitRenderer .setChildRenderers (getChildRenderers ());
241
+ }
242
+
243
+ return new LayoutResult (LayoutResult .FULL ,
244
+ getOccupiedAreaInCaseNothingWasWrappedWithFull (result , splitRenderer ), splitRenderer , null , null );
245
+ }
229
246
230
247
final AbstractRenderer [] splitAndOverflowRenderers = createSplitAndOverflowRenderers (
231
248
childPos , result .getStatus (), result , waitingFloatsSplitRenderers , waitingOverflowFloatRenderers );
232
249
233
250
AbstractRenderer splitRenderer = splitAndOverflowRenderers [0 ];
234
251
final AbstractRenderer overflowRenderer = splitAndOverflowRenderers [1 ];
235
252
overflowRenderer .deleteOwnProperty (Property .FORCED_PLACEMENT );
253
+ updateHeightsOnSplit (wasHeightClipped , splitRenderer , overflowRenderer );
236
254
237
255
if (isRelativePosition () && !positionedRenderers .isEmpty ()) {
238
256
overflowRenderer .positionedRenderers = new ArrayList <>(positionedRenderers );
239
257
}
240
258
241
259
// TODO DEVSIX-5086 When flex-wrap will be fully supported we'll need to update height on split
242
-
243
260
if (keepTogether ) {
244
261
splitRenderer = null ;
245
262
overflowRenderer .setChildRenderers (getChildRenderers ());
@@ -249,23 +266,15 @@ LayoutResult processNotFullChildResult(LayoutContext layoutContext,
249
266
250
267
applyAbsolutePositionIfNeeded (layoutContext );
251
268
252
- if ( Boolean . TRUE . equals ( getPropertyAsBoolean ( Property . FORCED_PLACEMENT )) || wasHeightClipped ) {
253
- if ( splitRenderer != null ) {
254
- splitRenderer . setChildRenderers ( getChildRenderers () );
255
- }
256
- return new LayoutResult (LayoutResult .FULL ,
257
- getOccupiedAreaInCaseNothingWasWrappedWithFull ( result , splitRenderer ), splitRenderer , null , null );
269
+ applyPaddings ( occupiedArea . getBBox (), paddings , true );
270
+ applyBorderBox ( occupiedArea . getBBox (), borders , true );
271
+ applyMargins ( occupiedArea . getBBox (), true );
272
+ if ( splitRenderer == null || splitRenderer . getChildRenderers (). isEmpty ()) {
273
+ return new LayoutResult (LayoutResult .NOTHING , null , null , overflowRenderer ,
274
+ result . getCauseOfNothing ()). setAreaBreak ( result . getAreaBreak () );
258
275
} else {
259
- applyPaddings (occupiedArea .getBBox (), paddings , true );
260
- applyBorderBox (occupiedArea .getBBox (), borders , true );
261
- applyMargins (occupiedArea .getBBox (), true );
262
- if (splitRenderer == null || splitRenderer .getChildRenderers ().isEmpty ()) {
263
- return new LayoutResult (LayoutResult .NOTHING , null , null , overflowRenderer ,
264
- result .getCauseOfNothing ()).setAreaBreak (result .getAreaBreak ());
265
- } else {
266
- return new LayoutResult (LayoutResult .PARTIAL , layoutContext .getArea (), splitRenderer ,
267
- overflowRenderer , null ).setAreaBreak (result .getAreaBreak ());
268
- }
276
+ return new LayoutResult (LayoutResult .PARTIAL , layoutContext .getArea (), splitRenderer ,
277
+ overflowRenderer , null ).setAreaBreak (result .getAreaBreak ());
269
278
}
270
279
}
271
280
@@ -354,7 +363,7 @@ private FlexItemInfo findFlexItemInfo(AbstractRenderer renderer) {
354
363
}
355
364
return null ;
356
365
}
357
-
366
+
358
367
@ Override
359
368
void fixOccupiedAreaIfOverflowedX (OverflowPropertyValue overflowX , Rectangle layoutBox ) {
360
369
// TODO DEVSIX-5087 Support overflow visible/hidden property correctly
@@ -373,6 +382,71 @@ public void addChild(IRenderer renderer) {
373
382
super .addChild (renderer );
374
383
}
375
384
385
+ private void fillSplitOverflowRenderersForPartialResult (AbstractRenderer splitRenderer ,
386
+ AbstractRenderer overflowRenderer , List <FlexItemInfo > line , IRenderer childRenderer ,
387
+ LayoutResult childResult ) {
388
+ // If we split, we remove (override) Property.ALIGN_ITEMS for the overflow renderer.
389
+ // because we have to layout the remaining part at the top of the layout context.
390
+ // TODO DEVSIX-5086 When flex-wrap will be fully supported we'll need to reconsider this.
391
+ // The question is what should be set/calculated for the next line
392
+ overflowRenderer .setProperty (Property .ALIGN_ITEMS , null );
393
+
394
+ float occupiedSpace = 0 ;
395
+ boolean metChildRendererInLine = false ;
396
+ for (final FlexItemInfo itemInfo : line ) {
397
+ // Split the line
398
+ if (itemInfo .getRenderer () == childRenderer ) {
399
+ metChildRendererInLine = true ;
400
+ if (childResult .getSplitRenderer () != null ) {
401
+ splitRenderer .addChildRenderer (childResult .getSplitRenderer ());
402
+ }
403
+
404
+ if (childResult .getOverflowRenderer () != null ) {
405
+ overflowRenderer .addChildRenderer (childResult .getOverflowRenderer ());
406
+ }
407
+ } else if (metChildRendererInLine ) {
408
+ // Process all following renderers in the current line
409
+ // We have to layout them to understand what goes where
410
+ final Rectangle neighbourBbox = getOccupiedAreaBBox ().clone ();
411
+ // Move bbox by occupied space
412
+ neighbourBbox .setX (neighbourBbox .getX () + occupiedSpace );
413
+ neighbourBbox .setWidth (itemInfo .getRectangle ().getWidth ());
414
+
415
+ // Y of the renderer has been already calculated, move bbox accordingly
416
+ neighbourBbox .setY (neighbourBbox .getY () - itemInfo .getRectangle ().getY ());
417
+
418
+ final LayoutResult neighbourLayoutResult = itemInfo .getRenderer ().layout (new LayoutContext (
419
+ new LayoutArea (childResult .getOccupiedArea ().getPageNumber (), neighbourBbox )));
420
+ // Handle result
421
+ if (neighbourLayoutResult .getStatus () == LayoutResult .PARTIAL &&
422
+ neighbourLayoutResult .getSplitRenderer () != null ) {
423
+ splitRenderer .addChildRenderer (neighbourLayoutResult .getSplitRenderer ());
424
+ } else if (neighbourLayoutResult .getStatus () == LayoutResult .FULL ) {
425
+ splitRenderer .addChildRenderer (itemInfo .getRenderer ());
426
+ } else {
427
+ // LayoutResult.NOTHING
428
+ }
429
+
430
+ if (neighbourLayoutResult .getOverflowRenderer () != null ) {
431
+ overflowRenderer .addChildRenderer (neighbourLayoutResult .getOverflowRenderer ());
432
+ } else {
433
+ // Here we might need to still occupy the space on overflow renderer
434
+ addSimulateDiv (overflowRenderer , itemInfo .getRectangle ().getWidth ());
435
+ }
436
+ } else {
437
+ // Process all preceeding renderers in the current line
438
+ // They all were layouted as FULL so add them into split renderer
439
+ splitRenderer .addChildRenderer (itemInfo .getRenderer ());
440
+
441
+ // But we also need to occupy the space on overflow renderer
442
+ addSimulateDiv (overflowRenderer , itemInfo .getRectangle ().getWidth ());
443
+ }
444
+
445
+ // X is nonzero only for the 1st renderer in line serving for alignment adjustments
446
+ occupiedSpace += itemInfo .getRectangle ().getX () + itemInfo .getRectangle ().getWidth ();
447
+ }
448
+ }
449
+
376
450
private void findMinMaxWidthIfCorrespondingPropertiesAreNotSet (MinMaxWidth minMaxWidth ,
377
451
AbstractWidthHandler minMaxWidthHandler ) {
378
452
// TODO DEVSIX-5086 When flex-wrap will be fully supported we'll find min/max width with respect to the lines
@@ -390,4 +464,9 @@ private void findMinMaxWidthIfCorrespondingPropertiesAreNotSet(MinMaxWidth minMa
390
464
}
391
465
}
392
466
467
+ private static void addSimulateDiv (AbstractRenderer overflowRenderer , float width ) {
468
+ final IRenderer fakeOverflowRenderer = new DivRenderer (
469
+ new Div ().setMinWidth (width ).setMaxWidth (width ));
470
+ overflowRenderer .addChildRenderer (fakeOverflowRenderer );
471
+ }
393
472
}
0 commit comments