Türkiye Online Medya Araştırması

İçeriğin rss beslemesi kullanımda değil Soru - Cevap Bölümü / Kategori: Programlama

17/03/2010 - 01:21:10 cevap (6) Okunma : 727 Bu yazıyı 0 kişi tuttu.

Combobox'ta fontları göstermek

etiketler : font

Merhaba arkadaşlar bir proje üzerinde uğraşıyorum fakat bir yerde takıldım.Combobox içinde bir klasör içindeki fontları göstermek istiyorum.Aynen şu linkte yapıldığı gibi.Birkaç araştırma yaptım fakat bir sonuç elde edemedim.Cevaplarınızı bekliyorum.

adres Safakizilkaya profilini göster
Safa kızılkaya 10.12.2009 06:01:17
En iyi cevap mı ?
Faydalı cevap

Label bileşenini genişleten özel bir CellRenderer sınıfı tanımlamanız ve bu Cellrenderer sınıfı aracılığı ile List bileşeninin içerdiği Label bileşeninin stilini her çağrıldığında yeniden formatlamanız gerekiyor.

Combobox, dropdown durumunda bir List bileşenini çalıştırır. List bileşeni ise satırları üretirken renderer olarak IcellRenderer arayüzünü implement eden bir sprite kullanır. DataProvider tarafından diyelim ki 3 nesne gönderilmişse; List bileşeni içerisinde bu sprite'ın 3 örneği alt alta dizilir. Kabaca durum böyle olduğuna göre, Sprite yerine Label bileşenini kullanmak ve bu bileşeni temel alan özel bir CellRenderer tanımlamak mantıklı olur.

Bu cellRenderer ise özgün bir TextFormat nesnesi içermelidir. TextFormat'ın font verisini ise Label her çağrıldığında değiştirebilmeliyiz. Bunu yapmanın en iyi yolu ise, Font nesnesini DataProvider aracılığı ile taşımaktan geçiyor. Çünkü DataProvider tarafından saklanan font nesnesine ICellRenderer arayüzünün "data" özelliği ile erişmek mümkün. Buna göre, eğer DataProvider'i bir for döngüsü içerisinde tanımlayıp font sınıflarımızı içeren bir array ile doldurursak istediğimizi elde etmiş oluruz. For döngüsü sona erdiğinde ComboBox'u besleyen DataProvider Arraydeki font sınıflarımızın tüm özelliklerini ICellRenderer arayüzüne servis edebilir hale gelecektir. Tabi tüm bunları yapabilmek için Flash uygulamamız bir Document Class ile çalışmalıdır. Bu Document Class kütüphanemizdeki font sınıflarımızı ya da sistemdeki fontları bir Array içerisine toplayacak, uygulamadaki bileşenleri sahneye ekleyecek ve bu bileşenlerin tanımlayacağımız CustomCellRenderer ile render edilmesini sağlayacak.

Kabaca manifestomuz bu.

Yeni bir Flash belgesi açın ve kütüphaneye bir ComboBox bileşeni ekleyin.

