sfont090706.rar



2.0에서 꽤 까다로웠던 기술인 런타임 폰트 공유(참고 URL)를 3.0에 와서는 훨씬 간단하게 구사할 수 있게 되었다.

 

그를 이용해 일반적인 Loader처럼 폰트 로드/공유할 수 있도록 만든 클래스가 SFont이다.

 

(내부적으로 (link)SLoader를 이용하므로 참고)

 

(참조 블로그 : http://blog.jidolstar.com/468)



- 사용법 : 폰트.swf의 파일경로와 라이브러리의 Font Class를 이용해 로드 후 .name 속성으로 폰트의 이름을 TextFormat에 적용하면된다.

import com.showjean.net.*;
import flash.net.*;
 
var sl:SFont = new SFont();
sl.addEventListener(Event.COMPLETE,completeHandler);
sl.addEventListener(IOErrorEvent.IO_ERROR,__eventHandler);
sl.addEventListener(ProgressEvent.PROGRESS, progressHandler);
sl.load("assets/kroe0554.swf", "kroeger05_54");
 
 
function completeHandler(event:Event):void {
        trace(event);
 
        var tf:TextFormat=txt.getTextFormat();
        var fn:String=sl.name;
        if (fn == null) {
        } else {
                tf.font=fn;
                txt.embedFonts=true;
                txt.defaultTextFormat=tf;
                txt.text="ABCDEFG12345 "+fn;
        }
}
 
function __eventHandler(event:Event):void {
        trace(event);
}
 
function progressHandler(event:ProgressEvent):void {
        trace("progressHandler: bytesLoaded=" + event.bytesLoaded + " bytesTotal=" + event.bytesTotal);
}


- 로드될 공유용 폰트.swf파일을 만드는 법

1. 새 fla파일을 생성하고 라이브러리 메뉴>new Font... 를 선택한다.

 

2. 공유할 폰트를 고르고 Name을 적당히 입력한다.



3. 폰트가 라이브러리에 등록되었다면 Linkage...를 선택한다.




4. Export for ActionScript와 Export in first frame 을 체크하고 Class에 사용할 이름을 넣는다.



5. 컴파일 후 swf파일을 적당한 위치에 놓는다.



- SFont.as : 유저가 사용하는 주클래스로 proxy의 성격을 띤다.

/**
 * SFont -
 *
 * @author: showjean in http://showjean.com/works, mobile , mailto:showjean@hanmail.net
 * @version: 1.0.0
 * @date: 2009.5.22.
 *
 * @comment: 유저가 사용하는 클래스, FontAsset의 proxy 성격을 가지고있다.
 */
package com.showjean.net{
 
        import flash.events.*;
 
        public class SFont extends EventDispatcher {
 
                protected var fontAsset:FontAsset;
 
                function SFont() {
                }
                // _____________________________________________________ public
                /**
                 * 폰트를 로드
                 * url: swf의 위치
                 * linkage: swf 라이브러리의 Font Class
                 */
                public function load(url:String,linkage:String):void {
                        if (fontAsset == null) {
 
                                fontAsset=FontAssetManager.getInstance().getFontAsset(url,linkage);
 
                                // 폰트가 이미 로드된 경우
                                if (fontAsset.isComplete()) {
 
                                        dispatchEvent(new Event(Event.COMPLETE));
 
                                        // 이미 로드에러인 경우
                                } else if (fontAsset.isError()) {
 
                                        dispatchEvent(new Event(IOErrorEvent.IO_ERROR));
 
                                } else {
 
                                        fontAsset.addEventListener(Event.OPEN,__eventHandler);
                                        fontAsset.addEventListener(Event.COMPLETE,__eventHandler);
                                        fontAsset.addEventListener(IOErrorEvent.IO_ERROR,__eventHandler);
                                        fontAsset.addEventListener(ProgressEvent.PROGRESS,__eventHandler);
                                        fontAsset.addEventListener(HTTPStatusEvent.HTTP_STATUS,__eventHandler);
 
                                }
                        }
                }
                /**
                 * 로드를 중지 또는 제거(등록된 폰트가 제거되지는 않는다)
                 */
                public function close():void {
                        dispose();                     
                        fontAsset=null;
                }
                /**
                 * 등록된 폰트의 이름을 반환
                 */
                public function get name():String {
                        return fontAsset ? fontAsset.name : null;
                }
                // _____________________________________________________ protected
                protected function dispose():void {
                        if (fontAsset) {
                                fontAsset.removeEventListener(Event.OPEN,__eventHandler);
                                fontAsset.removeEventListener(Event.COMPLETE,__eventHandler);
                                fontAsset.removeEventListener(IOErrorEvent.IO_ERROR,__eventHandler);
                                fontAsset.removeEventListener(ProgressEvent.PROGRESS,__eventHandler);
                                fontAsset.removeEventListener(HTTPStatusEvent.HTTP_STATUS,__eventHandler);
                                fontAsset.close();
                        }
                }
 
                // ____________________________________________________________ listener
                protected function __eventHandler(event:Event):void {
                        if (event.type == Event.COMPLETE || event.type == IOErrorEvent.IO_ERROR) {
                                dispose();
                        }
                        dispatchEvent(event);
                }
        }
}



- FontAsset : 폰트를 로드, 정보를 저장하는 클래스

/**
 * FontAsset -
 *
 * @author: showjean in http://showjean.com/works, mobile , mailto:showjean@hanmail.net
 * @version: 1.1.1
 * @date: 2009.7.6.
 *
 * @comment: FontAssetManager에서 생성되는 클래스로, font.swf파일을 로드하고 fontname까지 저장하고 있는다.
 */
package com.showjean.net{
 
        import flash.display.*;
        import flash.events.*;
        import flash.system.*;
        import flash.text.*;
        import flash.net.*;
        import flash.utils.*;
 
        public class FontAsset extends EventDispatcher {
 
                protected var __linkage:String;
                protected var __name:String;
                protected var loader:Loader;
 
                function FontAsset() {
                }
                // _____________________________________________________ public
                /**
                 * url: swf의 위치
                 * linkage: swf 라이브러리의 Font Class
                 *
                 * >다른 도메인의 폰트.swf를 로드해 올경우 LoaderContext를 설정한다
                 * >crossdomain.xml이 설정되어 있어야한다.
                 */
                public function load(url:String, linkage:String):void {
                        __linkage = linkage;
                        loader = new SLoader();
 
                        // LoaderContext
                        var context:LoaderContext=new LoaderContext();
                        context.checkPolicyFile=true;
                        context.applicationDomain = ApplicationDomain.currentDomain;
 
                        // 로컬에서 작동하지 않게
                        if ( Security.sandboxType == Security.REMOTE ) {
                                context.securityDomain=SecurityDomain.currentDomain;
                        }
 
                        loader.contentLoaderInfo.addEventListener(Event.OPEN,__completeHandler);
                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE,__completeHandler);
                        loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,__completeHandler);
                        loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,__completeHandler);
                        loader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, __completeHandler);
 
                        loader.load(new URLRequest(url), context);
                }
                /**
                 * 로드를 중지 또는 제거(등록된 폰트가 제거되지는 않는다)
                 */
                public function close():void {
                        dispose();
                }
                /**
                 * 등록된 폰트의 이름을 반환
                 */
                public function get name():String {
                        return __name;
                }
                /**
                 * 폰트로드가 완료되었는지 확인
                 */
                protected var _isComplete:Boolean = false;
                public function isComplete():Boolean {
                        return _isComplete;
                }
                /**
                 * 폰트로드가 실패했는지 확인
                 */
                protected var _isError:Boolean = false;
                public function isError():Boolean {
                        return _isError;
                }
                // _____________________________________________________ protected
                protected function dispose():void {
                        if (loader) {
                                loader.contentLoaderInfo.removeEventListener(Event.OPEN,__completeHandler);
                                loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,__completeHandler);
                                loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,__completeHandler);
                                loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,__completeHandler);
                                loader.contentLoaderInfo.removeEventListener(HTTPStatusEvent.HTTP_STATUS, __completeHandler);
 
                                // 폰트를 등록한 후에는 swf파일이 필요없다.
                                try {
                                        if (loader.content) {
                                                loader.unload();
                                        } else {
                                                loader.close();
                                        }
                                } catch (error:Error) {
                                        trace(this, error);
                                }
                                loader = null;
                                prevFontArr = null;
                                //trace(this, "dispose......");
                        }
                }
                protected function getIndexByName(font:Font):int{
                        for (var i:int = 0; i < prevFontArr.length; ++i) {
                                var item:Font = prevFontArr[i] as Font;
                                if (item.fontName == font.fontName) {
                                        return i;                                      
                                }       
                        }
                        return -1;
                }
                // ____________________________________________________________ listener
                protected var prevFontArr:Array
                protected function __completeHandler(event:Event):void {
                        if (event.type == Event.OPEN) {
                               
                                prevFontArr = Font.enumerateFonts(false);
                               
                        } else if (event.type == Event.COMPLETE) {
                                try {
                                       
                                        var className:String = getQualifiedClassName( loader.content );
                                        // flash에서 new Font로 라이브러리에 등록한 파일일 경우.
                                        if (className == "flash.display::MovieClip") {
                                                var fontclass:Class = loader.contentLoaderInfo.applicationDomain.getDefinition(__linkage)  as  Class;
                                                Font.registerFont(fontclass);
                                        } else {
                                                // flex sdk로 폰트를 임베드한 파일일 경우(unicodeRange로 캐릭터 범위를 지정할 수 있다)
                                                // 자동 등록되므로 아무것도 하지 않는다.
                                        }
                                       
                                        // 때에 따라서 배열의 앞쪽 또는 뒤쪽으로 추가되어서 어느쪽으로 추가되었는지 판별
                                        var arr:Array = Font.enumerateFonts(false);
                                       
                                        // 텍스트필드에 수동으로 임베드한 폰트들이 indexOf연산에 -1이 반환되어서 제대로 작동하지 않음
                                        /*for each(var font:Font in arr) {
                                                if (prevFontArr.indexOf(font) == -1) {
                                                        __name = font.fontName;
                                                        break;
                                                }
                                        }*/
                                        for each(var font:Font in arr) {
                                                if (getIndexByName(font) == -1) {
                                                        __name = font.fontName;
                                                        break;
                                                }
                                        }
                                        trace(this, "added font name: ", __name);
 
                                } catch (e:Error) {
                                        trace(this, "error - Font.registerFont............ ", e.toString());
                                        // 폰트 등록 에러일경우 다시 등록하거나, 폰트가 포함되지 않은 swf파일
                                }
                                _isComplete = true;
                                dispose();
 
                        } else if (event.type == IOErrorEvent.IO_ERROR) {
                                _isError = true;
                                dispose();
                        }
 
                        dispatchEvent(event);
                }
        }
}



