4

Edited Short Version:

The Adobe Flash docs list a property embedFonts on TextAreas:

A Boolean value that indicates whether the font specified in fontFamily is an embedded font. This style must be set to true if fontFamily refers to an embedded font. Otherwise, the embedded font is not used. If this style is set to true and fontFamily does not refer to an embedded font, no text is displayed. The default value is false.

Regarding the "If this style is set to true and fontFamily does not refer to an embedded font, no text is displayed" statement: How can I detect in ActionScript when this scenario happens?

TL;DR Original Version:

I have a flash application which loads external .swf files containing embedded fonts, so that these fonts can be used within the main application. We're accomplishing this by using the following ActionScript code on anything which uses custom fonts:

textBoxName.embedFonts = true;

However, sometimes the requested font is not available in the external .swf file which is loaded -- this often happens when someone makes changes to the external .swf and doesn't include all the fonts which were previously in there...

The reason is not important, what's important is that it's unavoidable and will happen. When it does, any text in a font that's not available does not display at all. For example:

  1. Main application is set up to use "Myriad". It's loading an external swf file which does contain Myriad along with a handful of other fonts
  2. Some time later, the external swf is updates to contain a new set of fonts, and Myriad is no longer one of them. But the main application is not updated.
  3. Now, all text in the main application that was in "Myriad" no longer displays at all.

Is there any way to either default the text to a font that is available, or, detect that the font is not available and run some ActionScript code?

EDIT: In case it matters, here's the code I'm using to load the fonts from the external swf files:

// Font Loader:
var loadedFonts = Array();
var fontPakLoadHandler = new Object();

fontPakLoadHandler.percent = 0;

fontPakLoadHandler.onLoadStart = function(target_mc:MovieClip)
{
    if(!SuspendEvents)
        ExternalInterface.call("fontLoadStart", _root.lcId);
}

fontPakLoadHandler.onLoadInit = function(target_mc:MovieClip)
{
    if(!SuspendEvents)
        ExternalInterface.call("fontLoadInit", _root.lcId);
}

fontPakLoadHandler.onLoadError = function(target_mc:MovieClip, errorCode:String, httpStatus:Number)
{
    if(!SuspendEvents)
        ExternalInterface.call("fontLoadError", _root.lcId, errorCode, httpStatus);
}

if(_root.fontPakProgress=='all')
{
    fontPakLoadHandler.onLoadProgress = function(target_mc:MovieClip, loadedBytes:Number, totalBytes:Number)
    {
        fontPakLoadHandler.percent = loadedBytes / totalBytes;
        if(!SuspendEvents)
            ExternalInterface.call("fontLoadProgress", _root.lcId, loadedBytes, totalBytes, fontPakLoadHandler.percent);
    }
}
else
{
    fontPakLoadHandler.onLoadProgress = function(target_mc:MovieClip, loadedBytes:Number, totalBytes:Number)
    {
        var perc = loadedBytes / totalBytes;

        if( (fontPakLoadHandler.percent < .75 && perc >= .75) ||
            (fontPakLoadHandler.percent < .50 && perc >= .50) ||
            (fontPakLoadHandler.percent < .25 && perc >= .25))
        {
            if(!SuspendEvents)
                ExternalInterface.call("fontLoadProgress", _root.lcId, loadedBytes, totalBytes, perc);
        }

        fontPakLoadHandler.percent = perc;
    }
}

fontPakLoadHandler.onLoadComplete = function(target_mc:MovieClip, httpStatus:Number)
{
    if(!SuspendEvents)
        ExternalInterface.call("flashReady", _root.lcId, true);
    //ExternalInterface.call("fontLoadComplete", _root.lcId, httpStatus);
}

var fontPakLoader = new MovieClipLoader();
fontPakLoader.addListener(fontPakLoadHandler);
Josh
  • 10,961
  • 11
  • 65
  • 108

1 Answers1

2

Unfortunately, there is no way to list all available embedded fonts in ActionScript 2, as there is with Font.enumerateFonts() in ActionScript 3. You can only get a list of the fonts that are installed on a user's computer via TextField.getFontList().

You could, however, manually supply a list of available font names (perhaps in xml) and load it into the main SWF. Then you could compare font names to this list every time you use an embedded font, and substitute a default font or even use a substitution map, if the desired one is not available.

It's not quite as elegant as automatically getting a complete list from the content, but it should do the trick without having to recompile your main app.

weltraumpirat
  • 22,544
  • 5
  • 40
  • 54
  • Oops, sorry, I just saw you're in AS2. Just forget I said anything, I'll try to come back with an answer that helps ;) – weltraumpirat Dec 22 '10 at 17:51
  • Okay, I changed the answer accordingly. – weltraumpirat Dec 22 '10 at 18:23
  • Thanks. The problem is, sometimes the text for TextFields is set via the `html` property... so, do I need to use an HTML parser to extract what fonts are being used? I guess I was hoping for an easier way... but one may just not exist :-) – Josh Dec 22 '10 at 18:29
  • If you can't influence how the text is structured, then I'm afraid not. You could try to have all font information come from stylesheets and parse the css instead. That should be far less complicated. – weltraumpirat Dec 22 '10 at 18:33
  • Or, if you knew which set of fonts would possibly be used by the loaded SWFs, you could write a list for those, as well, and look for each font with string.indexOf (fontName). – weltraumpirat Dec 22 '10 at 18:35
  • Thanks @weltraumpirat. I just changed my question and created the short version... any ideas on that..? – Josh Dec 22 '10 at 19:11
  • See definition: getTextRuns(beingIndex:int = 0, endIndex:int = int.MAX_VALUE):Array; getTextRuns returns an Array of flash.text.TextRun objects. A TextRun represents a continuous segment of text which has a SINGLE TEXT FORMAT. In other words, this function parses text in a TextField by its formating. All you have to do is iterate through the Array that is returned to see which fonts are being used. Each TextRun instance includes a beginIndex:int, endIndex:int, and textFormat:TextFormat object, so you can check the font there and update the fonts with setTextFormat using the begin/end indexes. – Triynko Sep 26 '13 at 22:54