Eğer uygulamanın sadece belirli fontları combobox içerisinde görüntülemesini amaçlıyorsanız kütüphaneye bu fontları sınıf halinde ekleyin. (kütüphane'yi açın, sağ tıklayın, "new font" tıklayın, bir isim verin, "export for actionscript" seçin) Eğer combobox içerisinde işletim sistemindeki tüm fontları görüntülemek istiyorsanız bunu yapmanıza gerek yok.

Flash belgesinin Document Class'ını "Main" olarak belirleyin ( Window-->Properties-->Publish--> Class: Main)

Dosyayı kaydedin.

Artık Document Class'ımızı ve CustomCellRenderer sınıfımızı tanımlayabiliriz.

Main.as:


package {
    import fl.controls.TextInput;
    import fl.controls.ComboBox;
    import fl.data.DataProvider;
    import fl.events.ListEvent;
    import flash.display.Sprite;
    import flash.text.*;

    public class Main extends Sprite {

        public var _tf:TextInput;
        public function Main() {
            var dp:DataProvider = new DataProvider();
            var fonts:Array=Font.enumerateFonts(false);//set (true) to load device fonts
            fonts.sortOn("fontName", Array.CASEINSENSITIVE);

            var i:Number;
            trace(fonts.length);
            for (i=0; i<fonts.length; i++) {
                dp.addItem( { label:fonts[i].fontName, data:fonts[i] } );
            }
            _tf=new TextInput();
            var cb:ComboBox = new ComboBox();
            _tf.x=0;
            _tf.y=200;
            _tf.height=30;
            _tf.width=300;
            _tf.text="Lorem ipsum dolor sit amet, consectetur adipiscing elit."
            ;
            addChild(_tf);
            cb.move(10,10);
            cb.prompt="Select an Embedded Font";
            cb.width=200;
            cb.dropdown.rowHeight=30;
            cb.dropdown.setStyle('cellRenderer', CustomCellRenderer);

            cb.dataProvider=dp;
            addChild(cb);
            cb.dropdown.addEventListener(ListEvent.ITEM_CLICK,onclick);
        }
        public function onclick(event:ListEvent):void {
            var inputTextFormat:TextFormat=new TextFormat();
            inputTextFormat.font=event.item.data.fontName;
            inputTextFormat.size=20;
            _tf.setStyle('textFormat', inputTextFormat);
            _tf.setStyle("embedFonts", true);
        }
    }
}

Document Class'ımız bu şekilde. Kodu incelediğinizde sınıfımızın, kütüphanede bulunan font sınıflarımızı bir array içerisine topladığını, sonra bir for döngüsü ile bu fontları DataProvider içerisine atadığını, sahneyi düzenlediğini ve


cb.dropdown.setStyle('cellRenderer', CustomCellRenderer);

ifadesi ile birazdan oluşturacağımız CustomCellRenderer sınıfını ComboBox'umuzun dropdown özelliğine "setStyle" metodunu kullanarak tanımladığını göreceksiniz.

O halde CustomCellRenderer sınıfımızı tanımlayalım:

CustomCellRenderer.as


package {
    import fl.controls.Label;
    import fl.controls.listClasses.ICellRenderer;
    import fl.controls.listClasses.ListData;
    import flash.text.TextFormat;
    public class CustomCellRenderer extends Label implements ICellRenderer {
        private var _listData:ListData;
        private var _data:Object;
        private var _selected:Boolean;
        public function CustomCellRenderer() {
            super();
        }
        public function set listData(newListData:ListData):void {

            _listData=newListData;

            var myFormat:TextFormat = new TextFormat();
            myFormat.font=_data.data.fontName;
            myFormat.size=24;
            text=_data.data.fontName;

            textField.embedFonts=true
            ;
            setStyle("textFormat", myFormat);
            setStyle("embedFonts", true);
        }

        public function get listData():ListData {
            return _listData;
        }
        public function set data(newData:Object):void {

            _data=newData;
        }
        public function get data():Object {

            return _data;
        }
        public function set selected(sl:Boolean):void {

            _selected=sl;

        }
        public function get selected():Boolean {

            return _selected;
        }
        public function setMouseState(state:String):void {

        }

    }
}

CustomCellRenderer sınıfında ise şu satırlar önemli:


var myFormat:TextFormat = new TextFormat();
            myFormat.font=_data.data.fontName;
            myFormat.size=24;
            text=_data.data.fontName;
            setStyle("textFormat", myFormat);

Tanımladığımız TextFormat'ın


myFormat.font=_data.data.fontName;

ifadesi ile font bilgisini elde ettiğine dikkat edin. Girizgahta IcellRenderer arayüzünün data özellliği ile dataProvider'in data özelliğine erişebildiğimizi belirtmiştim. Buna göre:


myFormat.font=_data.data.fontName;

ifadesi şu şekilde çözümlenebilir:


myFormat Text formatının fontu=IcellRenderer arayüzünün data özelliği tarafından taşınan DataProvider nesnesi'nin içerdiği font ismi

Sınıflarımızı Flash dosyamızla aynı dizine kaydedip testMovie yaptığınızda Dropdown bileşeninin kütüphanemizdeki font sınıfları ile doldurulduğunu ve her satırın farklı fontla formatlandığını ve sahnedeki inputtext bileşenin içeriğinin de ComboBox'tan seçtiğimiz font tarafından formatlandığını göreceksiniz.

Örnek dosya ektedir

Ekli Dosyalar

Dosyalara ulaşabilmek için, üye iseniz giriş yapın, değilseniz üye olun.

  • loadembeddedfontstocombobox.rar
adres ssan_ozgun profilini göster
Özgün Sandal 10.12.2009 14:49:24
En iyi cevap mı ?

Hocam ders niteliğinde bir cevap olmuş çok teşekkür ederim.Peki bu fontları kütüphaneden değil de dışardaki bir klasör içinden nasıl alabiliriz aynı şekilde ;çünkü bir sürü font var ve hepsini kütüphaneye almak dosya boyutunu baya artıracaktır.

adres Safakizilkaya profilini göster
Safa kızılkaya 10.12.2009 21:07:36
En iyi cevap mı ?
Faydalı cevap

Rica ederim. windows/fonts klasörü dışında bir başka klasörden (örneğin: htdocs/fonts) flash uygulamasına font yüklemek mümkün. Daha önce hiç test etmedim ama ExternalInterface sınıfı ve ByteArray sınıfının birlikte kullanımı ile bu yapılabilir.

Sizin linklediğiniz örnekte ise büyük ihtimalle sunucuda yerleşik bulunan bir klasör içerisinden fontlar swf formatında Flash uygulamasına dahil ediliyor. Bunun böyle olduğunu Fontların Combobox içerisine kesintili bir biçimde yükleniyor olmasından çıkarmak mümkün.

Fontların swf formatında yüklenmesine dair bir örnek hazırlayayım.

adres ssan_ozgun profilini göster
Özgün Sandal 10.12.2009 21:13:16
En iyi cevap mı ?

Teşekkür ederim bekliyorum cevabınızı.

adres Safakizilkaya profilini göster
Safa kızılkaya 14.12.2009 02:45:49
En iyi cevap mı ?

Yanıt göndermem biraz uzun sürüyor; eskisi kadar boş vaktim ne yazık ki yok.

Herhangi bir swf kaynağından uygulama içerisine font yüklemek için öncelikle yüklemek istediğimiz fontların söz konusu swf kaynağına bir biçimde dahil edilmiş olması gerekir.

Geçmişte bunu shared library, ya da library Class ile yaparken, CS4 sürümü ile birlikte, Flex için tanımlanmış olan EMBED metadata'sını kullanabilmekteyiz. Ben de bu örnekte fontları metadata yöntemi ile swf içerisine dahil edeceğim. Buna göre, sistemimizde Flex kurulu olmalıdır. Flex kurulu değilse Flex SDK'sı ile de EMBED metadata'sını CS4 uygulamalarında kullanmak mümkün.

Önce, ana uygulama içerisinde kullancağımız fontları içeren fonts.fla dosyamızı oluşturalım.

Yeni bir Flash belgesi açın ve fonts.fla ismiyle kaydedin.

Actions panelini açın ve aşağıdaki kodu ekleyin.


[Embed(systemFont="Bebas", fontName="BEBAS", mimeType="application/x-font")]
var _bebas:Class;
Font.registerFont(_bebas);
[Embed(systemFont="Brody", fontName="BRODY", mimeType="application/x-font")]
var _brody:Class;
Font.registerFont(_brody);
[Embed(systemFont="hotshot", fontName="HOTSHOT", mimeType="application/x-font")]
var _hotshot:Class;
Font.registerFont(_hotshot);

Kodu incelediğinizde, 3 adet font sınıfı oluşturduğumuzu göreceksiniz.


[Embed(systemFont="Bebas", fontName="BEBAS", mimeType="application/x-font")]

buradaki


systemFont="Bebas"

ifadesi windows/fonts klasörü içerisinde bulunan Bebas isimli fontu işaret eder. Siz burada kendi sisteminizdeki fontu belirtmelisiniz.

Embed metadatası değişik tanımlar içerebilir. Ben sadece sytemfont, fontName ve mimetype tanımlarını aldım. fontweight, unicodeRange ve fontfamily gibi tanımları da eklemeniz mümkün. Ancak tüm bu tanımların yerli yerine oturabilmesi için, embed etmek istediğiniz fontun da bu direktifleri karşılaması gerekiyor. Örneğin, fontweight="bold" tanımının çalışabilmesi için siteminizde fontun Bold versiyonunun olması gerekiyor.

Dosyamızı swf formatında export etmek istediğimizde Flash bize EMBED metadasını kullanabilmek için Flex SDK'sının yolunu soracaktır. Eğer sistemimizde Flex kurulu ise bu yol tanımlı gelir. "update library" butonuna tıklamamız yeterli olur. Eğer Flex kurulu değilse Flex sdk'sı nı Adobe'nin sitesinden indirin, Flex.swc dosyasını bulun ve fonts.fla dosyasına Flex.swc'yi ekleyin. (Publish Settings-->Flash-->Settings-->LibraryPath-->Flex.swc dosyasının yolu)

Şimdi ise SWF formatındaki dosyalardan embed edilmiş tüm fontların binary datasını ByteArray sınıfını kullanarak ayıklayan ve yeniden font nesnesine dönüştüren FontLoader sınıfımızı tanımlayalım.

Rus ActionScript geliştiricisi Denis Kolyako tarafından yazılmış FontLoader sınıfı bunun için biçilmiş kaftan.

Yeni bir ActionScript belgesi oluşturalım:

FontLoader.as


/**
* FontLoader 2.2 by Denis Kolyako. June 13, 2008. Last update: June 25, 2009.
* Visit http://etcs.ru for documentation, updates and more free code.
*
* You may distribute this class freely, provided it is not modified in any way (including
* removing this header or changing the package path).
* 
*
* Please contact etc[at]mail.ru prior to distributing modified versions of this class.
*/
/**
 * The FontLoader class lets you load any swf movie (ver. 6 or later), which contains embedded fonts to use these fonts in your application.
 */

package  {
    import flash.display.Loader;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.HTTPStatusEvent;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;
    import flash.text.Font;
    import flash.utils.ByteArray;
    import flash.utils.Endian;
    import flash.events.ErrorEvent;

    [Event(name="complete", type="flash.events.Event")]
    [Event(name="open", type="flash.events.Event")]
    [Event(name="ioError", type="flash.events.IOErrorEvent")]
    [Event(name="verifyError", type="flash.events.IOErrorEvent")]
    [Event(name="httpStatus", type="flash.events.HTTPStatusEvent")]
    [Event(name="progress", type="flash.events.ProgressEvent")]
    [Event(name="securityError", type="flash.events.SecurityErrorEvent")]

    public class FontLoader extends EventDispatcher {

        /**
         * @private
         */
        private static const SWF_HEADER:ByteArray = new ByteArray();

        /**
         * @private
         */
        private static const CLASS_CODE:ByteArray = new ByteArray();

        /**
         * @private
         */
        private static const CLASS_NAME_PREFIX:String = 'Font$';

        /**
         * @private
         */
        private static const TAG_DO_ABC:uint = ((72 << 6) | 0x3F);

        /**
         * @private
         */
        private static const TAG_SYMBOL_CLASS:uint = ((76 << 6) | 0x3f);

        /**
         * @private
         */
        private static var _initialized:Boolean = false;

        /**
         * @private
         */
        private static function init():void {
            if (FontLoader._initialized) return;
            var ba:SWFByteArray = new SWFByteArray();
            ba.writeBytesFromString(
                '7800055F00000FA000000C01004411080000004302FFFFFFBF150B0000000100466F6E744C69620000' +
                'BF1461020000010000000010002E00000000191272752E657463732E7574696C733A466F6E7400432F' + 
                '55736572732F6574632F4465736B746F702F50726F6A656374732F466F6E744C6F616465724C69622F' + 
                '7372633B72752F657463732F7574696C733B466F6E742E61731772752E657463732E7574696C733A46' + 
                '6F6E742F466F6E74175B4F626A65637420466F6E7420666F6E744E616D653D2208666F6E744E616D65' + 
                '0D2220666F6E745374796C653D2209666F6E745374796C650C2220666F6E74547970653D2208666F6E' + 
                '745479706502225D1B72752E657463732E7574696C733A466F6E742F746F537472696E670653747269' + 
                '6E6708746F537472696E67175F5F676F5F746F5F646566696E6974696F6E5F68656C700466696C6543' + 
                '2F55736572732F6574632F4465736B746F702F50726F6A656374732F466F6E744C6F616465724C6962' + 
                '2F7372632F72752F657463732F7574696C732F466F6E742E617303706F73033636380D72752E657463' + 
                '732E7574696C7304466F6E740A666C6173682E74657874064F626A6563740335373006050116021614' + 
                '161618010201030A07020607020807020A07020D07020E070315070415091501070217040000020000' + 
                '00040000040C0000000200020F02101211130F02101211180106070905000101054100020100000001' + 
                '030106440000010104000101040503D03047000001010105060EF103F018D030F019D04900F01A4700' + 
                '00020201050620F103F01CD0302C05F01DD00401A02C07A0D00402A02C09A0D00403A02C0BA0480000' + 
                '030201010421D030F103F0165D085D096609305D076607305D07660758001D1D6806F103F00B470000'
            ); // Magic bytes :-)
            ba.position = 0;
            ba.readBytes(FontLoader.SWF_HEADER);
            ba.length = 0;
            ba.writeBytesFromString(
                '392F55736572732F6574632F4465736B746F702F50726F6A656374732F466F6E744C6F616465724C69' + 
                '622F7372633B3B466F6E743030302E61730568656C6C6F2B48656C6C6F2C20776F726C642120497320' + 
                '616E79626F647920686572653F2057686F27732074686572653F0F466F6E743030302F466F6E743030' + 
                '300D72752E657463732E7574696C7304466F6E74064F626A6563740A666C6173682E74657874175F5F' + 
                '676F5F746F5F646566696E6974696F6E5F68656C700466696C65382F55736572732F6574632F446573' + 
                '6B746F702F50726F6A656374732F466F6E744C6F616465724C69622F7372632F466F6E743030302E61' + 
                '7303706F73023534060501160216071801160A00050702010703080702090705080300000200000006' + 
                '0000000200010B020C0E0D0F0101020904000100000001020101440100010003000101050603D03047' + 
                '0000010102060719F103F006D030EF01040008F007D049002C05F00885D5F009470000020201010527' + 
                'D030F103F00465005D036603305D046604305D026602305D02660258001D1D1D6801F103F002470000'
            ); // Another magic bytes :-)
            ba.position = 0;
            ba.readBytes(FontLoader.CLASS_CODE);
            ba.length = 0;
            FontLoader._initialized = true;
        }

        /**
         * Creates a new FontLoader object. If you pass a valid URLRequest object to the FontLoader constructor,
         * the constructor automatically calls the load() function.
         * If you do not pass a valid URLRequest object to the FontLoader constructor,
         * you must call the load() function or the stream will not load. 
         * 
         * @param request (default = null) — The URL that points to an external SWF file. 
         * @param autoRegister — Register loaded fonts automatically.
         */
        public function FontLoader(request:URLRequest = null, autoRegister:Boolean = true) {
            super();
            FontLoader.init();
            this._loader.dataFormat = URLLoaderDataFormat.BINARY;
            this._loader.addEventListener(Event.COMPLETE,                         this.handler_complete);
            this._loader.addEventListener(Event.OPEN,                             super.dispatchEvent);
            this._loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,             super.dispatchEvent);
            this._loader.addEventListener(IOErrorEvent.IO_ERROR,                 super.dispatchEvent);
            this._loader.addEventListener(ProgressEvent.PROGRESS,                 super.dispatchEvent);
            this._loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,     super.dispatchEvent);
            if (request) this.load(request, autoRegister);
        }

        /**
         * @private
         */
        private const _loader:URLLoader = new URLLoader();

        /**
         * @private
         */
        private var _bytes:ByteArray;

        /**
         * @private
         */
        private var _libLoader:Loader;

        /**
         * @private
         */
        private var _fontCount:uint;

        /**
         * @private
         */
        private var _autoRegister:Boolean = true;

        /**
         * Sets automatic font registration.
         */
        public function set autoRegister(value:Boolean):void {
            if (this._autoRegister == value) return;
            this._autoRegister = value;
            if (value) this.registerFonts();
        }

        public function get autoRegister():Boolean {
            return this._autoRegister;
        }

        public function get bytesLoaded():uint {
            return this._loader.bytesLoaded;
        }

        public function get bytesTotal():uint {
            return this._loader.bytesTotal;
        }

        /**
         * @private
         */
        private const _fonts:Array = new Array();

        /**
         * Returns an array of font classes, which you can use to register any extracted font.
         */
        public function get fonts():Array {
            return this._fonts.concat();
        }

        /**
         * Initiates loading of an external SWF file from the specified URL. You can load another swf file, when previous operation completed (or stream closed by user).
         * 
         * @param request:URLRequest — A URLRequest object specifying the URL to download. If the value of this parameter or the URLRequest.url property of the URLRequest object passed are null, Flash Player throws a null pointer error.  
         * @param autoRegister — Register loaded fonts automatically.
          * 
         * @event complete:Event — Dispatched after data has loaded and parsed successfully.
         * @event httpStatus:HTTPStatusEvent — If access is by HTTP, and the current Flash Player environment supports obtaining status codes, you may receive these events in addition to any complete or error event.
         * @event ioError:IOErrorEvent — The load operation could not be completed.
         * @event verifyError:IOErrorEvent — Dispatched when a parse operation fails (data has incorrect format).
         * @event open:Event — Dispatched when a load operation starts.
         * @event securityError:SecurityErrorEvent — A load operation attempted to retrieve data from a server outside the caller's security sandbox. This may be worked around using a policy file on the server. 
         */
        public function load(request:URLRequest, autoRegister:Boolean = true):void {
            this.close();
            this._fonts.length = 0;
            this._fontCount = 0;
            this._autoRegister = autoRegister;
            this._loader.load(request);
        }

        /**
         * Loads from binary data stored in a ByteArray object.
         * 
         * @param bytes:URLRequest — A ByteArray object. The specified ByteArray must contain valid SWF file. 
         * @param autoRegister — Register loaded fonts automatically.
          * 
         * @event complete:Event — Dispatched after data has loaded and parsed successfully.
         * @event httpStatus:HTTPStatusEvent — If access is by HTTP, and the current Flash Player environment supports obtaining status codes, you may receive these events in addition to any complete or error event.
         * @event ioError:IOErrorEvent — The load operation could not be completed.
         * @event verifyError:IOErrorEvent — Dispatched when a parse operation fails (data has incorrect format).
         * @event open:Event — Dispatched when a load operation starts.
         * @event securityError:SecurityErrorEvent — A load operation attempted to retrieve data from a server outside the caller's security sandbox. This may be worked around using a policy file on the server. 
         */
        public function loadBytes(bytes:ByteArray, autoRegister:Boolean = true):void {
            this.close();
            this._fonts.length = 0;
            this._fontCount = 0;
            this._autoRegister = autoRegister;
            this.analyze(bytes, true);
        }

        /**
         * Closes the stream, causing any download of data to cease.
         */
        public function close():void {
            try {
                this._loader.close();
            } catch (error:Error) {}

            if (this._libLoader) {
                this._libLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, this.handler_libComplete);

                try {
                    this._libLoader.close();
                } catch (error:Error) {}

                try {
                    this._libLoader.unload();
                } catch (error:Error) {}

                this._libLoader = null;
            }
        }

        /**
         * Registers all loaded fonts.
         */        
        public function registerFonts():void {
            for each (var font:Font in this._fonts) {
                Font.registerFont((font as Object).constructor);
            }
        }

        /**
         * @private
         */
        private function analyze(bytes:ByteArray, delayed:Boolean = false):void {
            var o:Object;
            var stringID:String;
            var id:uint;
            var fontID:uint;
            var tag:uint
            var length:uint;
            var pos:Number;
            var tempData:ByteArray;
            var fontSWF:ByteArray;
            var context:LoaderContext;
            var data:ByteArray;

            try {
                data = new SWFByteArray(bytes);
            } catch (error:Error) {
                if (delayed) {
                    this._libLoader = new Loader();
                    this._libLoader.addEventListener(Event.ENTER_FRAME, this.handler_delayedVerifyError);
                } else {
                    this.close();
                    super.dispatchEvent(new IOErrorEvent(IOErrorEvent.VERIFY_ERROR));
                }

                return;
            }

            var fontData:Object = new Object();
            var classCodeLength:uint = FontLoader.CLASS_CODE.length;

            while (data.bytesAvailable) {
                tag = data.readUnsignedShort();
                id = tag >> 6;
                length = ((tag & 0x3F) == 0x3F) ? data.readUnsignedInt() : (tag & 0x3F);
                pos = data.position;

                switch (id) {
                    case 13:
                    case 48:
                    case 62:
                    case 73:
                    case 75:
                    case 88:
                        fontID = data.readUnsignedShort();
                        tempData = fontData[fontID] as ByteArray;

                        if (!tempData) {
                            tempData = new ByteArray();
                            tempData.endian = Endian.LITTLE_ENDIAN;
                            fontData[fontID] = tempData;
                        }

                        if ((tag & 0x3F) == 0x3F) {
                            tempData.writeShort((id << 6) | 0x3F);
                            tempData.writeUnsignedInt(length);
                        } else {
                            tempData.writeShort((id << 6) | (length & 0x3F));
                        }

                        tempData.writeShort(fontID);
                        tempData.writeBytes(data, data.position, length - 2);
                    break;
                }

                data.position = pos + length;
            }

            tempData = new ByteArray();
            tempData.endian = Endian.LITTLE_ENDIAN;
            tempData.writeBytes(FontLoader.SWF_HEADER);
            id = 0;

            for (o in fontData) {
                data = fontData[o] as ByteArray;

                if (data) {
                    stringID = id.toString();
                    while (stringID.length < 3) stringID = '0' + stringID;
                    stringID = FontLoader.CLASS_NAME_PREFIX + stringID;
                    tempData.writeShort(FontLoader.TAG_DO_ABC);
                    tempData.writeUnsignedInt(10 + stringID.length + classCodeLength);
                    tempData.writeUnsignedInt(0x002E0010);
                    tempData.writeUnsignedInt(0x10000000);
                    tempData.writeByte(stringID.length);
                    tempData.writeUTFBytes(stringID);
                    tempData.writeByte(0);
                    tempData.writeBytes(FontLoader.CLASS_CODE);
                    tempData.writeBytes(data);
                    tempData.writeShort(FontLoader.TAG_SYMBOL_CLASS);
                    tempData.writeUnsignedInt(5 + stringID.length);
                    tempData.writeShort(1);
                    tempData.writeShort(o as uint);
                    tempData.writeUTFBytes(stringID);
                    tempData.writeByte(0);
                    id++;
                }
            }

            this._fontCount = id;

            if (this._fontCount) {
                tempData.writeUnsignedInt(0x00000040);
                fontSWF = new ByteArray();
                fontSWF.endian = Endian.LITTLE_ENDIAN;
                fontSWF.writeUTFBytes('FWS');
                fontSWF.writeByte(9);
                fontSWF.writeUnsignedInt(tempData.length + 8);
                fontSWF.writeBytes(tempData);
                this._libLoader = new Loader();
                this._libLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.handler_libComplete);
                context = new LoaderContext();

                if ('allowLoadBytesCodeExecution' in context) { // AIR compatibility
                    context['allowLoadBytesCodeExecution'] = true;
                }

                this._libLoader.loadBytes(fontSWF, context);
            } else {
                if (delayed) {
                    this._libLoader = new Loader();
                    this._libLoader.addEventListener(Event.ENTER_FRAME, this.handler_delayedComplete);
                } else {
                    this.close();
                    super.dispatchEvent(new Event(Event.COMPLETE));
                }
            }            
        }

        /**
         * @private
         */
        private function handler_delayedComplete(event:Event):void {
            this._libLoader.removeEventListener(Event.ENTER_FRAME, this.handler_delayedComplete);
            this._libLoader = null;
            this.close();
            super.dispatchEvent(new Event(Event.COMPLETE));
        }

        /**
         * @private
         */
        private function handler_delayedVerifyError(event:Event):void {
            this._libLoader.removeEventListener(Event.ENTER_FRAME, this.handler_delayedVerifyError);
            this._libLoader = null;
            this.close();
            super.dispatchEvent(new IOErrorEvent(IOErrorEvent.VERIFY_ERROR));
        }

        /**
         * @private
         */
        private function handler_complete(event:Event):void {
            this.analyze(this._loader.data as ByteArray);
        }

        /**
         * @private
         */
        private function handler_libComplete(event:Event):void {
            var id:String;
            var i:uint;
            var fontClass:Class;
            var font:Font;
            var domain:ApplicationDomain = this._libLoader.contentLoaderInfo.applicationDomain;

            for (i = 0;i < this._fontCount;i++) {
                id = i.toString();
                while (id.length < 3) id = '0' + id;
                id = FontLoader.CLASS_NAME_PREFIX + id;

                if (domain.hasDefinition(id)) {
                    fontClass = domain.getDefinition(id) as Class;
                    font = new fontClass() as Font;

                    if (font && font.fontName) { // Skip static fonts
                        this._fonts.push(font);
                        if (this._autoRegister) Font.registerFont(fontClass);
                    }
                }
            }

            this.close();
            super.dispatchEvent(new Event(Event.COMPLETE));
        }
    }
}