- FontAssetManager : FontAsset을 관리하는 싱글톤 클래스

/**
 * FontAssetManager -
 *
 * @author: showjean in http://showjean.com/works, mobile , mailto:showjean@hanmail.net
 * @version: 1.0.0
 * @date: 2009.5.22.
 *
 * @comment: SFont에서 이용하는 싱글톤 클래스로, FontAsset이 중복 생성되지 않도록 관리한다.
 */
package com.showjean.net{
 
        public class FontAssetManager {
 
                private static  var instance:FontAssetManager;
 
                protected var _fontsObject:Object=new Object();
 
                // _____________________________________________________ singleton
                /**
                 * 싱글톤 생성자
                 */
                function FontAssetManager( singletonForce:SingletonForce ) {
                }
 
                /**
                 * 싱글톤 클래스 접근 메서드
                 */
                public static function getInstance():FontAssetManager {
                        if ( !instance ) {
                                instance = new FontAssetManager( new SingletonForce() );
                        }
                        return instance;
                }
                // _____________________________________________________ public
                /**
                 * url: swf의 위치
                 * linkage: swf 라이브러리의 Font Class
                 *
                 * url을 object의 속성으로 저장된 FontAsset은 같은 url에 대해서는 하나의 객체만 존재하게 된다.
                 */
                public function getFontAsset(url:String, linkage:String):FontAsset {
                        var asset:FontAsset;
                        if (_fontsObject[url] == undefined) {
                                // 아직 로드전이라면 FontAsset생성, 로드 시작
                                asset = new FontAsset();
                                _fontsObject[url] = asset;
                               
                                try {
                                        asset.load(url, linkage);
                                } catch (e:Error) {
                                        trace(this, e);
                                }
                        } else {
                                // 로드중이거나 로드완료라면
                                asset = _fontsObject[url];
                                //trace(this, "이미 로드중... ", url);
                        }
                        return asset;
                }
        }
}
/**
* @private
* 싱글톤 패턴을 위한 클래스
*/
class SingletonForce {
}