Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Не могу зарегистрировать шрифт (http://www.flasher.ru/forum/showthread.php?t=169912)

Universe 14.10.2011 14:21

Не могу зарегистрировать шрифт
 
Пытаюсь сделать динамическую подгрузку шрифтов в приложение. Создаю флешку в которой создаю новый шрифт, делаю ему Linkage.
Затем в основном классе делаю загрузку этой свф"ки. Всё вроде бы ок, он спотыкаюсь при регистрации шрифта! В чём я допустил ошибку?

Код AS3:

package 
{
        import flash.display.Loader;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.net.URLRequest;
        import flash.text.Font;
        import flash.text.TextField;
        import flash.text.TextFieldAutoSize;
        import flash.utils.describeType;
        import flash.display.MovieClip;
        import flash.text.TextField;
        import flash.text.TextFormat;
        import flash.text.AntiAliasType;
        /**
        * ...
        * @author Andrey
        */

        public class Main extends Sprite
        {
 
                public function Main():void
                {
                        if (stage) init();
                        else addEventListener(Event.ADDED_TO_STAGE, init);
 
                }
 
                private function init(e:Event = null):void
                {
                        removeEventListener(Event.ADDED_TO_STAGE, init);
                        // entry point
 
                        loadFont("../lib/fontTest.swf");
                }
 
                  private function loadFont(url:String):void
                  {
              var loader:Loader = new Loader();
              loader.contentLoaderInfo.addEventListener(Event.COMPLETE, fontLoaded);
              loader.load(new URLRequest(url));
                          trace("LOADING...");
          }
 
          private function fontLoaded(e:Event):void
                  {
                                trace(e.target.applicationDomain.getDefinition("Alba"));
                            var FontLibrary:Class = e.target.applicationDomain.getDefinition("Alba") as Class;
                                Font.registerFont(FontLibrary.Alba);    //Вот тут вылазит ошибка [Fault] exception, information=TypeError: Error #2007: Параметр font не должен быть равен нулю.
                          drawText();
          }
 
          public function drawText():void
                  {
              var tf:TextField = new TextField();
              tf.defaultTextFormat = newTextFormat;
              tf.embedFonts = true;
              tf.antiAliasType = AntiAliasType.ADVANCED;
              tf.autoSize = TextFieldAutoSize.LEFT;
              tf.border = true;
                          tf.textColor = 0x000000;
              tf.text = "Scott was here\nScott was here too\nblah scott...:;*&^% ";
 
 
              addChild(tf);
          }
        }
 
}


stweet 14.10.2011 14:28

Код AS3:

package stlib.fon
{
        import flash.text.Font;
 
        public class RegistrationFonts extends Font
        {
 
                [Embed(source = 'sours/ARIAL.TTF',
                        fontFamily = 'arial',
                        embedAsCFF = 'false')]
                        private var Arial1:Class;
 
                [Embed(source = 'sours/ARIALBD.TTF',
                        fontFamily = 'arialbd',
                        embedAsCFF = 'false')]
                        private var Arial2:Class;
 
                [Embed(source = 'sours/ARIALBI.TTF',
                        fontFamily = 'arialbi',
                        embedAsCFF = 'false')]
                        private var Arial3:Class;
 
                [Embed(source = 'sours/ARIALI.TTF',
                        fontFamily = 'ariali',
                        embedAsCFF = 'false')]
                        private var Arial4:Class;
 
                [Embed(source = 'sours/ARIBLK.TTF',
                        fontFamily = 'ariblk',
                        embedAsCFF = 'false')]
                        private var Arial5:Class;
 
                [Embed(source = 'sours/WEBDINGS.TTF',
                        fontFamily = 'webdings',
                        embedAsCFF = 'false')]
                        private var Sumbol1:Class;
 
                [Embed(source = 'sours/WINGDING.TTF',
                        fontFamily = 'wingding',
                        embedAsCFF = 'false')]
                        private var Sumbol2:Class;
 
                public function RegistrationFonts()
                {
                        registerFont(Arial1);
                        registerFont(Arial2);
                        registerFont(Arial3);
                        registerFont(Arial4);
                        registerFont(Arial5);
                        registerFont(Sumbol1);
                        registerFont(Sumbol2);
                }
 
                // get all font name
                static public function get ALLFONTNAME ():String
                {
                        var _ALLFONTNAME        :String        = '';
 
                        var _arr                :Array        = Font.enumerateFonts();
                                _arr.sortOn ( "fontName", Array.CASEINSENSITIVE );
 
                        for (var i:int = 0; i < _arr.length; i++)
                                if (i != _arr.length - 1) _ALLFONTNAME += _arr[i].fontName + "\n";
                                else _ALLFONTNAME += _arr[i].fontName;
 
                        return _ALLFONTNAME;
                }
        }
}

Код AS3:

        public class Main extends Sprite 
        {
                RegistrationFonts;
 
                public function Main():void
                {
                        if (stage) init();
                        else addEventListener(Event.ADDED_TO_STAGE, init);
 
                }
 
                private function init(e:Event = null):void
                {
                        removeEventListener(Event.ADDED_TO_STAGE, init);
 
                        // startup
                }
        }


trng 14.10.2011 14:34

Из хелпа к Font:
Класс Font нельзя использовать для загрузки внешних шрифтов или для создания своего экземпляра Font. Класс Font следует использовать как абстрактный базовый класс.
Из хелпа к FontAsset:
FontAsset – это подкласс класса flash.text.Font, который представляет шрифты, встраиваемые в приложение Flex.
Встраиваемый шрифт может быть шрифтом TrueType (TTF) или OpenType (OTF).

Universe 14.10.2011 16:00

немного не понял ваш пример. Получается если я сделаю как у вас и у меня будет допустим 100 шрифтов, то юзеру придётся сидеть и ждать пока все 100 шрифтов загрузятся? Может тогда разбить всё на маленькие swf, в каждом из которых будет по шрифту и их подгружать, а уже после подгрузки регистрировать?

GBee 14.10.2011 16:04

Код AS3:

Font.registerFont(FontLibrary);


stweet 14.10.2011 16:15

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

Добавлено через 1 минуту
Код AS3:

Получается если я сделаю как у вас и у меня будет допустим 100 шрифтов, то юзеру придётся сидеть и ждать пока все 100 шрифтов загрузятся?

в моём примере они вкомпилины в проект.

Universe 15.10.2011 13:00

To GBee: не, так тоже не прокатывает - выдаёт ошибку
[Fault] exception, information=ArgumentError: Error #1508: Указано недопустимое значение для аргумента font.

fish_r 15.10.2011 14:17

Кто то из ребят писал: делают swc-ку со шрифтами (при чем уже с набором нужных глифов), потом в проекте нужный подключают - никаких головных болей (и лишнего веса). Я это редко юзаю ибо с ИДЕ работаю, мне проще через иде - лентяй :)

