libgdx / libgdx/libgdx

Sprite generation from TTF loaded via AssetManager is inconsistent across devices

Open
#2,859 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

fonts
Dominant language
Java
Stars
25.4k
Forks
6.5k
Avg merge
1d 16h
Merged PRs (30d)
5

Description

This is my first post here, I apologize in advance if it stinks.

I'm working on a resolution-independent game whereby I load graphics as vectors using TTFs and convert them to textures/sprites based on device requirements. This was working flawlessly and consistently across all tested devices until I employed the AssetManager to load the fonts. Now, glyph data appears to vary across devices and produces unexpected sprites. Note, I've had no issues on desktop and drawing directly from the bitmap font is still working correctly. However, I require rotation and tinting so as far as I know, I'm stuck with using sprites.

I've provided all relevant code snippets below just to make sure I'm not doing anything incorrectly, as well as screenshots of the inconsistency.

AssetLoader.load()

am                              = new AssetManager();
FileHandleResolver resolver     = new InternalFileHandleResolver();
am.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver));
am.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver));

FreeTypeFontLoaderParameter p   = new FreeTypeFontLoaderParameter();
p.fontParameters.size           = (int) (Gdx.graphics.getHeight() / 10);
p.fontParameters.flip           = true;
p.fontParameters.minFilter      = TextureFilter.Linear;
p.fontParameters.characters     = "PY023";
                                    // P down feather
                                    // Y quill feather
                                    // 0 full star, no outline
                                    // 2 half star and outline
                                    // 3 empty star, just outline
p.fontFileName                  = "f.ttf";
am.load("f.ttf", BitmapFont.class, p);

AssetLoader.loadProgress()

if(am.update()) {
    f       = am.get("f.ttf");
    fQuill  = Utils.getGlyphSprite('Y', f);
    fDown   = Utils.getGlyphSprite('P', f);
    sFull   = Utils.getGlyphSprite('0', f);
    sHalf   = Utils.getGlyphSprite('2', f);
    sEmpty  = Utils.getGlyphSprite('3', f);
}
return am.getProgress();

Utils.getGlyphSprite(char ch, BitmapFont f)

Glyph g     = f.getData().getGlyph(ch);
Sprite s    = new Sprite(f.getRegion().getTexture(), g.srcX, g.srcY, g.width, g.height);
s.flip(false, true);
s.setOrigin(g.width / 2, g.height / 2);
return s;

As an example, here is the painting of just the star outlines.

GameRenderer.paint()

spritebatch.draw(empty, loc.x - empty.getWidth() / 2, loc.y - empty.getHeight() / 2, empty.getOriginX(), empty.getOriginY(), empty.getWidth(), empty.getHeight(), scale.current, scale.current, rotation.current + 90);

This is the expected result, observed on desktop and a Nexus 4, Android 5.0.1.
screenshot_2015-02-18-17-27-30clip

This is a garbled result, observed on an HTC One S, Android 4.1.1; note the feathers in place of stars, though they're not correctly drawn either, the framing seems to be off a bit.
screenshot_2015-02-18-22-38-27clip

The Nexus 4 isn't entirely perfect either, it had garbled results too via the AssetManager until I started loading the font in sections. Desktop has always been perfect though, which is why I think this is more likely a bug in LibGDX than in my code.

Please let me know if there is any other information I can provide.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with AssetLoader.load() and AssetLoader.loadProgress(), then inspect Utils.getGlyphSprite(char, BitmapFont) and GameRenderer.paint() to trace how AssetManager-loaded glyph regions become sprites. Reproduce the differing glyph and texture-region results on the reported Android devices and compare them with desktop loading. Done means the requested glyph sprites render consistently across those environments.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, java
Domain
game-dev, mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.