Skip to content

Commit

Permalink
REFACTOR: Improve performance and memory useage of InlineText class.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
danfickle committed Nov 17, 2019
1 parent 7c716bc commit 0cd0989
Show file tree
Hide file tree
Showing 14 changed files with 112 additions and 338 deletions.
Expand Up @@ -2,6 +2,8 @@

import com.openhtmltopdf.context.StyleReference;
import com.openhtmltopdf.css.value.FontSpecification;
import com.openhtmltopdf.extend.FontContext;
import com.openhtmltopdf.extend.TextRenderer;
import com.openhtmltopdf.render.FSFont;
import com.openhtmltopdf.render.FSFontMetrics;

Expand Down Expand Up @@ -29,4 +31,8 @@ public interface CssContext {
StyleReference getCss();

FSFontMetrics getFSFontMetrics(FSFont font);

FontContext getFontContext();

TextRenderer getTextRenderer();
}
Expand Up @@ -20,8 +20,7 @@
*/
package com.openhtmltopdf.extend;

import java.awt.Rectangle;

import com.openhtmltopdf.layout.Breaker;
import com.openhtmltopdf.render.FSFont;
import com.openhtmltopdf.render.FSFontMetrics;
import com.openhtmltopdf.render.JustificationInfo;
Expand All @@ -32,17 +31,14 @@ public interface TextRenderer {
public void drawString(OutputDevice outputDevice, String string, float x, float y);
public void drawString(
OutputDevice outputDevice, String string, float x, float y, JustificationInfo info);

public void drawGlyphVector(OutputDevice outputDevice, FSGlyphVector vector, float x, float y);

public FSGlyphVector getGlyphVector(OutputDevice outputDevice, FSFont font, String string);

public float[] getGlyphPositions(OutputDevice outputDevice, FSFont font, FSGlyphVector fsGlyphVector);
public Rectangle getGlyphBounds(OutputDevice outputDevice, FSFont font, FSGlyphVector fsGlyphVector, int index, float x, float y);

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

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

public void setFontScale(float scale);
Expand Down
Expand Up @@ -858,7 +858,7 @@ private static List<Styleable> createGeneratedContentList(
}

if (content != null) {
InlineBox iB = new InlineBox(content, null);
InlineBox iB = new InlineBox(content);
iB.setContentFunction(contentFunction);
iB.setFunction(function);
iB.setElement(element);
Expand Down Expand Up @@ -1054,7 +1054,7 @@ private static void addColumnOrColumnGroup(

private static InlineBox createInlineBox(
String text, Element parent, CalculatedStyle parentStyle, Text node) {
InlineBox result = new InlineBox(text, node);
InlineBox result = new InlineBox(text);

if (parentStyle.isInline() && ! (parent.getParentNode() instanceof Document)) {
result.setStyle(parentStyle);
Expand Down
Expand Up @@ -23,6 +23,7 @@
import com.openhtmltopdf.css.constants.CSSName;
import com.openhtmltopdf.css.constants.IdentValue;
import com.openhtmltopdf.css.style.CalculatedStyle;
import com.openhtmltopdf.css.style.CssContext;
import com.openhtmltopdf.extend.FSTextBreaker;
import com.openhtmltopdf.render.FSFont;

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

// ====== handle nowrap
if (whitespace == IdentValue.NOWRAP) {
context.setEnd(context.getLast());
context.setWidth(c.getTextRenderer().getWidth(
c.getFontContext(), font, context.getCalculatedSubstring()));
context.setEnd(context.getLast());
context.setWidth(Breaker.getTextWidthWithLetterSpacing(c, font, context.getCalculatedSubstring(), letterSpacing));
return;
}

Expand All @@ -88,14 +90,12 @@ public static void breakText(LayoutContext c,
int n = context.getStartSubstring().indexOf(WhitespaceStripper.EOL);
if (n > -1) {
context.setEnd(context.getStart() + n + 1);
context.setWidth(c.getTextRenderer().getWidth(
c.getFontContext(), font, context.getCalculatedSubstring()));
context.setWidth(Breaker.getTextWidthWithLetterSpacing(c, font, context.getCalculatedSubstring(), letterSpacing));
context.setNeedsNewLine(true);
context.setEndsOnNL(true);
} else if (whitespace == IdentValue.PRE) {
context.setEnd(context.getLast());
context.setWidth(c.getTextRenderer().getWidth(
c.getFontContext(), font, context.getCalculatedSubstring()));
context.setWidth(Breaker.getTextWidthWithLetterSpacing(c, font, context.getCalculatedSubstring(), letterSpacing));
}
}

Expand Down Expand Up @@ -281,4 +281,13 @@ public static FSTextBreaker getLineBreakStream(String s, SharedContext shared) {
i.setText(s);
return i;
}

/**
* Gets the width of a string with letter spacing factored in.
* Favor this method over using the text renderer directly.
*/
public static int getTextWidthWithLetterSpacing(CssContext c, FSFont font, String text, float letterSpacing) {
float extraSpace = text.length() * letterSpacing;
return (int) (c.getTextRenderer().getWidth(c.getFontContext(), font, text) + extraSpace);
}
}
Expand Up @@ -161,7 +161,6 @@ public static void layoutContent(LayoutContext c, BlockBox box, int initialY, in

LineBreakContext lbContext = new LineBreakContext();
lbContext.setMaster(iB.getText());
lbContext.setTextNode(iB.getTextNode());
if (iB.isDynamicFunction()) {
lbContext.setMaster(iB.getContentFunction().getLayoutReplacementText());
}
Expand Down Expand Up @@ -958,7 +957,6 @@ private static InlineText layoutText(LayoutContext c, CalculatedStyle style, int
}

result.setMasterText(masterText);
result.setTextNode(lbContext.getTextNode());
result.setSubstring(lbContext.getStart(), lbContext.getEnd());
result.setWidth(lbContext.getWidth());
result.setTextDirection(textDirection);
Expand Down
Expand Up @@ -93,6 +93,7 @@ public class LayoutContext implements CssContext {

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

@Override
public TextRenderer getTextRenderer() {
return _sharedContext.getTextRenderer();
}
Expand Down Expand Up @@ -375,6 +376,7 @@ public ReplacedElementFactory getReplacedElementFactory() {
return _sharedContext.getReplacedElementFactory();
}

@Override
public FontContext getFontContext() {
return _fontContext;
}
Expand Down
Expand Up @@ -36,7 +36,6 @@ public class LineBreakContext {
private int _width;
private boolean _endsOnNL;
private boolean _endsOnSoftHyphen;
private Text _textNode;

public int getLast() {
return _master.length();
Expand Down Expand Up @@ -132,14 +131,6 @@ public void setEndsOnNL(boolean b) {
_endsOnNL = b;
}

public Text getTextNode() {
return this._textNode;
}

public void setTextNode(Text _text) {
this._textNode = _text;
}

public boolean isEndsOnSoftHyphen() {
return this._endsOnSoftHyphen;
}
Expand Down
Expand Up @@ -21,8 +21,6 @@
import java.text.BreakIterator;

import org.w3c.dom.Element;
import org.w3c.dom.Text;

import com.openhtmltopdf.bidi.BidiSplitter;
import com.openhtmltopdf.css.constants.CSSName;
import com.openhtmltopdf.css.constants.IdentValue;
Expand Down Expand Up @@ -73,12 +71,9 @@ public class InlineBox implements Styleable {

private String _pseudoElementOrClass;

private final Text _textNode;

public InlineBox(String text, Text textNode) {
public InlineBox(String text) {
_text = text;
_originalText = text;
_textNode = textNode;
}

private byte _textDirection;
Expand Down Expand Up @@ -503,8 +498,4 @@ public void truncateText() {
_text = "";
_originalText = "";
}

public Text getTextNode() {
return this._textNode;
}
}

0 comments on commit 0cd0989

Please sign in to comment.