Chapter 8. Customizing Application Appearance

The Flex framework has a great deal of functionality built into it, making it relatively easy to start building applications. All of the user interface components and layout containers greatly simplify the process of creating a new application because you can utilize all the functionality of the components without having to write all the code to make them work. As great as that is, it would be nearly useless in most cases if you couldn't customize the appearance of the components. Yet, as we’ll see in this chapter, customization of the appearance of Flex components is another built-in feature.

There are essentially two ways you can customize the appearance of components:

  • Apply styles.

  • Change skins.

Styles are settings such as color, font face, border settings, row height, and so on. These are settings that you can customize entirely programmatically both at compile time and at runtime. Styles allow you to customize a great deal of the appearance of components, yet they can go only so far. For example, if you want to change the background color of a button, you can do that using styles, but if you want to completely change the shape of a button (e.g., from a rounded rectangle to a trapezoid), you need to use a different technique in which you change the skins of the component. Skins can be graphical elements (e.g., PNG files) or programmatic elements (classes), and they allow you to not only customize the existing elements of a component, but also completely change which elements are used. Therefore, using custom skins allows you to alter the appearance of a component so completely that it is unrecognizable from its original default appearance. You can use both styles and skins at the same time (although oftentimes applying a skin will cancel out certain style settings).

In this chapter, we’ll look more closely at all the techniques you can use to customize application appearance through the use of styles and skins. We’ll also look at working with fonts, using Cascading Style Sheets (CSS), customizing an application preloader, and creating custom themes for styling.

Using Styles

Styles allow you to control a great many aspects of an application’s appearance, including colors, fonts, spacing, animation settings, and more. You can define and apply styles in many ways, each with its own advantages and disadvantages. These can be categorized as follows:

  • Instance styles

  • Class selectors (stylesheets)

  • Type selectors (stylesheets)

  • Global styles

Because there are so many ways to apply styles, it is actually possible to apply different values for the same style to a component using different ways to apply that style. For example, you can set the color of a button component using an instance style as well as using a type selector. Because this is possible, it’s necessary for Flex to have an order of precedence for the application of styles. That order (from greatest precedence to least) is the same as the list preceding this paragraph. That means that if Flex has to decide between an instance style and a type selector, it will use the value from the instance style.

Style Value Formats

There are lots of different styles, and each style has a required data type for its value. For example, the style used to set the font face (fontFamily) requires a string value specifying the name of the font to use, yet the style used to set the font size (fontSize) requires a numeric value. Behind the scenes, all styles accept values of one of these two data types: string and number. However, for convenience, some styles accept more than one type of value. For example, color styles should be specified using numeric values, but you can also specify one of the color strings, such as red or green. Those values are translated to number values behind the scenes. Also, some styles actually require number values of 0 or 1, but you can optionally specify a Boolean value of true or false. This next example sets the dropShadowEnabled property to 1, but it could also use the value true to achieve the same effect:

<mx:Style>
    VBox {
        backgroundColor: green;
        borderStyle: solid;
        dropShadowEnabled: 1;
    }
</mx:Style>
<mx:VBox width="200" height="200" />

Some styles allow you to specify a unit of measurement. However, Flex ignores all units of measurement, using only the numeric portion of the value. For example, when you specify a font size, you can also specify a unit of measurement such as pixels or points, though the result will always be the same regardless of what unit of measurement is specified (or if none is specified). This allows you to use the same stylesheets for your Flex applications that you might use with HTML applications. The following example sets the font-size property of a class selector to 15px, which is interpreted simply as 15 by Flex:

.example {
    font-size: 15px
}

Note

The Flex Style Explorer allows you to see what styles are available for Flex components, and you can adjust those settings in real time and see the generated CSS to create the style settings. You can view the Flex Style Explorer at http://examples.adobe.com/flex3/consulting/styleexplorer/Flex3StyleExplorer.html.

Instance Styles

