PDA

View Full Version : [AS3] Embedding multiple members of a font-family



Ego
April 18th, 2007, 06:15 PM
I've been compiling Actionscript 3 in Flex Builder a while now. Love the platform but I've run into a problem that doesn't seem to be documented enough and I really can't find a solution.

In Flex/AS3 font embedding has been totally revamped. You have to use the Embed tag. Simple embedding of a single font isn't a problem but when I try to embed multiple members of a font family, I get into trouble.

I want to embed Helvetica and Helvetica Bold in one of my projects. Embedding Helvetica isn't a problem but I can't get the bold to work.

If I just embed the bold font I get this error:

exception during transcoding: Font for alias 'Helvetica LT Std' with plain weight and style was not found at: file:/c:/GFX/fonts/HelveticaLTStd-Bold.ttf

Now I got it working in one project this way:

[Embed(source='fonts/HelveticaLTStd-Bold.ttf', source='fonts/HelveticaLTStd-Roman.ttf', fontFamily="Helvetica LT Std", mimeType="application/x-font-truetype")]
private static var FONT_HELVETICA:String;

But when I copied the exact code to another project and moved the fonts folders with it and recompiled. It didn't work! When I recompiled the project where it worked it still worked. But ever since that one project I haven't been able to get it working. I've got the feeling Flex is extremely buggy in this aspect.

So, how do I embed multiple parts of a font-family in Actionscript 3, compiled with Flex?

PS: Sorry for my sloppy English.

