Не удается заставить работать общую библиотеку среды выполнения Flash

Я использую Flash CS5 (активы) и FlashDevelop (код) для своего проекта. У нас есть около 20 fla/swf, которые содержат текстовые поля. Все наши текстовые поля используют один и тот же шрифт, а шрифт специфичен для нашей компании, поэтому он не будет установлен на чьих-либо компьютерах, поэтому его необходимо встроить.

Моя конечная цель — встроить один единственный шрифт, который будет использоваться во всех текстовых полях, по двум основным причинам:

  • Всякий раз, когда мы добавляем больше символов в шрифт (другие языки), нам нужно добавить их только один раз, а не 20 раз.
  • Размер файла не резко увеличивается

У меня большие трудности в попытке достичь этого. Кажется, что все, что я пытаюсь, символы отсутствуют (кажется, что встроены только символы, введенные в свойство text текстовых полей в каждом fla).

Последнее решение, которое я пытаюсь использовать, - это использование общих библиотек времени выполнения, так как это похоже на то, что оно должно работать. У меня есть фла под названием FNFont.fla. Он содержит только один объект в библиотеке — встроенный шрифт. Шрифт экспортируется в AS3, экспортируется в кадр 1 и экспортируется для общего доступа во время выполнения. URL-адрес FNFont.swf (все swf находятся в одной папке).

Во всех других фла я создаю объект шрифта при встраивании шрифта. Я отмечаю «Импорт для совместного использования во время выполнения» и даю ему то же имя класса, что и в FNFont.fla. URL-адрес: FNFont.swf. Fla(s) содержат много текстовых полей, использующих этот шрифт. Текстовые поля имеют экземпляры самих себя как дочерние элементы других мувиклипов.

Когда я запускаю программу и пытаюсь загрузить мувиклип, содержащий экземпляр одного из этих текстовых полей, я получаю сообщение об ошибке:

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

FontName — это имя класса объекта Font в FNFont.fla и всех других fla. Это не имя экземпляра текстового поля (и не имя класса), поэтому я не понимаю, как он считает, что это переменная. Кто-нибудь может пролить свет на это?

Спасибо


person Ashley Muller    schedule 18.10.2011    source источник


Ответы (3)


По моему опыту, вам нужно создавать новые TextFields на лету.

Вы не можете использовать TextFields, которые уже были скомпилированы в SWF, иначе вы получите описанную выше проблему.

Это одна из тех маленьких-больших ошибок, из-за которых трудно полюбить Adobe.

person Kevin Tamlyn    schedule 20.12.2011

Возможно, вы захотите найти «загрузку шрифтов во время выполнения», например:

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

or...

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

Создайте 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;

    }

}

Загрузите и зарегистрируйте SWF из своих приложений:

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);
}
person Jason Sturges    schedule 18.10.2011
comment
Я пробовал это раньше, и это не сработало. Несмотря на то, что мы могли видеть, что шрифт встраивается (используя enumerateFonts и отслеживая их после RegisterFont), многие символы по-прежнему отсутствовали. После декомпиляции некоторых swf-файлов мы заметили, что flash автоматически встраивает шрифт в каждый swf-файл, хотя у нас ничего не было в Text -> Font Embedding. Встраиваемые символы были символами, используемыми в свойстве Text каждого текстового поля в библиотеке. Текстовые поля использовали эти невидимые встроенные шрифты вместо шрифта, встроенного через RegisterFont. - person Ashley Muller; 18.10.2011

Я столкнулся с подобной проблемой некоторое время назад, и оказалось, что это проблема с установкой правильного ApplicationDomain в загрузчике.

Не уверен, что у вас похожая ситуация, но вот у меня.

  • CS5.5
  • У меня есть fonts.swf с несколькими шрифтами в библиотеке. Для каждого из них настроен экспорт для совместного использования во время выполнения, и им присвоено имя класса.
  • Есть основной swf, в который загружаются несколько дочерних swf.
  • Каждый дочерний swf имеет объекты шрифта без встраивания. Для объектов шрифтов устанавливается значение «Импорт для совместного использования во время выполнения», и им присваиваются те же имена классов, что и в файле fonts.swf.

В моем случае первый дочерний swf правильно загрузит fonts.swf и получит доступ к шрифтам. Второй дочерний swf-файл, пытающийся получить доступ к шрифтам, не перезагружает fonts.swf, и я получаю ту же ошибку, которую вы описали выше.

Мне кажется, что Flash старается не перезагружать шрифты, поскольку предполагает, что они уже зарегистрированы для всего приложения. Однако, поскольку каждый файл child.swf загружается в родительский файл со значением по умолчанию ApplicationDomain, дочерние элементы имеют доступ к пути к классам родительского элемента, но не друг к другу. Таким образом, первый дочерний элемент имеет доступ к шрифтам в fonts.swf, а второй дочерний элемент — нет, поскольку он находится в родственном, а не в родительском элементе.

Я считаю, что есть два способа обойти это:

  1. Загрузите файл fonts.swf в родительский файл swf, прежде чем кто-либо из дочерних элементов попытается получить к нему доступ.
  2. Установите для ApplicationDomain значение ApplicationDomain.currentDomain, чтобы дочерние SWF-файлы использовали тот же ApplicationDomain, что и основной родительский SWF-файл.

Я выбрал вариант 2, который решил проблему для меня.

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