Skip to content

Commit 0cd0989

Browse files
committed
REFACTOR: Improve performance and memory useage of InlineText class.
Also: + Remove code related to painting a selection of text. + Fixes to letter-spacing support on last line with trailing space. + New proof for letter spacing with Arabic (due to above fix). Hopefully this one is right.
1 parent 7c716bc commit 0cd0989

File tree

14 files changed

+112
-338
lines changed

14 files changed

+112
-338
lines changed

openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/CssContext.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.openhtmltopdf.context.StyleReference;
44
import com.openhtmltopdf.css.value.FontSpecification;
5+
import com.openhtmltopdf.extend.FontContext;
6+
import com.openhtmltopdf.extend.TextRenderer;
57
import com.openhtmltopdf.render.FSFont;
68
import com.openhtmltopdf.render.FSFontMetrics;
79

@@ -29,4 +31,8 @@ public interface CssContext {
2931
StyleReference getCss();
3032

3133
FSFontMetrics getFSFontMetrics(FSFont font);
34+
35+
FontContext getFontContext();
36+
37+
TextRenderer getTextRenderer();
3238
}

openhtmltopdf-core/src/main/java/com/openhtmltopdf/extend/TextRenderer.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@
2020
*/
2121
package com.openhtmltopdf.extend;
2222

