| « Cairngorm для Flash CS3 | Runtime embedded fonts in Flash CS3 » |
Динамическая загрузка шрифтов - Flash CS3
Разобравшись в длиннющем посте немецкого флешера решил его перевести и немного сократить. К Flex это не относится.
Задача: динамически загружать и использовать встроенные шрифты (embedded fonts) в Flash CS3 - Flash Player 9. Для Flash Player 8 и более ранних - Shared Fonts Manager (отдельное удовольствие
).
Что мы имеем? Класс Font, оттуда нам понадобятся функции enumerateFonts(Boolean):Array и registerFont(Class):void а также свойства fontName:String и fontStyle:String.
1. Создаем внешний .swf-контейнер для нужного шрифта
Создаем новый .fla для ActionScript 3.0. В библиотеке создаем новый шрифт - “New Font…” - в “Name” пишем что угодно (в будущем не пригодится), размер шрифта также не имеет значения. Параметры “Bold", “Italic” и “Bitmap text” а также выбор самого шрифта напрямую определяют вид вашего будущего шрифта.
Далее, выбираем созданный символ в библиотеке и жмем “Linkage…". Выбираем “Export for ActionScript” и “Export in first frame". “Export for runtime sharing” выбирать не надо. Базовым классом оставляем flash.text.Font. Имя класса “Class” будет в будущем играть большое значение, введите его. Создавать сам файл .as с классом необходимости нет, среда сама создаст нужный класс.
В настройках публикации оставляем только компиляцию .swf, публикуем. Один шрифт готов, а этот .fla готов к созданию остальных нужных шрифтов через “Save as…” чтобы не повторять все операции заново а лишь заменить шрифт, и имя класса для него.
2. Создание XML-описания для только что подготовленных шрифтов
Пусть наше основное приложение будет брать список шрифтов из XML-файла:
<?xml version="1.0" encoding="utf-8"?> <!-- title - имя шрифта для пользователя className - то, что вы ввели в поле Class раздела Linkage url - адрес .swf со шрифтом --> <fonts> <font title="Arial (smooth)" className="Arial" url="fonts/Arial.swf"/> <font title="Bell MT (smooth)" className="BellMT" url="fonts/BellMT.swf"/> <font title="Bodoni MT (smooth)" className="BodoniMT" url="fonts/BodoniMT.swf"/> ... </fonts>
Парсить этот XML мы будем в массив объектов типа MyFont:
- package com.yourname.yourproject.model
- {
- public class MyFont
- {
- public var title:String;
- public var className:String;
- public var url:String;
- }
- }
Делать MyFont наследником Font мне не хотелось т.к. Font олицетворяет уже загруженный и готовый к использованию шрифт, а у нас только описание для вершины в XML-файле. К тому же подобного наследника мы уже имеем - среда создала по одному дочернему классу для каждого шрифта.
3. Загрузим шрифт и будем его использовать
Пусть мы загрузили XML с описаниями, распарсили его в массив объектов MyFont. Загрузим .swf с нужным шрифтом через Loader с указаннием LoaderContext:
- loader = new Loader();
- var req:URLRequest = new URLRequest(usFont.url);
- var loaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
- loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
- loader.load(req, loaderContext);
Важно указать ApplicationDomain.currentDomain - шрифты будут загружаться в текущий домен, откуда мы их и будем забирать.
- private function completeHandler(event:Event):void
- {
- var fontClass:Class = ApplicationDomain.currentDomain. getDefinition(textEditVO.font.className) as Class;
- Font.registerFont(fontClass);
- var font:Font = new fontClass();
- // Теперь шрифт можно смело использовать:
- // tf.embeddedFonts = true;
- // var textFormat:TextFormat = new TextFormat(font.fontName);
- // tf.setTextFormat(textFormat);
- }
4. Комментарии.
Можно загружать шрифт не в текущий домен ApplicationDomain.currentDomain, а оставлять его в собственном домене. По событию Event.COMPLETE loader.contentLoaderInfo.applicationDomain инициализируется и до нашего шрифта можно добраться:
- // myFont:MyFont - нужный шрифт
- var fontClass:Class = loader.contentLoaderInfo.applicationDomain. getDefinition(myFont.className) as Class;
- var font:Font = new fontClass();
- Font.registerFont(font);
- // шрифт можно использовать:
- // tf.embeddedFonts = true;
- // ...
PS: А нужно ли это вообще?
Вот примеры того, как выглядят встроенные и обычные шрифты у пользователя. В принципе не смертельная (хотя очень заметная) разница на шрифтах размера больше 10px.

Но стоит сделать попиксельный экспорт в случае device font в BitmapData, отослать это на сервер и там мы увидим нечто (в случае embedded все хорошо):

Трекбек адрес этой записи
URL трекбека (щелкните правой кнопкой мыши и скопируйте ссылку)
2 комментариев
Мне интересно как это делалось. Так что:
СПАСИБО.
Станичку в закладки, в след проекте буду использовать
Регистрацию фонта вполне можно перенести в загружаемый swf.
Минус такой технологии в том, что шрифт экспортируется в swf только целиком, а не отдельно выбранные символы. Есть другой механизм подгрузки фонта, с весьма ограниченными возможностями, но без этого недостатка.




