From 0cd09893af364c184403497ed0a9cc4df8f3073a Mon Sep 17 00:00:00 2001 From: danfickle Date: Sun, 17 Nov 2019 17:41:31 +1100 Subject: [PATCH] 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. --- .../openhtmltopdf/css/style/CssContext.java | 6 + .../openhtmltopdf/extend/TextRenderer.java | 14 +- .../com/openhtmltopdf/layout/BoxBuilder.java | 4 +- .../com/openhtmltopdf/layout/Breaker.java | 23 +- .../openhtmltopdf/layout/InlineBoxing.java | 2 - .../openhtmltopdf/layout/LayoutContext.java | 2 + .../layout/LineBreakContext.java | 9 - .../com/openhtmltopdf/render/InlineBox.java | 11 +- .../com/openhtmltopdf/render/InlineText.java | 222 ++++++------------ .../render/RenderingContext.java | 2 + .../com/openhtmltopdf/layout/BreakerTest.java | 23 -- .../expected/text/letter-spacing-bidi.pdf | Bin 37498 -> 37491 bytes .../java2d/Java2DTextRenderer.java | 114 --------- .../pdfboxout/PdfBoxTextRenderer.java | 18 -- 14 files changed, 112 insertions(+), 338 deletions(-) diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/CssContext.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/CssContext.java index f709a26e6..ac75f46cf 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/CssContext.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/CssContext.java @@ -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; @@ -29,4 +31,8 @@ public interface CssContext { StyleReference getCss(); FSFontMetrics getFSFontMetrics(FSFont font); + + FontContext getFontContext(); + + TextRenderer getTextRenderer(); } diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/extend/TextRenderer.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/extend/TextRenderer.java index 1ed88b206..9fd9fed76 100755 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/extend/TextRenderer.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/extend/TextRenderer.java @@ -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; @@ -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); diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/BoxBuilder.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/BoxBuilder.java index 91b30be22..b9681cc0d 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/BoxBuilder.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/BoxBuilder.java @@ -858,7 +858,7 @@ private static List createGeneratedContentList( } if (content != null) { - InlineBox iB = new InlineBox(content, null); + InlineBox iB = new InlineBox(content); iB.setContentFunction(contentFunction); iB.setFunction(function); iB.setElement(element); @@ -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); diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/Breaker.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/Breaker.java index 716947572..d493b36bc 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/Breaker.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/Breaker.java @@ -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; @@ -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; } @@ -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)); } } @@ -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); + } } diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/InlineBoxing.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/InlineBoxing.java index 51d1370b2..40c51f687 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/InlineBoxing.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/InlineBoxing.java @@ -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()); } @@ -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); diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/LayoutContext.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/LayoutContext.java index 6a3b3ac61..6226cd642 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/LayoutContext.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/LayoutContext.java @@ -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(); } @@ -375,6 +376,7 @@ public ReplacedElementFactory getReplacedElementFactory() { return _sharedContext.getReplacedElementFactory(); } + @Override public FontContext getFontContext() { return _fontContext; } diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/LineBreakContext.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/LineBreakContext.java index 4cc52a18a..7f79297d1 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/LineBreakContext.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/LineBreakContext.java @@ -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(); @@ -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; } diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/InlineBox.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/InlineBox.java index 634e328c3..20e89187e 100755 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/InlineBox.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/InlineBox.java @@ -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; @@ -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; @@ -503,8 +498,4 @@ public void truncateText() { _text = ""; _originalText = ""; } - - public Text getTextNode() { - return this._textNode; - } } diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/InlineText.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/InlineText.java index 35a79bb19..ce3e9ea72 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/InlineText.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/InlineText.java @@ -20,11 +20,8 @@ */ package com.openhtmltopdf.render; -import java.awt.Rectangle; - -import org.w3c.dom.Text; - -import com.openhtmltopdf.extend.FSGlyphVector; +import com.openhtmltopdf.bidi.BidiSplitter; +import com.openhtmltopdf.layout.Breaker; import com.openhtmltopdf.layout.FunctionData; import com.openhtmltopdf.layout.LayoutContext; import com.openhtmltopdf.layout.WhitespaceStripper; @@ -40,58 +37,75 @@ public class InlineText { private InlineLayoutBox _parent; private int _x; + private int _width; private String _masterText; private int _start; private int _end; - private int _width; + private boolean _containedLF = false; - private FunctionData _functionData; + private boolean _trimmedLeadingSpace; + private boolean _trimmedTrailingSpace; - private boolean _containedLF = false; + static class InlineTextRareData { + FunctionData _functionData; + boolean _endsOnSoftHyphen = false; + float _letterSpacing = 0f; + byte _textDirection = BidiSplitter.LTR; + } - private short _selectionStart; - private short _selectionEnd; + private CharCounts _counts; - private float[] _glyphPositions; + private InlineTextRareData _rareData; - private boolean _trimmedLeadingSpace; - private boolean _trimmedTrailingSpace; - private Text _textNode; - private byte _textDirection; - private float _letterSpacing; - - private boolean _endsOnSoftHyphen; + private void ensureRareData() { + if (_rareData == null) { + _rareData = new InlineTextRareData(); + } + } /** * @param direction either LTR or RTL from BidiSplitter interface. */ public void setTextDirection(byte direction) { - this._textDirection = direction; + if (direction != BidiSplitter.LTR) { + ensureRareData(); + } + + if (_rareData != null) { + _rareData._textDirection = direction; + } } /** * @return either LTR or RTL from BidiSplitter interface. */ public byte getTextDirection() { - return this._textDirection; + return _rareData != null ? _rareData._textDirection : BidiSplitter.LTR; } public void setLetterSpacing(float letterSpacing) { - this._letterSpacing = letterSpacing; + if (letterSpacing != 0f) { + ensureRareData(); + } + + if (_rareData != null) { + _rareData._letterSpacing = letterSpacing; + } } public float getLetterSpacing() { - return this._letterSpacing; + return _rareData != null ? _rareData._letterSpacing : 0f; } public void trimTrailingSpace(LayoutContext c) { if (! isEmpty() && _masterText.charAt(_end-1) == ' ') { _end--; - setWidth(c.getTextRenderer().getWidth(c.getFontContext(), + setWidth(Breaker.getTextWidthWithLetterSpacing(c, getParent().getStyle().getFSFont(c), - getSubstring())); + getSubstring(), + getLetterSpacing())); setTrimmedTrailingSpace(true); } } @@ -171,28 +185,37 @@ public void setParent(InlineLayoutBox parent) { } public boolean isDynamicFunction() { - return _functionData != null; + return _rareData != null && _rareData._functionData != null; } public FunctionData getFunctionData() { - return _functionData; + return _rareData != null ? _rareData._functionData : null; } public void setFunctionData(FunctionData functionData) { - _functionData = functionData; + if (functionData != null) { + ensureRareData(); + } + + if (_rareData != null) { + _rareData._functionData = functionData; + } } public void updateDynamicValue(RenderingContext c) { - String value = _functionData.getContentFunction().calculate( - c, _functionData.getFunction(), this); + String value = _rareData._functionData.getContentFunction().calculate( + c, _rareData._functionData.getFunction(), this); _start = 0; _end = value.length(); _masterText = value; - _width = c.getTextRenderer().getWidth( - c.getFontContext(), getParent().getStyle().getFSFont(c), - value); + + setWidth(Breaker.getTextWidthWithLetterSpacing(c, + getParent().getStyle().getFSFont(c), + value, + getLetterSpacing())); } + @Override public String toString() { StringBuilder result = new StringBuilder(); result.append("InlineText: "); @@ -213,81 +236,6 @@ public String toString() { return result.toString(); } - public boolean updateSelection(RenderingContext c, Rectangle selection) { - ensureGlyphPositions(c); - float[] positions = _glyphPositions; - int y = getParent().getAbsY(); - int offset = getParent().getAbsX() + getX(); - - int prevSelectionStart = _selectionStart; - int prevSelectionEnd = _selectionEnd; - - boolean found = false; - _selectionStart = 0; - _selectionEnd = 0; - for (int i = 0; i < positions.length - 2; i += 2) { - Rectangle target = new Rectangle( - (int)(offset + (positions[i] + positions[i+2]) / 2), - y, - 1, - getParent().getHeight()); - if (selection.intersects(target)) { - if (! found) { - found = true; - _selectionStart = (short)(i / 2); - _selectionEnd = (short)(i / 2 + 1); - } else { - _selectionEnd++; - } - } - } - - return prevSelectionStart != _selectionStart || prevSelectionEnd != _selectionEnd; - } - - private void ensureGlyphPositions(RenderingContext c) { - if (_glyphPositions == null) { - FSGlyphVector glyphVector = c.getTextRenderer().getGlyphVector( - c.getOutputDevice(), - getParent().getStyle().getFSFont(c), - getSubstring()); - _glyphPositions = c.getTextRenderer().getGlyphPositions( - c.getOutputDevice(), - getParent().getStyle().getFSFont(c), - glyphVector); - } - } - - public boolean clearSelection() { - boolean result = _selectionStart != 0 || _selectionEnd != 0; - - _selectionStart = 0; - _selectionEnd = 0; - - return result; - } - - public boolean isSelected() { - return _selectionStart != _selectionEnd; - } - - public short getSelectionEnd() { - return _selectionEnd; - } - - public short getSelectionStart() { - return _selectionStart; - } - - public String getSelection() { - return getSubstring().substring(_selectionStart, _selectionEnd); - } - - public void selectAll() { - _selectionStart = 0; - _selectionEnd = (short)getSubstring().length(); - } - public String getTextExportText() { char[] ch = getSubstring().toCharArray(); StringBuilder result = new StringBuilder(); @@ -344,8 +292,18 @@ public void countJustifiableChars(CharCounts counts) { other++; } } + + if (isEndsOnSoftHyphen()) { + other++; + } + counts.setSpaceCount(counts.getSpaceCount() + spaces); - counts.setNonSpaceCount(counts.getNonSpaceCount() + other + (isEndsOnSoftHyphen() ? 1 : 0)); + counts.setNonSpaceCount(counts.getNonSpaceCount() + other); + + // Our own personal copy we can use in the calcTotalAdjustment method. + _counts = new CharCounts(); + _counts.setSpaceCount(spaces); + _counts.setNonSpaceCount(other); } public float calcTotalAdjustment(JustificationInfo info) { @@ -355,54 +313,30 @@ public float calcTotalAdjustment(JustificationInfo info) { return 0f; } - String s = getSubstring(); - int len = s.length(); - - float result = 0.0f; - for (int i = 0; i < len; i++) { - char c = s.charAt(i); - if (c == ' ' || c == '\u00a0' || c == '\u3000') { - result += info.getSpaceAdjust(); - } else if (!OpenUtil.isCodePointPrintable(c)) { - - } else { - result += info.getNonSpaceAdjust(); - } - } - - if (isEndsOnSoftHyphen()) { - result += info.getNonSpaceAdjust(); - } - - return result; + return (_counts.getSpaceCount() * info.getSpaceAdjust()) + + (_counts.getNonSpaceCount() * info.getNonSpaceAdjust()); } + public int getStart(){ return _start; } + public int getEnd(){ return _end; } - public void setSelectionStart(short s){ - _selectionStart = s; - } - public void setSelectionEnd(short s){ - _selectionEnd = s; - } - - public Text getTextNode() { - return this._textNode; - } - - public void setTextNode(Text node) { - this._textNode = node; - } public void setEndsOnSoftHyphen(boolean endsOnSoftHyphen) { - this._endsOnSoftHyphen = endsOnSoftHyphen; + if (endsOnSoftHyphen) { + ensureRareData(); + } + + if (_rareData != null) { + _rareData._endsOnSoftHyphen = endsOnSoftHyphen; + } } public boolean isEndsOnSoftHyphen() { - return this._endsOnSoftHyphen; + return _rareData != null ? _rareData._endsOnSoftHyphen : false; } } diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/RenderingContext.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/RenderingContext.java index 1551ebce8..224c58617 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/RenderingContext.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/RenderingContext.java @@ -101,6 +101,7 @@ public float getXHeight(FontSpecification parentFont) { return sharedContext.getXHeight(getFontContext(), parentFont); } + @Override public TextRenderer getTextRenderer() { return sharedContext.getTextRenderer(); } @@ -192,6 +193,7 @@ public void setOutputDevice(OutputDevice outputDevice) { this.outputDevice = outputDevice; } + @Override public FontContext getFontContext() { return fontContext; } diff --git a/openhtmltopdf-core/src/test/java/com/openhtmltopdf/layout/BreakerTest.java b/openhtmltopdf-core/src/test/java/com/openhtmltopdf/layout/BreakerTest.java index 399ca9090..3232e9992 100644 --- a/openhtmltopdf-core/src/test/java/com/openhtmltopdf/layout/BreakerTest.java +++ b/openhtmltopdf-core/src/test/java/com/openhtmltopdf/layout/BreakerTest.java @@ -96,29 +96,6 @@ public void drawString(OutputDevice outputDevice, String string, float x, float y, JustificationInfo info) { } - @Override - public void drawGlyphVector(OutputDevice outputDevice, - FSGlyphVector vector, float x, float y) { - } - - @Override - public FSGlyphVector getGlyphVector(OutputDevice outputDevice, - FSFont font, String string) { - return null; - } - - @Override - public float[] getGlyphPositions(OutputDevice outputDevice, - FSFont font, FSGlyphVector fsGlyphVector) { - return null; - } - - @Override - public Rectangle getGlyphBounds(OutputDevice outputDevice, FSFont font, - FSGlyphVector fsGlyphVector, int index, float x, float y) { - return null; - } - @Override public FSFontMetrics getFSFontMetrics(FontContext context, FSFont font, String string) { diff --git a/openhtmltopdf-examples/src/main/resources/visualtest/expected/text/letter-spacing-bidi.pdf b/openhtmltopdf-examples/src/main/resources/visualtest/expected/text/letter-spacing-bidi.pdf index 0c5278bff8a8ec4fb945b8735c7917d2b8c153d3..6b1ad944e7fd0bc4db04eb7b04e981d92200b37a 100644 GIT binary patch delta 821 zcmaiyziL!L6vi=ncexh=S_lRq*(Q}Rne%@J!r~ee8$of`&8`yAA`(R-tSLeiqNSZ- zULmar+FIE71ls!mmf9!?&fPR7w{WV%H{bc4^9}R+aOTJ1%$x0505C8@3YP#5o_{}s zG4h8;r~0>A;8;=8=e|E39H(D>Y;$zzP147~Qd`uSd2oRe49=$~7u)IOg@uAZ9i>0R z%Ppe3NlfR)SP*Nb?X7Q>?Adu=_h(wc08Y~UXrp9_4jA+FdJ3yL4JMjy-kD2ZM^;F7 zS~@$XQXuEbSuI^3_ev3TLN)Kxa4x+YFBGEYG<_K_mlDjy?2J>UL~)Ye!!q+}smcz? z^eB~DriV;vHQ!fq8gd1Aaa8hFoN4@+13>Nh9q*0L? zgO$8Ce4@=>HEj5dj|Cp(%xIpDiBpZ5zyR1t7n)1wKc+E#JD@GI9?`0;>54L&nHNAW wD-eAoxzfAZ?JWP-vQaJdAMR~-kgIODdbV?ava>tcd{B`F(Q0vV^~PHD7fkBEV*mgE delta 808 zcmah`J!@1!6vgn?I15_@Q4}n;NhORk_j3kGmGd?hW?$h{!#oF)1+Wepw2r>X5g}X5vzdf%ogn0V$ z%IL|pkbD-PY@bJ=itMxf9Dzd+uR$4XV|LFWk_QGxdp>^PP{AVrrHePsK8cnA=i_&d zNPQ^GrLIFvo^A2;%{s?iY}C#s(J`p!2pny)H?jGRs)N`#eVE?1qg(wdqfho@Z`(-| zCo7A6nuQ9m%z8a}aaB_E9PHybb|hsV?B@P6rzl?NuknTw`IwaZvA|d^7UjBq-KTXe z3Wyg$G?yi%2~tl7E@AKifpZCxI*Hgv`!e0?Bw95&)KFrh)&FLTXy30%H9<+@~YGD$gg%y_;R*G50nqOXGhyNHeL|G*YV9QuA zVvEPx){5p9Px;cqb~dlZ8t4*OdVr>|RdI^g+Ag(2qo|5~JH{aol0sb%b`S#&31k4n e9j%$m2k9==_xoG_qu8U9J5I2>xmiEn?fwCcrMgT2 diff --git a/openhtmltopdf-java2d/src/main/java/com/openhtmltopdf/java2d/Java2DTextRenderer.java b/openhtmltopdf-java2d/src/main/java/com/openhtmltopdf/java2d/Java2DTextRenderer.java index b6e6bea47..996a39b60 100644 --- a/openhtmltopdf-java2d/src/main/java/com/openhtmltopdf/java2d/Java2DTextRenderer.java +++ b/openhtmltopdf-java2d/src/main/java/com/openhtmltopdf/java2d/Java2DTextRenderer.java @@ -21,7 +21,6 @@ import java.awt.Font; import java.awt.Graphics2D; -import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.font.GlyphVector; @@ -33,7 +32,6 @@ import java.util.Map; import com.openhtmltopdf.bidi.BidiReorderer; -import com.openhtmltopdf.extend.FSGlyphVector; import com.openhtmltopdf.extend.FontContext; import com.openhtmltopdf.extend.OutputDevice; import com.openhtmltopdf.extend.TextRenderer; @@ -43,7 +41,6 @@ import com.openhtmltopdf.render.LineMetricsAdapter; import com.openhtmltopdf.util.Configuration; import com.openhtmltopdf.swing.AWTFSFont; -import com.openhtmltopdf.swing.AWTFSGlyphVector; /** @@ -171,27 +168,6 @@ private void adjustGlyphPositions( } } - @Override - public void drawGlyphVector(OutputDevice outputDevice, FSGlyphVector fsGlyphVector, float x, float y ) { - Object aaHint = null; - Object fracHint = null; - Graphics2D graphics = ((Java2DOutputDevice)outputDevice).getGraphics(); - - if ( graphics.getFont().getSize() > threshold ) { - aaHint = graphics.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); - graphics.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, antiAliasRenderingHint ); - } - fracHint = graphics.getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS); - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, fractionalFontMetricsHint); - - GlyphVector vector = ((AWTFSGlyphVector)fsGlyphVector).getGlyphVector(); - graphics.drawGlyphVector(vector, (int)x, (int)y ); - if ( graphics.getFont().getSize() > threshold ) { - graphics.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, aaHint ); - } - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, fracHint); - } - /** {@inheritDoc} * @param bidiReorderer */ public void setup(FontContext fontContext, BidiReorderer bidiReorderer) { @@ -384,96 +360,6 @@ public float[] getGlyphPositions(OutputDevice outputDevice, FSFont font, String return result; } - /** - * This method gets glyph bounds for purposes of selecting text. WE are not too worried about selecting text - * at this point so we just use the first font available. - */ - @Override - public Rectangle getGlyphBounds(OutputDevice outputDevice, FSFont font, FSGlyphVector fsGlyphVector, int index, float x, float y) { - Object aaHint = null; - Object fracHint = null; - Graphics2D graphics = ((Java2DOutputDevice)outputDevice).getGraphics(); - Font awtFont = ((AWTFSFont)font).getAWTFonts().get(0); - - if (awtFont.getSize() > threshold ) { - aaHint = graphics.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); - graphics.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, antiAliasRenderingHint ); - } - fracHint = graphics.getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS); - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, fractionalFontMetricsHint); - - GlyphVector vector = ((AWTFSGlyphVector)fsGlyphVector).getGlyphVector(); - - Rectangle result = vector.getGlyphPixelBounds(index, graphics.getFontRenderContext(), x, y); - - if (awtFont.getSize() > threshold ) { - graphics.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, aaHint ); - } - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, fracHint); - - return result; - } - - /** - * This method gets glyph positions for purposes of selecting text. WE are not too worried about selecting text - * at this point so we just use the first font available. - */ - @Override - public float[] getGlyphPositions(OutputDevice outputDevice, FSFont font, FSGlyphVector fsGlyphVector) { - Object aaHint = null; - Object fracHint = null; - Graphics2D graphics = ((Java2DOutputDevice)outputDevice).getGraphics(); - Font awtFont = ((AWTFSFont)font).getAWTFonts().get(0); - - if (awtFont.getSize() > threshold ) { - aaHint = graphics.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); - graphics.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, antiAliasRenderingHint ); - } - fracHint = graphics.getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS); - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, fractionalFontMetricsHint); - - GlyphVector vector = ((AWTFSGlyphVector)fsGlyphVector).getGlyphVector(); - - float[] result = vector.getGlyphPositions(0, vector.getNumGlyphs() + 1, null); - - if (awtFont.getSize() > threshold ) { - graphics.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, aaHint ); - } - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, fracHint); - - return result; - } - - /** - * This method gets a glyph vector for purposes of selecting text. WE are not too worried about selecting text - * at this point so we just use the first font available. - */ - @Override - public FSGlyphVector getGlyphVector(OutputDevice outputDevice, FSFont font, String text) { - Object aaHint = null; - Object fracHint = null; - Graphics2D graphics = ((Java2DOutputDevice)outputDevice).getGraphics(); - Font awtFont = ((AWTFSFont)font).getAWTFonts().get(0); - - if (awtFont.getSize() > threshold ) { - aaHint = graphics.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); - graphics.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, antiAliasRenderingHint ); - } - fracHint = graphics.getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS); - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, fractionalFontMetricsHint); - - GlyphVector vector = awtFont.createGlyphVector( - graphics.getFontRenderContext(), - text); - - if (awtFont.getSize() > threshold ) { - graphics.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, aaHint ); - } - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, fracHint); - - return new AWTFSGlyphVector(vector); - } - @Override public void setup(FontContext context) { // TODO Auto-generated method stub diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxTextRenderer.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxTextRenderer.java index 6b68b570d..85d532ef1 100644 --- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxTextRenderer.java +++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxTextRenderer.java @@ -19,14 +19,12 @@ */ package com.openhtmltopdf.pdfboxout; -import java.awt.Rectangle; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import com.openhtmltopdf.bidi.BidiReorderer; -import com.openhtmltopdf.extend.FSGlyphVector; import com.openhtmltopdf.extend.FontContext; import com.openhtmltopdf.extend.OutputDevice; import com.openhtmltopdf.extend.TextRenderer; @@ -364,22 +362,6 @@ public int getSmoothingLevel() { public void setSmoothingLevel(int level) { } - public Rectangle getGlyphBounds(OutputDevice outputDevice, FSFont font, FSGlyphVector fsGlyphVector, int index, float x, float y) { - throw new UnsupportedOperationException(); - } - - public float[] getGlyphPositions(OutputDevice outputDevice, FSFont font, FSGlyphVector fsGlyphVector) { - throw new UnsupportedOperationException(); - } - - public FSGlyphVector getGlyphVector(OutputDevice outputDevice, FSFont font, String string) { - throw new UnsupportedOperationException(); - } - - public void drawGlyphVector(OutputDevice outputDevice, FSGlyphVector vector, float x, float y) { - throw new UnsupportedOperationException(); - } - @Override public void setup(FontContext context) {