Flash player linux and unicode.
Sunday, May 31st, 2009Writing not english characters in swf applications under linux is a well known problem. These days I had some spare time to inspect it and try to fix it. So far I’ve a solution. I don’t know if this one is the best one or if there is a better way but I’m not an expert in flash/flex development. The idea is to replace characters that came from flash player by their original characters using their code. eg. “193” with “а” (а is in Cyrillic) and so on. I know this will fix the problem for specified language (Bulgarian in this case), but will not fix it in general, so I decided to make something like a character map and load replacements dynamically. I use JSON for characters map. Here is an example file:
{"193":"а", "194":"б", "215":"в", "199":"г", "196":"д", "197":"е", "214":"ж", "218":"з", "201":"и", "202":"й", "203":"к", "204":"л", "205":"м", "206":"н", "207":"о", "208":"п", "210":"р", "211":"с", "212":"т", "213":"у", "198":"ф", "200":"х", "195":"ц", "222":"ч", "219":"ш", "221":"щ", "216":"ь", "223":"ъ", "192":"ю", "209":"я" }
and the code that reads this file and replaces characters:
package net.iordanov { public class Cyrillic { import com.adobe.serialization.json.JSON; import mx.rpc.http.HTTPService; import mx.rpc.events.ResultEvent; import mx.rpc.events.FaultEvent; import mx.controls.Alert; private static var data:Object; public static function loadCharMap(file:String):void { var service:HTTPService = new HTTPService(); service.addEventListener("result", processJson); service.addEventListener("fault", failure); service.url = file; service.send(); } public static function processJson(event:ResultEvent):void { data = JSON.decode(event.result.toString()); } public static function failure(event:FaultEvent):void { Alert.show(event.toString()); } public static function correctLinux(str:String):String { var char:String; var charCode:Number; var ret:String = ""; for (var i:int = 0; i<str.length; i++) { char = str.charAt(i); charCode = str.charCodeAt(i); if (data[charCode]) { ret += data[charCode]; } else { ret +=char; } } return ret; } } }
An example mxml file witch tests the code above:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" layout="absolute" creationComplete="loadLang()"> <mx:Script> <![CDATA[ import net.iordanov.Cyrillic; import mx.rpc.events.ResultEvent; import mx.events.StyleEvent; private function fixLinux(event:Event):void { text1.text = Cyrillic.correctLinux(text1.text); } private function loadLang():void { Cyrillic.loadCharMap("http://dev.iordanov.net/flex/lang/bg.js"); } ]]> </mx:Script> <mx:TextInput id="text1" width="100" change="fixLinux(event)"/> </mx:Application>
and simple html to load this swf application.
<object width="550" height="400"> <param name="movie" value="somefilename.swf" /> <param name="wmode" value="transparent" /> <embed src="cyrillic.swf" width="550" height="400" wmode="transparent"></embed> </object>
Note that wmode must be set to transparent. In other case (I don’t know why, as I say I’m not an expert in flash/flex development) user must hold Ctrl key pressed while typing.