Instance styles are the styles set for a specific component instance. You can set instance styles using MXML or ActionScript. Setting instance styles using MXML is often referred to as setting an inline style, because you simply set the value for an attribute in the component tag. Here’s an example of a button component for which we’re setting the color style:

<mx:Button label="Example" color="red" />

You can set many inline styles at the same time. Here’s the same button with additional styles set inline:

<mx:Button label="Example" color="red" borderColor="yellow"
    cornerRadius="10" fontStyle="italic" />

You can also set styles on an instance using ActionScript via the setStyle() method. The setStyle() method is defined by UIComponent, which means that you can call the method for all (visual) Flex components. The setStyle() method requires two parameters: the name of the style property as a string (e.g., color) and the value for the property. Here’s an example that sets a button component’s color style:

button.setStyle("color", "red");

If you want to set many styles for a component, you need to call setStyle() for each style. Here’s an example that sets many styles for one component:

button.setStyle("color", "red");
button.setStyle("borderColor", "yellow");
button.setStyle("cornerRadius", 10);
button.setStyle("fontStyle", "italic");

If you apply styles using setStyle(), you can change styles at runtime. That means you can use setStyle() to change a style even if it was set inline. Example 8-1 sets the color style both inline and with ActionScript. Because setStyle() is called after the inline style was applied, the button label appears in red rather than green.

Example 8-1. Setting a style with setStyle()

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    initialize="initializeHandler(event)">
    <mx:Script>
        <![CDATA[
            private function initializeHandler(event:Event):void {
                button.setStyle("color", "red");
            }
        ]]>
    </mx:Script>
    <mx:Button id="button" label="Example" color="green" />
</mx:Application>

The following shows an interactive version that demonstrates how setStyle() allows you to make changes at runtime:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
        <![CDATA[
            private function changeColor(color: String):void {
                button.setStyle("color", color);
            }
        ]]>
    </mx:Script>
    <mx:Button id="button" label="Change Color"
        color="green" toggle="true"
        click="changeColor(button.selected ? 'blue' : 'red')" />
</mx:Application>

If you want to retrieve the style value for a specific instance, you can use the getStyle() method. The getStyle() method requires a parameter specifying the name of the style. The method then returns the current value of the style. The following example retrieves the color style value for the button and displays it:

<mx:Button id="button" label="Example" color="red" />
<mx:TextInput text="{button.getStyle('color').toString(16)}" />

Note

The use of toString() in the preceding code outputs the value using a radix of 16, effectively displaying the color in hexadecimal format.

Using CSS

Applying instance styles using inline style attributes is convenient. However, it has a major drawback in that it decentralizes style settings for the application, making it difficult to manage. Instead, you can use CSS to define styles for components. Although you can use CSS that gets loaded at runtime, this section deals only with CSS that is compiled into the Flex application. (We’ll look at runtime CSS in Runtime CSSˮ later in this chapter.)

CSS is a standard way for applying styles across platforms, languages, and frameworks. The syntax of CSS in Flex is identical to the syntax of CSS as it is used by HTML. For example, here’s a sample class selector for a Flex application written in CSS:

.example {
    color: red;
}

Note

Even though the syntax of CSS in Flex is identical to that used by HTML, some of the style properties available in HTML are not available in Flex.

When you define CSS for Flex applications, you have two basic options: external stylesheets and local style definitions. In both cases, the CSS is compiled into the Flex application, so they are functionally identical. However, there are advantages to each. External stylesheets enable you to more cleanly distinguish between layout (MXML) and style definitions (external CSS document). On the other hand, local style definitions are more convenient when you intend to use the style or styles in just one MXML file. For most applications external stylesheets are preferable.

An external stylesheet is a text file that you compile into a Flex application by using the source attribute of a Style MXML tag. The following code is an example of a Style tag that compiles in an external stylesheet defined in styles.css. The styles defined in the external document are then available within the MXML document within which the Style tag appears.

<mx:Style source="styles.css" />

If you want to define local style selector definitions, you can simply place the CSS between opening and closing Style tags, as in the following example:

<mx:Style>
    .example {
        color: red;
    }
</mx:Style>

Whether you’re using external stylesheets or local style definitions, you can define the same sorts of style selectors: class selectors and type selectors. Class selector names are differentiated from type selector names because they use a dot (.), as in the preceding example. A selector can define one or more styles. The preceding example defines just one style for the selector. The following example defines two styles for the selector

.example {
    color: red;
    font-style: italic;
}

When you want to apply a class selector to a component, you must set the styleName property of the component. The styleName value should be the name of the class selector, but without the initial dot. The following example sets the styleName property of a button to the example style selector:

<mx:Button label="Example" styleName="example" />

If you want to set the styleName property of a component using ActionScript, you can do that using standard dot syntax, as follows:

button.styleName = "example";

The other kind of selector is called a type selector, and it automatically applies to all components of the type that match the name of the selector. For example, you can define a type selector called Button, and it will automatically get applied to all buttons:

Button {
    color: red;
}

Type selectors work with all component types, including custom components. That means you can define type selectors for standard Flex components such as Button, Application, TileList, and so forth, but you can also define type selectors for custom Flex components, whether those components are third-party components or components that you and your team have written.

You cannot combine type and class selectors by defining class selectors that are specific to a type as you would in HTML. Flex will not throw an error in this case, but it will simply ignore the type. The following example illustrates this:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style>
        Button.example {
            color: green;
        }
        Label.example {
            color: yellow;
        }
    </mx:Style>
    <mx:Button label="button" styleName="example" />
    <mx:Label text="label" styleName="example" />
</mx:Application>

In this example, you might expect that the button text would appear in green and the label text in yellow. However, both appear with yellow text. That is because Flex ignores the type selector portion of the selector names, and instead both selectors are defined simply as class selectors with the same name (.green) and the second overwriting the first. The result is that the text for both the button and the label is yellow.

With both type and class selectors you can use comma-delimited lists to define the same property values for several selectors. For example, the following sets the color for Button and TextInput components:

Button, TextInput {
    color: red;
}

You can also define properties for a selector in more than one property grouping. For example, the following defines the color as red for Button and TextInput, but then it also sets the themeColor for Button:

Button, TextInput {
    color: red;
}
Button {
    themeColor: black;
}

Type selectors always take precedence over class selectors. Example 8-2 defines a type selector and a class selector. In this case, the font style is italic because the type selector sets it. However, because the class selector defines the color as green, the button label is green rather than red.

Example 8-2. Selector precedence

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style>
        Button {
            color: red;
            font-style: italic;
        }
        .example {
            color: green;
        }
    </mx:Style>
    <mx:Button label="Example" styleName="example" />
</mx:Application>

Neither local style definitions nor external stylesheets take precedence inherently. If you use both in one document, you will see that the order in which they appear in the document is what determines which takes precedence. Let’s look at a complete example that illustrates this. Here’s styles.css, an external stylesheet document. It contains just one style definition, a class selector called example:

.example {
    color: red;
    font-style: italic;
}

Example 8-3 is the MXML document that both uses this external stylesheet and has a local style definition for the same class selector. In this case, the button has a green and italicized label because the local style definition takes precedence over the external stylesheet, only because it appears after the external stylesheet included in the code.

Example 8-3. Order of style tags affects styles (part 1)

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style source="styles.css" />
    <mx:Style>
        .example {
            color: green;
        }
    </mx:Style>
    <mx:Button label="Example" styleName="example" />
</mx:Application>

Yet, if you reverse the order of the two Style tags, as in Example 8-4, you’ll see that the button label is now red. This is because when properties of the same name are defined for a selector multiple times, the last definition overrides previous definitions. In the case of this example, the latter definition is that which is imported into the document via the external .css file.

Example 8-4. Order of style tags affects styles (part 2)

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style>
        .example {
            color: green;
        }
    </mx:Style>
    <mx:Style source="styles.css" />
    <mx:Button label="Example" styleName="example" />
