Cannot get Flash Runtime Shared Library to work

2k Views Asked by At

I am using Flash CS5 (assets) and FlashDevelop (code) for my project. We have about 20 fla/swf's that contain textfields. All of our textfields use the same Font, and the font is specific to our company so won't be installed on anyones computers, hence it needs to be embedded.

My ultimate goal is to have one single font embedded that all of the textfields use, for 2 main reasons:

  • Whenever we add more characters to the font (other languages), we only need to add them once and not 20 times
  • The file size doesn't blow out dramatically

I'm having great difficulty in trying to achieve this. It seems that everything I try, characters are missing (only characters entered in the text property of the textfields in each fla seem to be embedded).

The latest solution I am trying is using Runtime Shared Libraries, as this seems like it should work. I have an fla called FNFont.fla. It contains just one object in the library, the embedded font. The font is exported to AS3, exported in frame 1 and exported for runtime sharing. The URL is FNFont.swf (all swf's are in the same folder).

In all the other fla's, I create the font object in font embedding. I tick Import for Runtime Sharing and give it the same class name as the one in FNFont.fla. The URL is FNFont.swf. The fla(s) contain many textfields using this font. The textfields have instances of themselves as children of other movieclips.

When I run the program and attempt to load a movieclip that contains an instance of one of these textfields, I get the error:

[Fault] exception, information=ReferenceError: Error #1065: Variable FontName is not defined.

FontName is the class name of the Font object in FNFont.fla and all other fla's. It is not the instance name of the textfield (nor the class name), so I don't understand how it thinks its a variable. Anyone able to shed some light on this?

Thanks

3

There are 3 best solutions below

1
On

You might want to search for "runtime font loading", such as:

http://www.mokisystems.com/blog/flash-as3-loading-fonts/

or...

http://nochump.com/blog/archives/20

Create a font asset SWF:

package {

    import flash.display.Sprite;

    public class FontLibrary extends Sprite {

        [Embed(systemFont='Bank Gothic', fontName='emBank Gothic', mimeType='application/x-font')]
        public static var BankGothicFont:Class;

    }

}

Load and register the SWF from your apps:

var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
loader.load(new URLRequest("fontlibrary.swf"));

private function completeHandler(event:Event):void {
    var FontLibrary:Class = event.target.applicationDomain.getDefinition("FontLibrary") as Class;
    Font.registerFont(FontLibrary.BankGothicFont);
    var tf:TextField = new TextField();
    tf.defaultTextFormat = new TextFormat("emBank Gothic", 12, 0);
    tf.embedFonts = true;
    tf.rotation = 15; // to demonstrate the embed worked
    tf.text = "blah blah blahnblah blah blahnblah blah blah ";
    addChild(tf);
}
0
On

In my experience you need to create new TextFields on the fly.

You cannot use TextFields that have already been compiled in the SWF, otherwise you get the problem you described above.

It's one of those little-big bugs that makes it hard to love Adobe.

0
On

I ran into a similar problem a while ago and it turned out it was an issue with setting the proper ApplicationDomain in the loader.

I'm not sure if you have a similar situation, but here's mine.

  • CS5.5
  • I have a fonts.swf with several fonts in the library. They're each set to Export for Runtime Sharing and they're given a class name.
  • There's a main swf into which several child swfs get loaded.
  • Each child swf has font objects with no embedding. The font objects are set to "Import for Runtime Sharing" and are givent he same class names as the fonts.swf.

In my case, the first child swf would load the fonts.swf correctly and access the fonts. The second child swf that tried to access the fonts would not reload the fonts.swf and I'd get the same error you describe above.

It seems to me that Flash is trying to be smart about not reloading the fonts since it's assuming they are already registered for the whole application. However, since each child.swf is loaded into the parent with the default ApplicationDomain the children have access to the class path of the parent, but not each other. Therefore, the first child has access to the fonts in fonts.swf, but the second child does not because they're in a sibling, not the parent.

I believe there are two ways around this:

  1. Load the fonts.swf into the parent swf before any of the children try to access it.
  2. Set the ApplicationDomain to ApplicationDomain.currentDomain so the child swfs share the same ApplicationDomain as the main parent swf.

I chose option 2, which fixed the problem for me.

var context : LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;                
var clipLoader:Loader = new Loader();
clipLoader.load(url, context);