Skip to content

Commit 6d9090a

Browse files
ars18wrwiText-CI
authored andcommitted
Apply text chunk's characteristics to a line only if the chunk is going to be drawn inside that line.
Add some new tests to demonstrate the issue. DEVSIX-2552 Autoported commit. Original commit hash: [d9f7ccd1f]
1 parent 842de3e commit 6d9090a

File tree

6 files changed

+125
-41
lines changed

6 files changed

+125
-41
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using System;
2+
using iText.Kernel.Colors;
3+
using iText.Kernel.Pdf;
4+
using iText.Kernel.Utils;
5+
using iText.Layout.Borders;
6+
using iText.Layout.Element;
7+
using iText.Layout.Properties;
8+
using iText.Test;
9+
10+
namespace iText.Layout {
11+
public class ParagraphTest : ExtendedITextTest {
12+
public static readonly String destinationFolder = NUnit.Framework.TestContext.CurrentContext.TestDirectory
13+
+ "/test/itext/layout/ParagraphTest/";
14+
15+
public static readonly String sourceFolder = iText.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
16+
.CurrentContext.TestDirectory) + "/resources/itext/layout/ParagraphTest/";
17+
18+
[NUnit.Framework.OneTimeSetUp]
19+
public static void BeforeClass() {
20+
CreateDestinationFolder(destinationFolder);
21+
}
22+
23+
/// <exception cref="System.IO.IOException"/>
24+
/// <exception cref="System.Exception"/>
25+
[NUnit.Framework.Test]
26+
public virtual void CannotPlaceABigChunkOnALineTest01() {
27+
String outFileName = destinationFolder + "cannotPlaceABigChunkOnALineTest01.pdf";
28+
String cmpFileName = sourceFolder + "cmp_cannotPlaceABigChunkOnALineTest01.pdf";
29+
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
30+
Document doc = new Document(pdfDocument);
31+
Paragraph p = new Paragraph().SetBorder(new SolidBorder(ColorConstants.YELLOW, 0));
32+
p.Add(new Text("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").SetBorder
33+
(new SolidBorder(ColorConstants.RED, 0)));
34+
p.Add(new Text("b").SetFontSize(100).SetBorder(new SolidBorder(ColorConstants.BLUE, 0)));
35+
doc.Add(p);
36+
doc.Close();
37+
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
38+
, "diff"));
39+
}
40+
41+
/// <exception cref="System.IO.IOException"/>
42+
/// <exception cref="System.Exception"/>
43+
[NUnit.Framework.Test]
44+
public virtual void CannotPlaceABigChunkOnALineTest02() {
45+
String outFileName = destinationFolder + "cannotPlaceABigChunkOnALineTest02.pdf";
46+
String cmpFileName = sourceFolder + "cmp_cannotPlaceABigChunkOnALineTest02.pdf";
47+
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
48+
Document doc = new Document(pdfDocument);
49+
Paragraph p = new Paragraph().SetBorder(new SolidBorder(ColorConstants.YELLOW, 0));
50+
p.Add(new Text("smaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaall").SetFontSize(5).SetBorder
51+
(new SolidBorder(ColorConstants.RED, 0)));
52+
p.Add(new Text("biiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiig"
53+
).SetFontSize(20).SetBorder(new SolidBorder(ColorConstants.BLUE, 0)));
54+
doc.Add(p);
55+
doc.Close();
56+
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
57+
, "diff"));
58+
}
59+
60+
/// <exception cref="System.IO.IOException"/>
61+
/// <exception cref="System.Exception"/>
62+
[NUnit.Framework.Test]
63+
public virtual void WordWasSplitAndItWillFitOntoNextLineTest01() {
64+
String outFileName = destinationFolder + "wordWasSplitAndItWillFitOntoNextLineTest01.pdf";
65+
String cmpFileName = sourceFolder + "cmp_wordWasSplitAndItWillFitOntoNextLineTest01.pdf";
66+
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
67+
Document doc = new Document(pdfDocument);
68+
Paragraph p = new Paragraph().SetBorder(new SolidBorder(ColorConstants.YELLOW, 0)).SetTextAlignment(TextAlignment
69+
.RIGHT);
70+
for (int i = 0; i < 5; i++) {
71+
p.Add(new Text("aaaaaaaaaaaaaaaaaaaaa" + i).SetBorder(new SolidBorder(ColorConstants.BLUE, 0)));
72+
}
73+
doc.Add(p);
74+
doc.Close();
75+
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
76+
, "diff"));
77+
}
78+
}
79+
}