</mx:Application>

Style Properties

In Flex, all style property names must be capable of being treated as variables. For this reason, it’s necessary that all style property names follow the naming rules for variables, meaning they must consist of alphabetic and numeric characters. Notably, variable names cannot contain hyphens. However, traditional CSS style property names use hyphens (e.g., font-family), and for this reason, Flex supports both hyphenated and camel-case style property names in CSS. (Flex converts hyphenated style property names to the camel-case equivalent behind the scenes.) For example, if you want to set the font name, you can use the style property font-family or fontFamily when using CSS. However, you cannot use hyphenated style properties in ActionScript using setStyle() or with inline styles.

Using StyleManager

Behind the scenes, Flex converts all CSS to ActionScript instructions that are managed by a class called mx.managers.StyleManager. In most cases, it is not necessary to work directly with the StyleManager class. However, in the event that you want to have greater runtime control over styles applied as either class selectors or type selectors, you’ll need to work with StyleManager.

The StyleManager class allows you to access and configure existing selectors that were created via CSS, and it allows you to add new selectors programmatically. To access an existing selector use the static method called getStyleDeclaration(). The method requires a string parameter specifying the name of the selector. The name of the selector should include the initial dot for class selectors. The method returns an mx.styles.CSSStyleDeclaration object representing the selector:

var selector:CSSStyleDeclaration =
StyleManager.getStyleDeclaration(".exampleSelector");

Note

If you try to access a selector that does not exist, the Flex application will throw a runtime error.

You can use the setStyle() method for a CSSStyleDeclaration object to edit the styles for that object. The setStyle() method for CSSStyleDeclaration is identical to the method of the same name for UIComponent. You pass it the name of the style and the new value, as in the following example:

selector.setStyle("color", "red");

If you want to add a new selector at runtime that wasn’t defined at compile time, you can do so by constructing a new CSSStyleDeclaration object and then adding it to the StyleManager using the setStyleDeclaration() method. The setStyleDeclaration() method allows you to specify the name of the selector (specifying null will cause the StyleManager to use the name of the selector from the CSSStyleDeclaration object), the CSSStyleDeclaration object, and a Boolean value indicating whether to immediately update the styles for affected components:

var selector:CSSStyleDeclaration = new CSSStyleDeclaration(".newSelector");
StyleManager.setStyleDeclaration(null, selector, true);

Setting a style declaration is a computationally expensive operation. If you are going to set more than one style declaration at a time, it is best to set the third parameter of the setStyleDeclaration() method to false for all but the last method call:

StyleManager.setStyleDeclaration(".newSelector1", selector1, false);
StyleManager.setStyleDeclaration(".newSelector2", selector2, false);
StyleManager.setStyleDeclaration(".newSelector3", selector3, false);
StyleManager.setStyleDeclaration(".newSelector4", selector4, true);

You should be careful when using setStyleDeclaration() that you don’t mistakenly overwrite an existing selector. Most component types already have type selectors defined in the defaults.css document (found in the default theme used by Flex, as discussed in Themesˮ later in this chapter) that is compiled into Flex applications by default. That means that even if you didn’t define a Button type selector, your Flex application is probably using one that it compiled in from defaults.css. Therefore, if you replace the Button type selector with a call to setStyleDeclaration(), you will lose all the style settings that buttons have by default if you haven’t explicitly given values to those styles in your new selector. The better option in most cases is to get a reference to the existing CSSStyleDefinition object and edit the style values for that object using setStyle().

Global Styles

You can apply global styles using the global selector. You can set the global selector in external stylesheets, in local style definitions, or by using StyleManager. Global styles always have the lowest precedence. That means that a global style will be applied only if it’s not overridden by a higher-priority setting such as a type selector, a class selector, or an instance style. Example 8-5 uses a global selector along with a class selector. In this example, the first button is green and italic, and the second button uses just the global style settings.

