/* * * + Thai.as (Sleepy Type Tool) version 1.3.3 * - online service : http://services.sleepydesign.com/typetool/ * - source : http://code.google.com/p/sleepytypetool/ * */ /* * Copyright (C) 2005-2007 Todsaporn Banjerdkit (katopz), sleepydesign.com. * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be included in all copies * or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ /* * * + feature * - จัดตำแหน่งตำแหน่งสระ/วรรณยุกต์ ที่ลอย หรือทับหาง * - แก้ไขปัญหาการแสดงผล ญ ในโปรแกรม Adobe Photoshop 7 * - แก้ไขปัญหาภาษาไทยพิมพ์ไม่ได้ในโปรแกรม Adobe CS,CS2 * - สร้าง embed font สำหรับ Flash * - ตัวปัดบรรทัด(0x0D0A)ตัด Carriage Return(0x0D)+ Line Feed(0x0A) เหลือแค่ (0x0A) * - ยกเลิกการแก้ไขจากตัวที่แก้ (fix)ไปแล้ว (beta) * * + to do * - clean stupid/ugly/encap code * - loop/bitwise optimize * - convert to as3 * * + target * - อ่อ้อ๊อ๋อ์อํอ็ป่ป้ป๊ป๋ป์ปํป็อั่อั้อั๊อั๋ปั่ปั้ปั๊ปั๋อิ่อี้อึ๊อื๋ปิ่ปี้ปึ๊ปื๋ปิ์อำอ่ำอ้ำอ๊ำอ๋ำปำป่ำป้ำป๊ำป๋ำปุ่ปุ้ปุ๊ปุ๋อุอูอฺญญุญูญฺฤุฤูฤฺฎุฎูฎฺฏุฏูฏฺฐฐุฐูฐฺ * * + thaiStyle * - {isFixFloat:true, isFixTail:true, isFixAum:true, isFixLowTail:true, isFixYoying:false, isFixYoyingTail:true} * * + fontFamily * - psl_ad = PSL-AD,DB-,JS-,Courier * - psl_sp = PSL,PSL-SP,NP,UPC,DSE,Tahoma * - ds = DS- * * + outputType * - multibyte * - multibyte_cs * - ascii_ps7 * * + example #1 * - var target:Thai = new Thai(inputString:String, inputThaiStyle:Object) * * + example #2 * - var target:Thai = new Thai(inputString:String) * - target.setThaiStyle(inputThaiStyle:Object) * - target.applyThaiStyle() * - target.removeThaiStyle() * * + example #3 * - var target:Thai = new Thai().getEmbedString(); * */ class testResource.com.sleepydesign.utils.Thai extends String { //----------style private var thaiStyle = new Object(); //----------static private var tone = new String(); private var vowel = new String(); private var bottomVowel = new String(); private var aum = new String(); private var longTail = new String(); private var lowTail = new String(); private var yoying = new String(); private var yoyingPS7 = new String(); private var yoyingNoTail = new String(); private var thothan = new String(); private var thothanNoTail = new String(); //----------dynamic private var highTone = new String(); private var lowTone = new String(); private var lowerleftTone = new String(); private var lowerleftVowel = new String(); private var lowBottomVowel = new String(); private var aumCombo = new String(); private var escapeChar = new String(); //------------------------------get/set function set _value(inputString:String):Void { super(inputString); } function get _value():String { return super; } //------------------------------function private function fixYoYing(target:String):String { //default if (target == undefined) { target = new String(_value); } var resultString = ""; if (thaiStyle.isFixYoying || thaiStyle.isFixYoyingTail) { for (var i = 0; i-1); //char code var charCode = Number(target.charCodeAt(i)); //skip newline var isNewline:Boolean = (char == newline); if (!isNewline && ((yoying+thothan).indexOf(char)>-1)) { //next is bottomVowel? var isBeforeBottomVowel = (bottomVowel.indexOf(target.charAt(i+1))>-1) && (i+1127) && (charCode<3584) && (charCode<0xF000)) { //ascii -> unicode charCode = charCode+3585-161; } resultString += String.fromCharCode(charCode); } else { resultString += char; } } //return return resultString; } public function unicodeToAscii(target:String):String { //default if (target == undefined) { target = new String(_value); } //result var resultString:String = new String(); for (var i = 0; i3584) && (charCode<0xF000)) { //unicode ->ascii charCode = charCode-3585+161; } if (charCode<128) { resultString += char; } else { resultString += chr(charCode); } } else { resultString += char; } } //return return resultString; } private function ps7Chr(target:String):String { //default if (target == undefined) { target = new String(_value); } var resultString = ""; for (var i = 0; i-1); //skip some var isEscape = (escapeChar != undefined) && (escapeChar.indexOf(char)>-1); //char code var charCode = Number(target.charCodeAt(i)); //skip newline var isNewline:Boolean = (char == newline); //only thai and not fixed if (!isNewline && !isLowBottomVowel && (charCode>3584) && !isEscape) { //unicode ->ascii charCode = charCode-3585+161; resultString += chr(charCode); } else { resultString += target.charAt(i); } } //return return resultString; } private function csChr(target:String):String { //default if (target == undefined) { target = new String(_value); } //result var resultString = ""; for (var i = 0; i3584) && (charCode<0xF000)) { //unicode ->ascii charCode = charCode-3585+161; } if (charCode<126) { resultString += char; } else { resultString += String.fromCharCode("0xF0"+charCode.toString(16)); } } else { resultString += char; } } //return return resultString; } private function removeCSChr(target:String):String { //default if (target == undefined) { target = new String(_value); } //result var resultString = ""; for (var i = 0; i128)) { if ((charCode>3584) && (charCode<0xF000)) { //unicode ->ascii charCode = -charCode+3585-161; } //resultString += String.fromCharCode(charCode-0xF000+3585-161); if (charCode<126) { resultString += char; } else { resultString += String.fromCharCode(charCode-0xF000+3585-161); //resultString += String.fromCharCode("0xF0"+charCode.toString(16)); } } else { resultString += char; } //trace(charCode); } //return return resultString; } private function removePS7Chr(target:String):String { //default if (target == undefined) { target = new String(_value); } var resultString = ""; for (var i = 0; i-1); //skip some var isEscape = (escapeChar != undefined) && (escapeChar.indexOf(char)>-1); //char code var charCode = Number(target.charCodeAt(i)); //skip newline var isNewline:Boolean = (char == newline); //only thai and not fixed //if (!isNewline && !isLowBottomVowel && (charCode>3584) && !isEscape) { //trace("*"+charCode); if (!isNewline && !isLowBottomVowel && (charCode<3584-21) && !isEscape) { //trace("*"+charCode+"<"+(3584-21)); //unicode ->ascii charCode = charCode+3585-161; //resultString += chr(charCode); resultString += String.fromCharCode(charCode); //trace("**"+charCode); } else { //resultString += target.charAt(i); charCode = charCode-3585+161; resultString += String.fromCharCode(charCode); //trace("***"+target.charAt(i)); } } //return return resultString; } public function removeThaiStyle(target:String, inputThaiStyle:Object):String { //default if (target == undefined) { target = new String(_value); } if (inputThaiStyle == undefined) { inputThaiStyle = thaiStyle } //trace("setFontFamily : "+inputThaiStyle.fontFamily); //trace(inputThaiStyle.fontFamily == undefined) if (inputThaiStyle.fontFamily == undefined) { inputThaiStyle.fontFamily = "psl_ad"; } //result //setFontFamily //trace("fontFamily : "+inputThaiStyle.fontFamily); //trace("outputType : "+inputThaiStyle.outputType); setFontFamily(inputThaiStyle.fontFamily); //prepare asciiToUnicode if (inputThaiStyle.fontFamily == "psl_ad") { switch (inputThaiStyle.outputType) { case "multibyte_cs" : target = removeCSChr(target); //trace("asciiToUnicode : "+inputThaiStyle.fontFamily); yoyingPS7 = asciiToUnicode(yoyingPS7); yoyingNoTail = asciiToUnicode(yoyingNoTail); thothanNoTail = asciiToUnicode(thothanNoTail); //is that fixed? highTone,lowTone,lowerleftTone,lowerleftVowel,lowBottomVowel,aumCombo highTone = asciiToUnicode(highTone); lowTone = asciiToUnicode(lowTone); lowerleftTone = asciiToUnicode(lowerleftTone); lowerleftVowel = asciiToUnicode(lowerleftVowel); lowBottomVowel = asciiToUnicode(lowBottomVowel); aumCombo[0] = asciiToUnicode(aumCombo[0]); aumCombo[1] = asciiToUnicode(aumCombo[1]); break; case "ascii_ps7" : target = removePS7Chr(target); //trace("removePS7Chr : "+target); break; } } //result var resultString = ""; for (var i = 0; i-1) { char = yoying.charAt(0); } if (yoyingNoTailPos>-1) { char = yoying.charAt(0); } if (thothanNoTailPos>-1) { char = thothan.charAt(0); } //unfix : tone,vowel,bottomVowel,aum if (highTonePos>-1) { char = tone.charAt(highTonePos); } if (lowTonePos>-1) { char = tone.charAt(lowTonePos); } if (lowerleftTonePos>-1) { char = tone.charAt(lowerleftTonePos); } if (lowerleftVowelPos>-1) { char = vowel.charAt(lowerleftVowelPos); } if (lowBottomVowelPos>-1) { char = bottomVowel.charAt(lowBottomVowelPos); } if ((aumComboPos_0>-1) && (aumComboPos_1>-1) && ((aumComboPos_1-aumComboPos_0) == 1)) { char = aum.charAt(aumComboPos_0); } //grab resultString += char; } if (inputThaiStyle.fontFamily != "psl_ad") { switch (inputThaiStyle.outputType) { case "multibyte_cs" : resultString = removeCSChr(resultString); break; case "ascii_ps7" : //need fix //trace("removePS7Chr : "+resultString); resultString = removePS7Chr(resultString); //trace("removePS7Chr : "+resultString); break; } } //return return resultString; } private function fixFloat(target:String):String { //default if (target == undefined) { var target = new String(_value); } //result var resultString = ""; for (var i = 0; i-1) && (i>=1); var isAfter2LongTail = (longTail.indexOf(target.charAt(i-2))>-1) && (i>=2); //---------------------------vowel ///is that vowel? var vowelPos = vowel.indexOf(char); //lowerleftVowel = สระ = ปิปีปึปืปั if (thaiStyle.isFixTail && (vowelPos>-1) && isAfterLongTail) { char = lowerleftVowel.charAt(vowelPos); } //is that bottomVowel? var bottomVowelPos = bottomVowel.indexOf(char); //---------------------------tone //is that tone? var tonePos = tone.indexOf(char); //skip newline var isNewline:Boolean = (char == newline); //tone found if (!isNewline && thaiStyle.isFixFloat && (tonePos>-1)) { //previous char is tone var isAfterTone = (tone.indexOf(target.charAt(i-1))>-1) && (i>=1); //next is aum? var isBeforeAum = (aum.indexOf(target.charAt(i+1))>-1) && (i+1-1) && (i>=1); //prev is lowvowel? var isAfterLowVowel = (lowerleftVowel.indexOf(target.charAt(i-1))>-1) && (i>=1); if (!isAfterTone && !isBeforeAum && !isAfterVowel) { if (thaiStyle.isFixTail && isAfterLongTail) { //avoid tail by move high tone to lower left char = lowerleftTone.charAt(tonePos); } else { //just pull 'em down char = lowTone.charAt(tonePos); } } if (thaiStyle.isFixTail) { var isAfterBottomVowel = (bottomVowel.indexOf(target.charAt(i-1))>-1)&& (i>=1); if (isAfter2LongTail && (isAfterVowel || isAfterLowVowel)) { //highTone = ปิ่ปิ้ปิ๊ปิ๋ char = highTone.charAt(tonePos); } else if (isAfter2LongTail && isAfterBottomVowel) { //bottomVowel = ปุ่ปุ้ปุ๊ปุ๋ char = lowerleftTone.charAt(tonePos); } else if (isAfterLongTail && isBeforeAum) { //highTone = ป่ำป้ำป๊ำป๋ำ char = highTone.charAt(tonePos); } } } //---------------------------bottomVowel //is that bottomVowel? //var bottomVowelPos = bottomVowel.indexOf(char); var isAfterLowTail = (lowTail.indexOf(target.charAt(i-1))>-1) && (i>=1); //ญุญูญฺ if ((bottomVowelPos>-1) && isAfterLowTail && thaiStyle.isFixLowTail) { char = lowBottomVowel.charAt(bottomVowelPos); } //---------------------------aum //is that aum? var isAum = (aum.indexOf(char)>-1); var isAfterTone = (tone.indexOf(target.charAt(i-1))>-1) && (i>=1); var isAfterLongTailTone = isAfter2LongTail && isAfterTone; //ปำฟำฝำ,ป่ำป้ำป๊ำป๋ำ if (thaiStyle.isFixAum && isAum && (isAfterLongTail || isAfterLongTailTone)) { //break aum char = aumCombo; } //---------------------------grab resultString += char; } //return return resultString; } private function replace(target:String, source_chr:String, replace_chr:String):String { //default if (target == undefined) { var target = new String(_value); } if (source_chr == undefined) { var source_chr = ""; } if (replace_chr == undefined) { var replace_chr = ""; } //result var resultString = target.split(source_chr).join(replace_chr); //return return resultString; } public function applyThaiStyle(target:String):String { //default if (target == undefined) { var target = new String(_value); } //result var resultString:String = new String(); //fix Yoying target = fixYoYing(target); //fix Float target = fixFloat(target); //outputType : multibyte_cs, ascii_ps7, multibyte switch (thaiStyle.outputType) { case "multibyte_cs" : resultString = csChr(target); break; case "ascii_ps7" : resultString = ps7Chr(target); break; default : resultString = target; break; } //fix newline (0x0D0A->0x0A) if (thaiStyle.isFixLineFeed) { resultString = replace(resultString, String.fromCharCode(0x000D), String.fromCharCode(0x000A)); } //else { //resultString = replace(resultString, String.fromCharCode(0x000D), String.fromCharCode(0x000D)+String.fromCharCode(0x000A)); //} //return return resultString; } private function setFontFamily(fontFamily:String) { if (fontFamily == undefined) { thaiStyle.fontFamily = "psl_ad"; } else { thaiStyle.fontFamily = fontFamily; } switch (fontFamily) { case "ds" : //ยกเว้น อ่อ้อ๊อ๋อ์ //highTone = วรรณยุกต์ = ป่ำป้ำป๊ำป๋ำ highTone = new String(String.fromCharCode(0x203A)+String.fromCharCode(0x0153)+String.fromCharCode(0x009D)+String.fromCharCode(0x009D)+String.fromCharCode(0xF717)+String.fromCharCode(0x2122)+String.fromCharCode(0x0161)); //lowTone lowTone = new String(String.fromCharCode(0x2039)+String.fromCharCode(0x0152)+String.fromCharCode(0x008D)+String.fromCharCode(0x008E)+String.fromCharCode(0x008F)+String.fromCharCode(0x0E4D)+String.fromCharCode(0x0E47)); //วรรณยุกต์ = ป่ป้ป๊ป๋ป์ปํป็ lowerleftTone = new String(String.fromCharCode(0x2020)+String.fromCharCode(0x2021)+String.fromCharCode(0x02C6)+String.fromCharCode(0x2030)+String.fromCharCode(0x0160)+String.fromCharCode(0x2122)+String.fromCharCode(0x0161)); //สระซ้าย = ปิปีปึปืปั lowerleftVowel = new String(String.fromCharCode(0x00D4)+String.fromCharCode(0x00D5)+String.fromCharCode(0x00D6)+String.fromCharCode(0x00D7)+String.fromCharCode(0x02DC)); //สระล่าง = ญุญูญฺ lowBottomVowel = new String(String.fromCharCode(0x00FC)+String.fromCharCode(0x00FD)+String.fromCharCode(0x00FE)); //aum = สระอำ aumCombo = new String(String.fromCharCode(0x2122)+String.fromCharCode(0x00D2)); //ยกเว้น อ่อ้อ๊อ๋อ์,ป่ป้ป๊ป๋ป์ปํป็,ป่ำป้ำป๊ำป๋ำ,อำ escapeChar = new String(String.fromCharCode(0x2039)+String.fromCharCode(0x0152)+String.fromCharCode(0x008D)+String.fromCharCode(0x008E)+String.fromCharCode(0x008F))+lowerleftTone+highTone+new String(String.fromCharCode(0x00D2)); //ญ,ฐ yoyingNoTail = new String(String.fromCharCode(0x0090)); thothanNoTail = new String(String.fromCharCode(0x0080)); break; case "psl_ad" : //highTone = วรรณยุกต์ = ป่ำป้ำป๊ำป๋ำ highTone = new String(String.fromCharCode(0x009B)+String.fromCharCode(0x009C)+String.fromCharCode(0x009D)+String.fromCharCode(0x009E)+String.fromCharCode(0x009F)+String.fromCharCode(0x0E4D)+String.fromCharCode(0x0E47)); //lowTone lowTone = new String(String.fromCharCode(0x008B)+String.fromCharCode(0x008C)+String.fromCharCode(0x008D)+String.fromCharCode(0x008E)+String.fromCharCode(0x008F)+String.fromCharCode(0x0E4D)+String.fromCharCode(0x0E47)); //tone = วรรณยุกต์ = ป่ป้ป๊ป๋ป์ปํป็ lowerleftTone = new String(String.fromCharCode(0x0086)+String.fromCharCode(0x0087)+String.fromCharCode(0x0088)+String.fromCharCode(0x0089)+String.fromCharCode(0x008A)+String.fromCharCode(0x0099)+String.fromCharCode(0x009A)); //lowerleftVowel = สระ = ปิปีปึปืปั lowerleftVowel = new String(String.fromCharCode(0x0081)+String.fromCharCode(0x0082)+String.fromCharCode(0x0083)+String.fromCharCode(0x0084)+String.fromCharCode(0x0098)); //bottomVowel = สระล่าง = ญุญูญฺ lowBottomVowel = new String(String.fromCharCode(0xF0FC)+String.fromCharCode(0xF0FD)+String.fromCharCode(0xF0FE)); //aum = สระอำ aumCombo = new String(String.fromCharCode(0x0099)+String.fromCharCode(0x0E32)); //ญ,ฐ yoyingNoTail = new String(String.fromCharCode(0xF090)); thothanNoTail = new String(String.fromCharCode(0xF080)); break; case "psl_sp" : //highTone = วรรณยุกต์ = ป่ำป้ำป๊ำป๋ำ highTone = new String(String.fromCharCode(0xF713)+String.fromCharCode(0xF714)+String.fromCharCode(0xF715)+String.fromCharCode(0xF716)+String.fromCharCode(0xF717)+String.fromCharCode(0x0E4D)+String.fromCharCode(0x0E47)); //lowTone lowTone = new String(String.fromCharCode(0xF70A)+String.fromCharCode(0xF70B)+String.fromCharCode(0xF70C)+String.fromCharCode(0xF70D)+String.fromCharCode(0xF70E)+String.fromCharCode(0x0E4D)+String.fromCharCode(0x0E47)); //วรรณยุกต์ = ป่ป้ป๊ป๋ป์ปํป็ lowerleftTone = new String(String.fromCharCode(0xF705)+String.fromCharCode(0xF706)+String.fromCharCode(0xF707)+String.fromCharCode(0xF708)+String.fromCharCode(0xF709)+String.fromCharCode(0xF711)+String.fromCharCode(0xF712)); //สระซ้าย = ปิปีปึปืปั lowerleftVowel = new String(String.fromCharCode(0xF701)+String.fromCharCode(0xF702)+String.fromCharCode(0xF703)+String.fromCharCode(0xF704)+String.fromCharCode(0xF710)); //สระล่าง = ญุญูญฺ lowBottomVowel = new String(String.fromCharCode(0xF718)+String.fromCharCode(0xF719)+String.fromCharCode(0xF71A)); //aum = สระอำ aumCombo = new String(String.fromCharCode(0xF711)+String.fromCharCode(0x0E32)); //ญ,ฐ yoyingNoTail = new String(String.fromCharCode(0xF70F)); thothanNoTail = new String(String.fromCharCode(0xF700)); break; } } public function setThaiStyle(inputThaiStyle:Object) { //--------default style //fontFamily thaiStyle.fontFamily = "psl_ad"; //fix thaiStyle.isFixFloat = true; thaiStyle.isFixTail = true; thaiStyle.isFixAum = true; thaiStyle.isFixLowTail = true; thaiStyle.isFixYoying = false; thaiStyle.isFixYoyingTail = true; thaiStyle.isFixLineFeed = false; //outputType : multibyte, multibyte_cs, ascii_ps7 //thaiStyle.outputType = "multibyte_cs"; //--------custom style if (inputThaiStyle != undefined) { for (var i in inputThaiStyle) { thaiStyle[i] = inputThaiStyle[i]; } } } //-----------------constructor public function Thai(inputString:String, inputThaiStyle:Object) { trace("Thai.as version 1.3.3") //------------------------i hate CodePage ;( //System.useCodepage = true; //------------------------set style setThaiStyle(inputThaiStyle); //------------------------set table setFontFamily(thaiStyle.fontFamily); //inputType : ascii -> multibyte, //------------------------unicode mapping table //วรรณยุกต์ = อ่อ้อ๊อ๋อ์อํอ็ tone = new String(String.fromCharCode(0x0E48)+String.fromCharCode(0x0E49)+String.fromCharCode(0x0E4A)+String.fromCharCode(0x0E4B)+String.fromCharCode(0x0E4C)+String.fromCharCode(0x0E4D)+String.fromCharCode(0x0E47)); //สระ = อิอีอึอือั vowel = new String(String.fromCharCode(0x0E34)+String.fromCharCode(0x0E35)+String.fromCharCode(0x0E36)+String.fromCharCode(0x0E37)+String.fromCharCode(0x0E31)); //สระล่าง = อุอูอฺ bottomVowel = new String(String.fromCharCode(0x0E38)+String.fromCharCode(0x0E39)+String.fromCharCode(0x0E3A)); //สระอำ aum = new String(String.fromCharCode(0x0E33)); //ปฝฟ longTail = new String(String.fromCharCode(0x0E1B)+String.fromCharCode(0x0E1D)+String.fromCharCode(0x0E1F)); //ญญฎฏฐฤฦ lowTail = new String(String.fromCharCode(0xF0AD)+String.fromCharCode(0x0E0D)+String.fromCharCode(0x0E0E)+String.fromCharCode(0x0E0F)+String.fromCharCode(0x0E10)+String.fromCharCode(0x0E24)+String.fromCharCode(0x0E26)); //ญ,ฐ yoying = new String(String.fromCharCode(0x0E0D)); yoyingPS7 = new String(String.fromCharCode(0xF0AD)); thothan = new String(String.fromCharCode(0x0E10)); //------------------------ascii to unicode //***have to add to style for ascii input inputString = asciiToUnicode(inputString); //------------------------return if (inputString != undefined) { _value = applyThaiStyle(inputString); } else { _value = new String(); } } }