Skip to content

Commit 83e4837

Browse files
authored
Fix issue 2057: Take letter-spacing into account for width calculation (#2060)
1 parent 3884504 commit 83e4837

File tree

3 files changed

+30
-22
lines changed

3 files changed

+30
-22
lines changed

engine/org.eclipse.birt.report.engine/src/org/eclipse/birt/report/engine/nLayout/area/impl/LineArea.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ public void setBaseLevel(byte baseLevel) {
8181

8282
@Override
8383
public void addChild(IArea area) {
84-
// FIXME ?
8584
int childHorizontalSpan = area.getX() + area.getWidth();
8685
int childVerticalSpan = area.getY() + area.getHeight();
8786

@@ -122,28 +121,28 @@ public void align(boolean endParagraph, LayoutContext context) {
122121
boolean isJustified = CSSValueConstants.JUSTIFY_VALUE.equals(align) && !endParagraph;
123122

124123
// single line
125-
int spacing = width - currentIP;
126-
spacing -= adjustSpacingForSoftHyphen();
124+
int spaceRemaining = width - currentIP;
125+
spaceRemaining -= adjustSpacingForSoftHyphen();
127126
int adjustLeftWhiteSpace = ignoreLeftMostWhiteSpace();
128127
int adjustRightWhiteSpace = ignoreRightMostWhiteSpace();
129128
if ((isRightAligned)) {
130129
Iterator<IArea> iter = getChildren();
131130
while (iter.hasNext()) {
132131
AbstractArea area = (AbstractArea) iter.next();
133132
if (parent.content.isDirectionRTL()) {
134-
area.setPosition(spacing + area.getX(), area.getY());
133+
area.setPosition(spaceRemaining + area.getX(), area.getY());
135134
} else {
136-
area.setPosition(spacing + area.getX() + adjustRightWhiteSpace, area.getY());
135+
area.setPosition(spaceRemaining + area.getX() + adjustRightWhiteSpace, area.getY());
137136
}
138137
}
139138
} else if (isCentered) {
140139
Iterator<IArea> iter = getChildren();
141140
while (iter.hasNext()) {
142141
AbstractArea area = (AbstractArea) iter.next();
143-
area.setPosition(spacing / 2 + area.getX() - adjustLeftWhiteSpace + adjustRightWhiteSpace, area.getY());
142+
area.setPosition(spaceRemaining / 2 + area.getX() - adjustLeftWhiteSpace + adjustRightWhiteSpace, area.getY());
144143
}
145144
} else if (isJustified) {
146-
justify(spacing, adjustLeftWhiteSpace, adjustRightWhiteSpace);
145+
justify(spaceRemaining, adjustLeftWhiteSpace, adjustRightWhiteSpace);
147146
} else {
148147
// is left aligned
149148
if (parent.content != null && !parent.content.isDirectionRTL()) {
@@ -182,14 +181,16 @@ private int adjustSpacingForSoftHyphen() {
182181
private int ignoreRightMostWhiteSpace() {
183182
if (lastTextArea != null) {
184183
String text = lastTextArea.getText();
184+
int letterSpacing = lastTextArea.getTextStyle().getLetterSpacing();
185185
if (null != text) {
186186
char[] charArray = text.toCharArray();
187187
int len = charArray.length;
188188
while (len > 0 && (charArray[len - 1] <= ' ')) {
189189
len--;
190190
}
191191
if (len != charArray.length) {
192-
return lastTextArea.getTextWidth(text.substring(len));
192+
return (1 + charArray.length - len) * letterSpacing
193+
+ lastTextArea.getTextWidth(text.substring(len));
193194
}
194195
}
195196
}
@@ -200,14 +201,15 @@ private int ignoreLeftMostWhiteSpace() {
200201
TextArea firstTextArea = findFirstNonEmptyTextArea(this);
201202
if (firstTextArea != null) {
202203
String text = firstTextArea.getText();
204+
int letterSpacing = lastTextArea.getTextStyle().getLetterSpacing();
203205
if (null != text) {
204206
char[] charArray = text.toCharArray();
205207
int len = 0;
206208
while (len < charArray.length && (charArray[len] <= ' ')) {
207209
len++;
208210
}
209211
if (len > 0) {
210-
return firstTextArea.getTextWidth(text.substring(0, len));
212+
return len * letterSpacing + firstTextArea.getTextWidth(text.substring(0, len));
211213
}
212214
}
213215
}

engine/org.eclipse.birt.report.engine/src/org/eclipse/birt/report/engine/nLayout/area/impl/TextArea.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,9 @@ private String calculateText() {
243243
*
244244
* @since 4.14
245245
*/
246-
public void addWord(int textLength, WordWidth wordWidth) {
246+
public void addWord(int textLength, WordWidth wordWidth, int letterSpacing) {
247247
this.textLength += textLength;
248-
this.width += wordWidth.width;
248+
this.width += wordWidth.width + textLength * letterSpacing;
249249
this.softHyphenWidth = wordWidth.softHyphenWidth;
250250
}
251251

@@ -332,13 +332,18 @@ public void accept(IAreaVisitor visitor) {
332332
visitor.visitText(this);
333333
}
334334

335+
/**
336+
* Return the text width, ignoring wordSpacing and letterSpacing.
337+
*
338+
* @param text
339+
* @return text width
340+
*/
335341
public int getTextWidth(String text) {
336342
FontInfo fontInfo = style.getFontInfo();
337343
if (null != fontInfo) {
338344
return (int) (style.getFontInfo().getWordWidth(text) * PDFConstants.LAYOUT_TO_PDF_RATIO);
339-
} else {
340-
return 0;
341345
}
346+
return 0;
342347
}
343348

344349
@Override

engine/org.eclipse.birt.report.engine/src/org/eclipse/birt/report/engine/nLayout/area/impl/TextCompositor.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ private void addWordIntoTextArea(TextArea textArea, Word word) {
358358

359359
int adjustWordSize = fontInfo.getItalicAdjust() + width;
360360
if (textArea.hasSpace(adjustWordSize + wordWidth.softHyphenWidth * letterSpacing)) {
361-
addWord(textArea, textLength, wordWidth);
361+
addWord(textArea, textLength, wordWidth, letterSpacing);
362362
wordVestige = null;
363363
if (remainWords.hasWord()) {
364364
// test if we can append the word spacing
@@ -385,7 +385,7 @@ private void addWordIntoTextArea(TextArea textArea, Word word) {
385385
} else {
386386
// If width of a word is larger than the max line width,
387387
// add it into the line directly.
388-
addWord(textArea, textLength, wordWidth);
388+
addWord(textArea, textLength, wordWidth, letterSpacing);
389389
}
390390
} else {
391391
wordVestige = null;
@@ -401,26 +401,27 @@ private void doWordBreak(String str, TextArea area) {
401401
IHyphenationManager hm = new DefaultHyphenationManager();
402402
Hyphenation wb = hm.getHyphenation(str);
403403
FontInfo fi = area.getStyle().getFontInfo();
404+
int letterSpacing = textStyle.getLetterSpacing();
404405
if (area.getMaxWidth() < 0) {
405-
addWordVestige(area, 1, new WordWidth(fi, wb.getHyphenText(0, 1)), str.substring(1));
406+
addWordVestige(area, 1, new WordWidth(fi, wb.getHyphenText(0, 1)), str.substring(1), letterSpacing);
406407
return;
407408
}
408409
int endHyphenIndex = hyphen(0, area.getMaxWidth() - area.getWidth(), wb, fi);
409410
// current line can't even place one character. Force to add the first
410411
// character into the line.
411412
if (endHyphenIndex == 0 && area.getWidth() == 0) {
412-
addWordVestige(area, 1, new WordWidth(fi, wb.getHyphenText(0, 1)), str.substring(1));
413+
addWordVestige(area, 1, new WordWidth(fi, wb.getHyphenText(0, 1)), str.substring(1), letterSpacing);
413414
} else {
414415
WordWidth wordWidth = new WordWidth(fi, wb.getHyphenText(0, endHyphenIndex));
415416
// Take letter spacing into account
416417
wordWidth = new WordWidth(wordWidth.width + textStyle.getLetterSpacing() * (endHyphenIndex - 1), 0);
417-
addWordVestige(area, endHyphenIndex, wordWidth, str.substring(endHyphenIndex));
418+
addWordVestige(area, endHyphenIndex, wordWidth, str.substring(endHyphenIndex), letterSpacing);
418419
}
419420
}
420421

421422
private void addWordVestige(TextArea area, int vestigeTextLength, WordWidth vestigeWordWidth,
422-
String vestigeString) {
423-
addWord(area, vestigeTextLength, vestigeWordWidth);
423+
String vestigeString, int letterSpacing) {
424+
addWord(area, vestigeTextLength, vestigeWordWidth, letterSpacing);
424425
if (vestigeString.length() == 0) {
425426
wordVestige = null;
426427
} else {
@@ -469,8 +470,8 @@ private WordWidth getWordWidth(FontInfo fontInfo, Word word) {
469470
return new WordWidth(fontInfo, word.getValue());
470471
}
471472

472-
private void addWord(TextArea textArea, int textLength, WordWidth wordWidth) {
473-
textArea.addWord(textLength, wordWidth);
473+
private void addWord(TextArea textArea, int textLength, WordWidth wordWidth, int letterSpacing) {
474+
textArea.addWord(textLength, wordWidth, letterSpacing);
474475
}
475476

476477
private void addWord(TextArea textArea, int textLength) {

0 commit comments

Comments
 (0)