Fabricated Technobabble

View Original

Resource Bundles and Fonts

If you've been working with Flash for a while, especially FlashBuilder, you've probably heard of resource bundles. If you are like me you heard they had something to do with localization. Then you quickly forgot about them. The truth is they aren't only for localization. In fact, they are a really good way to centralize and manage resources in actionscript project. They also happen to work really well for localization. So if they do more than just localization, what are resource bundles.

What are Resource Bundles

I hate to state the obvious, but resource bundles are bundles of...wait for it...resources! So with that the next question is, "What is a resource?"

    A resource could be a...

  • ...String
  • ...Image
  • ...Config Value
  • ...Font

Why would you want to use them?

Okay, now you know what resources are. You've managed these resources in other ways. Why would you want to use resource bundles over the way you already do?

    Here are a few good reasons

  • 2 words, cleaner code
  • easier localization
  • change text, configs, etc. in one spot

How to setup

Before we get into using resource bundles with fonts, it is important to know how to set them up. Also you might want to know how to use them with the other, simpler types of resources. There are many great articles already available online if you want to search. I plan to write a "how to setup resource bundles" post next week so check back then.

I hate fonts (but I understand they make stuff look good)

I have always dreaded working with embedded fonts on a flash project. Even though I've done it many times, and should know how, each project has brought its own wrinkle that has caused grief for me. Embedding fonts via resource bundles gives you more control over the specifics of the font. Also, since it is built into development with the Flex SDK, you can more readily change them for your needs right in the project. Need to embed more characters? Change to/from CFF embedding? Just type in the appropriate text and you are done. Depending on your development environment you may need to clean your project.

One other point, I recently work on a localization project for game that was already live. Even though we had all the text strings externalized this project sucked and was slow going. If I had my strings, and other resources, setup in resource bundles I would have been halfway done with the project before I even started. So enough talk, how can we use resource bundles to help with font embedd?

Embedding fonts with resource bundles

A font gets embedded in a resource bundle much like an image get embedded, using the Embed metatag. In fact it is awfully similar to using the Embed metatag as you would in an actionscript file.

It might look something like this:

#a file called fonts.properties

AFontDesignersLove="ComicSans"
ComicSans=Embed(
	source="./assets/fonts/comic.ttf", 
	fontName="ComicSans", 
	embedAsCFF="false", 
	mimeType="application/x-font", 
	advancedAntiAliasing="true", 
	unicodeRange="U+0020-007E")

The backslash() is useful in property files to make long entries more readable. I'm all about readable, editable code.

To use this font in its current form would work like this:

[ResourceBundle("fonts")]
public class MyFontUsingClass {

// put some other code here

	var resources:IResourceManager = ResourceManager.getInstance();
	var fontName:String = resources.getString("fonts", "AFontDesignersLove");
	var format:TextFormat = new TextFormat(fontName, FONT_SIZE);

	_questionField = new TextField();
	_questionField.defaultTextFormat = format;
	_questionField.embedFonts = true;

// put some more code here

You probably noticed a couple things here:

  • I lied - designers hate Comic Sans
  • I also put the font name (string resource) in the property file and just used it to bring in the font.

Once you use the resource bundle metatag in your code for a bundle that has fonts, those fonts are already embedded in your code. There is no need to do the old Font.registerFont() silliness. At least not when you compile the resource bundle into your swf.

The above code is still a bit heavy and I'd hate to have to write it every time. My advice is to clean it up into something that looks a bit more like this:

_questionField.defaultTextFormat = Fonts.getFormat();
_questionField.embedFonts = true;

Depending on what type of format data is used, you might need to make this a little more robust than this but aiming towards this will make you enjoy the benefits gained from embedding fonts this way. For now, I leave this as an exercise for the reader. I plan to write an article on some resource bundle good practices* in the future.