Ego
April 20th, 2007, 08:44 AM
* Bump * :*(

DKreeK
September 29th, 2007, 07:29 AM
I have the same problem. Somebody have a solution ?

Egon
April 24th, 2008, 10:12 AM
Right, better late than never..... add a fontWeight description to the embed tags
e.g.


// Normal
[Embed(source = "../../../../flash_assets/Vectora LT Std/VectoraLTStd-Roman.otf", fontWeight= "normal", fontFamily = "Vectora")]
private static var Vectora:Class;

// Bold
[Embed(source = "../../../../flash_assets/Vectora LT Std/VectoraLTStd-Bold.otf", fontWeight= "bold", fontFamily = "Vectora")]
private static var VectoraBold:Class;

justsomeguy
July 4th, 2008, 02:36 AM
I've been googling for half a day and pulling a lot of hair out until I found this post.
I thought I'd summarize this great bit of wisdom with some key words for anyone else searching out there.
Specifically, in my case I had issues with using multiple fonts with CSS in an HTML textfield.

The Setup

You're using AS3/CS3/Flex/mxmlc. You've got some texfields with HTML code and a little CSS for good clean markup. You'd like to embed some fonts to make sure things appear consistently on any platform.

The Problem

After learning about the "Embed" meta tag you've managed to embed a font and display it. But variations of fonts (bold, italic) come in different files and you can't get them to work at the same time in a single text field.

After some thinking you decided to embed several fonts under the same family name, like so:


[Embed(source="../fonts/Verdana.ttf", fontWeight="normal", fontName="VerdanaRegular", fontFamily="Verdana", mimeType="application/x-font-truetype")]
public static const VerdanaRegularTTF:String;

[Embed(source="../fonts/Verdana_Bold.ttf", fontWeight="bold", fontName="VerdanaBold", fontFamily="Verdana", mimeType="application/x-font-truetype")]
public static const VerdanaBoldTTF:String;
Then you try to pass the fontFamily to CSS:



...
var defaultStyle:Object = new Object();
defaultStyle.fontFamily="Verdana";
But this doesn't work. CSS doesn't recognize the fontFamily from the Embed tag; it only recognizes the fontName tag.

You also try to set a text format for your textfield (thinking of passing the fontFamily name with format.font="Verdana"). But it seems that 'format' isn't allowed with CSS.

The Solution

Use a single fontName for the fonts when embedding them. Pass this single fontName to CSS (you don't need to include a fontFamily field). Also make sure to include the proper fontStyle/fontWeight fields when embedding italic/bold fonts. Finally, remember to set the "embedFonts" property to 'true' for your textfield.

Here are the important snippets. Embedding:



[Embed(source="../fonts/Verdana.ttf", fontName="Verdana", mimeType="application/x-font-truetype")]
public static const VerdanaTTF:String;

[Embed(source="../fonts/Verdana_Bold.ttf", fontWeight="bold", fontName="Verdana", mimeType="application/x-font-truetype")]
public static const VerdanaBoldTTF:String;

[Embed(source="../fonts/Verdana_Italic.ttf", fontStyle="italic", fontName="Verdana", mimeType="application/x-font-truetype")]
public static const VerdanaItalicTTF:String;

[Embed(source="../fonts/Verdana_Bold_Italic.ttf", fontWeight="bold", fontStyle="italic", fontName="Verdana", mimeType="application/x-font-truetype")]
public static const VerdanaBoldItalicTTF:String;
Using CSS with the textfield:



var defaultStyle:Object = new Object();
defaultStyle.fontFamily = "Verdana";

var style:StyleSheet = new StyleSheet();
style.setStyle(".defaultStyle", defaultStyle);

var t:TextField = new TextField();
t.embedFonts = true;
t.styleSheet = style;
t.htmlText = "<span class='defaultStyle'>My <b>bold</b> text</span>";
And you're done.

daidai
July 4th, 2008, 05:44 AM
how/why is using

[Embed(source="../fonts/Verdana_Bold_Italic.ttf", fontWeight="bold", fontStyle="italic", fontName="Verdana", mimeType="application/x-font-truetype")]
public static const VerdanaBoldItalicTTF:String;

better than adding the font to the FLA library and assigning the Font's link, then declaring it in the code like in this example

myFormat.font = myFont.fontName; (myFont being the embedded font, taken from http://www.adobe.com/devnet/flash/quickstart/embedding_fonts/#section1)

justsomeguy
July 4th, 2008, 05:09 PM
I use the [Embed] tag because I'm using Flex2 SDK + mxmlc, not the Flash IDE -- just pure plain text actionscript files (the compiler is free by the way and runs on Linux). Adding the font to the library should be equivalent, but I have no experience with it myself. Also, I can't use myFormat.font for textfields with CSS styles attached because the compiler gives errors. So I use style.fontFamily="Verdana" instead. So what you're doing seems fine in your case, but won't work for other situations.

daidai
July 4th, 2008, 08:47 PM
I use the [Embed] tag because I'm using Flex2 SDK + mxmlc, not the Flash IDE -- just pure plain text actionscript files (the compiler is free by the way and runs on Linux). Adding the font to the library should be equivalent, but I have no experience with it myself. Also, I can't use myFormat.font for textfields with CSS styles attached because the compiler gives errors. So I use style.fontFamily="Verdana" instead. So what you're doing seems fine in your case, but won't work for other situations.
ok, thanks

latcho
November 25th, 2008, 03:32 PM
justsomeguy: thanks for this valuable info !
Latcho

bmo
November 25th, 2008, 05:15 PM
Anybody care to shed some light on this for a Mac Post Script Type 1 font?

Like a good little programmer, even though I compile with the Flash IDE (we have design work to consider as well!) I do my programming in class files. Getting PS font to embed with the embed tag just doesn't work. How do I get it to work in these cases? It seems this question has been asked many times on the internet, but never answered...

There is an ugly hack to make it work - create a textfield and embed the font and characters you could use, make it a movieclip and name the dynamic textfield within... then instantiate with the constructor / symbol class... I would prefer to avoid work arounds if somebody knows a legitimate way of doing this, as Adobe (hopefully) intended.

Brian

gdog
November 30th, 2008, 04:17 AM
Yes you can do this http://www.allflashwebsite.com/article/embedding-fonts-in-flash-cs3-the-good-way

See the section at the bottom of the article. If FontForge supports the filetype then you should be able to convert to TTF and embed the font that way.


Anybody care to shed some light on this for a Mac Post Script Type 1 font?

Like a good little programmer, even though I compile with the Flash IDE (we have design work to consider as well!) I do my programming in class files. Getting PS font to embed with the embed tag just doesn't work. How do I get it to work in these cases? It seems this question has been asked many times on the internet, but never answered...

There is an ugly hack to make it work - create a textfield and embed the font and characters you could use, make it a movieclip and name the dynamic textfield within... then instantiate with the constructor / symbol class... I would prefer to avoid work arounds if somebody knows a legitimate way of doing this, as Adobe (hopefully) intended.

Brian

danee987
August 4th, 2009, 02:13 PM
I was reading this thread and this is exactly what I need to do except I am loading my fonts at runtime which means I have to register my font with flash. If I need say Arial to have regular and bold embedded how is it that I register the font with flash since the bold and regular version both are embedded separately?

johnkakoulides
August 31st, 2009, 11:28 PM
I was reading this thread and this is exactly what I need to do except I am loading my fonts at runtime which means I have to register my font with flash. If I need say Arial to have regular and bold embedded how is it that I register the font with flash since the bold and regular version both are embedded separately?

Like this:

[Embed(systemFont="Helvetica", fontName="helvetica", mimeType="application/x-font", unicodeRange="U+0020-U+007D")]
private var Helvetica:Class;

[Embed(systemFont="Helvetica", fontName="helvetica", fontWeight="bold", mimeType="application/x-font", unicodeRange="U+0020-U+007D")]
private var HelveticaBold:Class;

Font.registerFont(Helvetica);
Font.registerFont(HelveticaBold);

theDestry
October 2nd, 2009, 08:02 PM
I've been working on a project that needs dynamically embedded fonts. I'm using flex to compile the font swfs, and loading them into an application I'm building with the flash IDE. The font class, for arial, looks something like this...

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package {
import flash.display.Sprite;
public class _Arial extends Sprite {
[Embed(source='_arial.ttf', fontFamily='_arial')]
public static var _arial:Class;

[Embed(source='_arial_bold.ttf', fontFamily='_arial', fontWeight='bold')]
public static var _arial_bold:Class;

[Embed(source='_arial_italic.ttf', fontFamily='_arial', fontStyle='italic')]
public static var _arial_italic:Class;

[Embed(source='_arial_bold_italic.ttf', fontFamily='_arial', fontWeight='bold', fontStyle='italic')]
public static var _arial_bold_italic:Class;

public static var styles:Array = new Array( { label:"normal", fontName:"_arial", fontClass:"_arial" }, { label:"bold", fontName:"_arial", fontClass:"_arial_bold" }, { label:"italic", fontName:"_arial", fontClass:"_arial_italic" }, { label:"bold italic", fontName:"_arial", fontClass:"_arial_bold_italic" } );

public static var name:String = "Arial";
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Basically, after loading in the swf...

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static private function loadHandler(e:Event):void
{
var regex:RegExp = /fonts\/(.*?).swf/;
var className:String = regex.exec(e.target.url)[1];
var FontClass:Class = e.target.applicationDomain.getDefinition(className ) as Class;

PropertiesControl.input["text"].fontNameComboBox.addItem({label:FontClass.name});
__fontList.push(FontClass.name);
__fonts[FontClass.name] = FontClass.styles as Array;

for (var i:Number=0; i<FontClass.styles.length; i++) {
Font.registerFont(FontClass[FontClass.styles[i].fontClass]);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

The only reason I'm using RegExp to parse the url to derive the font name is because the font list is going to be assembled by php. I've only recently built this class, but so far it seems like a pretty reliable way to load fonts dynamically.

Does anyone know if there's a way to embed device fonts on the fly? You can get the list of available device fonts using "Font.getEnumerableFonts()" method, but the returned array is filled with Font objects, and "Font.registerFont(fontObj[i] as Class);" doesn't work (and may be unnecessary for all I know).

Thanks everyone for the awesome thread!