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 {
}