import flash.utils.ByteArray;
import flash.utils.Endian;
import flash.geom.Rectangle;

internal class SWFByteArray extends ByteArray {

    /**
     * @private
     */
    private static const TAG_SWF:String = 'FWS';

    /**
     * @private
     */
    private static const TAG_SWF_COMPRESSED:String = 'CWS';

    public function SWFByteArray(data:ByteArray=null):void {
        super();
        super.endian = Endian.LITTLE_ENDIAN;
        var endian:String;
        var tag:String;
        var position:uint;

        if (data) {
            endian = data.endian;
            position = data.position;
            data.endian = Endian.LITTLE_ENDIAN;
            data.position = 0;

            if (data.bytesAvailable > 26) {
                tag = data.readUTFBytes(3);

                if (tag == SWFByteArray.TAG_SWF || tag == SWFByteArray.TAG_SWF_COMPRESSED) {
                    this._version = data.readUnsignedByte();
                    data.readUnsignedInt();
                    data.readBytes(this);
                    if (tag == SWFByteArray.TAG_SWF_COMPRESSED) super.uncompress();
                } else throw new ArgumentError('Error #2124: Loaded file is an unknown type.');

                this.readHeader();
            } else {
                throw new ArgumentError('Insufficient data.');
            }

            data.endian = endian;
            data.position = position;
        }
    }

