#flash #fonts #shared-libraries #embedded-fonts #rsl
#flash #шрифты #общие библиотеки #встроенные -шрифты #rsl
Вопрос:
Я использую Flash CS5 (ресурсы) и FlashDevelop (код) для своего проекта. У нас есть около 20 файлов формата fla / swf, содержащих текстовые поля. Все наши текстовые поля используют один и тот же шрифт, и шрифт специфичен для нашей компании, поэтому он не будет установлен ни на чьих компьютерах, поэтому его необходимо встроить.
Моя конечная цель — внедрить один единственный шрифт, который используют все текстовые поля, по 2 основным причинам:
- Всякий раз, когда мы добавляем больше символов в шрифт (на других языках), нам нужно добавлять их только один раз, а не 20 раз
- Размер файла не увеличивается резко
Мне очень трудно добиться этого. Кажется, что все, что я пытаюсь, символы отсутствуют (только символы, введенные в свойство text текстовых полей в каждом fla, похоже, встроены).
Последнее решение, которое я пытаюсь, — это использование общих библиотек времени выполнения, поскольку кажется, что оно должно работать. У меня есть fla с именем FNFont.fla. Он содержит только один объект в библиотеке, встроенный шрифт. Шрифт экспортируется в формат AS3, экспортируется в кадре 1 и экспортируется для совместного использования во время выполнения. URL-адрес — FNFont.swf (все swf-файлы находятся в одной папке).
Во всех других fla я создаю объект font в font embedding . Я отмечаю Import для совместного использования во время выполнения и присваиваю ему то же имя класса, что и в FNFont.fla. URL-адрес — FNFont.swf. FLA (ы) содержат много текстовых полей, использующих этот шрифт. Текстовые поля имеют экземпляры самих себя как дочерних элементов других видеороликов.
Когда я запускаю программу и пытаюсь загрузить видеоролик, содержащий экземпляр одного из этих текстовых полей, я получаю сообщение об ошибке:
[Fault] exception, information=ReferenceError: Error #1065: Variable FontName is not defined.
FontName — это имя класса объекта Font в FNFont.fla и всех других fla. Это не имя экземпляра текстового поля (и не имя класса), поэтому я не понимаю, как он считает его переменной. Кто-нибудь может пролить свет на это?
Спасибо
Ответ №1:
По моему опыту, вам нужно создавать новые TextFields
на лету.
Вы не можете использовать TextFields
те, которые уже были скомпилированы в SWF
, иначе вы получите проблему, описанную выше.
Это одна из тех маленьких ошибок, из-за которых сложно любить Adobe.
Ответ №2:
Возможно, вам захочется выполнить поиск «загрузка шрифтов во время выполнения», например:
http://www.mokisystems.com/blog/flash-as3-loading-fonts/
или…
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);
}
Комментарии:
1. Я пробовал это ранее, и это не сработало. Несмотря на то, что мы могли видеть, что шрифт внедрялся (используя enumerateFonts и отслеживая их после registerFont), все еще не хватало многих символов. После декомпиляции некоторых swf-файлов мы заметили, что flash автоматически встраивает шрифт в каждый swf-файл, хотя у нас ничего не было в Text -> Font Embedding . Внедряемые символы были символами, используемыми в свойстве Text каждого текстового поля в библиотеке. Текстовые поля использовали эти невидимые встроенные шрифты вместо шрифта, встроенного через registerFont.
Ответ №3:
Некоторое время назад я столкнулся с подобной проблемой, и оказалось, что это проблема с настройкой правильного ApplicationDomain
в загрузчике.
Я не уверен, что у вас похожая ситуация, но вот моя.
- CS5.5
- У меня есть
fonts.swf
несколько шрифтов в библиотеке. Каждый из них настроен на экспорт для совместного использования во время выполнения, и им присваивается имя класса. - Существует основной swf-файл, в который загружается несколько дочерних swf-файлов.
- Каждый дочерний swf-файл содержит объекты шрифтов без встраивания. Для объектов шрифтов установлено значение «Импорт для совместного использования во время выполнения», и им присваиваются те же имена классов, что и для fonts.swf.
В моем случае первый дочерний swf-файл правильно загрузит fonts.swf и получит доступ к шрифтам. Второй дочерний swf-файл, который пытался получить доступ к шрифтам, не будет перезагружать шрифты.swf и я получили бы ту же ошибку, которую вы описали выше.
Мне кажется, что Flash пытается быть умным, не перезагружая шрифты, поскольку предполагается, что они уже зарегистрированы для всего приложения. Однако, поскольку каждый дочерний элемент.swf загружается в родительский файл по умолчанию ApplicationDomain
. дочерние элементы имеют доступ к пути к классу родительского файла, но не друг к другу. Таким образом, первый дочерний элемент имеет доступ к шрифтам в fonts.swf
, а второй дочерний элемент нет, потому что они находятся в родственном, а не родительском.
Я считаю, что есть два способа обойти это:
- Загрузите шрифты.swf в родительский swf-файл, прежде чем кто-либо из дочерних элементов попытается получить к нему доступ.
- Установите
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);