Dynamic Textfields in Flash AS3 and Their Bugs

October 19, 2009 · Posted in advice, code, work 

I do a ton of localizations for web-based media (over 30 countries) and have run across several bugs in Flash where the characters don’t show up for certain fonts, especially for translations with non-latin characters (such as Russian, Chinese, Japanese and even Hungarian and German). I always complain about them, and instead of just complaining, I figured I’d share some of the solutions since they’re bugs in Flash and may not have obvious solutions.

Obvious Solutions

The obvious solution when you have a dynamic text field, that is either driven from XML, RSS, or other external document or data source, is to embed the font’s character sets. Obviously if you are going to be using Korean in your Flash application, you want to embed the Korean character sets so the Korean characters show up in the font you have chosen. However, with so much emphasis on branding these days, not all specialized fonts have characters in Korean.

For example, the Star Wars Jedi font that I once worked with has absolutely no other characters beyond A-Z, a-z and numerals. Forget Spanish and it’s tildes, forget German and its umlauts, but Russian?! Ha! Everyone knows there were no Russian Jedis! So, what to do?

Dynamic Font Swap!

There are several nuances to Flash character embedding (ok, there’s probably a few hundred as I find at least one new one a week). Unfortunately Star Wars applications with the Jedi font won’t work in any language but High Schooler English since they don’t use punctuation either. So we have to change the font to something more appropriate if we want to use another language. Here’s the ActionScript 3 (AS3) code, which I’ll explain a bit after:

// Get previous text format from text field to save other settings
var newTextFormat:TextFormat = theTextField_txt.getTextFormat();

// Change font size if applicable
if( fontSize_num != 0 )
{
newTextFormat.size = fontSize_num;
}
// If we need to replace the font, do that here
if( isSpecialCharacterSet_bool )
{
newTextFormat.font = defaultFont_str; // set font
newTextFormat.bold = false;
newTextFormat.kerning = false;

theTextField_txt.embedFonts = false; // kill the embedded font
theTextField_txt.rotation = 0;
}

theTextField_txt.setTextFormat( newTextFormat ); // Apply altered text format

Ok, so what does that all mean? We take the textfield’s font properties (say, Jedi Font, size 14pt, embedded characters, etc) and alter some of the properties we need to so that our application can speak to our Russian Jedi friends. This particular code will accept a fontsize_num variable in case you want to alter the font size of the text so that it will fit within the given textbox because we all know Russian Jedi Masters are sometimes really wordy!

Next, we have a variable isSpecialCharacterSet_bool, that if true, will execute the font swap that we need. You can set this variable via XML to control, on a per language basis (having a separate XML file per language), if you want to swap fonts. After that is the defaultFont_str variable, which we can also set via XML to determine which font we want to use as a replacement of our Star Wars Jedi font. Recommended fonts are _sans, _serif, Arial and Helvetica as those are fonts that include almost every character known to modern languages.

Then, we turn off bold because, believe it or not, a bolded font is an entirely different character set and causes all sorts of other problems. We also turn off kerning because it’s a ridiculous feature that doesn’t work and I guarantee will mess up your dynamic text fields, foreign or otherwise.

The next two lines are super important:

theTextField_txt.embedFonts = false; // kill the embedded font
theTextField_txt.rotation = 0;

Unless you embed ALL the font characters that Flash will let you, you won’t have your foreign language characters, which I don’t recommend anyway due to a huge increase in file size and also for the fact that it still won’t work (I’ve tried, trust me on this one). So, even though everyone has _sans, _serif, Arial and Helvetica on their computer (which allows us to display the characters without embedding them), if you DO embed some character sets, it won’t show up. Go ahead, create a dynamic text field in Arial, embed A-Z, a-z, numerals and punctuation and watch it NOT show up when you assign a string in Russian to it. Go back, click “Don’t Embed” on the textfield and watch as your Russian characters show up again. So, we programmatically disallow fonts from being embedded.

Another thing you’d think Adobe could have gotten right but doesn’t seem to care about the non-English speaking community, a.k.a. the 6 billion other people on this planet, is the bug that if a foreign character exists in a textfield that is even slightly rotated, the entire textfield disappears. So, thank you Adobe for wasting my time with your poorly programmed textfields. The trick though, is to simply make the textfield’s rotation 0. Strangest thing ever, but give it a try if you don’t believe me. And if the textfield’s parent movieclip is rotated, not your child textfield within said MC, try:

theTextField_txt.parent.rotation = 0;

You can also programatically set the multiline property if translated text seems to be a bit wordy. But you should probably have set up your textfields to handle the expanded text anyway.

Put that code into a function and throw the textfield at it and additionally the font size (which I usually get from the XML node’s property). Unfortunately, you have to do this for every textfield and every time you set the text, but if you plan and build your Flash applications correctly, this should be a simple addition to your application framework. If it’s not obvious, let me know and I’ll write another article on best practices for localizing your Flash applications.

Flash Textfields Are Still Broken!

What isn’t broken in Flash? If you’ve delved deeper into Flash than simple animations, you’ve more than likely run into several on your own. Most of the time, restarting Flash will work, but other times, some detective work must be done in order to sort out the workarounds.

Masked fonts

If your dynamic textfield is masked, in anyway, fonts won’t show up if you disallow font embedding. Why? Well isn’t it obvious? Flash is broken. So, don’t mask your fonts if you want them to work internationally.

So many thanks to Adobe, we enjoy overpaying for your products so that they’re full of bugs. I’ve worked in Flash since the late 90s and I can’t remember them EVER releasing a patch for it. Just a new version that you have to pay several hundred dollars for. So my advice is to use an open standard for your applications and websites since those always support international languages.

Did you find this useful?

If you found this page useful, please consider helping us out by checking out the links on the right. Thanks!

Comments