    /**
     * @private
     */
    private var _bitIndex:uint;

    /**
     * @private
     */
    private var _version:uint;

    public function get version():uint {
        return this._version;
    }

    /**
     * @private
     */
    private var _frameRate:Number;

    public function get frameRate():Number {
        return this._frameRate;    
    }

    /**
     * @private
     */
    private var _rect:Rectangle;

    public function get rect():Rectangle {
        return this._rect;
    }

    public function writeBytesFromString(bytesHexString:String):void {
        var length:uint = bytesHexString.length;

        for (var i:uint = 0;i<length;i += 2) {
            var hexByte:String = bytesHexString.substr(i, 2);
            var byte:uint = parseInt(hexByte, 16);
            writeByte(byte);
        }
    }

    public function readRect():Rectangle {
        var pos:uint = super.position;
        var byte:uint = this[pos];
        var bits:uint = byte >> 3;
        var xMin:Number = this.readBits(bits, 5) / 20;
        var xMax:Number = this.readBits(bits) / 20;
        var yMin:Number = this.readBits(bits) / 20;
        var yMax:Number = this.readBits(bits) / 20;
        super.position = pos + Math.ceil(((bits * 4) - 3) / 8) + 1;
        return new Rectangle(xMin, yMin, xMax - xMin, yMax - yMin);
    }

