Specifying certain unicode-ranges for embedded fonts

In a previous post (“Embedding and animating fonts in a Flex application“), we looked at embedding a font in a Flex application so we could animate, rotate, and set the alpha for a Text control. Well, as we learnt, sometimes embedding a whole font face can dramatically increase the size of the final SWF output. In this post we’ll look at only specifying a certain range of characters for an embedded font, which will help reduce file sizes.

Full code after the jump.

Before we get too far, we’ll quickly look at some of the font basics. If you’re a Windows user, a good place to start is with the Character Map application. Its a little Window’s utility that gets installed on most modern operating systems and lets you quickly browse a font’s supported characters, different character sets, filter characters by Unicode subranges, search for certain characters (such as © or ®), see a characters Unicode value as well as character code. It also lets you quickly copy certain characters to the clipboard for easy copy-pasting between applications. Because I can never remember where the application gets installed, or where to find its icon, it is usually just easiest to type “charmap” from a command prompt. If you have a modern-day keyboard, hit Windows+R to bring up the Run dialog, type “charmap”, hit Enter, and get ready to be amazed! Most of the features I mentioned before are cleverly hidden behind the “Advanced view” checkbox, so if you’re feeling up to the challenge check that checkbox to go to advanced view, otherwise the basic view will do just fine for now. At the top of the Character Map application is a Font drop down menu which lists all the fonts you currently have installed on your system. If you just downloaded a TrueType font (TTF) and didn’t install it into the Fonts directory (C:\Windows\Fonts by default), it won’t be listed here. Don’t worry if your specific font isn’t listed here, it isn’t the end of the world. Select any old font and click around.

If you want to embed the numbers 0-9, you would click on “0” and note it’s Unicode value (U+0030), then click on “9” and do the same (U+0039). Now, in your Flex application, you would specify this range in the @font-family style block like so:

unicode-range: U+0030-U+0039;

If you wanted to specify multiple ranges, you would just separate them with commas:

unicode-range:
    U+0030-U+0039, /* 0-9 */
    U+0041-U+0051, /* Uppercase A-Z */
    U+0052-U+007A; /* Lowercase a-z */

And if you just want to embed the whole range of all uppercase, lowercase, punctuation, and symbols, you could just specify the following unicode range:

@font-face {
    src: url('assets/base02.ttf');
    font-family: Base02;
    unicode-range: U+0021-U+007B; /* whole range of uppercase, lowercase, symbols and punctuation. */
}

Again, use the character map if you want to find additional character such as the copyright symbol (©) or other symbols.

Remember, all fonts may not include special “extended” characters such as copyright symbols, dollar signs, fractions, pound signs, euro signs, etc. Make sure you check that your font includes the characters you need.

Now, with that out of the way, lets look at a full sample of unicode-range embedding in action!

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/07/specifying-certain-unicode-ranges-for-embedded-fonts/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Script>
        <![CDATA[
            /* Import all the easing classes so its
               easier to switch between them on the
               fly without tweaking import statements. */
            import mx.effects.easing.*;
        ]]>
    </mx:Script>

    <mx:Style>
        @font-face {
            src: url('assets/base02.ttf');
            font-family: Base02;
            unicode-range: U+0021-U+007B; /* whole range of uppercase, lowercase, symbols and punctuation. */
        }

        .MyEmbeddedFont {
            font-family: Base02;
            font-size: 14px;
        }
    </mx:Style>

    <!-- Set zoom effect for 2.5 seconds (2500 milliseconds) and use the Elastic.easeOut easing method. -->
    <mx:Zoom id="zoom" duration="2500" easingFunction="Elastic.easeOut" target="{embeddedText}" />

    <!-- Use advanced font anti-aliasing for the embedded font, set the rotation to 5 degrees, alpha to 80% and loop the animation. -->
    <mx:Text id="embeddedText" text="The quick brown fox jumped over the lazy dog." styleName="MyEmbeddedFont" rotation="5" alpha="0.8" fontAntiAliasType="advanced" creationComplete="zoom.play();" effectEnd="zoom.play()" />

</mx:Application>

