/** * Gets a NumericShaper for the specified unicode range. * The NumericShaper supports only a single range and * hence is not contextual. * * @param singleRange the specified unicode single range. * * @return the NumericShaper for the specified unicode range. */ public static NumericShaper getShaper(int singleRange) { singleRange &= ALL_RANGES; return new NumericShaper(singleRange, EUROPEAN, false); }
/** * Returns range corresponding to the specified script index. * * @param index specified script index * * @return one of the range constants according to the specified script index. */ private int getRangeFromIndex(int index){ if (index < 0 || index >= MAX_INDEX){ throw rangeException(index); } return 1 << index; }
private static NumericShaper getNumericShaperArabicIndic() { if (numericShaperArabicIndic == null) { numericShaperArabicIndic = NumericShaper.getShaper(NumericShaper.ARABIC); // NumericShaper.EASTERN_ARABIC actually corresponds to Unicode EXTENDED ARABIC-INDIC DIGIT } return numericShaperArabicIndic; }
/** * @return the leading height before/after a text line */ public float getLeading() { // fix invalid leadings (leading == 0) double l = layout.getLeading(); if (l == 0) { // see https://stackoverflow.com/questions/925147 // we use a 115% value instead of the 120% proposed one, as this seems to be closer to LO/OO l = (layout.getAscent()+layout.getDescent())*0.15; } return (float)l; }
private FontRenderContext getFontRenderContext() { return new FontRenderContext( null, useAntiAliasing ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON : RenderingHints.VALUE_TEXT_ANTIALIAS_OFF, RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT); }
/** Queues the glyphs in the specified text to be loaded. Note that the glyphs are not actually loaded until * {@link #loadGlyphs()} is called. */ public void addGlyphs (String text) { if (text == null) throw new IllegalArgumentException("text cannot be null."); char[] chars = text.toCharArray(); GlyphVector vector = font.layoutGlyphVector(GlyphPage.renderContext, chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); for (int i = 0, n = vector.getNumGlyphs(); i < n; i++) { int codePoint = text.codePointAt(vector.getGlyphCharIndex(i)); Rectangle bounds = getGlyphBounds(vector, i, codePoint); getGlyph(vector.getGlyphCode(i), codePoint, bounds, vector, i); } }
/** * * @return width if this text run */ public float getWidth(){ return layout.getAdvance(); }
private Shape getOutline(final TextLayout textLayout) { return textLayout.getOutline(null); }
/** @return May be null. */ private Glyph getGlyph (char c) { char[] chars = {c}; GlyphVector vector = unicodeFont.getFont().layoutGlyphVector(GlyphPage.renderContext, chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); Rectangle bounds = vector.getGlyphPixelBounds(0, GlyphPage.renderContext, 0, 0); return unicodeFont.getGlyph(vector.getGlyphCode(0), c, bounds, vector, 0); }
/** * Transforms the encoding of the text, starting from the character * at index start and transforming count characters. * * @param text the text to be shaped. * @param start the start offset of the text. * @param count the number of characters to be shaped. */ public void shape(char[] text, int start, int count) { if (isContextual()){ contextualShape(text, start, count, fDefaultContextIndex); } else { nonContextualShape(text, start, count); } }
/** Returns the distance from the y drawing location to the top most pixel of the specified text. */ public int getYOffset (String text) { if (text == null) throw new IllegalArgumentException("text cannot be null."); if (renderType == RenderType.FreeType && bitmapFont != null) return (int)bitmapFont.getAscent(); int index = text.indexOf('\n'); if (index != -1) text = text.substring(0, index); char[] chars = text.toCharArray(); GlyphVector vector = font.layoutGlyphVector(GlyphPage.renderContext, chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); int yOffset = ascent + vector.getPixelBounds(null, 0, 0).y; return yOffset; }
private int getGlyphCode (Font font, int codePoint) { char[] chars = Character.toChars(codePoint); GlyphVector vector = font.layoutGlyphVector(GlyphPage.renderContext, chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); return vector.getGlyphCode(0); } }
private Rectangle getGlyphBounds (GlyphVector vector, int index, int codePoint) { Rectangle bounds; bounds = vector.getGlyphPixelBounds(index, GlyphPage.renderContext, 0, 0); if (renderType == RenderType.Native) { if (bounds.width == 0 || bounds.height == 0) bounds = new Rectangle(); else bounds = metrics.getStringBounds("" + (char)codePoint, GlyphPage.scratchGraphics).getBounds(); } if (codePoint == ' ') bounds.width = spaceWidth; return bounds; }
/** * Creates NumericShaper with specified parameters. * * @param ranges specified ranges to be shaped * @param defaultContext default context range * @param isContextual specifies if the instance is contextual */ private NumericShaper(int ranges, int defaultContext, boolean isContextual){ this.fRanges = ranges; this.fDefaultContextIndex = getIndexFromRange(defaultContext); this.fContextual = isContextual; if (!fContextual){ fSingleRangeIndex = getIndexFromRange(ranges); } }
/** Queues the glyphs in the specified text to be loaded. Note that the glyphs are not actually loaded until * {@link #loadGlyphs()} is called. */ public void addGlyphs (String text) { if (text == null) throw new IllegalArgumentException("text cannot be null."); char[] chars = text.toCharArray(); GlyphVector vector = font.layoutGlyphVector(GlyphPage.renderContext, chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); for (int i = 0, n = vector.getNumGlyphs(); i < n; i++) { int codePoint = text.codePointAt(vector.getGlyphCharIndex(i)); Rectangle bounds = getGlyphBounds(vector, i, codePoint); getGlyph(vector.getGlyphCode(i), codePoint, bounds, vector, i); } }
/** @return May be null. */ private Glyph getGlyph (char c) { char[] chars = {c}; GlyphVector vector = unicodeFont.getFont().layoutGlyphVector(GlyphPage.renderContext, chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); Rectangle bounds = vector.getGlyphPixelBounds(0, GlyphPage.renderContext, 0, 0); return unicodeFont.getGlyph(vector.getGlyphCode(0), c, bounds, vector, 0); }
/** Returns the distance from the y drawing location to the top most pixel of the specified text. */ public int getYOffset (String text) { if (text == null) throw new IllegalArgumentException("text cannot be null."); if (renderType == RenderType.FreeType && bitmapFont != null) return (int)bitmapFont.getAscent(); int index = text.indexOf('\n'); if (index != -1) text = text.substring(0, index); char[] chars = text.toCharArray(); GlyphVector vector = font.layoutGlyphVector(GlyphPage.renderContext, chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); int yOffset = ascent + vector.getPixelBounds(null, 0, 0).y; return yOffset; }
private int getGlyphCode (Font font, int codePoint) { char[] chars = Character.toChars(codePoint); GlyphVector vector = font.layoutGlyphVector(GlyphPage.renderContext, chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); return vector.getGlyphCode(0); } }
private Rectangle getGlyphBounds (GlyphVector vector, int index, int codePoint) { Rectangle bounds; bounds = vector.getGlyphPixelBounds(index, GlyphPage.renderContext, 0, 0); if (renderType == RenderType.Native) { if (bounds.width == 0 || bounds.height == 0) bounds = new Rectangle(); else bounds = metrics.getStringBounds("" + (char)codePoint, GlyphPage.scratchGraphics).getBounds(); } if (codePoint == ' ') bounds.width = spaceWidth; return bounds; }
/** * Gets the NumericShaper for the specified unicode ranges. * The OR logical operation should be used for multiple ranges: * NumericShaper.DEVANAGARI | NumericShaper.BENGALI. * The NumericShaper returned by this method is contextual * in that it supports multiple character ranges, depending * on the context. * * @param ranges the unicode ranges. * * @return the NumericShaper for the specified ranges. */ public static NumericShaper getContextualShaper(int ranges) { ranges &= ALL_RANGES; return new NumericShaper(ranges, EUROPEAN, true); }