Font issue in MinimalComps

Mar 22 2010 Published by under Components, Flash

Send to Kindle

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.

Send to Kindle

18 responses so far. Comments will be closed after post is one year old.

  • 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 :(

  • Øyvind Nordhagen says:

    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.

  • Bindiry says:

    SDK 3.5 fixed!

  • LZNPDE says:

    Thanks for the information Keith, I was wondering why my fonts weren’t being embedded when using flex sdk 4.0

  • vic says:

    Why not load the font at runtime?

  • Keyston says:

    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..

  • CharlesG says:

    Thanks a lot, was looking for this information

  • Adam says:

    This is like the 5th time I’ve found something really helpful here, thanks!

  • rock solid says:

    I’m not using flex, but thanks for sharing.

  • [...] The remainder of the <fx:Style> tag is provided in the prior post.  I had a bit of trouble with the local() syntax, so I provided the direct url for the font   When embedding fonts in a Flex 4 application, take care to note whether the component using the font is Halo or Spark or a dynamically created text field. DefineType4 is now in the Text Layout Framework, which is documented here.  The implication is whether or not embedAsCFF is true (Spark) or false (otherwise).  Keith Peters has also blogged on this topic. [...]

  • guéric says:

    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”

  • Sam says:

    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.

  • Bruno says:

    Thanks again Keith, that’s exactly what I needed!

  • m3xican says:

    thanks for sharing, this solved my problem too!

    P.S.
    shame on Adobe for this…

  • [...] Cutting to the chase: I created pf_ronda_seven.swf from the pf_ronda_seven.ttf font using the fontswf command line utility bundled with Flash Builder 4.7 from labs.adobe.com. It was important to use the -3 option when running fontswf so my font SWF would use DefineFont3 and be compatible with regular text fields. The default is DefineFont4 for creating text swfs for use with TLF text fields. For more context about DefineFont3 vs DefineFont4, read about Keith Peters’ experience with it when Flex 4 was released in 2010: http://www.bit-101.com/blog/?p=2555 [...]

  • EMebane says:

    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