Example 8-5. Using a global selector with a class selector

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
    <mx:Style>
        global {
            color: red;
            font-style: italic;
        }
        .example {
            color: green
        }
    </mx:Style>
    <mx:Button label="Example 1" styleName="example" />
    <mx:Button label="Example 2" />
</mx:Application>

Reviewing Style Precedence

Style precedence can be a little confusing at first because there are simply so many ways to set styles. For that reason, we’ll now summarize the precedence. From highest precedence to lowest, here’s the list:

  • Instance style set with setStyle()

  • Inline style

  • Class selector set with StyleManager

  • Class selector set in the stylesheet

  • Type selector set with StyleManager

  • Type selector set in the stylesheet

  • Global styles

Working with Fonts

When you want to customize the font used by components within your Flex application, you’ll need to know the specifics of how to work with font outlines. The first important thing to understand in regard to this topic is how Flex differentiates types of fonts. In terms of how Flex deals with fonts, there are three types of fonts:

System fonts

These are the fonts that are installed on the user’s system. Just as an HTML page can display text using a font installed on the user’s system, so too can Flex applications.

Device fonts

There are three device fonts: _sans, _serif, and _typewriter, which resolve to the most similar system font on the user’s computer.

Embedded fonts

Flex applications allow you to embed font outlines within the .swf file, so you can guarantee that all users will see the same font even if they don’t have it installed on their system.

System fonts

When you use system fonts, you add no additional file size to the Flex application by embedding fonts. You can specify system fonts simply by specifying the name of the system font to use for the fontFamily (or font-family) style, as in the following example:

font-family: Verdana;

The problem with system fonts is that the user must have the font. Otherwise, the text will render using the default system font. For this reason, it’s usually a good idea to specify system fonts as a fallback list. You can specify the value for font-family as a comma-delimited list of font names. The Flex application will try to use the first font on the list, and if it cannot find that system font, it will use the next font on the list.

font-family: Verdana, Arial, Helvetica;

Device fonts

Device fonts are not specific fonts, but rather names of font categories. Flex recognizes three device fonts: _sans, _serif, and _typewriter. These device fonts resolve to a system font that is in a general font category. For example, _sans usually resolves to Arial or Helvetica, _serif usually resolves to Times New Roman, and _typewriter usually resolves to Courier or Courier New. Using device fonts is a way to virtually guarantee that the text will appear in a general style (i.e., sans-serif, serif, or monotype). When you use a device font name in CSS, you must enclose the value in quotation marks:

font-family: "_sans";

Note

Often when you use system fonts it is advisable to add a device font as the last font in the fallback list, as in the following example:

font-family: Verdana, Arial, Helvetica, "_sans";

Embedded fonts

Although there are use cases for system fonts and device fonts, the fonts most frequently used in Flex applications are embedded fonts. Embedded fonts compile the font outlines into the .swf, guaranteeing that all users will see the text in the same font. The potential downside of embedded fonts is that they increase the size of the .swf file. However, considering that Flex applications are rich Internet applications, the actual file size increase for an embedded font is usually insubstantial. The exception to that would be the use of extended characters and multibyte fonts, for use with languages such as Japanese and Chinese. Yet even in some of those cases, the file size increase can sometimes be mitigated by embedding only the outlines for the fonts required by the application.

There are other reasons to embed fonts besides wanting to guarantee consistent fonts for all users. Embedded fonts solve a few problems with system fonts. System fonts in Flex applications cannot be rotated, nor can you adjust the alpha of system fonts. If you attempt to rotate system fonts, the text disappears. If you attempt to adjust the alpha of a system font, you will not see an effect. However, if you embed the font, you can both rotate the text and adjust the alpha. Furthermore, system fonts are not anti-aliased. When you increase the size of system fonts the aliasing is more apparent, and it will look like the text has jagged edges. Embedded fonts are anti-aliased, meaning they look better at larger sizes. (Note that this is a double-edged sword because anti-aliased text is less legible at smaller font sizes. We’ll look at the solution to this in “Using FlashType” later in this chapter.)

