It was brought to my attention today that there was a possible issue in the MinimalComps regarding font embedding. If you were to compile the component source with the Flex 4 SDK, no labels on any components would show up. If you use the precompiled SWC, you’d be fine, as this was compiled with the 3.4 SDK. But if you were using the zipped source checked out the source with SVN and compiled under SDK 4.x, you’d hit this problem.
With a quick bit of research, I learned that with Flex 4, there is a new type of embedding for fonts. Traditional font embedding is called DefineFont3. The new stuff is called DefineFont4. Let’s call them DF3 and DF4 for short here. It turns out that the new text components in Flex 4 require DF4. Yet, the old fashioned TextField requires DF3. Guess what the default is? Yes, DF4. This means that using the exact same syntax for embedding will now make embedded fonts in TextFields not work. The solution is, when embedding a font, to tell it to NOT use DF4. The original syntax for this was to add
cff="false" to the Embed tag. The current syntax is
embedAsCFF="false". So, in that sense, this is an easy fix.
With FlashBuilder 4 and Flex 4 being officially released today, I decided to upgrade the SWC to use the Flex 4 SDK for compiling. I changed the Embed tag as above. So now, compiling in FlashBuilder 4 or otherwise using the 4.x SDK should work fine. Of course, this creates the opposite problem. If you are compiling in Flex Builder 3 or a 3.x SDK, it will not recognize embedAsCFF in the Embed tag and your code will not compile. I looked into conditional compiling, but as far as I can tell, that’s not going to be a real solution in this case unless I can inject a compiler definition. But since I’m just distributing source, not a build system, I don’t see a way to do that.
So the two choices are:
A. Don’t use embedAsCFF and compile the SWC under 3.x.
B. Use embedAsCFF and compile the SWC under 4.x.
Either way, anyone using the other SDK will have a problem. However, if I go with A, the people using 4.x will not see the font show up, but will get no useful error of any kind. If I go with B, the people using 3.x will get a compiler error pointing them to the Embed statement in Component.as. That is much more useful.
So, if you look at Component.as, you will now see this:
// NOTE: Flex 4 introduces DefineFont4, which is used by default and does not work in native text fields. // Use the embedAsCFF="false" param to switch back to DefineFont4. In earlier Flex 4 SDKs this was cff="false". // So if you are using the Flex 3.x sdk compiler, switch the embed statment below to expose the correct version. // Flex 4.x sdk: [Embed(source="/assets/pf_ronda_seven.ttf", embedAsCFF="false", fontName="PF Ronda Seven", mimeType="application/x-font")] // Flex 3.x sdk: // [Embed(source="/assets/pf_ronda_seven.ttf", fontName="PF Ronda Seven", mimeType="application/x-font")] private var Ronda:Class;
So, if you are using 4.x, all should be well. If you are using 3.x, you’ll get an error which should take you right to this exact point. Hopefully you’ll be able to figure things out from my detailed explanation and fix it.
Again, if you are using the precompiled SWC, it shouldn’t matter what SDK you are using, at the SWC is all wrapped up in its own little package. This will only be a problem if you are linking to the source classes themselves.
I know this whole thing presented a problem for Adobe, but I feel they broke some fundamental rules here. They broke a commonly used API. If you have function foo() that makes ThingX’s, you don’t just suddenly change it so it makes ThingY’s instead, and add a new parameter that you can use to force it to make ThingX’s again. You either make a foo2() function or allow foo to take an optional parameter to force it to make the new ThingY’s. You don’t break existing code. Anyway, that’s what we’re stuck with, and I did the best I could with it.