Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Внедрение Шрифта. Runtime Loading. (http://www.flasher.ru/forum/showthread.php?t=202235)

Fogflasher 04.07.2013 12:37

Внедрение Шрифта. Runtime Loading.
 
Лебенсборн чыхыртма, православные.

Вот еще один базовый нуб-вопрос.

Читаю Мука. Пробую реализовать пример из главы Loading Fonts at Runtime.
Подход, насколько я понял, там следующий:

1. Создать вспомогательный файл с именем Fonts.fla, докУмент класс которого выглядит, например, так:
Код AS3:

package
{
  import flash.display.*;
  import flash.text.*;
 
 
  public class Fonts extends Sprite
  {
        [Embed(source="c:/windows/fonts/verdana.ttf", fontFamily="Verdana")]
    private var verdana:Class;
 
    [Embed(source="c:/windows/fonts/verdanab.ttf", fontFamily="Verdana", fontWeight="bold")]
    private var verdanaBold:Class;
 
        // Constructor
    public function Fonts()
        {
      // Register this class's embedded fonts in the global font list
      Font.registerFont(verdana);
      Font.registerFont(verdanaBold);
    }
 
 
  }
}

2.Создать основной файл, например RuntimeFont.fla, докУмент класс которого выглядит примерно так:
Код AS3:

package
{
          import flash.display.*;
          import flash.text.*;
          import flash.events.*;
          import flash.net.*;
 
 
          public class RuntimeFont extends Sprite
          {
                        public function RuntimeFont()
                        {
                          // Load the .swf file that contains the embedded fonts
                          var loader:Loader = new Loader();
                          loader.contentLoaderInfo.addEventListener(Event.INIT, initListener);
                          loader.load(new URLRequest("Fonts.swf"));
                        }
 
 
                        private function initListener (e:Event):void
                        {
                          // The font has loaded, so now display the formatted text
                          outputMsg();
                        }
 
 
                        private function outputMsg():void
                        {
                          // Create the text field
                          var t:TextField = new TextField();
                          t.embedFonts = true;
 
 
                          t.text = "And the First Ones shall awaken on that day" +
                                            "\nWhen man will return to the stars!";
 
                          addChild(t);
                        }
 
          }
}

3. В библиотеке этого основного файла создать New Font, указать любое имя, выбрать в списке, для данного случая шрифт Verdana.
Потом войти в Linkage Properties и поставить галочку Export for Action Script.
В результате появится неприятное предупреждение "A definition for this class could not be found in the classpath... ", но мы его тупо за-ОК-йиваем.

Ну вот и всё, походу дела.

Запускаю RuntimeFont и получаю вот такую ошибку:

Код:

TypeError: Error #2007: Parameter font must be non-null.
        at flash.text::Font$/registerFont()
        at Fonts$iinit()


Где прокол? В чем ошибка?

P.S. Если запустить отдельно Fonts.fla - то выдается та же ошибка, вероятно трабл в этом файле.
Однако там я ничего не менял (кроме более наглядного расположения кода), он взят прямо из книги.

Примечание: На всякий случай сообщу, что у меня Adobe Flash CS3 Professional (version 9.0).
Впрочем, примеры из книги должны быть универсальны для всех версий, наверное.

PainKiller 04.07.2013 13:42

1. тем посвященных ембеду шрифтом на форуме навалом, воспользуйтесь поиском.
2.
Цитата:

В библиотеке этого основного файла создать New Font, указать любое имя, выбрать в списке, для данного случая шрифт Verdana.
Потом войти в Linkage Properties и поставить галочку Export for Action Script.
Это зачем? вы же грузите шрифт, зачем его ембедить в основной флешке.
3. Ошибка у вас валится потому что в загружаемой флешке переменные verdana и verdanaBold приходят null. Почему это интересный вопрос, в первую очередь я бы проверил пути к шрифтам.

Fogflasher 04.07.2013 13:59

Painkiller,

1. Я поиск юзал немного, но навскидку нужное не нашел. Посмотрю еще конешно...

2. У Мука такой алгоритм. Правда повествование сумбурное какое-то (почему-то именно в этой главе), иногда и не понять, что он советует для Flash IDE а что для Flex, например. Может я чего не разобрал.

3. С путями всё ОК, Windows XP SP3, c:\windows\fonts\verdana.ttf - такой путь и такой файл существуют.
Может дело не с путями а с fontFamily? Странный параметер. Вот если например у меня вообще есть левый шрифт, типа Chiller, то как определить его fontFamily, не понятно.

Korchy 04.07.2013 14:10

2 Fogflasher

см. п. 8

http://korchy.livejournal.com/85656.html

Fogflasher 04.07.2013 15:48

Вложений: 1
Korchy, Спасибо, изучаю...

Но если навскидку оценить, то это весьма неслабо, с точки зрения уровня нуба, конешно.
Кто бы мог подумать что нужно столько сторонних извратов, типа super() для EventDispatcher...

Хочу пока спросить по поводу другого вашего поста с именем "Встраивание шрифта в Adobe Flash CS".

Получилось вот так:

1. Создал такой объект в библиотеке:
Вложение 29781

2. Написал такой код в докУмент классе проекта:

Код AS3:

package
{
          import flash.display.*;
          import flash.text.*;
          import flash.events.*;
          import flash.net.*;
 
          public class RuntimeFont extends Sprite
          {
                        public function RuntimeFont()
                        {
 
                                  var Text1:TextField = new TextField();
                                Text1.embedFonts = true;
 
                                Text1.width = 500;                                       
                                Text1.height = 350;                                       
                                Text1.x = 25;                                                       
                                Text1.y = 25;                                                       
 
                                var TFormat1:TextFormat = new TextFormat();
                                TFormat1.font = "Chiller"+"_"+"30"+"pt_st";
 
                                Text1.text = "Testing embedding technique...";
                                Text1.setTextFormat(TFormat1);
 
                                addChild(Text1);
 
                        }
 
          }
 
}

И оно заработало. Уже хорошо.

Но есть два момента:

1. Размер шрифта какой-то очень маленький...
Я специально менял значение 30 на 200 (и в строке кода, и в имени объекта), но как ни странно размер остается точно таким же.
Глюк? Или что-то не так...

2. Пробовал вместо BitmapText шрифта создать обычный, галку не ставить. Указал шрифт CyrilicHover и имя вписал: CyrilicHover_name, (размер = 100).
В коде прописал его сначала так:
Код AS3:

TFormat1.font = "CyrillicHover_name";

, но это нихрена не дало, пустой экран.

Тогда вписал
Код AS3:

TFormat1.font = "CyrillicHover";

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

Korchy 05.07.2013 01:25

2 Fogflasher

А у используемых вами шрифтов есть вообще поддержка такого большого размера? Я с большими размерами не экспериментировал, мне хватало 10-12, максимум 14 размеров.

Fogflasher 05.07.2013 09:35

Korchy,
Я не знаю, а как определить эту поддержку?
Я думал что у ttf шрифтов размер какбэ любой может быть.

Попробовал немного другой подход:

Код AS3:

package
{
  import flash.display.*;
  import flash.text.*;
  import flash.events.*;
 
  public class FontEmbed extends Sprite
  {
 
 
        //--- Constructor ---//
          public function FontEmbed()
          {
 
                var TFormat1:TextFormat = new TextFormat();
                TFormat1.font = new Chiller_embed().fontName;  //Manually created class name in Library
 
                var txtField:TextField = new TextField();
                txtField.defaultTextFormat = TFormat1;
 
                txtField.embedFonts = true;
                txtField.text =  "\nAnd Humanity shall one day Rediscover...";
 
                addChild(txtField);
    }
  }
}

Но в этом случае непонятно, если ставить галочку BitmapText, то где прописывать вот это вот более хитрое имя файла, типа Chiller_30_pt_st.

Wolsh 05.07.2013 09:57

http://flasher.ru/forum/showthread.php?t=169912

Korchy 05.07.2013 13:10

Вложений: 2
2 Fogflasher

Попробуйте сначала сделать точно по тому, как я написал в посте по ссылке (это где "встроить шрифты стандартным образом"). Вот пример с вашим шрифтом Chiller размера 30 встроенном в проект. Заодно приложил файлы проекта (сделано на коленке в CS4).

tmpfont.swf   (15.7 Кб)

Fogflasher 05.07.2013 16:01

Wolsh, спасибо прочитал.

Пробовал ваш пример (что на второй странице) реализовать в IDE, но не получилось.
Видимо Korchy прав, и тэги эмбэдд вообще не воспринимаются Флэшем ИДЭ.

Пример от Dimarik слишком абстрактен, нехватает пэкиджей и конструкторов.

То что вы в архиве приаттачили очевидно сделано не во флэш...
Я подозреваю что вы работаете на Flex или еще чем-то таком, что мне незнкомо.

Добавлено через 5 минут
Korchy, благодарю за пример. Всё работает.

Хотя, в принципе я так всё и делал.
Просто я принципиально не указывал строку TFormat.size = 30;
Мне казалось, что формат имени Chiller_30pt_st вместе с указанием 30 в форме ввода должно автоматически давать шрифт этого размера.

А выходит что нихрена: все три 30-ки должны работать в связке.

Fogflasher 25.07.2013 12:51

Runtime version
 
Вложений: 2
Пробую запустить программу Korchy по внедрению шрифтов.

Создал файл Font1.fla, в котором вот такие настройки:
PROPERTIES:
Вложение 29844

LINKAGE:
Вложение 29845

Далее, создал файл класса, который он привел в своем блоге, подставив имена, а также оставив только одну строку с регистерфонт:

Код AS3:

package
{
  import flash.display.Loader;
  import flash.display.LoaderInfo;
  import flash.events.Event;
  import flash.events.EventDispatcher;
  import flash.net.URLRequest;
  import flash.text.Font;
 
  public class FontsManager extends EventDispatcher
  {
 
      private var FontsLoader:Loader;
      private var FontsLoaderInfo:LoaderInfo;
      private var FontsLoaded:Boolean;
      // Константы событий
      public static const FONTS_LOADED:String = "EvFontsLoaded"; // шрифт загружен
 
      public function FontsManager()
          {
        // Конструктор
        super();
        FontsLoaded = false;
      }
 
      public function LoadFontsFromExternalSWF(Value:String):void
          {
        // Загрузить swf со шрифтами
        if (FontsLoaded == false)
                {
            FontsLoader = new Loader();
            FontsLoaderInfo = FontsLoader.contentLoaderInfo;
            FontsLoaderInfo.addEventListener(Event.COMPLETE, OnFontsLoaded);
            FontsLoader.load(new URLRequest(Value));
        }
      }
 
      private function OnFontsLoaded(e:Event):void
          {
        // SWF со шрифтами загружена
        if(FontsLoaded==false)
                {
            Font.registerFont(Class(LoaderInfo(e.target).applicationDomain.getDefinition("CyrillicHover")));
//          Font.registerFont(Class(LoaderInfo(e.target).applicationDomain.getDefinition("FontName1Italic")));
//          Font.registerFont(Class(LoaderInfo(e.target).applicationDomain.getDefinition("FontName1Bold")));
//          Font.registerFont(Class(LoaderInfo(e.target).applicationDomain.getDefinition("FontName2")));
            FontsLoaded = true;
            FontsLoaderInfo.removeEventListener(Event.COMPLETE, OnFontsLoaded);
            dispatchEvent(new Event(FontsManagerVn.FONTS_LOADED));
        }
      }
 
      public static function CorrectFontName(vFontName:String, vFontSize:uint=12):String
          {
        // Проверка, есть ли такой встроенный (загруженный из сторонней SWF) шрифт заданного размера
        // если есть - возвращает его имя, если нет - возвращает исходное имя шрифта
        var EmbeddedFonts:Array = Font.enumerateFonts(false);
        for (var i:uint = 0; i < EmbeddedFonts.length; i++)
                {
            if (Font(EmbeddedFonts[i]).fontName == vFontName + "_" + String(vFontSize) + "pt_st")
                        {
              return vFontName + "_" + String(vFontSize) + "pt_st";
            }
        }
        return vFontName;
      }
 
  }
}

Далее сделал основной класс, в котором ввёл такой код:
Код AS3:

package
{
          import flash.display.*;
          import flash.events.*;
          import flash.net.*;
          import flash.text.*;
 
          public class Runtime_font_embed extends MovieClip
          {
 
                        public function Runtime_font_embed()
                        {
 
 
                        var MyFontsManager:FontsManager = new FontsManager();
                        MyFontsManager.addEventListener(FontsManager.FONTS_LOADED, Continue);
                        MyFontsManager.LoadFontsFromExternalSWF("Font1.swf");
 
                        var text1 = new TextField();
                        var format1 = new TextFormat();
                        format1.font = FontsManager.CorrectFontName("CyrillicHover", 30);
                        text1.setTextFormat(format1);
 
                        }
 
 
          }
 
}

И в результате выполнения получаю:

Цитата:

1120: Access of undefined property FontsManagerVn. dispatchEvent(new Event(FontsManagerVn.FONTS_LOADED));
(Думал, может проблема в именах, поигрался с заменой Name1 на CyrillicHover и обратно, но нифига.)

Что не так с этим FontsManagerVn?

Korchy 25.07.2013 23:54

2 Fogflasher
Да, это моя опечатка - это же название собственно класса.
Уберите буковки Vn в конце наименования класса в строке dispatchEvent(new Event(FontsManagerVn.FONTS_LOADED));
должно быть так: dispatchEvent(new Event(FontsManager.FONTS_LOADED));

Fogflasher 26.07.2013 11:49

Korchy, Спасибо, исправил.

Но появилась теперь другая ошибка:

Цитата:

1120: Access of undefined property Continue. MyFontsManager.addEventListener(FontsManager.FONTS_LOADED, Continue);

Korchy 26.07.2013 12:09

2 Fogflasher

> Функция Continue будет вызвана после загрузки swf со шрифтами для продолжения работы программы.

Создайте функцию с таким именем, или со своим, и его подставьте в эту строчку. После того, как шрифт будет загружен, будет произведен вызов этой функции. В эту функцию вынесете вот этот кусок
Код AS3:

var text1 = new TextField();
var format1 = new TextFormat();
format1.font = FontsManager.CorrectFontName("CyrillicHover", 30);
text1.setTextFormat(format1);

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

Fogflasher 26.07.2013 12:14

А можно как-то на примере это в коде показать?

Вот например я пробую так:

Код AS3:

package
{
          import flash.display.*;
          import flash.events.*;
          import flash.net.*;
          import flash.text.*;
 
          public class Runtime_font_embed extends MovieClip
          {
 
                        public function Runtime_font_embed()
                        {
 
 
                        //        Оформив класс загрузчика шрифтов, в основной функции проекта вызываем загрузку:
                        var MyFontsManager:FontsManager = new FontsManager();
                                MyFontsManager.addEventListener(FontsManager.FONTS_LOADED, Continue);
                                MyFontsManager.LoadFontsFromExternalSWF("Font1.swf");
 
                        }
 
                        public function Continue()
                        {
                                var text1 = new TextField();
                                var format1 = new TextFormat();
                                format1.font = FontsManager.CorrectFontName("CyrillicHover", 30);
                                text1.setTextFormat(format1);
                        }
 
 
          }
 
}

И получаю такую Output ошибку:

Цитата:

ArgumentError: Error #1063: Argument count mismatch on Runtime_font_embed/Continue(). Expected 0, got 1.
at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at FontsManager/::OnFontsLoaded()

Korchy 26.07.2013 12:54

2 Fogflasher

Вы прочитали у Мука главу посвященную обработке событий?
Функция Continue - обработчик события. Обработчики требуют указания в параметрах события, которое они получают. О чем вам в ошибке впрямую и пишется - функция ожидает 0 параметров, а получает 1.
Обозначьте параметр, ответственный за событие:

Код AS1/AS2:

public function Continue(e:Event):void {
}


Fogflasher 26.07.2013 14:44

Korchy, жаль если я раздражаю вас своей тупостью, но да, я ее читал.
Правда скорее в ознакомительном режиме, без закрепления всех деталей и ньюансов, для понимания.

Подозрение на аргументы у меня было, но я воспринял смысл ошибки как прямо противоположный: "Ждет 0, имеет 1", как будто бы "некий аргумент уже есть... и то что я его не вижу еще нихрена не означает, мало ли..." А тут всё проще оказалось.

Теперь программа работает без ошибок. Значение format1.font трэйсится как CyrillicHover_30pt_st, что очевидно правильно.

Однако проблема в том, что фонт почему-то не применяется.

Я сначала подумал что код функции Continue имеет ошибки:
Код AS3:

public function Continue(e:Event)
                        {
                                var text1 = new TextField();
                                text1.autoSize = TextFieldAutoSize.LEFT;
                                text1.x = 80;
                                text1.y = 80;
                                text1.width = 200;
                                text1.text = "Text Embedding - это непросто!";
 
 
                                var format1 = new TextFormat();
                                format1.font = FontsManager.CorrectFontName("CyrillicHover", 30);
                                format1.color = 0x0011CC;
                                format1.size = 30;
                                format1.align = TextFormatAlign.LEFT;
 
 
                                text1.setTextFormat(format1);
 
                                trace("text1.text", text1.text);
                                trace("format1.font", format1.font);
 
                                addChild(text1);
 
                        }

Однако текст выдается, и цвет применяется, то есть setFormat работает...

Может быть проблема в файле Fonts.fla?
Может я чего-то недопонял и какой-то код там должен быть.

Добавлено через 22 минуты
Блин, всё же очень просто...

'Слона то я и не приметил', забыл строку:
Код AS3:

text1.embedFonts = true;

Korchy, Теперь всё работает, благодарю за помощь! ^_^


Часовой пояс GMT +4, время: 22:14.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.