    public function readBits(length:uint, start:int = -1):Number {
        if (start < 0) start = this._bitIndex;
        this._bitIndex = start;
        var byte:uint = this[super.position];
        var out:Number = 0;
        var shift:Number = 0;
        var currentByteBitsLeft:uint = 8 - start;
        var bitsLeft:Number = length - currentByteBitsLeft;

        if (bitsLeft > 0) {
            super.position++;
            out = this.readBits(bitsLeft, 0) | ((byte & ((1 << currentByteBitsLeft) - 1)) << (bitsLeft));
        } else {
            out = (byte >> (8 - length - start)) & ((1 << length) - 1);
            this._bitIndex = (start + length) % 8;
            if (start + length > 7) super.position++;
        }

        return out;
    }

    public function traceArray(array:ByteArray):String { // for debug
        var out:String = '';
        var pos:uint = array.position;
        var i:uint = 0;
        array.position = 0;

        while (array.bytesAvailable) {
            var str:String = array.readUnsignedByte().toString(16).toUpperCase();
            str = str.length < 2 ? '0'+str : str;
            out += str+' ';
        }

        array.position = pos;
        return out;
    }

    /**
     * @private
     */
    private function readFrameRate():void {
        if (this._version < 8) {
            this._frameRate = super.readUnsignedShort();
        } else {
            var fixed:Number = super.readUnsignedByte()/0xFF;
            this._frameRate = super.readUnsignedByte() + fixed;
        }
    }