23-
import java.awt.Rectangle;
24-
23+
import com.openhtmltopdf.layout.Breaker;
2524
import com.openhtmltopdf.render.FSFont;
2625
import com.openhtmltopdf.render.FSFontMetrics;
2726
import com.openhtmltopdf.render.JustificationInfo;
@@ -32,17 +31,14 @@ public interface TextRenderer {
3231
public void drawString(OutputDevice outputDevice, String string, float x, float y);
3332
public void drawString(
3433
OutputDevice outputDevice, String string, float x, float y, JustificationInfo info);
35-
36-
public void drawGlyphVector(OutputDevice outputDevice, FSGlyphVector vector, float x, float y);
37-
38-
public FSGlyphVector getGlyphVector(OutputDevice outputDevice, FSFont font, String string);
39-
40-
public float[] getGlyphPositions(OutputDevice outputDevice, FSFont font, FSGlyphVector fsGlyphVector);
41-
public Rectangle getGlyphBounds(OutputDevice outputDevice, FSFont font, FSGlyphVector fsGlyphVector, int index, float x, float y);
4234

4335
public FSFontMetrics getFSFontMetrics(
4436
FontContext context, FSFont font, String string );
4537

38+
/**
39+
* Rarely need to use this method directly.
40+
* Instead favor {@link Breaker} static method instead.
41+
*/
4642
public int getWidth(FontContext context, FSFont font, String string);
4743

4844
public void setFontScale(float scale);

openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/BoxBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,7 @@ private static List<Styleable> createGeneratedContentList(
858858
}
859859

860860
if (content != null) {
861-
InlineBox iB = new InlineBox(content, null);
861+
InlineBox iB = new InlineBox(content);
862862
iB.setContentFunction(contentFunction);
863863
iB.setFunction(function);
864864
iB.setElement(element);
@@ -1054,7 +1054,7 @@ private static void addColumnOrColumnGroup(
10541054

10551055
private static InlineBox createInlineBox(
10561056
String text, Element parent, CalculatedStyle parentStyle, Text node) {
1057-
InlineBox result = new InlineBox(text, node);
1057+
InlineBox result = new InlineBox(text);
10581058

10591059
if (parentStyle.isInline() && ! (parent.getParentNode() instanceof Document)) {
10601060
result.setStyle(parentStyle);

openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/Breaker.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.openhtmltopdf.css.constants.CSSName;
2424
import com.openhtmltopdf.css.constants.IdentValue;
2525
import com.openhtmltopdf.css.style.CalculatedStyle;
26+
import com.openhtmltopdf.css.style.CssContext;
2627
import com.openhtmltopdf.extend.FSTextBreaker;
2728
import com.openhtmltopdf.render.FSFont;
2829

@@ -72,12 +73,13 @@ public static void breakText(LayoutContext c,
7273
LineBreakContext context, int avail, CalculatedStyle style) {
7374
FSFont font = style.getFSFont(c);
7475
IdentValue whitespace = style.getWhitespace();
76+
float letterSpacing = style.hasLetterSpacing() ?
77+
style.getFloatPropertyProportionalWidth(CSSName.LETTER_SPACING, 0, c) : 0f;
7578

7679
// ====== handle nowrap
7780
if (whitespace == IdentValue.NOWRAP) {
78-
context.setEnd(context.getLast());
79-
context.setWidth(c.getTextRenderer().getWidth(
80-
c.getFontContext(), font, context.getCalculatedSubstring()));
81+
context.setEnd(context.getLast());
82+
context.setWidth(Breaker.getTextWidthWithLetterSpacing(c, font, context.getCalculatedSubstring(), letterSpacing));
8183
return;
8284
}
8385

@@ -88,14 +90,12 @@ public static void breakText(LayoutContext c,
8890
int n = context.getStartSubstring().indexOf(WhitespaceStripper.EOL);
8991
if (n > -1) {
9092
context.setEnd(context.getStart() + n + 1);
91-
context.setWidth(c.getTextRenderer().getWidth(
92-
c.getFontContext(), font, context.getCalculatedSubstring()));
93+
context.setWidth(Breaker.getTextWidthWithLetterSpacing(c, font, context.getCalculatedSubstring(), letterSpacing));
9394
context.setNeedsNewLine(true);
9495
context.setEndsOnNL(true);
9596
} else if (whitespace == IdentValue.PRE) {
9697
context.setEnd(context.getLast());
97-
context.setWidth(c.getTextRenderer().getWidth(
98-
c.getFontContext(), font, context.getCalculatedSubstring()));
98+
context.setWidth(Breaker.getTextWidthWithLetterSpacing(c, font, context.getCalculatedSubstring(), letterSpacing));
9999
}
100100
}
101101

@@ -281,4 +281,13 @@ public static FSTextBreaker getLineBreakStream(String s, SharedContext shared) {
281281
i.setText(s);
282282
return i;
283283
}
284+
285+
/**
286+
* Gets the width of a string with letter spacing factored in.
287+
* Favor this method over using the text renderer directly.
288+
*/
289+
public static int getTextWidthWithLetterSpacing(CssContext c, FSFont font, String text, float letterSpacing) {
290+
float extraSpace = text.length() * letterSpacing;
291+
return (int) (c.getTextRenderer().getWidth(c.getFontContext(), font, text) + extraSpace);
292+
}
284293
}

openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/InlineBoxing.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ public static void layoutContent(LayoutContext c, BlockBox box, int initialY, in
161161

162162
LineBreakContext lbContext = new LineBreakContext();
163163
lbContext.setMaster(iB.getText());
164-
lbContext.setTextNode(iB.getTextNode());
165164
if (iB.isDynamicFunction()) {
166165
lbContext.setMaster(iB.getContentFunction().getLayoutReplacementText());
167166
}
@@ -958,7 +957,6 @@ private static InlineText layoutText(LayoutContext c, CalculatedStyle style, int
958957
}
959958

960959
result.setMasterText(masterText);
961-
result.setTextNode(lbContext.getTextNode());
962960
result.setSubstring(lbContext.getStart(), lbContext.getEnd());
963961
result.setWidth(lbContext.getWidth());
964962
result.setTextDirection(textDirection);

openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/LayoutContext.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public class LayoutContext implements CssContext {
9393

9494
private Boolean isPrintOverride = null; // True, false, or null for no override.
9595

96+
@Override
9697
public TextRenderer getTextRenderer() {
9798
return _sharedContext.getTextRenderer();
9899
}
@@ -375,6 +376,7 @@ public ReplacedElementFactory getReplacedElementFactory() {
375376
return _sharedContext.getReplacedElementFactory();
376377
}
377378

379+
@Override
378380
public FontContext getFontContext() {
379381
return _fontContext;
380382
}

openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/LineBreakContext.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ public class LineBreakContext {
3636
private int _width;
3737
private boolean _endsOnNL;
3838
private boolean _endsOnSoftHyphen;
39-
private Text _textNode;
4039

4140
public int getLast() {
4241
return _master.length();
@@ -132,14 +131,6 @@ public void setEndsOnNL(boolean b) {
132131
_endsOnNL = b;
133132
}
134133

135-
public Text getTextNode() {
136-
return this._textNode;
137-
}
138-
139-
public void setTextNode(Text _text) {
140-
this._textNode = _text;
141-
}
142-
143134
public boolean isEndsOnSoftHyphen() {
144135
return this._endsOnSoftHyphen;
145136
}

openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/InlineBox.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
import java.text.BreakIterator;
2222

2323
import org.w3c.dom.Element;
24-
import org.w3c.dom.Text;
25-
2624
import com.openhtmltopdf.bidi.BidiSplitter;
2725
import com.openhtmltopdf.css.constants.CSSName;
2826
import com.openhtmltopdf.css.constants.IdentValue;
@@ -73,12 +71,9 @@ public class InlineBox implements Styleable {
7371

7472
private String _pseudoElementOrClass;
7573

76-
private final Text _textNode;
77-
78-
public InlineBox(String text, Text textNode) {
74+
public InlineBox(String text) {
7975
_text = text;
8076
_originalText = text;
81-
_textNode = textNode;
8277
}
8378

8479
private byte _textDirection;
@@ -503,8 +498,4 @@ public void truncateText() {
503498
_text = "";
504499
_originalText = "";
505500
}
506-
507-
public Text getTextNode() {
508-
return this._textNode;
509-
}
510501
}

0 commit comments

Comments
 (0)