본문 바로가기

Blog/Flex

[Flex AIR] 안드로이드에서 한글이 깨져 나오는 경우

안드로이드는 4.4 kikat 으로 나날이 버전업되고 Flex는 Apache Flex 4.12, AIR 14로 지속적인 업데이트가 이루어지고 있음에도 물구하고 여전히 Flex4.6에 AIR 3.7기반으로 뭔가를 열심히 나름 뚝딱거리고 있는 가운데 중대 버그 발견으로 블로깅 할만한 꺼리가 생겨 널리 이롭게 하고자...


문제의 증상

한글이 깨져서 박스모양으로 나타나거나 글자가 사라지는 증상이 있었습니다.


문제가 발생한 디바이스

* 안드로이드 4.3, 4.4 가 설치된 일부 (삼성)디바이스

* 갤럭시 노트 10.1인치, 갤럭시 노트 12.2인치

Bug report 링크

[Adobe bugbase] https://bugbase.adobe.com/index.cfm?event=bug&id=3732973

[Adobe]
Korean characters are displayed as blank box on the TextField in Galaxy Note 3/Android 4.4/AIR 
http://forums.adobe.com/message/6130947

Chinese and Japanese text gone in Adobe Air 4.0b and Android 4.4
http://forums.adobe.com/message/5983828

Displaying Chinese in spark List does not work in Android 4.4.2
https://issues.apache.org/jira/browse/FLEX-34115

[Apatch]
Flex SDK 4.11 some components cannot display Chinese characters on Android 4.4.x
https://issues.apache.org/jira/browse/FLEX-34037

Apatch Flex 버그 등록 (34257)
https://issues.apache.org/jira/browse/FLEX-34257

vote를 많이 해주셔야 빨리 수정됩니다.!!

추가) http://apache-flex-users.2333346.n4.nabble.com/Korean-text-not-displayed-in-spark-Label-td4053.html


테스트 후 문제 해결이 확인된 SDK

* Flex4.6 with AIR3.7 확인됨

* Apatch Flex4.12.1 with AIR14.0 확인됨


해결 원리

폰트를 Embeding하여 랜더링을 일괄적으로 적용
단, 컴포넌트마다 Embeding 옵션이 달라야 정상적으로 표시됨
(폰트 용량 플러스 알파로 파일크기 증가함)

그런데 StyleableTextField는 embedAsCFF=false로 임베딩된 폰트만 지원된다고 하네요. 
(
Embedding Fonts in Flex Mobile Projects - http://blogs.adobe.com/jasonsj/2011/08/embedding-fonts-in-flex-mobile-projects.html)

  • All mobile skins, LabelItemRenderer and IconItemRenderer use StyleableTextField (based on TextField) instead of the Flash Text Engine (FTE)
  • The Spark Label component uses FTE
  • StyleableTextField only supports embedded fonts with embedAsCFF=false
  • You have to embed fonts twice, once with embedAsCFF=false and again as embedAsCFF=true, to use fonts in both types of text components
  • Avoid using embedded fonts with editable text (TextInput and TextArea)

정리하면 Label을 제외한 모든 모바일 스킨은 모두 StyleableTextField를 사용하는데, StyleableTextField는 embedAsCFF=false인 폰트만 지원한다는 겁니다.


해결 방법

Step 1: mxml 파일에 css 파일을 링크시킨다.

<fx:Style source="fontEmbedcss.css"></fx:Style>


Step 2: css 파일에서 폰트를 Embeding 시킨다.

폰트는 두가지 방식으로 임베딩 시킨다. embedAsCFF = true인것과 embedAsCFF = false인것 두가지로...

@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";

@font-face{
src:url("asset/malgun.ttf");
fontFamily:"malgun";
embedAsCFF:false;
}
@font-face{
src:url("asset/malgun.ttf");
fontFamily:"malgun_CFF";
embedAsCFF:true;
}
global{
fontFamily:"malgun";
}


Step 3: 텍스트가 표현되는 컴포넌트에 임베딩된 폰트를 적용한다.

embedAsCFF = true 인 글꼴을 사용할 컴포넌트 :

RichEditableText는 아쉽게도 softKeyBoard로 한글입력이 되지 않았다. (레퍼런스에 따르면 mobileDevice profile로 설정된 application에서 사용하지 말것을 권하고 있다.)

s|RichEditableText{
fontFamily:"malgun_CFF";
}
s|Label{
fontFamily:"malgun_CFF";
}


embedAsCFF = false 인 글꼴을 사용할 컴포넌트 :
(global style이 적용되었으므로 따로 지정해 주지 않아도 됨)

s|TextInput{
skin-class:ClassReference("spark.skins.mobile.TextInputSkin");
fontFamily:"malgun";
}
s|TextArea{
skin-class:ClassReference("spark.skins.mobile.TextAreaSkin");
fontFamily:"malgun";
}
s|RadioButton{
skin-class:ClassReference("spark.skins.mobile.RadioButtonSkin");
fontFamily:"malgun";
}
s|CheckBox{
skin-class:ClassReference("spark.skins.mobile.CheckBoxSkin");
fontFamily:"malgun";
}
......


fontWeight: bold 인 글꼴을 사용할 컴포넌트 : (볼드체 임베딩)

@font-face{
src:url("asset/malgunbd.ttf");
fontFamily:"malgun_b";
embedAsCFF:false;
fontWeight:bold;
}
s|Button{
fontFamily:"malgun_b";
}

그런데 제 경우엔 폰트 임베딩 할때 css 파일에서 
embedAsCFF:false; fontWeight: bold;
이렇게 설정하면 아예 임베딩이 안된다는 에러가 납니다. 볼드체를 지원하는 글꼴이어야 합니다.
그래서 저는 다음과 같이 합의보았습니다.

s|Button{

fontFamily:"malgun";
fontWeight: normal;
}


Step 4: embedAsCFF 값이 맞지않는 폰트를 지정하는 경우

콘솔창에 다음과 같은 문구가 나옵니다.

warning: incompatible embedded font 'malgun_CFF' specified for spark.skins.mobile::RadioButtonSkin (RadioButtonSkin13) . 

This component requires that the embedded font be declared with embedAsCFF=false.

이 문구는 RadioButtonSkin에는 embedAsCFF=false로 지정된 폰트를 사용하라는 경고문구입니다.
경고대로 수정해주면 됩니다.

다른 컴포넌트들도 위 문구를 확인하여 해당 폰트를 지정해줍니다.