    /**
     * @private
     */
    private function readHeader():void {
        this._rect = this.readRect();
        this.readFrameRate();        
        super.readShort(); // num of frames
    }
}

Sınıf, bir dizi byteArray direktifi ve bu direktiflerin sonuçlarına göre elde edilmiş font verisinin çözümleyen bloklardan oluşuyor. Epey uzun olduğu için satırları burada çözümlemek istemem:)

Bu sınıfı da kaydettikten sonra Flash uygulamamızı çalıştıracak olan Document Class'ı tanımlayalım:

Main.as


package {
    import fl.controls.TextInput;
    import fl.controls.ComboBox;
    import fl.data.DataProvider;
    import flash.events.Event;
    import fl.events.ListEvent;
    import flash.net.URLRequest;
    import flash.display.Sprite;
    import flash.text.*;
    import FontLoader;
    public class Main extends Sprite {

        public var dp:DataProvider=new DataProvider();
        private const _loader:FontLoader = new FontLoader();
        private const _tf:TextInput= new TextInput();
        private const cb:ComboBox = new ComboBox();
        public function Main() {
            _loader.addEventListener(Event.COMPLETE, this.handler_complete);
            _loader.load(new URLRequest('fonts.swf'));
        }
        private function handler_complete(event:Event):void {

            var fonts:Array=_loader.fonts;
            for (var i:Number=0; i<fonts.length; i++) {
                dp.addItem( { label:fonts[i].fontName, data:fonts[i] } );

                _tf.x=0;
                _tf.y=200;
                _tf.height=30;
                _tf.width=300;
                _tf.text="Lorem Ipsum Dolor Sit Amet.,?!";
                addChild(_tf);
                cb.move(10,10);
                cb.prompt="";
                cb.width=200;
                cb.dropdown.rowHeight=30;
                cb.dropdown.setStyle('cellRenderer', CustomCellRenderer);
                cb.dataProvider=dp;
                addChild(cb);
                cb.dropdown.addEventListener(ListEvent.ITEM_CLICK,onclick);

            }
        }
        public function onclick(event:ListEvent):void {
            var inputTextFormat:TextFormat=new TextFormat();
            inputTextFormat.font=event.item.data.fontName;
            inputTextFormat.size=20;
            _tf.setStyle('textFormat', inputTextFormat);
            _tf.setStyle("embedFonts", true);
            event.item.label=event.item.data.fontName;

        }
    }
}

