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:
[as3]
// 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;
[/as3]
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.
I haven’t started using Flex 4 yet, but when I do this will really come in handy for some of the TextField-embedded fonts I have. Thanks for the tip!
Lovely. We’re just about to finish a game here and I was curious why it doesn’t embed fonts at all when compiled in FDT4. I had no time to check it out yet, so you saved me a few whiles, thanks :]
ugh, why did they change the syntax for the same attribute ?! That’s annoying 🙁
Thanks that’s good knowledge to have! I do hope Adobe had a real good reason for doing this. Otherwise it’s kind of embarrassing.
SDK 3.5 fixed!
Thanks for the information Keith, I was wondering why my fonts weren’t being embedded when using flex sdk 4.0
Why not load the font at runtime?
Couldn’t you use the Config::debug{} Config::release{} method by doing something like
CONFIG::f3{ entry with normal embed}
CONFIG::f4{ entry with embedAsCff}
Then by adding -define=CONFIG::f3,true/false or -define+=CONFIG::f4,true/false
just a thought..
Thanks a lot, was looking for this information
This is like the 5th time I’ve found something really helpful here, thanks!
I’m not using flex, but thanks for sharing.
i can’t remember where i saw that information but the easy fix described was to open the flex/frameworks/flex-config.xml, find the managers and move down to the bottom of the list the manager-class: flash.fonts.AFEFontManager
this works the same with flex 3 & 4 SDKs
so i didn’t have to use embedAsCFF=”false”
Wow, you’re a lifesaver.
My laptop crashed and I had to reinstall everything so I upgraded my sdk to 4.1 since it was the most recent. I was trying to work out why all my textfields had disappeared. I assumed I had changed something to break it – it didn’t occur to me that adobe would do something like this. Someone working there needs a kicking.
Thanks again Keith, that’s exactly what I needed!
thanks for sharing, this solved my problem too!
P.S.
shame on Adobe for this…
I updated MinimalComps to use the new font SWF embedding required in ASC 2.0 (currently released on labs.adobe.com). It’s on GitHub here: https://github.com/ElliotMebane/minimalcomps
and more details about using fontswf and embedding the font are here: http://www.roguish.com/blog/?p=550