There are a handful of ways to embed fonts. First we’ll look at how to embed fonts when you have the font file (a .ttf file). You can embed these fonts using the Embed metadata tag within ActionScript. To embed the font this way use the source attribute to specify the path to the .ttf file and the fontName attribute to specify the name of the font as you will want to reference it throughout your application. For the metadata tag to work, you must place it just before a variable declaration of type Class. You will not need to use the variable at all, but the compiler requires this.

Here’s an example that embeds a font called Century Gothic from the .ttf file using the fontName of gothicCentury:

[Embed(source="GOTHIC.ttf", fontName="gothicCentury")]
private var _centuryGothic:Class;

Once you’ve embedded the font, you can use the fontName value to reference it just as you would any other font, as shown in Example 8-6.

Example 8-6. Embedding a font using the Embed metadata tag

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style>
        global {
            fontFamily: gothicCentury;
        }
    </mx:Style>
    <mx:Script>
        <![CDATA[

            [Embed(source="GOTHIC.ttf", fontName="gothicCentury")]
            private var _centuryGothic:Class;

        ]]>
    </mx:Script>
    <mx:TextArea text="Example Text" />
</mx:Application>

When you embed a font, only one set of the font outlines is embedded. In Example 8-6, only the standard font outlines are embedded, not the bold or italic outlines. In Example 8-7, you can clearly see the effects of this when you try to add a button instance to the preceding example.

Example 8-7. Missing font outlines cause default fonts to appear

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style>
        global {
            fontFamily: gothicCentury;
        }
    </mx:Style>
    <mx:Script>
        <![CDATA[

            [Embed(source="GOTHIC.ttf", fontName="gothicCentury")]
            private var _centuryGothic:Class;

        ]]>
    </mx:Script>
    <mx:TextArea text="Example Text" />
    <mx:Button label="Example" />
</mx:Application>

Because buttons default to using the bold version of a font, Example 8-7 will use the Century Gothic font for the text area, but it will use the default system font for the button label. To fix this, we must also embed the bold font outlines for the same font using the same fontName value. However, this time we need to set the fontWeight attribute to bold; see Example 8-8. (If you want to embed the italicized font outlines, you should set fontStyle to italic.)

Example 8-8. Embedding standard and bold font outlines

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style>
        global {
            fontFamily: gothicCentury;
        }
    </mx:Style>
    <mx:Script>
        <![CDATA[

            [Embed(source="GOTHIC.ttf", fontName="gothicCentury")]
            private var _centuryGothic:Class;

            [Embed(source="GOTHICB.ttf", fontName="gothicCentury",
fontWeight="bold")]
            private var _centuryGothicBold:Class;

        ]]>
    </mx:Script>
    <mx:TextArea text="Example Text" />
    <mx:Button label="Example" />
</mx:Application>

You can also embed fonts from CSS using the @font-face directive. This is particularly useful when you use external stylesheets because then you can compile them to use as themes or as runtime CSS. However, it’s also equally okay to use this technique for local style definitions simply because you prefer the syntax to the Embed metadata tag. In the following examples, we’ll use local style definitions for the sake of simplicity and clarity.

The @font-face directive allows for all the same attributes/properties as the Embed metadata tag when embedding fonts. The exceptions are that the source attribute of the metadata tag is called src in the @font-face directive and fontName from the metadata tag is called fontFamily in the directive. Furthermore, the value of the src attribute should be wrapped in url(), as shown in the following example:

@font-face {
    src: url("GOTHIC.ttf");
    fontFamily: gothicCentury;
}

Example 8-9 is the earlier MXML example rewritten with @font-face directives.

Example 8-9. Using the @font-face directive

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style>
        @font-face {
            src: url("GOTHIC.ttf");
            fontFamily: gothicCentury;
        }
        @font-face {
            src: url("GOTHICB.ttf");
            fontFamily: gothicCentury;
            fontWeight: bold;
        }
        global {
            fontFamily: gothicCentury;
        }
    </mx:Style>
    <mx:TextArea text="Example Text" />
    <mx:Button label="Example" />