Bir önceki örneğimizi çalıştıran Document Class ile oldukça benzer bir yapısı var. Yalnızca font kaynağımızın değiştiğini söyleyebilirim. Daha önce fontlar uygulama içerisinde gömülü olduğu için "enumarateFonts" direktifini kullanıyorduk; şimdi ise fontlar bir başka swf içerisinde bulunduğu için bu fontları FontLoader sınıfı aracılığı ile uygulamaya dahil ediyoruz. Loader olarak yerleşik Loader sınıfı yerine FontLoader sınıfını kullandığımıza dikkat edin.

Yeni bir Flash uygulaması açın. Kütüphaneye bir adet Combobox ve bir adet textInput bileşeni ekleyin, Uygulamanın Document Class'ını "Main" olarak belirleyin ve bir isim vererek diğer dosyalarımızla aynı dizine kaydedin.

Uygulamayı test ettiğinizde fonts.swf içerisinde bulunan fontların combobox içerisinde kendi fontlarıyla görüntülendiğini ve textInput'ta yazılı metnin fontunun da seçimimize bağlı olarak değiştiğini göreceksiniz.

Denis Kolyako'nun herhangi bir swf kaynağından embed edilmiş fontları ayıklayan uygulamasına şu linkten erişebilirsiniz: FontLoader