in4core 15.10.2011 14:24

Цитата:

Кто то из ребят писал: делают swc-ку со шрифтами
Так в IDE и делают.

Так к слову, после подключения swc

Код AS3:

public class EventsController extends EventDispatcher implements IEventDispatcher
        {
                private static var _ed:EventDispatcher;
 
                private var _myriad:Font                                        = new Myriad_font as Font;
                private var _arial_bold:Font                                = new Arial_bold as Font;


dimarik 15.10.2011 14:30

Шрифты можно использовать без регистрации. Они будут доступны в том ApplicationDomain, куда загружены. Во флекс вовсе не используется механизм Font.registerFont(), потому что после этого невозможно выгрузить swf, содержащий этот шрифт. Вместо этого ввели понятие FontContext, который поддерживают все модули, созданные во флекс. Специальный билдер в модуле выдает UITextField или какой другой компонент, содержащий текст из своего контекста (ApplicationDomain). После этого в компоненте можно использовать embed fonts.

Статья.

GBee 15.10.2011 21:10

Цитата:

To GBee: не, так тоже не прокатывает - выдаёт ошибку
[Fault] exception, information=ArgumentError: Error #1508: Указано недопустимое значение для аргумента font.
А что такое Alba? Это точно шрифт? А не мувик какой-нить?

Wolsh 16.10.2011 01:03

dimarik, а можно поподробнее? У меня не получается без регистрации, даже если гружу в ApplicationDomain.currentDomain.
То есть вот так работает:
(SWF со шрифтом, Fonts это класс Документа)
Код AS3:

package  
{
        import flash.display.Sprite;
        import flash.text.Font;
 
        public class Fonts extends Sprite
        {
                [Embed(source='../lib/consola.ttf', fontName="consola")] public const CONSOLA:Class;
 
                public function Fonts()
                {
                        Font.registerFont(CONSOLA);
                }
        }
}

(загружающая SWF)
Код AS3:

package 
{
        import flash.display.Loader;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.net.URLRequest;
        import flash.system.ApplicationDomain;
        import flash.system.LoaderContext;
        import flash.text.Font;
        import flash.text.TextField;
        import flash.text.TextFormat;
 
        public class Main extends Sprite
        {
                public function Main():void
                {
                        var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
                        var loader:Loader = new Loader();
                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
                        loader.load(new URLRequest("consola.swf"), context);
                }
 
                private function onComplete(event:Event):void
                {
                        trace(Font.enumerateFonts()); // [object Fonts_CONSOLA]
                        var format:TextFormat = new TextFormat("consola", 16);
                        var txt:TextField = new TextField();
                        addChild(txt);
                        txt.embedFonts = true;
                        txt.defaultTextFormat = format;
                        txt.width = 400;
                        txt.text = "I'm your Consola Font!"
                }
        }
}

Это работает и без указания контекста лоадеру. Но вот без регистрации – никак))

