/** Adds cached glyphs to the active BitmapFontCache as the char index progresses. */ private void addMissingGlyphs () { // Add additional glyphs to layout array, if any int glyphLeft = glyphCharIndex - cachedGlyphCharIndex; if (glyphLeft < 1) return; // Get runs GlyphLayout layout = super.getGlyphLayout(); Array<GlyphRun> runs = layout.runs; // Iterate through GlyphRuns to find the next glyph spot int glyphCount = 0; for (int runIndex = 0; runIndex < glyphRunCapacities.size; runIndex++) { int runCapacity = glyphRunCapacities.get(runIndex); if ((glyphCount + runCapacity) < cachedGlyphCharIndex) { glyphCount += runCapacity; continue; } // Get run and increase glyphCount up to its current size Array<Glyph> glyphs = runs.get(runIndex).glyphs; glyphCount += glyphs.size; // Next glyphs go here while (glyphLeft > 0) { // Skip run if this one is full int runSize = glyphs.size; if (runCapacity == runSize) { break; } // Put new glyph to this run cachedGlyphCharIndex++; glyphCount++; glyphLeft--; glyphs.add(glyphCache.get(cachedGlyphCharIndex)); } } }
@Override public void getGlyphs (GlyphRun run, CharSequence str, int start, int end, boolean tightBounds) { if (packer != null) packer.setPackToTexture(true); // All glyphs added after this are packed directly to the texture. super.getGlyphs(run, str, start, end, tightBounds); if (dirty) { dirty = false; packer.updateTextureRegions(regions, parameter.minFilter, parameter.magFilter, parameter.genMipMaps); } }
public void getGlyphs (GlyphRun run, CharSequence str, int start, int end, boolean tightBounds) { if (packer != null) packer.setPackToTexture(true); // All glyphs added after this are packed directly to the texture. super.getGlyphs(run, str, start, end, tightBounds); if (dirty) { dirty = false; packer.updateTextureRegions(regions, parameter.minFilter, parameter.magFilter, parameter.genMipMaps); } }
private void drawUnderline(Batch batch, GlyphLayout glyphLayout, float dx, float dy) { if (!style.isUnderlined()) { // Not underlined -> abort return; } float thickness = underlineMetrics.getUnderlineThickness(); float underlineDy = underlineMetrics.getUnderlinePosition() - font.getCapHeight(); if (ydown) { underlineDy = -underlineDy; } underlineDy -= font.getAscent(); float x = getX() + dx; float y = getY() + dy + underlineDy - thickness / 2; for (GlyphRun run : glyphLayout.runs) { float runX = run.x + run.xAdvances.get(0); float runWidth = 0f; for (int n = 0; n < run.glyphs.size; n++) { runWidth += run.xAdvances.get(1 + n); // Glyph offsets start at index 1 } batch.draw(getBlankTexture(), x + runX, y + run.y, runWidth, thickness); } }
private static Glyph getGlyph(GlyphLayout layout, int index) { int offset = 0; for (GlyphRun run : layout.runs) { if (index < offset) { break; } if (index - offset < run.glyphs.size) { return run.glyphs.get(index - offset); } offset += run.glyphs.size; } throw new ArrayIndexOutOfBoundsException(index); }
private static int getGlyphCount(GlyphLayout layout) { int count = 0; for (GlyphRun run : layout.runs) { count += run.glyphs.size; } return count; }
private void addToCache (GlyphLayout layout, float x, float y) { // y += 5f * font.getScaleY(); // Check if the number of font pages has changed. int pageCount = font.regions.size; if (pageVertices.length < pageCount) { float[][] newPageVertices = new float[pageCount][]; System.arraycopy(pageVertices, 0, newPageVertices, 0, pageVertices.length); pageVertices = newPageVertices; int[] newIdx = new int[pageCount]; System.arraycopy(idx, 0, newIdx, 0, idx.length); idx = newIdx; IntArray[] newPageGlyphIndices = new IntArray[pageCount]; int pageGlyphIndicesLength = 0; if (pageGlyphIndices != null) { pageGlyphIndicesLength = pageGlyphIndices.length; System.arraycopy(pageGlyphIndices, 0, newPageGlyphIndices, 0, pageGlyphIndices.length); } for (int i = pageGlyphIndicesLength; i < pageCount; i++) newPageGlyphIndices[i] = new IntArray(); pageGlyphIndices = newPageGlyphIndices; tempGlyphCount = new int[pageCount]; } layouts.add(layout); requireGlyphs(layout); for (int i = 0, n = layout.runs.size; i < n; i++) { GlyphRun run = layout.runs.get(i); Array<Glyph> glyphs = run.glyphs; FloatArray xAdvances = run.xAdvances; float color = run.color.toFloatBits(); float gx = x + run.x, gy = y + run.y; for (int ii = 0, nn = glyphs.size; ii < nn; ii++) { Glyph glyph = glyphs.get(ii); gx += xAdvances.get(ii); addGlyph(glyph, gx, gy, color); } } currentTint = whiteTint; // Cached glyphs have changed, reset the current tint. }
public void draw(Batch batch, float dx, float dy, float visibleGlyphs) { if (visibleGlyphs == 0 || glyphLayout.runs.size == 0) { return; // Nothing to draw } applyScale(); { if (visibleGlyphs < 0f || visibleGlyphs >= glyphCount) { // Text fully visible drawUnderline(batch, glyphLayout, dx, dy); drawLayout(batch, glyphLayout, dx, dy); } else { // Text partially visible int visible = (int)visibleGlyphs; GlyphRun run = glyphLayout.runs.first(); Array<Glyph> glyphs = run.glyphs; FloatArray xAdvances = run.xAdvances; Object[] oldGlyphs = glyphs.items; float[] oldXAdvances = xAdvances.items; int oldSize = glyphs.size; if (isRightToLeft()) { int invisible = oldSize - visible; for (int n = 0; n < invisible; n++) { dx += xAdvances.get(n); } setGlyphs(glyphs, Arrays.copyOfRange(oldGlyphs, invisible, oldSize)); xAdvances.items = Arrays.copyOfRange(oldXAdvances, invisible, xAdvances.size); } glyphs.size = visible; drawUnderline(batch, glyphLayout, dx, dy); drawLayout(batch, glyphLayout, dx, dy); if (isRightToLeft()) { setGlyphs(glyphs, oldGlyphs); xAdvances.items = oldXAdvances; } glyphs.size = oldSize; } } resetScale(); }
void updateDisplayText() { BitmapFont font = style.font; BitmapFontData data = font.getData(); String text = this.text; int textLength = text.length(); StringBuilder buffer = new StringBuilder(); for (int i = 0; i < textLength; i++) { char c = text.charAt(i); buffer.append(data.hasGlyph(c) ? c : ' '); } String newDisplayText = buffer.toString(); if (passwordMode && data.hasGlyph(passwordCharacter)) { if (passwordBuffer == null) passwordBuffer = new StringBuilder(newDisplayText.length()); if (passwordBuffer.length() > textLength) passwordBuffer.setLength(textLength); else { for (int i = passwordBuffer.length(); i < textLength; i++) passwordBuffer.append(passwordCharacter); } displayText = passwordBuffer; } else displayText = newDisplayText; layout.setText(font, displayText); glyphPositions.clear(); float x = 0; if (layout.runs.size > 0) { GlyphRun run = layout.runs.first(); FloatArray xAdvances = run.xAdvances; fontOffset = xAdvances.first(); for (int i = 1, n = xAdvances.size; i < n; i++) { glyphPositions.add(x); x += xAdvances.get(i); } } else fontOffset = 0; glyphPositions.add(x); if (selectionStart > newDisplayText.length()) selectionStart = textLength; }