</mx:Application>

Flex allows you to embed a font in a different manner as well. Rather than embedding the font by way of the .ttf file, you can use the font name as it’s recognized by the computer system. When you want to do this, you can use the Embed metadata tag. Rather than using the source attribute, you should use the systemFont and specify the name of the font as it’s known by the system. Additionally, when you specify a system font name, you must also specify the MIME type by using the mimeType attribute. The value should be either application/x-font or application/x-font-truetype. Example 8-10 uses system font names to embed fonts.

Example 8-10. Embedding fonts by system name

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style>
        global {
            fontFamily: gothicCentury;
        }
    </mx:Style>
    <mx:Script>
        <![CDATA[

            [Embed(systemFont="Century Gothic", fontName="gothicCentury",
mimeType="application/x-font")]
            private var _centuryGothic:Class;

            [Embed(systemFont="Century Gothic", fontName="gothicCentury",
fontWeight="bold", mimeType="application/x-font")]
            private var _centuryGothicBold:Class;

        ]]>
    </mx:Script>
    <mx:TextArea text="Example Text" />
    <mx:Button label="Example" />
</mx:Application>

You can also embed fonts by name using CSS. To do so, you should wrap the src value using local() rather than url(). The following example illustrates how this works:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style>
        @font-face {
            src: local("Century Gothic");
            fontFamily: gothicCentury;
        }
        @font-face {
            src: local("Century Gothic");
            fontFamily: gothicCentury;
            fontWeight: bold;
        }
        global {
            fontFamily: gothicCentury;
        }
    </mx:Style>
    <mx:TextArea text="Example Text" />
    <mx:Button label="Example" />
</mx:Application>

Embedding font subsets

When you embed a font, by default all the outlines are embedded, regardless of what characters are used in the application. In some cases your application may not use all the font outlines, and in those cases it's unnecessary and wasteful to embed all the font outlines. For that reason, Flex lets you specify ranges of characters to embed using the unicodeRange attribute for @font-face or the Embed metadata tag. The unicodeRange attribute lets you specify one or more Unicode values or ranges of Unicode values. The Unicode values must be in the form U+code, such as U+00A1. You can specify ranges by placing a hyphen between two values, as in U+00A1-U+00FF. Specify more than one value or range by delimiting them with commas, as in Example 8-11.

Example 8-11. Embedding font subset ranges

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style>
        @font-face {
            src: url("GOTHIC.ttf");
            fontFamily: gothicCentury;
            unicodeRange: U+0041-U+007F;
        }
        @font-face {
            src: url("GOTHICB.ttf");
            fontFamily: gothicCentury;
            fontWeight: bold;
            unicodeRange: U+0041-U+007F;
        }
        global {
            fontFamily: gothicCentury;
        }
    </mx:Style>
    <mx:TextArea text="++ Example Text ++" />
    <mx:Button label="Example" />
</mx:Application>

Example 8-11 embeds the range of standard Latin alphabet characters, but not the + character. That means the alphabetic characters in the components show up, but the + characters do not. Example 8-12 embeds the + character as well.

Example 8-12. Embedding lists of font subsets

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style>
        @font-face {
            src: url("GOTHIC.ttf");
            fontFamily: gothicCentury;
            unicodeRange: U+0041-U+007F,U+002B;
        }
        @font-face {
            src: url("GOTHICB.ttf");
            fontFamily: gothicCentury;
            fontWeight: bold;
            unicodeRange: U+0041-U+007F,U+002B;
        }
        global {
            fontFamily: gothicCentury;
        }
    </mx:Style>
    <mx:TextArea text="++ Example Text ++" />
    <mx:Button label="Example" />
</mx:Application>

You can also use named ranges that you define in the compiler configuration file you specify using the -load-config attribute. If you want to add named ranges to the compiler configuration file, you must add the values in the following format:

<flex-config>
    <compiler>
        <fonts>
            <languages>
                <language-range>
                    <lang>Alpha And Plus</lang>
                    <range>U+0041-U+007F,U+002B</range>
                </language-range>
            </languages>
        </fonts>
    </compiler>
</flex-config>

Note

If you want to add more than one named range, you can simply add more language-range tags nested within the languages tag.

You can then specify the named range as the value for the unicodeRange attribute. The name must appear in quotes, as in Example 8-13.

Example 8-13. Embedding fonts by named ranges

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style>
        @font-face {
            src: url("GOTHIC.ttf");
            fontFamily: gothicCentury;
            unicodeRange: "Alpha And Plus";
        }
        @font-face {
            src: url("GOTHICB.ttf");
            fontFamily: gothicCentury;
            fontWeight: bold;
            unicodeRange: "Alpha And Plus";
        }
        global {
            fontFamily: gothicCentury;
        }
    </mx:Style>
    <mx:TextArea text="++ Example Text ++" />
    <mx:Button label="Example" />
</mx:Application>

To simplify things you can use predefined ranges. The predefined ranges are in the flash-unicode-table.xml document in the frameworks subdirectory of the SDK directory. If you want to use these predefined ranges, you can copy and paste the language-range tags from the flash-unicode-table.xml document to your configuration file.

Using advanced anti-aliasing

In Flex 3 it is possible to leverage greater control over embedded fonts using something called advanced anti-aliasing. Advanced anti-aliasing allows you to control text appearance with additional styles:

fontSharpness

A value from −400 to 400 (the default value is 0) specifying how crisp the edges of the font appear. The higher the value is, the crisper the edges. Lowering the value for smaller fonts usually makes the fonts more legible.

fontThickness

A value from −200 to 200 (the default value is 0) specifying how thick the edges of the font should be.

Note

Advanced anti-aliasing also allows you to use the fontAntiAliasType and fontGridFitType styles, which are beyond the scope of this book. You can consult the Flex documentation for more details on these styles.

Example 8-14 uses two sliders that allow you to adjust the sharpness and thickness of the font in order to see the effects.

Example 8-14. Adjusting FlashType properties

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Style>
        global {
            fontFamily: gothicCentury;
            fontSize: 50;
        }
    </mx:Style>
    <mx:Script>
        <![CDATA[

            [Embed(systemFont="Century Gothic", fontName="gothicCentury",
mimeType="application/x-font")]
            private var _centuryGothic:Class;

            [Embed(systemFont="Century Gothic", fontName="gothicCentury",
fontWeight="bold", mimeType="application/x-font")]
            private var _centuryGothicBold:Class;

            private function sharpnessChangeHandler(event:Event):void {
                StyleManager.getStyleDeclaration("global").setStyle("fontSharpness",
sharpnessSlider.value);
            }

            private function thicknessChangeHandler(event:Event):void {
                StyleManager.getStyleDeclaration("global").setStyle("fontThickness",
thicknessSlider.value);
            }


        ]]>
    </mx:Script>
    <mx:Button label="Example" />
    <mx:HSlider id="sharpnessSlider" value="0" minimum="−400" maximum="400"
liveDragging="true" change="sharpnessChangeHandler(event)" />
    <mx:HSlider id="thicknessSlider" value="0" minimum="−200" maximum="200"
liveDragging="true" change="thicknessChangeHandler(event)" />
</mx:Application>

Advanced anti-aliasing is enabled for embedded fonts by default. Although there is no difference in runtime performance between advanced and nonadvanced anti-aliased fonts, there are compile-time performance hits when using advanced anti-aliasing. If you don’t intend to use any of the styles enabled by advanced anti-aliasing and you are embedding a lot of fonts and notice compiler slowness, you can disable advanced anti-aliasing for the fonts using the advancedAntiAliasing attribute in the @font-face directive or Embed metadata tag:

@font-face {
    src: url("GOTHIC.ttf");
    fontFamily: gothicCentury;
    advancedAntiAliasing: false;
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset