@@ -68,6 +68,7 @@ This file is part of the iText (R) project.
68
68
import com .itextpdf .layout .minmaxwidth .MinMaxWidthUtils ;
69
69
import com .itextpdf .layout .property .AreaBreakType ;
70
70
import com .itextpdf .layout .property .FloatPropertyValue ;
71
+ import com .itextpdf .layout .property .OverflowPropertyValue ;
71
72
import com .itextpdf .layout .property .Property ;
72
73
import com .itextpdf .layout .property .UnitValue ;
73
74
import com .itextpdf .layout .property .VerticalAlignment ;
@@ -89,6 +90,7 @@ protected BlockRenderer(IElement modelElement) {
89
90
public LayoutResult layout (LayoutContext layoutContext ) {
90
91
overrideHeightProperties ();
91
92
boolean wasHeightClipped = false ;
93
+ boolean wasParentsHeightClipped = layoutContext .isClippedHeight ();
92
94
int pageNumber = layoutContext .getArea ().getPageNumber ();
93
95
94
96
boolean isPositioned = isPositioned ();
@@ -130,7 +132,11 @@ public LayoutResult layout(LayoutContext layoutContext) {
130
132
float [] paddings = getPaddings ();
131
133
applyBordersPaddingsMargins (parentBBox , borders , paddings );
132
134
133
- if (blockWidth != null && (blockWidth < parentBBox .getWidth () || isPositioned || rotation != null )) {
135
+ OverflowPropertyValue overflowX = this .<OverflowPropertyValue >getProperty (Property .OVERFLOW_X );
136
+ Float blockMaxHeight = retrieveMaxHeight ();
137
+ OverflowPropertyValue overflowY = (null == blockMaxHeight || blockMaxHeight > parentBBox .getHeight ()) && !wasParentsHeightClipped ? OverflowPropertyValue .FIT : this .<OverflowPropertyValue >getProperty (Property .OVERFLOW_Y );
138
+
139
+ if (blockWidth != null && (blockWidth < parentBBox .getWidth () || isPositioned || rotation != null || (null != overflowX && !OverflowPropertyValue .FIT .equals (overflowX )))) {
134
140
// TODO DEVSIX-1174
135
141
UnitValue widthVal = this .<UnitValue >getProperty (Property .WIDTH );
136
142
if (widthVal != null && widthVal .isPercentValue () && widthVal .getValue () == 100 ) {
@@ -139,15 +145,16 @@ public LayoutResult layout(LayoutContext layoutContext) {
139
145
}
140
146
}
141
147
142
- Float blockMaxHeight = retrieveMaxHeight ();
143
- if (!isFixedLayout () && null != blockMaxHeight && blockMaxHeight < parentBBox .getHeight ()
148
+ if (!isFixedLayout () && null != blockMaxHeight && (blockMaxHeight < parentBBox .getHeight () || (null != overflowY && !OverflowPropertyValue .FIT .equals (overflowY )))
144
149
&& !Boolean .TRUE .equals (getPropertyAsBoolean (Property .FORCED_PLACEMENT ))) {
150
+ if (blockMaxHeight < parentBBox .getHeight ()) {
151
+ wasHeightClipped = true ;
152
+ }
145
153
float heightDelta = parentBBox .getHeight () - (float ) blockMaxHeight ;
146
154
if (marginsCollapsingEnabled && !isCellRenderer ) {
147
155
marginsCollapseHandler .processFixedHeightAdjustment (heightDelta );
148
156
}
149
157
parentBBox .moveUp (heightDelta ).setHeight ((float ) blockMaxHeight );
150
- wasHeightClipped = true ;
151
158
}
152
159
153
160
List <Rectangle > areas ;
@@ -174,7 +181,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
174
181
if (marginsCollapsingEnabled ) {
175
182
childMarginsInfo = marginsCollapseHandler .startChildMarginsHandling (childRenderer , layoutBox );
176
183
}
177
- while ((result = childRenderer .setParent (this ).layout (new LayoutContext (new LayoutArea (pageNumber , layoutBox ), childMarginsInfo , floatRendererAreas )))
184
+ while ((result = childRenderer .setParent (this ).layout (new LayoutContext (new LayoutArea (pageNumber , layoutBox ), childMarginsInfo , floatRendererAreas , wasHeightClipped || wasParentsHeightClipped )))
178
185
.getStatus () != LayoutResult .FULL ) {
179
186
if (marginsCollapsingEnabled ) {
180
187
if (result .getStatus () != LayoutResult .NOTHING ) {
@@ -189,6 +196,9 @@ public LayoutResult layout(LayoutContext layoutContext) {
189
196
occupiedArea .setBBox (Rectangle .getCommonRectangle (occupiedArea .getBBox (), layoutBox ));
190
197
} else if (result .getOccupiedArea () != null && result .getStatus () != LayoutResult .NOTHING ) {
191
198
occupiedArea .setBBox (Rectangle .getCommonRectangle (occupiedArea .getBBox (), result .getOccupiedArea ().getBBox ()));
199
+ if (occupiedArea .getBBox ().getWidth () > layoutBox .getWidth () && !(null == overflowX || OverflowPropertyValue .FIT .equals (overflowX ))) {
200
+ occupiedArea .getBBox ().setWidth (layoutBox .getWidth ());
201
+ }
192
202
}
193
203
194
204
if (FloatingHelper .isRendererFloating (this ) || isCellRenderer ) {
@@ -350,6 +360,9 @@ public LayoutResult layout(LayoutContext layoutContext) {
350
360
if (result .getOccupiedArea () != null ) {
351
361
if (!FloatingHelper .isRendererFloating (childRenderer )) { // this check is needed only if margins collapsing is enabled
352
362
occupiedArea .setBBox (Rectangle .getCommonRectangle (occupiedArea .getBBox (), result .getOccupiedArea ().getBBox ()));
363
+ if (occupiedArea .getBBox ().getWidth () > layoutBox .getWidth () && !(null == overflowX || OverflowPropertyValue .FIT .equals (overflowX ))) {
364
+ occupiedArea .getBBox ().setWidth (layoutBox .getWidth ());
365
+ }
353
366
}
354
367
}
355
368
if (marginsCollapsingEnabled ) {
@@ -370,6 +383,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
370
383
causeOfNothing = result .getCauseOfNothing ();
371
384
}
372
385
}
386
+ float overflowPartHeight = getOverflowPartHeight (overflowY , layoutBox );
373
387
if (marginsCollapsingEnabled && !isCellRenderer ) {
374
388
marginsCollapseHandler .endMarginsCollapse (layoutBox );
375
389
}
@@ -388,7 +402,10 @@ public LayoutResult layout(LayoutContext layoutContext) {
388
402
if (isFixedLayout ()) {
389
403
occupiedArea .getBBox ().moveDown ((float ) blockMinHeight - occupiedArea .getBBox ().getHeight ()).setHeight ((float ) blockMinHeight );
390
404
} else {
391
- float blockBottom = Math .max (occupiedArea .getBBox ().getBottom () - ((float ) blockMinHeight - occupiedArea .getBBox ().getHeight ()), layoutBox .getBottom ());
405
+ float blockBottom = occupiedArea .getBBox ().getBottom () - ((float ) blockMinHeight - occupiedArea .getBBox ().getHeight ());
406
+ if ((null == overflowY || OverflowPropertyValue .FIT .equals (overflowY )) && blockBottom < layoutBox .getBottom ()) {
407
+ blockBottom = layoutBox .getBottom ();
408
+ }
392
409
occupiedArea .getBBox ()
393
410
.increaseHeight (occupiedArea .getBBox ().getBottom () - blockBottom )
394
411
.setY (blockBottom );
@@ -444,6 +461,10 @@ public LayoutResult layout(LayoutContext layoutContext) {
444
461
}
445
462
applyVerticalAlignment ();
446
463
464
+ if (wasHeightClipped ) {
465
+ occupiedArea .getBBox ().moveUp (overflowPartHeight ).decreaseHeight (overflowPartHeight );
466
+ }
467
+
447
468
FloatingHelper .removeFloatsAboveRendererBottom (floatRendererAreas , this );
448
469
LayoutArea editedArea = FloatingHelper .adjustResultOccupiedAreaForFloatAndClear (this , layoutContext .getFloatRendererAreas (), layoutContext .getArea ().getBBox (), clearHeightCorrection , marginsCollapsingEnabled );
449
470
@@ -535,8 +556,29 @@ public void draw(DrawContext drawContext) {
535
556
536
557
drawBackground (drawContext );
537
558
drawBorder (drawContext );
559
+
560
+ OverflowPropertyValue overflowX = this .<OverflowPropertyValue >getProperty (Property .OVERFLOW_X );
561
+ OverflowPropertyValue overflowY = this .<OverflowPropertyValue >getProperty (Property .OVERFLOW_Y );
562
+ boolean processOverflow = OverflowPropertyValue .HIDDEN .equals (overflowX ) || OverflowPropertyValue .HIDDEN .equals (overflowY );
563
+
564
+ if (processOverflow ) {
565
+ drawContext .getCanvas ().saveState ();
566
+ Rectangle clippedArea = drawContext .getDocument ().getPage (occupiedArea .getPageNumber ()).getPageSize ();
567
+ Rectangle area = getBorderAreaBBox ();
568
+ if (OverflowPropertyValue .HIDDEN .equals (overflowX )) {
569
+ clippedArea .setX (area .getX ()).setWidth (area .getWidth ());
570
+ }
571
+ if (OverflowPropertyValue .HIDDEN .equals (overflowY )) {
572
+ clippedArea .setY (area .getY ()).setHeight (area .getHeight ());
573
+ }
574
+ drawContext .getCanvas ().rectangle (clippedArea ).clip ().newPath ();
575
+ }
576
+
538
577
drawChildren (drawContext );
539
578
drawPositionedChildren (drawContext );
579
+ if (processOverflow ) {
580
+ drawContext .getCanvas ().restoreState ();
581
+ }
540
582
541
583
endRotationIfApplied (drawContext .getCanvas ());
542
584
endElementOpacityApplying (drawContext );
@@ -735,6 +777,16 @@ protected void correctPositionedLayout(Rectangle layoutBox) {
735
777
}
736
778
}
737
779
780
+ float getOverflowPartHeight (OverflowPropertyValue overflowY , Rectangle parentBox ) {
781
+ float difference = 0 ;
782
+ if (null != overflowY && OverflowPropertyValue .FIT != overflowY ) {
783
+ if (occupiedArea .getBBox ().getBottom () < parentBox .getBottom ()) {
784
+ difference = parentBox .getBottom () - occupiedArea .getBBox ().getBottom ();
785
+ }
786
+ }
787
+ return difference ;
788
+ }
789
+
738
790
protected float applyBordersPaddingsMargins (Rectangle parentBBox , Border [] borders , float [] paddings ) {
739
791
float parentWidth = parentBBox .getWidth ();
740
792
@@ -777,7 +829,8 @@ protected MinMaxWidth getMinMaxWidth(float availableWidth) {
777
829
778
830
MinMaxWidth correctMinMaxWidth (MinMaxWidth minMaxWidth ) {
779
831
Float width = retrieveWidth (-1 );
780
- if (width != null && width >= 0 && width >= minMaxWidth .getChildrenMinWidth ()) {
832
+ OverflowPropertyValue overflowX = this .<OverflowPropertyValue >getProperty (Property .OVERFLOW_X );
833
+ if (width != null && width >= 0 && (width >= minMaxWidth .getChildrenMinWidth () || !OverflowPropertyValue .FIT .equals (overflowX ))) {
781
834
minMaxWidth .setChildrenMaxWidth ((float ) width );
782
835
minMaxWidth .setChildrenMinWidth ((float ) width );
783
836
}
0 commit comments