Записки о Flash

FontLoader v. 2.1

FontLoader обновился до версии 2.1. По просьбам зарубежных товарищей, FontLoader теперь работает в среде AIR, а также добавился новый метод loadBytes, аналогичный одноименному методу класса Loader.


16 comments

16 Comments so far

  1. Max Basmanov June 19th, 2009 09:38

    Скачал последний FontLoader. Спасибо огромное – пример выглядит очень достояно.
    Только у меня возникла одна проблема:
    - беру от демку и собираю пример (как из фла так и только из .as) – все работает, даже с моими файлами со шрифтами.
    - беру свой класс, включаю в него FontLoader, копирую из демки кусок загрузки шрифта. все собираю. при запуске вываливает exception: “тип файла не соответствует содержимому”.

    установлен на машине: FP 10.0 r22
    flashdevelop, flex sdk 3.4, flash cs4

    при сборке как под 9 так и под 10 – картина идентичная.

    подозреваю, что проблема кроется в пресловутой секъюрности. а именно: у меня есть главный swf приложения, который загружает в себя другие с того же домена, достает из них классы и создает объекты из этих классов на форме приложения.
    класс по словам адобовских статей импортируется в сендбокс главной флешки
    context.applicationDomain = ApplicationDomain.currentDomain;
    //new ApplicationDomain();//если делать так – ниче не работает – т.к. запрещает общатся классам друг с другом
    loader.load(urequest,context);

    потом загруженный класс загружает шрифты из отдельного файлика и применяет к своим строчкам внутри.

    заранее благодарен за помощь

  2. Max Basmanov June 19th, 2009 09:49

    есть проблемы в работе при загрузке шрифта подгруженным классом.

  3. etc June 19th, 2009 10:02

    Это давний баг в плеере, FontLoader тут непричем. Решить проблему можно, если FontLoader будет находится в основном домене приложения.

  4. Max Basmanov June 19th, 2009 11:25

    Так оно все и находится в основном домене.
    стартовый layout.swf, runningstring.swf, шрифты: ru_georgia.swf ru_myslcct.swf – все лежать в одном домене.
    Изначально загружается layout.swf,
    потом, используя ClassLoader подгружается runningstring.swf. При этом ClassLoader выполняет
    context.applicationDomain = ApplicationDomain.currentDomain;
    loader.load(urequest,context);
    У него есть событие окончания загрузки, в котором:
    var runtimeClassRef:Class = rsLoader.getClass(“RunningString”);
    loRunningStringContainer = new runtimeClassRef();

    Внутри класса RunningString в конструкторе создается FontLoader.
    При загрузке шрифта rsFontLoader.addEventListener(Event.COMPLETE, fontsLoaded);
    rsFontLoader.load(new URLRequest(fntHost+fntName+”.swf”));

    в функции fontsLoaded:
    trace(“fonts Loaded”);
    trace(Font.enumerateFonts());
    и далее по тексту применение шрифта…

    При этом exception возникает еще до trace.

    То как плеер работает со шрифтами я уже понял :( даже официальный запрос на адоб нашел за решением этой проблемы. То, что шрифты, которые по идее регистрируются в системе видны только в рамках класса, который выполнил Font.registerFont(FontToLoad); я уже тоже ощутил.

    я просто пытаюсь понять в чем проблема и как ее решить.

    заранее благодарен.

    П.С. а как код вкладывать, чтоб он красиво выглядел? с раскраской и номерами строчек?

  5. etc June 19th, 2009 13:36

    Тег <code>, ftf к сожалению не работает.

    А можно собрать примерчик с косяком?

  6. Max Basmanov June 19th, 2009 14:03

    ок, соберу, выложу с линком

  7. Max Basmanov June 19th, 2009 18:09

    после длительных поисков, косяк нашелся…
    протупил я :(

    основная идея в следующем:
    сервер при неправильном линке выдает стартовую страницу.
    по итогу:
    - при правильном линке все отлично
    - при битом линке возникает эксепшин и мувик останавливается.

    есть предложение:
    добавить в класс FontLoader обработку эесепшинов подобного плана и свои события:
    public static var FONTS_LOADED:String = “fontsLoaded”;
    public static var IO_LOAD_ERROR:String = “ioLoadError”;
    public static var SEC_LOAD_ERROR:String = “secLoadError”;
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler);
    loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
    loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler);

    private function completeHandler(e:Event):void {
    dispatchEvent(new Event(ClassLoader.CLASS_LOADED));
    }
    private function ioErrorHandler(e:Event):void {
    dispatchEvent(new Event(ClassLoader.IO_LOAD_ERROR));
    }
    private function securityErrorHandler(e:Event):void {
    dispatchEvent(new Event(ClassLoader.SEC_LOAD_ERROR));
    }

    а в местах возможного возникновения эксепшнов добавить их поимку и утилизацию с выдаванием ивента.

    таким образом была бы модель нормальной обработки подобных ситуаций

  8. etc June 19th, 2009 19:06

    Эмм, вообще говоря, все стандартные события Loader-а FontLoader высылает, в метатегах это указано дополнительно.

  9. Max Basmanov June 25th, 2009 11:19

    ок, ситуация следующая:
    при битом линке на файл сервер выдает стартовую страницу. и вот здесь начинается самое интересное:
    1.если использовать iFontLoader.load(new URLRequest(fntHost + fntName + “.swf”), true);
    IOErrorEvent.IO_ERROR не подымается, а загрузчик переходит к функции
    private function analyze(bytes:ByteArray, delayed:Boolean = false):void {
    и отдает ей загруженные байты.
    2. функция analyze абсолютно не в курче, что там в этих байтах лежит и начинает их обрабатывать как совершенно нормальный файл.
    3. внутри функции чозается от этих байтов SWFByteArray(bytes), в котором ризбираются заголовки и т.д., где оно и падает окончательно, т.к. в байтах лежит html, а далеко не swf.
    4. в конструкторе SWFByteArray подымается иксепшн, который нигде не ловится и не обрабатывается и не превращается в ивент, что не позволяет его обработать далее и валит все приложение, которое попыталось подгрузить несуществующий шрифт.

    что нужно сделать для решения проблемы:
    1. добавляем в class SWFByteArray
    private var goodSWF:Boolean = true;
    public function get swfIsGood():Boolean {
    return goodSWF;
    }
    2. в конструкторе находим и комментируем строчку
    throw new ArgumentError(‘Error #2124: Loaded file is an unknown type.!!!!’);
    вместо нее вставляем
    goodSWF = false;
    3. кусок this.readHeader(); заменяем на
    try {
    this.readHeader();
    }catch (error:Error) {
    goodSWF = false;
    }
    4. косок
    data.endian = endian;
    data.position = position;
    меняем на
    try{
    data.endian = endian;
    data.position = position;
    }catch (error:Error) {
    goodSWF = false;
    }
    это нужно сделать т.к. в особо тяжких случаях возниказ иксепшн попытки чтения за пределами файла

    5. в функции readFrameRate() класса SWFByteArray
    перед блоком if добавляем try {
    послеблока if (всего) добавляем
    }catch (error:Error) {
    goodSWF = false;
    }

    6. в функции readHeader() класса SWFByteArray
    перед
    this._rect = this.readRect();
    this.readFrameRate();
    super.readShort(); // num of frames
    добавляем try {
    после
    }catch (error:Error) {
    goodSWF = false;
    }

    и теперь самое главное:
    в функции analyze класса FontLoader:
    1. тип переменной data меняем на SWFByteArray, получая:
    var data:SWFByteArray = new SWFByteArray(bytes);

    2. добавляем еще одну переменную
    var tmpData:ByteArray;

    3. дальше собственно идет обработка загруженных данных, чтобы все не падало там делаем следующее:
    перед циклом while (data.bytesAvailable) { добавляем
    if (data.swfIsGood) {

    после окончания последнего блока if (this._fontCount) {
    (собственно в самом конце функции)
    добавляем
    else {
    super.dispatchEvent(new Event(IOErrorEvent.IO_ERROR));
    }

    4. в цикле for (o in fontData) { меняем
    data = fontData[o] as ByteArray; на
    tmpData = fontData[o] as ByteArray;

    затем меняем
    if (data) { на
    if (tmpData) {

    затем меняем
    tempData.writeBytes(data); на
    tempData.writeBytes(tmpData);

    ВСЕ! :)

    !теперь мы можем нормально отреагировать на загрузку неправильного файла. и ничего в иксепшн не упадет.

  10. Max Basmanov June 25th, 2009 11:24

    собственно сам файлик с изменениями
    http://avaks.kiev.ua/max/fontloader.as
    :)

  11. etc June 25th, 2009 11:42

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

  12. lordB8r November 10th, 2009 18:01
  13. Vitaliy February 1st, 2010 23:49

    Скажите пожалуста эта прога может витянуть встроеный шрифт из swf-ки. Если нет, то не подскажите случайно чем это можна сделать.

  14. etc February 2nd, 2010 05:03

    Это не программа. И что значит «вытянуть»?

  15. Vitaliy February 2nd, 2010 09:06

    Витянуть значит экспортировать. Говарю сразу такие экспортери как Sothnic SWF Decompiler экспортируют шрифт только в еще одну swf, а толку от этого никакова. Мне нужен шрифт именно в ttf формате или ином юзабельном формате.
    Извиняюсь про Fontloader я невнимательно прочел, как я понимаю это какаето библиотека класов что ли.

  16. etc February 2nd, 2010 09:10

    FontLoader, в общем, вам не подойдет.

Leave a reply