Universe 16.10.2011 19:23

Цитата:

А что такое Alba? Это точно шрифт? А не мувик какой-нить?
Alba - да, это шрифт такой

что-то я в конец запутался!:)
Мне просто нужно создать в проекте выпадающий список в котором будет возможность выбрать шрифт для текстового поля. Шрифтов заказчик хочет порядка 100, поэтому боюсь как бы swf из-за этого не стал размером эдак 50 мб! Ещё и хочет чтобы потом их можно было убирать/добавлять через админку без перекомпиляции.(Делаю редактор футболок)
Как бы вы реализовали эту задачу? Чтобы шрифты не увеличивали объём проекта и чтобы их потом можно было заменять без перекомпиляции?
На счёт первого я думал что оптимальным вариантом будет создать для каждого шрифта отдельную флешку которую подгружать при клике в выпадающем списке. Но тут возникает некоторая проблема - смотрел примеры таких редакторов и там в выпадающем списке текст написан тем шрифтом который выбираешь, конечно можно просто проэмбедить нужные символы, а весь список уже загружать по одному как написал ранее, но может ещё какойто способ подскажете?
А по поводу без перекомпиляции - я пока вообще не представляю, можно ли это сделать?

Wolsh 16.10.2011 20:42

Нельзя. SWF вообще не содержит файл шрифта, когда Вы его внедряете. Компиллятор делает из файла (TTF например) особый ресурс в виде векторных картинок-глифов и минимальной информацией. Получить из свфки исходный шрифт как он был до компиляции невозможно – его уже нет. Другими словами, загрузить файл шрифта в скомпиленную свфку можно, но для плеера это не будет шрифтом, плеер не понимает форматы шрифта, даже device fonts отображает не плеер, а система. Плеер умеет работать только с тем внутренним форматом, который создает компилятор. Вывод - компилировать свфки с внедренным шрифтом придется. Другое дело, что это можно автоматизировать, создавая их на сервере с помощью РНР-модуля, так что заказчику останется лишь загружать шрифты через CMSку. Также РНР мог бы делать превьюшки с нужным текстом и регистрировать это все в XML (к примеру). Тогда в списке шрифтов Вы показываете превьюшки и по клику загружаете нужный SWF со шрифтом... Ну я так это вижу.

