private void nextEngineRecord(int start, int limit, int script, int lang, Font2D font, int gmask) { EngineRecord er = null; if (_ercount == _erecords.size()) { er = new EngineRecord(); _erecords.add(er); } else { er = (EngineRecord)_erecords.get(_ercount); } er.init(start, limit, font, script, lang, gmask); ++_ercount; } /** * Storage for layout to build glyph vector data, then generate a real GlyphVector */ public static final class GVData { public int _count; // number of glyphs, >= number of chars public int _flags; public int[] _glyphs; public float[] _positions; public int[] _indices; private static final int UNINITIALIZED_FLAGS = -1; public void init(int size) { _count = 0; _flags = UNINITIALIZED_FLAGS; if (_glyphs == null || _glyphs.length < size) { if (size < 20) { size = 20; } _glyphs = new int[size]; _positions = new float[size * 2 + 2]; _indices = new int[size]; } } public void grow() { grow(_glyphs.length / 4); // always grows because min length is 20 } public void grow(int delta) { int size = _glyphs.length + delta; int[] nglyphs = new int[size]; System.arraycopy(_glyphs, 0, nglyphs, 0, _count); _glyphs = nglyphs; float[] npositions = new float[size * 2 + 2]; System.arraycopy(_positions, 0, npositions, 0, _count * 2 + 2); _positions = npositions; int[] nindices = new int[size]; System.arraycopy(_indices, 0, nindices, 0, _count); _indices = nindices; } public void adjustPositions(AffineTransform invdtx) { invdtx.transform(_positions, 0, _positions, 0, _count); } public StandardGlyphVector createGlyphVector(Font font, FontRenderContext frc, StandardGlyphVector result) { // !!! default initialization until we let layout engines do it if (_flags == UNINITIALIZED_FLAGS) { _flags = 0; if (_count > 1) { // if only 1 glyph assume LTR boolean ltr = true; boolean rtl = true; int rtlix = _count; // rtl index for (int i = 0; i < _count && (ltr || rtl); ++i) { int cx = _indices[i]; ltr = ltr && (cx == i); rtl = rtl && (cx == --rtlix); } if (rtl) _flags |= GlyphVector.FLAG_RUN_RTL; if (!rtl && !ltr) _flags |= GlyphVector.FLAG_COMPLEX_GLYPHS; } // !!! layout engines need to tell us whether they performed // position adjustments. currently they don't tell us, so // we must assume they did _flags |= GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS; } int[] glyphs = new int[_count]; System.arraycopy(_glyphs, 0, glyphs, 0, _count); float[] positions = null; if ((_flags & GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS) != 0) { positions = new float[_count * 2 + 2]; System.arraycopy(_positions, 0, positions, 0, positions.length); } int[] indices = null; if ((_flags & GlyphVector.FLAG_COMPLEX_GLYPHS) != 0) { indices = new int[_count]; System.arraycopy(_indices, 0, indices, 0, _count); } if (result == null) { result = new StandardGlyphVector(font, frc, glyphs, positions, indices, _flags); } else { result.initGlyphVector(font, frc, glyphs, positions, indices, _flags); } return result; } } /** * Utility class to keep track of script runs, which may have to be reordered rtl when we're * finished. */ private final class EngineRecord { private int start; private int limit; private int gmask; private int eflags; private LayoutEngineKey key; private LayoutEngine engine; EngineRecord() { key = new LayoutEngineKey(); } void init(int start, int limit, Font2D font, int script, int lang, int gmask) { this.start = start; this.limit = limit; this.gmask = gmask; this.key.init(font, script, lang); this.eflags = 0; // only request canonical substitution if we have combining marks for (int i = start; i < limit; ++i) { int ch = _textRecord.text[i]; if (isHighSurrogate((char)ch) && i < limit - 1 && isLowSurrogate(_textRecord.text[i+1])) { // rare case ch = toCodePoint((char)ch,_textRecord.text[++i]); // inc } int gc = getType(ch); if (gc == NON_SPACING_MARK || gc == ENCLOSING_MARK || gc == COMBINING_SPACING_MARK) { // could do range test also this.eflags = 0x4; break; } } this.engine = _lef.getEngine(key); // flags? } void layout() { _textRecord.start = start; _textRecord.limit = limit; engine.layout(_sd, _mat, gmask, start - _offset, _textRecord, _typo_flags | eflags, _pt, _gvdata); } }}Lines 501–668 of 668. Previous lines
private void nextEngineRecord(int start, int limit, int script, int lang, Font2D font, int gmask) { EngineRecord er = null; if (_ercount == _erecords.size()) { er = new EngineRecord(); _erecords.add(er); } else { er = (EngineRecord)_erecords.get(_ercount); } er.init(start, limit, font, script, lang, gmask); ++_ercount; } /** * Storage for layout to build glyph vector data, then generate a real GlyphVector */ public static final class GVData { public int _count; // number of glyphs, >= number of chars public int _flags; public int[] _glyphs; public float[] _positions; public int[] _indices; private static final int UNINITIALIZED_FLAGS = -1; public void init(int size) { _count = 0; _flags = UNINITIALIZED_FLAGS; if (_glyphs == null || _glyphs.length < size) { if (size < 20) { size = 20; } _glyphs = new int[size]; _positions = new float[size * 2 + 2]; _indices = new int[size]; } } public void grow() { grow(_glyphs.length / 4); // always grows because min length is 20 } public void grow(int delta) { int size = _glyphs.length + delta; int[] nglyphs = new int[size]; System.arraycopy(_glyphs, 0, nglyphs, 0, _count); _glyphs = nglyphs; float[] npositions = new float[size * 2 + 2]; System.arraycopy(_positions, 0, npositions, 0, _count * 2 + 2); _positions = npositions; int[] nindices = new int[size]; System.arraycopy(_indices, 0, nindices, 0, _count); _indices = nindices; } public void adjustPositions(AffineTransform invdtx) { invdtx.transform(_positions, 0, _positions, 0, _count); } public StandardGlyphVector createGlyphVector(Font font, FontRenderContext frc, StandardGlyphVector result) { // !!! default initialization until we let layout engines do it if (_flags == UNINITIALIZED_FLAGS) { _flags = 0; if (_count > 1) { // if only 1 glyph assume LTR boolean ltr = true; boolean rtl = true; int rtlix = _count; // rtl index for (int i = 0; i < _count && (ltr || rtl); ++i) { int cx = _indices[i]; ltr = ltr && (cx == i); rtl = rtl && (cx == --rtlix); } if (rtl) _flags |= GlyphVector.FLAG_RUN_RTL; if (!rtl && !ltr) _flags |= GlyphVector.FLAG_COMPLEX_GLYPHS; } // !!! layout engines need to tell us whether they performed // position adjustments. currently they don't tell us, so // we must assume they did _flags |= GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS; } int[] glyphs = new int[_count]; System.arraycopy(_glyphs, 0, glyphs, 0, _count); float[] positions = null; if ((_flags & GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS) != 0) { positions = new float[_count * 2 + 2]; System.arraycopy(_positions, 0, positions, 0, positions.length); } int[] indices = null; if ((_flags & GlyphVector.FLAG_COMPLEX_GLYPHS) != 0) { indices = new int[_count]; System.arraycopy(_indices, 0, indices, 0, _count); } if (result == null) { result = new StandardGlyphVector(font, frc, glyphs, positions, indices, _flags); } else { result.initGlyphVector(font, frc, glyphs, positions, indices, _flags); } return result; } } /** * Utility class to keep track of script runs, which may have to be reordered rtl when we're * finished. */ private final class EngineRecord { private int start; private int limit; private int gmask; private int eflags; private LayoutEngineKey key; private LayoutEngine engine; EngineRecord() { key = new LayoutEngineKey(); } void init(int start, int limit, Font2D font, int script, int lang, int gmask) { this.start = start; this.limit = limit; this.gmask = gmask; this.key.init(font, script, lang); this.eflags = 0; // only request canonical substitution if we have combining marks for (int i = start; i < limit; ++i) { int ch = _textRecord.text[i]; if (isHighSurrogate((char)ch) && i < limit - 1 && isLowSurrogate(_textRecord.text[i+1])) { // rare case ch = toCodePoint((char)ch,_textRecord.text[++i]); // inc } int gc = getType(ch); if (gc == NON_SPACING_MARK || gc == ENCLOSING_MARK || gc == COMBINING_SPACING_MARK) { // could do range test also this.eflags = 0x4; break; } } this.engine = _lef.getEngine(key); // flags? } void layout() { _textRecord.start = start; _textRecord.limit = limit; engine.layout(_sd, _mat, gmask, start - _offset, _textRecord, _typo_flags | eflags, _pt, _gvdata); } } }