Örnek dosya ektedir.

Ekli Dosyalar

Dosyalara ulaşabilmek için, üye iseniz giriş yapın, değilseniz üye olun.

  • loadexternalfontstocombobox.rar
adres ssan_ozgun profilini göster
Özgün Sandal 14.12.2009 13:45:18
En iyi cevap mı ?

Çok teşekkür ederim hocam yardımlarınız için.Elinize sağlık konu ayrı bir derleme oldu =) Kolay gelsin.

aç-kapa Bu Yazıyı Tutanlar

bu yazıyı tutan kimse yok.

yeni üyelik | şifremi unuttum

aç-kapa Toplantı Özgür Yazılım ve Linux Günleri '10

Özgür Yazılım ve Linux Günleri '10

İstanbul Bilgi Üniversitesi Bilgisayar Bilimleri Bölümü ve Linux Kullanıcıları Derneği'nin 9 yıldır düzenlemekte oldukları etkinlikler bu yıl `Özgür Y...
Kategori: Toplantı

aç-kapa Yarışma 3. Uluslararası Ekslibris Yarışması: İstanbul 2010

3. Uluslararası Ekslibris Yarışması: İstanbul 2010

İstanbul Ekslibris Dernegi, Feyziye Mektepleri Vakfı ve Işık Üniversitesi, kitaplar için mülkiyet işareti olarak kabul edilen ve üzerinde estetik dege...
Kategori: Yarışma

aç-kapa Konferans Yeni Medya ve Etkileşim Konferansı 2010 - Marmara Üniversitesi

Yeni Medya ve Etkileşim Konferansı 2010 - Marmara Üniversitesi

Generally speaking, the term "New" brought about debates. We try to open up and elucidate the term "New" along with "Interact...
Kategori: Konferans

aç-kapa Konferans 3. Uluslararası Gelecek İçin Öğrenme Alanında Yenilikler Konferansı 2010: e-Öğrenme

3. Uluslararası Gelecek İçin Öğrenme Alanında Yenilikler Konferansı 2010: e-Öğrenme

Konferans ile ilgili ayrıntılı bilgiye aşağıdaki bağlantıdan ulaşabilirsiniz: http://www.futurelearning.org.tr/katilim_cagrisitr.pdf ...
Kategori: Konferans

üyeler Son Kahramanlar...

stats Kimler Burada? web stats

Son 1 dakika içinde MMIstanbul' da 51 (50 kayıtlı, 1 ziyaretçi) kullanıcı varmış. Login durumda olanlar aşağıda:

...

Blog Bölümü Blogevi.com'a Taşınıyor

Selam arkadaşlar MMIstanbul'da , tasarımcı ve programcıların blog yazılarını "feedleyerek" MMIstanbul okurlarını MMIstanbul dışın ...

7.500'üncü üyemiz Cem Koç!

Neler Yapılabilir?

500 Hatası Hakkında!

Reklam, MMIstanbul ve Yeni Projeler (Durumumuz Bu Tarzında)

coldfusion mysql ubuntu
 
sponsor adobe istanbul