dimarik 17.10.2011 10:48

Wolsh, необходимо создавать текстовое поле в контексте Fonts.

Код AS3:

public class Fonts extends Sprite {
 
    public function createMethod(c:Class):Object {
        return new c();
    }
 
}

Код AS3:

public class Main extends Sprite {
 
    /**
    * Это обработчик Event.COMPLETE лоадера, загрузившего Fonts.swf
    */

    private function handler_loadComplete(event:Event):void {
        const li:LoaderInfo = event.target as LoaderInfo;
        const textField:TextField = (li.content as Object).createMethod(flash.text.TextField) as TextField;
        const textFormat:TextFormat = textField.defaultTextFormat;
        textFormat.font = "consola";
        textField.embedFonts = true;
        textField.defaultTextFormat = textFormat;
        textField.text = "Consola Font!";
    }
 
}


Aziz Zaynutdinoff 17.10.2011 11:51

Создавать объекты через метод другого класса… извращение какое-то

-De- 17.10.2011 13:02

Цитата:

Сообщение от Aziz Zaynutdinoff (Сообщение 1039784)
Создавать объекты через метод другого класса… извращение какое-то

Нормальная практика.
http://en.wikipedia.org/wiki/Factory_method_pattern

PS: правда когда в с++ детектор утечек памяти показывает в фабричный метод и нету стека, то приходится чесать репу %)

Wolsh 17.10.2011 13:10

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

dimarik 17.10.2011 13:31

Денискин утилитарный класс, который это позволяет.

Universe 18.10.2011 18:44

блин, что не делаю никак не работает!(((
пишет ошибку
Код:

[Fault] exception, information=ReferenceError: Error #1065: Переменная AsianGuy не определена.
после загрузки ролика!
хотя она там есть

Код AS3:

package 
{
        import flash.display.Sprite;
        import flash.events.Event;
 
        /**
        * ...
        * @author Andrey
        */

        public class Main extends Sprite
        {
                [Embed(source='../lib/fonts/Asian Guy.ttf', fontName = 'AsianGuy', mimeType = 'application/x-font-truetype', embedAsCFF = 'false')]
                public static var AsianGuy:Class;
 
                public function Main():void
                {
                        trace("Asian 123");
                }
        }
 
}

Добавлено через 38 минут
Wolsh, при использовании вашего способа у меня вылазит таже ошибка!

Wolsh 18.10.2011 19:44

Вложений: 1
Код AS3:

const li:LoaderInfo = event.target as LoaderInfo;
var c:Class = li.applicationDomain.getDefinition("Main_AsianGuy") as Class;
trace(c)

Только зачем Вам эти классы, я так и не понял.
Что Вы с ними делать-то будете, экземпляры создавать?))

Добавлено через 1 час 10 минут
Вот проект со способом от dimarika. И так шрифты отображаются, и классы по getDefinition выковыриваются, если очень хочется сделать регистрацию и юзать в родных текстфилдах.
Какие ошибки у Вас, я не могу телепатически узнать.
(если решите перекомпилить consola.swf, Вам придется добавить в папку lib/ 4 файла этого шрифта. Затем ставите галочку Always compile на класс FontsPack.as, компилите, удаляете старую consola.swf и переименовываете FontsLibrary2.swf в consola.swf. Переставляете Always compile обратно и компилите проект)

Universe 19.10.2011 15:25

Вложений: 1
спасибо за пример, Wolsh!
Сделал также как в примере, только со своим шрифтом, ошибок при компиляции не выдаёт, но и текст никакой не показывает когда textField.embedFonts = true;
Вот сам проект

Wolsh 19.10.2011 17:19

Пробел забыли:
Цитата:

fontFamily = 'Asian Guy',
но:
Цитата:

public const FONT_FAMILY:String = "AsianGuy";

Universe 20.10.2011 16:42

Вложений: 1
поменял, но всё равно не работает!:(

dimarik 20.10.2011 17:51

embedAsCFF="false"

Wolsh 20.10.2011 18:03

У меня работает после добавления пробела.
Я компилил в стареньком ФД со старым сдк, поэтому embedAsCFF не указывал. Вам бы стоило указать, тем более что флаг CFF Вы установили в тру))

