Skip to content

Commit 60234f2

Browse files
committed
Fix overflow functionality to process rotation and long words correctly. Minor changes.
DEVSIX-992
1 parent 2b3980f commit 60234f2

File tree

10 files changed

+231
-65
lines changed

10 files changed

+231
-65
lines changed

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
196196
occupiedArea.setBBox(Rectangle.getCommonRectangle(occupiedArea.getBBox(), layoutBox));
197197
} else if (result.getOccupiedArea() != null && result.getStatus() != LayoutResult.NOTHING) {
198198
occupiedArea.setBBox(Rectangle.getCommonRectangle(occupiedArea.getBBox(), result.getOccupiedArea().getBBox()));
199-
if (occupiedArea.getBBox().getWidth() > layoutBox.getWidth()) {
199+
if (occupiedArea.getBBox().getWidth() > layoutBox.getWidth() && !(null == overflowX || OverflowPropertyValue.FIT.equals(overflowX))) {
200200
occupiedArea.getBBox().setWidth(layoutBox.getWidth());
201201
}
202202
}
@@ -360,7 +360,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
360360
if (result.getOccupiedArea() != null) {
361361
if (!FloatingHelper.isRendererFloating(childRenderer)) { // this check is needed only if margins collapsing is enabled
362362
occupiedArea.setBBox(Rectangle.getCommonRectangle(occupiedArea.getBBox(), result.getOccupiedArea().getBBox()));
363-
if (occupiedArea.getBBox().getWidth() > layoutBox.getWidth()) {
363+
if (occupiedArea.getBBox().getWidth() > layoutBox.getWidth() && !(null == overflowX || OverflowPropertyValue.FIT.equals(overflowX))) {
364364
occupiedArea.getBBox().setWidth(layoutBox.getWidth());
365365
}
366366
}
@@ -469,6 +469,10 @@ public LayoutResult layout(LayoutContext layoutContext) {
469469
}
470470
applyVerticalAlignment();
471471

472+
if (wasHeightClipped) {
473+
occupiedArea.getBBox().moveUp(overflowPartHeight).decreaseHeight(overflowPartHeight);
474+
}
475+
472476
FloatingHelper.removeFloatsAboveRendererBottom(floatRendererAreas, this);
473477
LayoutArea editedArea = FloatingHelper.adjustResultOccupiedAreaForFloatAndClear(this, layoutContext.getFloatRendererAreas(), layoutContext.getArea().getBBox(), clearHeightCorrection, marginsCollapsingEnabled);
474478

@@ -484,10 +488,6 @@ public LayoutResult layout(LayoutContext layoutContext) {
484488
}
485489
}
486490
}
487-
if (wasHeightClipped) {
488-
editedArea.getBBox().moveUp(overflowPartHeight).decreaseHeight(overflowPartHeight);
489-
occupiedArea.getBBox().moveUp(overflowPartHeight).decreaseHeight(overflowPartHeight);
490-
}
491491

492492
if (null == overflowRenderer) {
493493
return new LayoutResult(LayoutResult.FULL, editedArea, null, null, causeOfNothing);

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,16 @@ static void removeFloatsAboveRendererBottom(List<Rectangle> floatRendererAreas,
224224
static LayoutArea adjustResultOccupiedAreaForFloatAndClear(IRenderer renderer, List<Rectangle> floatRendererAreas,
225225
Rectangle parentBBox, float clearHeightCorrection, boolean marginsCollapsingEnabled) {
226226
LayoutArea occupiedArea = renderer.getOccupiedArea();
227-
LayoutArea editedArea = occupiedArea.clone();
227+
LayoutArea editedArea = occupiedArea;
228228
if (isRendererFloating(renderer)) {
229+
editedArea = occupiedArea.clone();
229230
if (occupiedArea.getBBox().getWidth() > 0) {
230231
floatRendererAreas.add(occupiedArea.getBBox());
231232
}
232233
editedArea.getBBox().setY(parentBBox.getTop());
233234
editedArea.getBBox().setHeight(0);
234235
} else if (clearHeightCorrection > 0 && !marginsCollapsingEnabled) {
236+
editedArea = occupiedArea.clone();
235237
editedArea.getBBox().increaseHeight(clearHeightCorrection);
236238
}
237239

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

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -336,26 +336,7 @@ public void draw(DrawContext drawContext) {
336336

337337
PdfXObject xObject = ((Image) (getModelElement())).getXObject();
338338
beginElementOpacityApplying(drawContext);
339-
OverflowPropertyValue overflowX = this.parent.<OverflowPropertyValue>getProperty(Property.OVERFLOW_X);
340-
OverflowPropertyValue overflowY = this.parent.<OverflowPropertyValue>getProperty(Property.OVERFLOW_Y);
341-
boolean processOverflow = OverflowPropertyValue.HIDDEN.equals(overflowX) || OverflowPropertyValue.HIDDEN.equals(overflowY);
342-
if (processOverflow) {
343-
drawContext.getCanvas().saveState();
344-
345-
Rectangle clippedArea = drawContext.getDocument().getPage(occupiedArea.getPageNumber()).getPageSize();
346-
if (OverflowPropertyValue.HIDDEN.equals(overflowX)) {
347-
clippedArea.setX(occupiedArea.getBBox().getX()).setWidth(occupiedArea.getBBox().getWidth());
348-
}
349-
if (OverflowPropertyValue.HIDDEN.equals(overflowY)) {
350-
clippedArea.setY(occupiedArea.getBBox().getY()).setHeight(occupiedArea.getBBox().getHeight());
351-
}
352-
353-
drawContext.getCanvas().rectangle(clippedArea).clip().newPath();
354-
}
355339
canvas.addXObject(xObject, matrix[0], matrix[1], matrix[2], matrix[3], (float) fixedXPosition + deltaX, (float) fixedYPosition);
356-
if (processOverflow) {
357-
drawContext.getCanvas().restoreState();
358-
}
359340
endElementOpacityApplying(drawContext);
360341
if (Boolean.TRUE.equals(getPropertyAsBoolean(Property.FLUSH_ON_DRAW))) {
361342
xObject.flush();

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ public LineLayoutResult layout(LayoutContext layoutContext) {
204204
// when floating span is split on other line;
205205
// TODO may be process floating spans as inline blocks always?
206206

207-
if (childPos > 0) {
207+
if (!wasXOverflowChanged && childPos > 0) {
208208
oldXOverflow = this.<OverflowPropertyValue>getProperty(Property.OVERFLOW_X);
209209
wasXOverflowChanged = true;
210210
setProperty(Property.OVERFLOW_X, OverflowPropertyValue.FIT);
@@ -295,7 +295,7 @@ public LineLayoutResult layout(LayoutContext layoutContext) {
295295
setProperty(Property.OVERFLOW_X, OverflowPropertyValue.FIT);
296296
}
297297
if (childResult == null) {
298-
if (childPos > 0) {
298+
if (!wasXOverflowChanged && childPos > 0) {
299299
oldXOverflow = this.<OverflowPropertyValue>getProperty(Property.OVERFLOW_X);
300300
wasXOverflowChanged = true;
301301
setProperty(Property.OVERFLOW_X, OverflowPropertyValue.FIT);
@@ -402,7 +402,13 @@ public LineLayoutResult layout(LayoutContext layoutContext) {
402402

403403
boolean wordWasSplitAndItWillFitOntoNextLine = false;
404404
if (childResult instanceof TextLayoutResult && ((TextLayoutResult) childResult).isWordHasBeenSplit()) {
405+
if (wasXOverflowChanged) {
406+
setProperty(Property.OVERFLOW_X, oldXOverflow);
407+
}
405408
LayoutResult newLayoutResult = childRenderer.layout(new LayoutContext(new LayoutArea(layoutContext.getArea().getPageNumber(), layoutBox, wasParentsHeightClipped)));
409+
if (wasXOverflowChanged) {
410+
setProperty(Property.OVERFLOW_X, OverflowPropertyValue.FIT);
411+
}
406412
if (newLayoutResult instanceof TextLayoutResult && !((TextLayoutResult) newLayoutResult).isWordHasBeenSplit()) {
407413
wordWasSplitAndItWillFitOntoNextLine = true;
408414
}

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
135135
Border[] borders = getBorders();
136136
float[] paddings = getPaddings();
137137
float additionalWidth = applyBordersPaddingsMargins(parentBBox, borders, paddings);
138-
if (blockWidth != null && (blockWidth < parentBBox.getWidth() || isPositioned || (null != overflowX && OverflowPropertyValue.FIT != overflowX))) {
138+
if (blockWidth != null && (blockWidth < parentBBox.getWidth() || isPositioned || rotation != null || (null != overflowX && OverflowPropertyValue.FIT != overflowX))) {
139139
parentBBox.setWidth((float) blockWidth);
140140
}
141141

@@ -324,7 +324,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
324324
} else {
325325
if (Boolean.TRUE.equals(getPropertyAsBoolean(Property.FORCED_PLACEMENT))) {
326326
occupiedArea.setBBox(Rectangle.getCommonRectangle(occupiedArea.getBBox(), currentRenderer.getOccupiedArea().getBBox()));
327-
if (occupiedArea.getBBox().getWidth() > layoutBox.getWidth()) {
327+
if (occupiedArea.getBBox().getWidth() > layoutBox.getWidth() && !(null == overflowX || OverflowPropertyValue.FIT.equals(overflowX))) {
328328
occupiedArea.getBBox().setWidth(layoutBox.getWidth());
329329
}
330330
parent.setProperty(Property.FULL, true);
@@ -354,7 +354,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
354354
}
355355
if (lineHasContent) {
356356
occupiedArea.setBBox(Rectangle.getCommonRectangle(occupiedArea.getBBox(), processedRenderer.getOccupiedArea().getBBox()));
357-
if (occupiedArea.getBBox().getWidth() > layoutBox.getWidth()) {
357+
if (occupiedArea.getBBox().getWidth() > layoutBox.getWidth() && !(null == overflowX || OverflowPropertyValue.FIT.equals(overflowX))) {
358358
occupiedArea.getBBox().setWidth(layoutBox.getWidth());
359359
}
360360
}
@@ -429,13 +429,12 @@ public LayoutResult layout(LayoutContext layoutContext) {
429429
}
430430
}
431431

432-
FloatingHelper.removeFloatsAboveRendererBottom(floatRendererAreas, this);
433-
LayoutArea editedArea = FloatingHelper.adjustResultOccupiedAreaForFloatAndClear(this, layoutContext.getFloatRendererAreas(), layoutContext.getArea().getBBox(), clearHeightCorrection, marginsCollapsingEnabled);
434-
435432
if (wasHeightClipped) {
436-
editedArea.getBBox().moveUp(overflowPartHeight).decreaseHeight(overflowPartHeight);
437433
occupiedArea.getBBox().moveUp(overflowPartHeight).decreaseHeight(overflowPartHeight);
438434
}
435+
FloatingHelper.removeFloatsAboveRendererBottom(floatRendererAreas, this);
436+
LayoutArea editedArea = FloatingHelper.adjustResultOccupiedAreaForFloatAndClear(this, layoutContext.getFloatRendererAreas(), layoutContext.getArea().getBBox(), clearHeightCorrection, marginsCollapsingEnabled);
437+
439438

440439
if (null == overflowRenderer) {
441440
return new MinMaxWidthLayoutResult(LayoutResult.FULL, editedArea, null, null, null).setMinMaxWidth(minMaxWidth);

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,9 +302,7 @@ protected void flushWaitingDrawingElements() {
302302
protected void shrinkCurrentAreaAndProcessRenderer(IRenderer renderer, List<IRenderer> resultRenderers, LayoutResult result) {
303303
if (currentArea != null) {
304304
OverflowPropertyValue overflowY = renderer.<OverflowPropertyValue>getProperty(Property.OVERFLOW_Y);
305-
float resultRendererHeight = null == overflowY || OverflowPropertyValue.FIT.equals(overflowY) || FloatingHelper.isRendererFloating(renderer)
306-
? result.getOccupiedArea().getBBox().getHeight()
307-
: renderer.getOccupiedArea().getBBox().getHeight();
305+
float resultRendererHeight = result.getOccupiedArea().getBBox().getHeight();
308306
currentArea.getBBox().setHeight(currentArea.getBBox().getHeight() - resultRendererHeight);
309307
if (currentArea.isEmptyArea() && resultRendererHeight > 0) {
310308
currentArea.setEmptyArea(false);

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,6 @@ public LayoutResult layout(LayoutContext layoutContext) {
174174
FloatingHelper.adjustFloatedBlockLayoutBox(this, layoutBox, null, floatRendererAreas, floatPropertyValue);
175175
}
176176

177-
boolean isFirstOnLine = parent instanceof LineRenderer && null != parent.getOccupiedArea() && parent.getOccupiedArea().getBBox().getX() == layoutBox.getX();
178-
179177
float[] margins = getMargins();
180178
applyMargins(layoutBox, margins, false);
181179
Border[] borders = getBorders();
@@ -314,7 +312,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
314312
previousCharPos = ind;
315313

316314
if (nonBreakablePartFullWidth + italicSkewAddition + boldSimulationAddition > layoutBox.getWidth()) {
317-
if ((null == overflowX || OverflowPropertyValue.FIT.equals(overflowX)) || !isFirstOnLine) {
315+
if ((null == overflowX || OverflowPropertyValue.FIT.equals(overflowX))) {
318316
// we have extracted all the information we wanted and we do not want to continue.
319317
// we will have to split the word anyway.
320318
break;
@@ -409,10 +407,10 @@ public LayoutResult layout(LayoutContext layoutContext) {
409407
if (line.start == -1) {
410408
line.start = currentTextPos;
411409
}
412-
currentTextPos = (forcePartialSplitOnFirstChar || null == overflowX || OverflowPropertyValue.FIT.equals(overflowX) || !isFirstOnLine) ? firstCharacterWhichExceedsAllowedWidth : nonBreakablePartEnd+1;
410+
currentTextPos = (forcePartialSplitOnFirstChar || null == overflowX || OverflowPropertyValue.FIT.equals(overflowX)) ? firstCharacterWhichExceedsAllowedWidth : nonBreakablePartEnd+1;
413411
line.end = Math.max(line.end, currentTextPos);
414412
wordSplit = !forcePartialSplitOnFirstChar && (text.end != currentTextPos);
415-
if (wordSplit || !(forcePartialSplitOnFirstChar || null == overflowX || OverflowPropertyValue.FIT.equals(overflowX) || !isFirstOnLine)) {
413+
if (wordSplit || !(forcePartialSplitOnFirstChar || null == overflowX || OverflowPropertyValue.FIT.equals(overflowX))) {
416414
currentLineAscender = Math.max(currentLineAscender, nonBreakablePartMaxAscender);
417415
currentLineDescender = Math.min(currentLineDescender, nonBreakablePartMaxDescender);
418416
currentLineHeight = Math.max(currentLineHeight, nonBreakablePartMaxHeight);

0 commit comments

Comments
 (0)