@@ -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 ;
@@ -130,26 +131,33 @@ public LayoutResult layout(LayoutContext layoutContext) {
130
131
float [] paddings = getPaddings ();
131
132
applyBordersPaddingsMargins (parentBBox , borders , paddings );
132
133
133
- if (blockWidth != null && (blockWidth < parentBBox .getWidth () || isPositioned || rotation != null )) {
134
+ OverflowPropertyValue overflowX = this .<OverflowPropertyValue >getProperty (Property .OVERFLOW_X );
135
+ OverflowPropertyValue overflowY = this .<OverflowPropertyValue >getProperty (Property .OVERFLOW_Y );
136
+
137
+ if (blockWidth != null && (blockWidth < parentBBox .getWidth () || isPositioned || rotation != null || (null != overflowX && !OverflowPropertyValue .FIT .equals (overflowX )))) {
134
138
// TODO DEVSIX-1174
135
139
UnitValue widthVal = this .<UnitValue >getProperty (Property .WIDTH );
136
- if (widthVal != null && widthVal .isPercentValue () && widthVal .getValue () == 100 ) {
140
+ if (widthVal != null && widthVal .isPercentValue () && widthVal .getValue () == 100 && ( null == overflowX || OverflowPropertyValue . FIT . equals ( overflowX )) ) {
137
141
} else {
138
142
parentBBox .setWidth ((float ) blockWidth );
139
143
}
140
144
}
141
145
142
146
Float blockMaxHeight = retrieveMaxHeight ();
143
- if (!isFixedLayout () && null != blockMaxHeight && blockMaxHeight < parentBBox .getHeight ()
147
+ if (!isFixedLayout () && null != blockMaxHeight && ( blockMaxHeight < parentBBox .getHeight () || ( null != overflowY && ! OverflowPropertyValue . FIT . equals ( overflowY )) )
144
148
&& !Boolean .TRUE .equals (getPropertyAsBoolean (Property .FORCED_PLACEMENT ))) {
149
+ if (blockMaxHeight < parentBBox .getHeight ()) {
150
+ wasHeightClipped = true ;
151
+ }
145
152
float heightDelta = parentBBox .getHeight () - (float ) blockMaxHeight ;
146
153
if (marginsCollapsingEnabled && !isCellRenderer ) {
147
154
marginsCollapseHandler .processFixedHeightAdjustment (heightDelta );
148
155
}
149
156
parentBBox .moveUp (heightDelta ).setHeight ((float ) blockMaxHeight );
150
- wasHeightClipped = true ;
151
157
}
152
158
159
+ Rectangle contentBoxToFit = parentBBox .clone ();
160
+
153
161
List <Rectangle > areas ;
154
162
if (isPositioned ) {
155
163
areas = Collections .singletonList (parentBBox );
@@ -188,7 +196,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
188
196
|| Boolean .TRUE .equals (getPropertyAsBoolean (Property .FILL_AVAILABLE_AREA ))) {
189
197
occupiedArea .setBBox (Rectangle .getCommonRectangle (occupiedArea .getBBox (), layoutBox ));
190
198
} else if (result .getOccupiedArea () != null && result .getStatus () != LayoutResult .NOTHING ) {
191
- occupiedArea .setBBox (Rectangle .getCommonRectangle (occupiedArea .getBBox (), result .getOccupiedArea ().getBBox ()));
199
+ occupiedArea .setBBox (Rectangle .getCommonRectangle (occupiedArea .getBBox (), result .getOccupiedArea ().getBBox ()). setWidth ( occupiedArea . getBBox (). getWidth ()) );
192
200
}
193
201
194
202
if (FloatingHelper .isRendererFloating (this ) || isCellRenderer ) {
@@ -349,7 +357,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
349
357
350
358
if (result .getOccupiedArea () != null ) {
351
359
if (!FloatingHelper .isRendererFloating (childRenderer )) { // this check is needed only if margins collapsing is enabled
352
- occupiedArea .setBBox (Rectangle .getCommonRectangle (occupiedArea .getBBox (), result .getOccupiedArea ().getBBox ()));
360
+ occupiedArea .setBBox (Rectangle .getCommonRectangle (occupiedArea .getBBox (), result .getOccupiedArea ().getBBox ()). setWidth ( occupiedArea . getBBox (). getWidth ()) );
353
361
}
354
362
}
355
363
if (marginsCollapsingEnabled ) {
@@ -388,7 +396,10 @@ public LayoutResult layout(LayoutContext layoutContext) {
388
396
if (isFixedLayout ()) {
389
397
occupiedArea .getBBox ().moveDown ((float ) blockMinHeight - occupiedArea .getBBox ().getHeight ()).setHeight ((float ) blockMinHeight );
390
398
} else {
391
- float blockBottom = Math .max (occupiedArea .getBBox ().getBottom () - ((float ) blockMinHeight - occupiedArea .getBBox ().getHeight ()), layoutBox .getBottom ());
399
+ float blockBottom = occupiedArea .getBBox ().getBottom () - ((float ) blockMinHeight - occupiedArea .getBBox ().getHeight ());
400
+ if ((null == overflowY || OverflowPropertyValue .FIT .equals (overflowY )) && blockBottom < layoutBox .getBottom ()) {
401
+ blockBottom = layoutBox .getBottom ();
402
+ }
392
403
occupiedArea .getBBox ()
393
404
.increaseHeight (occupiedArea .getBBox ().getBottom () - blockBottom )
394
405
.setY (blockBottom );
@@ -426,6 +437,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
426
437
correctPositionedLayout (layoutBox );
427
438
}
428
439
440
+ float overflowPartHeight = getOverflowPartHeight (overflowY , contentBoxToFit );
429
441
applyPaddings (occupiedArea .getBBox (), paddings , true );
430
442
applyBorderBox (occupiedArea .getBBox (), borders , true );
431
443
applyMargins (occupiedArea .getBBox (), true );
@@ -459,6 +471,9 @@ public LayoutResult layout(LayoutContext layoutContext) {
459
471
}
460
472
}
461
473
}
474
+ if (wasHeightClipped ) {
475
+ occupiedArea .getBBox ().moveUp (overflowPartHeight ).decreaseHeight (overflowPartHeight );
476
+ }
462
477
463
478
if (null == overflowRenderer ) {
464
479
return new LayoutResult (LayoutResult .FULL , editedArea , null , null , causeOfNothing );
@@ -535,8 +550,29 @@ public void draw(DrawContext drawContext) {
535
550
536
551
drawBackground (drawContext );
537
552
drawBorder (drawContext );
553
+
554
+ OverflowPropertyValue overflowX = this .<OverflowPropertyValue >getProperty (Property .OVERFLOW_X );
555
+ OverflowPropertyValue overflowY = this .<OverflowPropertyValue >getProperty (Property .OVERFLOW_Y );
556
+ boolean processOverflow = OverflowPropertyValue .HIDDEN .equals (overflowX ) || OverflowPropertyValue .HIDDEN .equals (overflowY );
557
+
558
+ if (processOverflow ) {
559
+ drawContext .getCanvas ().saveState ();
560
+ Rectangle clippedArea = drawContext .getDocument ().getPage (occupiedArea .getPageNumber ()).getPageSize ();
561
+ Rectangle area = getBorderAreaBBox ();
562
+ if (OverflowPropertyValue .HIDDEN .equals (overflowX )) {
563
+ clippedArea .setX (area .getX ()).setWidth (area .getWidth ());
564
+ }
565
+ if (OverflowPropertyValue .HIDDEN .equals (overflowY )) {
566
+ clippedArea .setY (area .getY ()).setHeight (area .getHeight ());
567
+ }
568
+ drawContext .getCanvas ().rectangle (clippedArea ).clip ().newPath ();
569
+ }
570
+
538
571
drawChildren (drawContext );
539
572
drawPositionedChildren (drawContext );
573
+ if (processOverflow ) {
574
+ drawContext .getCanvas ().restoreState ();
575
+ }
540
576
541
577
endRotationIfApplied (drawContext .getCanvas ());
542
578
endElementOpacityApplying (drawContext );
@@ -735,6 +771,16 @@ protected void correctPositionedLayout(Rectangle layoutBox) {
735
771
}
736
772
}
737
773
774
+ protected float getOverflowPartHeight (OverflowPropertyValue overflowY , Rectangle parentBox ) {
775
+ float difference = 0 ;
776
+ if (null != overflowY && OverflowPropertyValue .FIT != overflowY ) {
777
+ if (occupiedArea .getBBox ().getBottom () < parentBox .getBottom ()) {
778
+ difference = parentBox .getBottom () - occupiedArea .getBBox ().getBottom ();
779
+ }
780
+ }
781
+ return difference ;
782
+ }
783
+
738
784
protected float applyBordersPaddingsMargins (Rectangle parentBBox , Border [] borders , float [] paddings ) {
739
785
float parentWidth = parentBBox .getWidth ();
740
786
0 commit comments