【问题标题】:embedding a font in a swf using as3使用 as3 在 swf 中嵌入字体
【发布时间】:2012-09-27 15:05:39
【问题描述】:

我有一个项目使用 flash(以及 AIR for android 和最终的 iOS)来翻译一些短语。虽然大多数字体都很好,但在用户选择语言后我必须加载一些字体。一年多以前,我生成了几个 swf 文件(孟加拉语和乌尔都语)并将它们放在我的 Web 服务器上。然后,Flash 应用程序会在需要时加载它们,一切正常...... 然而,当我接近实施该项目时,我认为我应该为管道中的其他语言生成 swf 文件,但由于某种原因我无法管理它!不用说,我已经放错了(整理)我所做的两种字体的原始 AS3 源代码。

package   
{  
    import flash.display.Sprite;  
    import flash.events.Event;  
    public class ArabicF extends Sprite   
    {       
        [Embed(source = "trado.ttf",
        fontName = "ArabicX",
        fontFamily = "ArabicY",
        fontWeight = "normal",
        fontStyle = "normal",
        mimeType = "application/x-font",
        advancedAntiAliasing="true",
        embedAsCFF="true")]  
        public static const ArabicZ:Class;  
    }   
}  

这已经从一个更简单的形式扩展,因为我添加了一些东西来让它工作,我必须尝试所有真假排列。我加载 swf 正常,但无法提取类。我在 swf 类和参数之前嵌入的两种字体都具有相同的名称并且它们工作正常(即 乌尔都语.swf 然后稍后: var FontClass:Class = evt.target.applicationDomain.getDefinition("Urdu") as Class; 然后 Font.registerFont(FontClass.Urdu);
在使用上述 Arabic.swf 调用 .as 应用程序中我尝试

trace("1 Arabic "+evt.target.applicationDomain.hasDefinition("ArabicF"));  
trace("2 Arabic "+evt.target.applicationDomain.hasDefinition("Arabic"));  
trace("3 ArabicX "+evt.target.applicationDomain.hasDefinition("ArabicX"));  
trace("4 ArabicY "+evt.target.applicationDomain.hasDefinition("ArabicY"));  
trace("5 ArabicZ "+evt.target.applicationDomain.hasDefinition("ArabicZ"));  

但都返回假

PS 还尝试使用 fontswf.bat 生成 Arabic.swf,这似乎再次生成了一个非常相似的 swf 文件,但我无法从中提取类

PPS 我使用的是 flashdevelop,字体 swf 设置为 AS3 标准项目编译器选项。

【问题讨论】:

  • 有几种方法可以调试此类问题。首先,您可以检查该类是否实际导出到 SWF 文件中(使用 link-report.xml 或 SWF Investigator (labs.adobe.com/technologies/swfinvestigator) 之类的工具。然后,您可以看到,一旦加载了字体库 SWF,@987654325 @ 给你。问题是,我不确定你嵌入字体的方式创建的类定义与你给的名字完全匹配。
  • 安托万。非常感谢指向 swfinvestigator 的指针,它似乎是 A1,毫无疑问会帮助我解决这个问题。目前,我发现我现在制作的 swf 和一年前制作的 swf 几乎没有任何区别。在我将目标从 flash 10 更改为 flash 9 后,它们非常接近。旧的包含额外的标签DefineFontName,并具有DefineFont3,而新的具有DefineFont4。它当然看起来包含类 ArabicF 和 ArabicF_ArabicZ,所以我认为即使字体有问题 getDefinition() 也会起作用!

标签: actionscript-3 fonts embed


【解决方案1】:

我不使用 Flash Develop,但也许我可以从我的实现中提供一些观点。


如果我想嵌入 Arial,嵌入的 swf 将“为 ActionScript 导出”嵌入的字体。在其文档类中,使用registerFont(),如下所示:

Font.registerFont(Arial);

与其他所有 swf 一样,您可以使用 Loader 将其导入运行时,此时该字体将可用于您的全局表。您可以使用enumerateFonts()查询已注册字体的完整列表。

var fontList:Array = Font.enumerateFonts();
for (var i:int = 0; i < fontList.length; i++) {
    trace(fontList[i].fontName);
}

假设我们有一个名为“txt”的 TextField,那么您可以使用 setTextFormat() 实现该字体,如下所示:

var format:TextFormat = new TextFormat();
format.font = "Arial";
txt.embedFonts = true;
txt.antiAliasType = AntiAliasType.ADVANCED;
txt.setTextFormat(format);
txt.defaultTextFormat = format;

Adobe 就使用这些last two settings 的免责声明:

"当您将 TextFormat 对象应用到文本字段时,使用 TextField.defaultTextFormat 属性或 TextField.setTextFormat() 方法,仅应用其定义的属性。使用 TextField.defaultTextFormat 属性在您之前应用格式 向 TextField 添加文本,并使用 setTextFormat() 方法添加 将文本添加到 TextField 之后进行格式化。”

正如我之前所说,我的工作流程不使用 Flash Develop,而是使用 Flash IDE 将字体嵌入到 swfs 中。您的结果可能会有所不同,但请注意您必须将 embedFonts 设置为 true,否则它不会响应您的嵌入字体。我以前在这个问题上掉过头发。

希望对您有所帮助。干杯,

【讨论】:

  • Atriace,也谢谢您。我可以很好地将字体加载到我的应用程序中。一年前我嵌入到 swf 文件中的字体,但不是我现在尝试嵌入的字体!我不记得必须这样做,但也许我必须在嵌入 AS3 中注册字体,甚至将 embedFonts 设置为 true。导入字体后,我必须注册字体,所以我觉得可以。我必须使用 TextBlock、TextElement 等来让一些从右到左的字体与 flash 一起正常工作(即不是 TextField),所以我认为 Adob​​e 的免责声明不适用。
【解决方案2】:

好的,如果其他人遇到类似的问题,这是答案的第一阶段(真的是我原来问题的答案)仍然需要弄清楚如何让字体在 flash.font.engine 设备中使用!

关键部分是:

第 1 点。嵌入字体 swf 的名称必须与调用脚本中注册的任何名称不冲突。离奇和(据我所知)无证。即我有一个通过 xml 服务上传到 xml 对象的语言列表,其中包括例如“英语”,但是字体加载在我将可加载字体文件变为“EnglishF.swf”之前不起作用。显而易见的选择只是“ English.swf' 失败。所以我嵌入的字体源现在被称为 EnglishF.swf 并显示为:

package 
{
import flash.display.Sprite;
import flash.text.Font;
import flash.system.Security;

Security.allowDomain("*");
/**
 * ...
 * @author patrick
 */
public class EnglishF extends Sprite 
{       
    [Embed(source = "Kingthings Exeter.ttf",
        fontName = "EnglishF",
        fontFamily = "EnglishF",
        fontWeight = "normal",
        fontStyle = "normal",
        mimeType = "application/x-font",
        advancedAntiAliasing="true",
        embedAsCFF="true")]
        public static var myFont:Class;
}   
}  

使用脚本如下:

private function fontLoaded(evt:Event):void { 
        var FontClass:Class
        if (evt.target.applicationDomain.hasDefinition(font1Name)) FontClass = evt.target.applicationDomain.getDefinition(font1Name) as Class;
        else if (evt.target.applicationDomain.hasDefinition(font2Name)) FontClass = evt.target.applicationDomain.getDefinition(font2Name) as Class;
        try {
            Font.registerFont(FontClass.myFont);
            trace("successfully loaded " + FontClass);
        } catch (err:Error) { 
            trace("couldn't register font "+FontClass.myFont+" =>"+err);
        }
    }  

嵌入式脚本中关于安全性的行是因为第 2 点:registerFont 不能跨域工作。事实上 Security.allowDomain() 没有工作,为了调试它,我不得不在 PC 上复制/粘贴 swf 文件并相应地更改 loader.load(URLRequest())

仍然存在一个问题,尽管字体已注册并声称与 flash.text.engine TextElement 要求兼容,但仍无法像以下那样使用:

        _tl = new Array();

        var block:TextBlock = new TextBlock();
        var font:FontDescription = new FontDescription(fontName);
        var formt:ElementFormat = new ElementFormat(font, fontSize);
//following gives 'true EnglishF'
trace(FontDescription.isFontCompatible(fontName,"normal","normal"), formt.fontDescription.fontName);
        formt.color = colr;
        var span:TextElement = new TextElement(text, formt);
        block.content = span;

        _tl[0] = null;
        _tl[0] = block.createTextLine(null, width);
        var tl:TextLine;
// after here justification and addition lines  

如果以及当我弄清楚为什么这不起作用时,我会发布一些东西(除非有人为我这样做!)

【讨论】:

猜你喜欢
  • 2010-11-15
  • 2012-10-10
  • 1970-01-01
  • 2010-09-26
  • 2011-12-10
  • 2012-02-08
  • 2013-07-17
  • 1970-01-01
  • 2010-11-07
相关资源
最近更新 更多