Universe 20.10.2011 18:31

Цитата:

embedAsCFF
А на что вообще влияет этот параметр?

dimarik 20.10.2011 18:38

На новый DefineFont4 для flash.text.engine

Wolsh 20.10.2011 18:43

CFF это новый формат представления шрифта в SWF-файле. Он расширен, содержит гораздо больше данных для типографики, чем старый формат. Старый используется во flash.text.TextField, a CFF - в flash.text.engine.

Universe 20.10.2011 18:44

не знаю...поставил embedAsCFF = false, перекомпилил флешку со шрифтом, переименовал её, загрузил в основой проект...но всё по старому, как только ставлю embedFonts = true - текст исчезает!((((
Может я както компилю её не правильно? Делал всё как описал Wolsh!

Wolsh 20.10.2011 19:04

Вложений: 1
Но у меня то компилится)))

Universe 20.10.2011 20:33

Wolsh, а вы чтото меняли при компиляции? Просто не могу по коду отличий заметить

Добавлено через 15 минут
кстати, в своём первом примере вы использовали 4 разных шрифта Consola, а как определить есть ли в шрифте italic или bold?

dimarik 20.10.2011 21:28

Так что ли?
Код AS3:

[Embed(source="font.ttf"...blablabla)]
private static const ASIAN_GUY:Class;
 
const font:Font = new ASIAN_GUY();
font.fontStyle;
font.fontName;
font.fontType;


Psycho Tiger 20.10.2011 22:47

Код AS3:

private var const ASIAN_GUY:Class;

:}

Wolsh 20.10.2011 22:53

Цитата:

как определить есть ли в шрифте italic или bold?
В одном файле – одно начертание. Я конечно не суперзнаток темы, но во всяком случае ни разу не слышал/не встречал, чтобы в одном файле были разные стили.

smithy 21.10.2011 14:35

Можно делать так:
в Flash внедрить шрифты, экспортировать каждый по 2 раза, наследуя от mx.core.FontAsset и flash.text.Font, называя соответственно "MyFontFlex" и "MyFont"

Пытаемся зарегистрировать сначала один, в случае неудачи второй:
Код AS3:

var fontClass:Class;
var fontName:String= "MyFont";
var domain:ApplicationDomain= ...; // домен, в который загружена swf со шрифтами
 
fontClass = domain.getDefinition( fontName ) as Class;
 
try
{
        Font.registerFont( fontClass );
}
        // не удалось зарегистрировать
catch( error:Error )
{
        fontClass = domain.getDefinition( fontName + "Flex" ) as Class;
        try
        {
                Font.registerFont( fontClass );
        }
                // и тут не удалось зарегистрировать
        catch ( error:Error )
        {
 
        }
}

И если я все правильно помню, то если swf со шрифтами грузится локальной swfкой, то зарегистрируется шрифт MyFontFlex. В противном случае надо грузить swf со шрифтами с контекстом
Код AS3:

new LoaderContext( true, ApplicationDomain.currentDomain, SecurityDomain.currentDomain )

и тогда зарегистрируется MyFont.


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

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