itext/itext.layout/itext/layout/renderer/LineRenderer.cs

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,14 @@ source product.
5555

5656
namespace iText.Layout.Renderer {
5757
public class LineRenderer : AbstractRenderer {
58+
private const float MIN_MAX_WIDTH_CORRECTION_EPS = 0.001f;
59+
5860
protected internal float maxAscent;
5961

6062
protected internal float maxDescent;
6163

6264
protected internal byte[] levels;
6365

64-
private const float MIN_MAX_WIDTH_CORRECTION_EPS = 0.001f;
65-
6666
private float maxTextAscent;
6767

6868
private float maxTextDescent;
@@ -71,8 +71,8 @@ public class LineRenderer : AbstractRenderer {
7171

7272
private float maxBlockDescent;
7373

74-
// bidi levels
7574
// AbstractRenderer.EPS is not enough here
75+
// bidi levels
7676
public override LayoutResult Layout(LayoutContext layoutContext) {
7777
Rectangle layoutBox = layoutContext.GetArea().GetBBox().Clone();
7878
bool wasParentsHeightClipped = layoutContext.IsClippedHeight();
@@ -375,28 +375,45 @@ public override LayoutResult Layout(LayoutContext layoutContext) {
375375
}
376376
}
377377
}
378-
maxAscent = Math.Max(maxAscent, childAscent);
379-
if (childRenderer is TextRenderer) {
380-
maxTextAscent = Math.Max(maxTextAscent, childAscent);
381-
}
382-
else {
383-
if (!isChildFloating) {
384-
maxBlockAscent = Math.Max(maxBlockAscent, childAscent);
378+
bool newLineOccurred = (childResult is TextLayoutResult && ((TextLayoutResult)childResult).IsSplitForcedByNewline
379+
());
380+
bool shouldBreakLayouting = childResult.GetStatus() != LayoutResult.FULL || newLineOccurred;
381+
bool wordWasSplitAndItWillFitOntoNextLine = false;
382+
if (shouldBreakLayouting && childResult is TextLayoutResult && ((TextLayoutResult)childResult).IsWordHasBeenSplit
383+
()) {
384+
if (wasXOverflowChanged) {
385+
SetProperty(Property.OVERFLOW_X, oldXOverflow);
386+
}
387+
LayoutResult newLayoutResult = childRenderer.Layout(new LayoutContext(new LayoutArea(layoutContext.GetArea
388+
().GetPageNumber(), layoutBox), wasParentsHeightClipped));
389+
if (wasXOverflowChanged) {
390+
SetProperty(Property.OVERFLOW_X, OverflowPropertyValue.FIT);
391+
}
392+
if (newLayoutResult is TextLayoutResult && !((TextLayoutResult)newLayoutResult).IsWordHasBeenSplit()) {
393+
wordWasSplitAndItWillFitOntoNextLine = true;
385394
}
386395
}
387-
maxDescent = Math.Min(maxDescent, childDescent);
388-
if (childRenderer is TextRenderer) {
389-
maxTextDescent = Math.Min(maxTextDescent, childDescent);
390-
}
391-
else {
392-
if (!isChildFloating) {
393-
maxBlockDescent = Math.Min(maxBlockDescent, childDescent);
396+
if (!wordWasSplitAndItWillFitOntoNextLine) {
397+
maxAscent = Math.Max(maxAscent, childAscent);
398+
if (childRenderer is TextRenderer) {
399+
maxTextAscent = Math.Max(maxTextAscent, childAscent);
400+
}
401+
else {
402+
if (!isChildFloating) {
403+
maxBlockAscent = Math.Max(maxBlockAscent, childAscent);
404+
}
405+
}
406+
maxDescent = Math.Min(maxDescent, childDescent);
407+
if (childRenderer is TextRenderer) {
408+
maxTextDescent = Math.Min(maxTextDescent, childDescent);
409+
}
410+
else {
411+
if (!isChildFloating) {
412+
maxBlockDescent = Math.Min(maxBlockDescent, childDescent);
413+
}
394414
}
395415
}
396416
float maxHeight = maxAscent - maxDescent;
397-
bool newLineOccurred = (childResult is TextLayoutResult && ((TextLayoutResult)childResult).IsSplitForcedByNewline
398-
());
399-
bool shouldBreakLayouting = childResult.GetStatus() != LayoutResult.FULL || newLineOccurred;
400417
float currChildTextIndent = anythingPlaced ? 0 : lineLayoutContext.GetTextIndent();
401418
if (hangingTabStop != null && (TabAlignment.LEFT == hangingTabStop.GetTabAlignment() || shouldBreakLayouting
402419
|| childRenderers.Count - 1 == childPos || childRenderers[childPos + 1] is TabRenderer)) {
@@ -436,25 +453,13 @@ public override LayoutResult Layout(LayoutContext layoutContext) {
436453
widthHandler.UpdateMaxChildWidth(maxChildWidth_1 + currChildTextIndent);
437454
}
438455
}
439-
occupiedArea.SetBBox(new Rectangle(layoutBox.GetX(), layoutBox.GetY() + layoutBox.GetHeight() - maxHeight,
440-
curWidth, maxHeight));
456+
if (!wordWasSplitAndItWillFitOntoNextLine) {
457+
occupiedArea.SetBBox(new Rectangle(layoutBox.GetX(), layoutBox.GetY() + layoutBox.GetHeight() - maxHeight,
458+
curWidth, maxHeight));
459+
}
441460
if (shouldBreakLayouting) {
442461
LineRenderer[] split = Split();
443462
split[0].childRenderers = new List<IRenderer>(childRenderers.SubList(0, childPos));
444-
bool wordWasSplitAndItWillFitOntoNextLine = false;
445-
if (childResult is TextLayoutResult && ((TextLayoutResult)childResult).IsWordHasBeenSplit()) {
446-
if (wasXOverflowChanged) {
447-
SetProperty(Property.OVERFLOW_X, oldXOverflow);
448-
}
449-
LayoutResult newLayoutResult = childRenderer.Layout(new LayoutContext(new LayoutArea(layoutContext.GetArea
450-
().GetPageNumber(), layoutBox), wasParentsHeightClipped));
451-
if (wasXOverflowChanged) {
452-
SetProperty(Property.OVERFLOW_X, OverflowPropertyValue.FIT);
453-
}
454-
if (newLayoutResult is TextLayoutResult && !((TextLayoutResult)newLayoutResult).IsWordHasBeenSplit()) {
455-
wordWasSplitAndItWillFitOntoNextLine = true;
456-
}
457-
}
458463
if (wordWasSplitAndItWillFitOntoNextLine) {
459464
split[1].childRenderers.Add(childRenderer);
460465
split[1].childRenderers.AddAll(childRenderers.SubList(childPos + 1, childRenderers.Count));
@@ -1288,14 +1293,14 @@ private bool IsInlineBlockChild(IRenderer child) {
12881293
}
12891294

12901295
internal class RendererGlyph {
1296+
public Glyph glyph;
1297+
1298+
public TextRenderer renderer;
1299+
12911300
public RendererGlyph(Glyph glyph, TextRenderer textRenderer) {
12921301
this.glyph = glyph;
12931302
this.renderer = textRenderer;
12941303
}
1295-
1296-
public Glyph glyph;
1297-
1298-
public TextRenderer renderer;
12991304
}
13001305
}
13011306
}

port-hash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
ef19e7b3ccbf8d37a7f84b3a149a8a32bb2f84e4
1+
d9f7ccd1f52be146f3cb22d7d96fa1d062df30df

0 commit comments

Comments
 (0)