Shocking? No, not really, because we saw the new unicode-range style earlier in the pre-code discussion. But what kind of filesize savings did we encounter by only embedding a “small range” of characters? Well, in this case, none really. The Base02 font really only has the regular letters, numbers, punctuation and symbols to begin with, so our SWF size is still ~260 KB, same as the previous article where we didn’t specify a range at all.

But what if we only specify the exact characters that we need, the uppercase “T”, full range of lowercase letters and the period? Well, as luck has it, I did just that:

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/07/specifying-certain-unicode-ranges-for-embedded-fonts/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Script>
        <![CDATA[
            /* Import all the easing classes so its
               easier to switch between them on the
               fly without tweaking import statements. */
            import mx.effects.easing.*;
        ]]>
    </mx:Script>

    <mx:Style>
        @font-face {
            src: url('assets/base02.ttf');
            font-family: Base02;
            unicode-range:
                U+0054-U+0054, /* T */
                U+0061-U+007A, /* a-z */
                U+002E-U+002E; /* . (period) */
        }

        .MyEmbeddedFont {
            font-family: Base02;
            font-size: 14px;
        }
    </mx:Style>

    <!-- Set zoom effect for 2.5 seconds (2500 milliseconds) and use the Elastic.easeOut easing method. -->
    <mx:Zoom id="zoom" duration="2500" easingFunction="Elastic.easeOut" target="{embeddedText}" />

    <!-- Use advanced font anti-aliasing for the embedded font, set the rotation to 5 degrees, alpha to 80% and loop the animation. -->
    <mx:Text id="embeddedText" text="The quick brown fox jumped over the lazy dog." styleName="MyEmbeddedFont" rotation="5" alpha="0.8" fontAntiAliasType="advanced" creationComplete="zoom.play();" effectEnd="zoom.play()" />

</mx:Application>

Yeah, the same big snippet for a minor little tweak, but hey. I’m sure it makes somebody’s life easier if they can grab all the code in one place instead of copying from two sources.

So, with the bare minimum of characters embedded, what is the new file size of the SWF? My main SWF file is now down to 193 KB (down from ~260 KB), which is about 74% of its original size, and only 46 KB larger than the same example without any embedded font. Not too bad for a tiny bit of work! Of course, its pretty easy when you know exactly which characters are used. If we were using the font for multiple text fields or a TextInput/TextArea control you would probably need to embed the whole range of characters since you couldn’t be sure of what the user would be entering.

View source is enabled in the following example.

[Base02]

8 thoughts on “Specifying certain unicode-ranges for embedded fonts

  1. Hi
    Thx for all supporting help from your website

    Now here i am in trouble and i need your help.
    The problem is like we have three diffrent-2 project and we want to make one common RSL file for all. i mean here as we used component it increase the size of .swf file so here i want to maintain all component like button,datagrid……etc into that RSL file so that in rest of application we dont need to increase the .swf file size,, i mean as per my knowledge “framework.swc” has all definition of all component and which one we are using it gives related files into .swf. now is it possible if we maintain all component into one RSL file so that In rest of application we need only include that perticular .swc (RSL) like Cairngron.swf work..

    plz help me out…

    thx
    Maneesh

  2. hi

    i have embeded the mangal.ttf which has devnagari(Hindi) characters
    Now i m trying to type in textbox which has font family set as mangal
    by enabling hindi language in my operating system(win xp)
    when i try to type into the textbox (????) such symbol appears.

    pls help me out

    thanx in advance

    rn786

  3. When I try to embed the font with the specified unicode range I get the following error:

    transcoding parameter ‘unicodeRange’ is not supported by ‘flex2.compiler.media.MovieTranscoder’

    Please help!

    Thanks a lot in advance

  4. Can I just say again that you’re the greatest. Every time I have a flex question a little googling has me ending up here. I was trying to figure out how to actually find the ranges. Thanks for the tip on using the character map.

  5. @ Targo and also for others who got same error

    use unicodeRange property while embedding using embed

    [Embed(source=”./assets/times.ttf”,fontFamily=”timesNewRomanFont”, mimeType=”application/x-font-truetype”, unicodeRange=”U+0021-U+007B”)]

Comments are closed.