Libgdx Freetype font glitches on android?

I’ve been working on a little app lately and I decided to use freetype for the font and it’s been working great on the desktop client. However, on Android, I get these weird glitches in the drawing of some characters, and some characters won’t draw at all. If I change the font size by the slightest bit, the characters that aren’t working start to work, but other characters stop working then. I don’t know if anyone else has had this problem before. Any help would be greatly appreciated. Here are some pictures to show exactly what I’m talking about. http://imgur.com/a/0y7wo

This is difficult to answer without more information. Is there any code you can share with us?

Sure thing. Here is the wrapper that I have for Freetype fonts:

package com.toasted.misspelled;

import java.util.HashMap;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
import com.badlogic.gdx.utils.Align;

public class Font{
	
	public static Font font0;
	public static Font font1;
	public static Font font2;
	public static void init(){
		font0 = scale(Gdx.graphics.getWidth() / 9, Color.WHITE, null);
		font1 = scale((int) (Gdx.graphics.getWidth() / 9 * 3.1f), Color.WHITE, null);
		font2 = scale((int) (Gdx.graphics.getWidth() / 9 * .81f), Color.WHITE, null);
	}

	private static FreeTypeFontGenerator fgen = new FreeTypeFontGenerator(Gdx.files.internal("ArchivoBlack.otf"));
	public static Font getFont(int size, Color color, Color outline){
		if(fontCache.get(new FontInfo(size, color, outline)) != null)
			return fontCache.get(new FontInfo(size, color, outline));
			
		FreeTypeFontParameter parameter = new FreeTypeFontParameter();
		//parameter.borderColor = outline;
		//parameter.borderWidth = 1;
		parameter.size = size;
		parameter.color = color;
		parameter.shadowOffsetX = 2;
		parameter.shadowOffsetY = 2;
		parameter.shadowColor = Color.GRAY;
		Font f = new Font(fgen.generateFont(parameter), size);
		fontCache.put(new FontInfo(size, color, outline), f);
		
		return f;
	}
	private static Font scale(int size, Color color, Color outline){
		return getFont((int)(size * Renderer.scale.x), color, outline);
	}
	public static void dispose(){
		fgen.dispose();
	}
	private static class FontInfo {
		int size;
		Color color;
		Color outlineColor;
		public FontInfo(int size, Color color, Color outlineColor){
			this.size = size;
			this.color = color;
			this.outlineColor = outlineColor;
		}
		public boolean equals(Object o){
			FontInfo fi = null;
			if(o instanceof FontInfo) fi = (FontInfo)o;
			if(fi == null) return false;
			return size == fi.size && color.equals(fi.color) && fi.outlineColor.equals(this.outlineColor);
		}
	}
	private static HashMap<FontInfo, Font> fontCache = new HashMap<FontInfo, Font>();
	private BitmapFont bitmap;
	public int size = 0;
	private GlyphLayout gl = new GlyphLayout();
	public Font(BitmapFont font, int size){
		this.bitmap = font;
		this.size = size;
	}
	public void draw(Renderer g, String s, float x, float y){
		bitmap.draw(g, s, x, y + bitmap.getLineHeight() - bitmap.getAscent() * 2);
	}
	public void draw(Renderer g, String s, float x, float y, float w){
		gl.setText(bitmap, s);
		bitmap.draw(g, s, x - gl.width / 2, y, w, Align.left, false);
	}
	public float getRaise(){
		return -bitmap.getDescent();
	}
	public float getCap(){
		return bitmap.getCapHeight();
	}
	public float getWidth(String s){
		gl.setText(bitmap, s);
		return gl.width;
	}
	public float getHeight(){
		return bitmap.getLineHeight();
	}
	public Color getColor(){
		return bitmap.getColor();
	}
	public void setColor(Color c){
		bitmap.setColor(c);
	}
	public void draw(Renderer g, String s, float x, float y, float w, boolean wrap){
		bitmap.draw(g, s, x, y, w, Align.left, wrap);
	}
	public BitmapFont getBitmap(){
		return bitmap;
	}

And here is what one of the draw calls looks like:

Font.font2.draw(g, "HIGH SCORE:", getWidth() / 2 - Font.font2.getWidth("HIGH SCORE:") / 2, getHeight() * .25f);

I can’t see what’s wrong with that, but then I don’t know what your

Renderer

class looks like.

You could try running something like this to figure out at what sizes it fails, and then look at the data generated by the font generator to figure out what’s going wrong;


package com.bornander.stuff;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;

import javafx.scene.text.Font;

public class MyGdxGame extends ApplicationAdapter {
	SpriteBatch batch;
	FreeTypeFontGenerator generator;
	BitmapFont bitmapFont;
    int size = 4;
	
	@Override
	public void create () {
		batch = new SpriteBatch();
		generator = new FreeTypeFontGenerator(Gdx.files.internal("ArchivoBlack.otf"));
	    getNextSize();

        Gdx.input.setInputProcessor(new InputAdapter() {
            @Override
            public boolean touchDown(int screenX, int screenY, int pointer, int button) {
                MyGdxGame.this.getNextSize();
                return super.touchDown(screenX, screenY, pointer, button);
            }
        });
	}

    private void getNextSize() {
        ++size;
        FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
        parameter.size = size;
        parameter.color = Color.WHITE;
        parameter.shadowOffsetX = 2;
        parameter.shadowOffsetY = 2;
        parameter.shadowColor = Color.GRAY;

        bitmapFont = generator.generateFont(parameter);
    }

	@Override
	public void render () {
		Gdx.gl.glClearColor(0, 0, 0, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		batch.begin();
		String text = "HIGH SCORE:" + size;
		GlyphLayout layout = new GlyphLayout();
		layout.setText(bitmapFont, text);

		float x = (Gdx.graphics.getWidth() - layout.width) / 2.0f;
		float y = (Gdx.graphics.getHeight() - layout.height) / 2.0f;
		bitmapFont.draw(batch, text, x, y);
		batch.end();
	}
}

That will write a string of your choice centered on screen, and increase the font size every time to tap the screen.