Archive for February 27, 2012

Kerning, OpenGL, and Android. (Oh, my!)

Android has this nifty feature where you can distribute a TTF with your app. Since games use OpenGL to render everything (including text), I was using a TTF-to-PNG converter that I wrote for my XNA book back in 2007.

Fancier fonts use something called kerning to make the text look more natural. For example, “Hijack” in certain fonts has a noticeable overlap between the “i” and “j”. That’s great for print and web, but it makes converting the glyphs to sprites a pain.

The way my utility “disabled” kerning was to draw each character to a separate surface and scan for the bounds of the rendered pixels. Remember, the utility was a part of the content production workflow. It sounds like a lot of work, but it was an offline, build-time tool — the place you want to do repetitive, laborious stuff.

Well, having the ability to use custom TTFs at runtime appeals to me. But, my old build-time logic wasn’t going to cut it. It turns out that Android provides a way for you to know exactly how much a glyph is influenced by kerning.

There are two basic ways to get the width of a character — Paint.measureText and Paint.getTextBounds. Paint.measureText will give you the exact number of pixels that the rendered character will occupy, but you don’t know how much the glyph will be shifted when drawn.

Paint.getTextBounds also reports the width (via getWidth), but the “left” property tells you where the character will start. For example, the font I’m using reports the “left” bounds of the “j” character to be “-9″ (Gochi Hand @20pt).

The code to calculate the width looks something like this:

Rect bounds = new Rect();
paint.getTextBounds(allChars, i, i+1, bounds);
float leading = -bounds.left;
float width = bounds.width();

When you actually draw the character to your texture, you just need to offset the x location with the value in “leading”.

c.drawText(chr, x+leading, y, paint);

Now, you have a sprite font that’s kerning-aware. While I’m currently ignoring the leading space once the glyph is rendered, I could just as easily incorporate that data into the sprite font rendering logic, adding kerning to my in-game text.

Isometric C&C? Youbetcha.

In typical Joe fashion, I couldn’t just do a straight port of Andrew’s Creatures and Castles game to Android. I thought it might be fun to render his existing level data in an isometric engine. Same game, same rules, new look. Early tests have been promising.

C&C in 2.5d?

Of course the new style means that I can’t reuse any of the existing level / sprite images. The assets you see in the screenshot are all placeholders that I threw together in Illustrator this weekend. My app supports sprite tinting, as well as some other simple effect (like flip and rotate).

Replacing the art will take precious time away from coding, but it’s not as bad as it sounds. I’ll be able to put my XNA-inspired Android game lib through some heavier testing, and I’ll be able to add cutesy extras like avatar customization.