หน้า: [1] 2
 
ผู้เขียน หัวข้อ: แนวคิดการแก้สระลอยในแฟลช  (อ่าน 17061 ครั้ง)
0 สมาชิก และ 1 ขาจร กำลังดูหัวข้อนี้
หลังจากที่ผมพยายามศึกษาสคริปต์แก้สระลอยของเฮีย (?) katopz อยู่นานสองนาน
เพื่อจะได้สามารถแก้สระลอยใน sIFR ซึ่งเวอร์ชั่นต่ำสุดของ Flash Player ที่ใช้คือ 6.0 และ ActionScript 1.0

แต่สคริปต์แก้สระลอยของ SleepyDesign นี่ มันเป็น Class ครับ
ซึ่ง Class จะใช้ได้ตั้งแต่ ActionScript 2.0 ขึ้นไปเท่านั้น

ตอนแรกผมค่อนข้างงงกับสคริปต์พอสมควร
ไม่ใช่พอสมควรแหละครับ ไม่รู้เรื่องเลย

แนวคิดในการแก้สระลอยโดยใช้ ActionScript ที่ผมแกะออกมาคร่าวๆ ก็คือ
การทำ Loop พิจารณาตัวอักษรแต่ละตัว ว่าตัวนี้เป็นตัวไหน ตัวต่อไปหรือก่อนหน้าเป็นตัวอันนี้หรือเปล่า บลา บลา บลา

ก่อนอื่นควรจะรู้จักฟังก์ชั่นหลักๆก่อน

String.charAt(index)
String คือชื่อ String หรือข้อความครับ
index คือตัวเลขครับ โดยเลข 0 หมายถึงตัวอักษรตัวแรกของ String
โดยจะมีผลลัพธ์คือ ตัวอักษรของ String ตัวที่เรากำหนด โดย 0 คือตัวแรก 1 คือตัวที่สอง ไปเรื่อยๆ...

เช่น
โค้ด:
var myString = "Hello World!";
var char = myString.charAt(0);
ผลลัพธ์ที่ได้ออกมา (ในที่นี้คือค่าของตัวแปร char) จะเป็นตัว H ใหญ่ครับ

String.indexOf(character)
String คือชื่อ String หรือข้อความเหมือนเดิมครับ
character คือตัวอักษรครับ
โดยจะมีผลลัพธ์ออกมาคือตำแหน่งของตัวอักษรนั้นๆใน String หรือข้อความที่ปรากฏเป็นตัวแรกครับ

เช่น
โค้ด:
var myString = "Hello World!";
var charPos = myString.indexOf("o");
ค่าของตัวแปร charPos คือ 4

แต่ถ้าใน String หรือข้อความดังกล่าวไม่มีตัวอักษรที่ต้องการอยู่เลย ค่าที่ออกมาจะเป็น -1 ครับ

String.length
ผลที่ได้คือความยาวของ String หรือข้อความครับ

เช่น
โค้ด:
var myString = "123";
var stringLength = myString.length;
ค่าตัวแปร stringLength คือ 3 ครับ

mbchr(index)
index คือตัวเลข ซึ่งเป็นรหัส ASCII ของตัวอักษรครับ

อย่างเช่น
โค้ด:
var firstVar = mbchr(124);
var secondVar = mbchr(0x0E01);
ค่าของ firstVar จะเป็นตัว | ครับ (| เป็นตัวอักษรที่ 124)
และค่าของ secondVar จะเป็น ก ไก่ครับ (ก มีรหัสยูนิโคดคือ 0E01)

ในที่นี้จะทดลองสร้าง Flash Preview ที่แก้ f กับ i ที่ติดกันให้กลายเป็น fi อัตโนมัติ

ก่อนอื่นก็คือวิธีบัญญัติฟังก์ชั่น
คล้ายๆกับใน php และภาษาทั่วไปนั่นแหละครับ
แต่ใน actionscript จะ Case Sensitive หรือให้ความสำคัญกับตัวพิมพ์เล็กและใหญ่

โค้ด:
function ชื่อฟังก์ชั่น(ตัวแปร) {
  คำสั่ง
}

โดยการกำหนดเช่นนี้ หมายถึงว่า ถ้าเราใส่ฟังก์ชั่นให้กับตัวแปร ฟังก์ชั่นก็ต้องทำแบบนี้ๆ เช่น
โค้ด:
function myFunction(string) {
trace(string);
}
myFunction("สามเป็นเกย์");
แล้วจะมีคำว่า "สามเป็นเกย์" ออกมาทาง Output Panel ครับ
(คำสั่ง trace หมายถึงให้แสดงผลใน Output Panel)

เช่นเดียวกับอันนี้
โค้ด:
function toFI(target) {
 คำสั่ง
}

ตรงคำสั่งนี้เองเป็นส่วนที่สั่งงานให้แก้ f กับ i เป็น fi
โดยใช้ Loop อย่างที่บอกแต่ตอนแรก

ตัวอย่างการใช้ Loop เช่น
โค้ด:
for (var num = 1; num < 18; num++) {
  [i]do somethings[/i]
}
หมายถึง ให้ตัวแปร num เท่ากับ 1 (var num = 1)
ถ้าตัวแปร num น้อยกว่า 18 (num < 18)
ให้ทำสิ่งต่อไปนี้ (do somethings)
และบวกเพิ่ม num อีก 1 (num++)
ผลที่ได้ก็คือ มันจะ do somethings 17 ครั้ง

เช่นเดียวกันกับอันนี้นั่นแหละครับ
โค้ด:
function toFI(codetarget) {
for (var i = 0; i < target.length; i++) {
  [i]do somethings[/i]
}
}

ใช่แล้วครับ ทำ Loop พิจารณาตัวอักษรแต่ละตัว รายตัวเลยทีเดียว

โดย target.length ก็คือ ความยาวของ String ที่ชื่อ target นั่นเองครับ

var i = 0
กำหนดให้ i เท่ากับ 0 (กำหนดขึ้นมาใหม่ ไม่ได้อ้างอิงจากไหนครับ)

i < target.length
ถ้า i ยังน้อยกว่าความยาวของข้อความที่พิจารณาอยู่

do somethings
ให้ทำสิ่งต่อไปนี้

i++
และบวกเพิ่ม i อีกหนึ่ง

ผลลัพธ์ก็คือมันจะ do somethings ทั้งหมดตามความยาวของ String ซึ่งก็หมายถึงจะ do somethings กับทุกตัวอักษรนั่นเอง

แน่นอน ว่าตรง do somethings ระหว่าง for {...} นั่นเองที่จะเป็นตัวทำให้ f กับ i กลายเป็น fi มาดูสคริปต์เต็มๆกันเลยดีกว่า

โค้ด:
function toFI(target) {
var resultString = "";
for (var i = 0; i < target.length; i++) {
  var char = target.charAt(i);
  var fChar = "f";
  var iChar = "i";
  var fiChar = mbchr(0xFB01); // FB01 คือรหัสยูนิโคดของ fi
  if ((char == fChar) && (target.charAt(i+1) == iChar) && (i+1 < target.length)) {
    resultString += fiChar;
  }
  else if ((char == iChar) && (target.charAt(i-1) == fChar) && (i > 0)) {
    resultString += "";
  }
  else {
    resultString += char;
  }
}
return (resultString);
}

อธิบายคือ

var resultString = "";
กำหนดให้ resultString เป็น String ว่างๆ

for (var i = 0; i < target.length; i++) {
เปิด for ... (อธิบายแล้ว)

var char = target.charAt(i);
กำหนดตัวแปร char ให้เท่ากับตัวอักษรตัวที่ i (เมื่อ i = 0 ตัวแปร char เท่ากับตัวอักษรตัวแรก)

var fChar = "f";
กำหนดตัวแปร fChar ให้เท่ากับตัวอักษร f เล็ก

var iChar = "i";
กำหนดตัวแปร iChar ให้เท่ากับตัวอักษร i เล็ก

var fiChar = mbchr(0xFB01);
กำหนดตัวแปร fiChar ให้เท่ากับตัวอักษร fi ที่ติดกัน (Ligature)

if ((char == fChar) && (target.charAt(i+1) == iChar) && (i+1 < target.length)) {
ถ้าตัวอักษรตัวที่ i เป็นตัวอักษร f เล็ก (char == fChar)
และตัวอักษรตัวต่อไป (ตัวที่ i+1) เป็นตัว i เล็ก (target.charAt(i+1) == iChar)
และไม่เป็นตัวสุดท้ายของข้อความ (i+1 < target.length)
ให้

resultString += fiChar;
เพิ่ม resultString เข้าด้วยตัวอักษร fi

else if ((char == iChar) && (target.charAt(i-1) == fChar) && (i > 0)) {
ถ้าไม่ใช่อย่างข้างต้น แต่ตัวอักษรตัวที่ i เป็นตัวอักษร i เล็ก (char == iChar)
และตัวอักษรตัวก่อนหน้า (ตัวที่ i-1) เป็นตัว f เล็ก ซึ่งถูกแทนที่ด้วย fi ไปแล้ว
และตัวอักษรตัวที่ i นี้ไม่ใช่ตัวอักษรตัวแรก

resultString += "";
ก็ไม่ต้องเพิ่มตัวอะไรเข้าไปใน resultString

else {
และถ้านอกเหนือจากนี้

resultString += char;
ก็ให้เพิ่มตัวอักษรตัวที่ i นั้นแหละ เข้าใน resultString

ดังนั้นเมื่อประมวลผลจน i >= target.length แล้ว resultString จะประกอบไปด้วยตัวอักษรที่ผ่านการกรั่นกรองแล้วทุกตัว

ตัวอย่างเช่น ข้อความ "fifa cup"
ตัวอักษรแรกเป็นตัว f และตัวอักษรต่อไปเป็นตัว i และไม่ได้เป็นตัวสุดท้าย
เพิ่ม fi เข้าใน resultString
จะได้ resultString ตอนนี้เป็น "fi"

ตัวอักษรตัวที่สองเป็นตัว i และก่อนหน้าเป็นตัว f และไม่ได้เป็นตัวแรก
ไม่ต้องเพิ่มอะไร (หรือเพิ่ม "") เข้าใน resultString
จะได้ resultString เป็น "fi" ดังเดิม

ตัวต่อไปอีก เป็นตัว f แต่ตัวต่อไปไม่ใช่ตัว i ดังนั้นเพิ่มตัว f เข้าไปใน resultString ดื้อๆ
และต่อไปเรื่อยๆ

สุดท้ายสั่งให้ return
ก็คือสั่งให้ส่งกลับค่านี้ออกมานั่นเอง
(return ตรงข้ามกับ trace คือต้องดึงกลับมาใช้ต่อ)

บางคนอาจเถียงว่า มันก็มีฟังก์ชั่นสำหรับ replace ใน ActionScript ไม่ใช่หรือ
ใช่ครับ แต่อันข้างบนนี่สาธิตเพื่อให้เข้าใจง่าย
แต่มันค่อนข้างประยุกต์ใช้ได้ดีกับการที่อักษรต้องมาเจอกันหลายตัว ไม่ใช่แค่สองตัวอย่าง fi

วิธีแรกที่สาธิตนี้ เหมือนตรวจสอบว่า A = B หรือเปล่า
ส่วนวิธีที่สองนี้ จะตรวจสอบว่า A เป็นสมาชิกของเซต B หรือเปล่า
เช่น

โค้ด:
function fixFloat(target) {
var resultString = "";
for (var i = 0; i > target.length; i++) {
  var char = target.charAt(i);
  // สระปกติ อิอีอึอือัอํอ็
  var vowel = mbchr(0x0E34)+mbchr(0x0E35)+mbchr(0x0E36)+mbchr(0x0E37)+mbchr(0x0E31)+mbchr(0x0E4D)+mbchr(0x0E47);
  // สระหลบหาง ปิปีปึปืปัปํป็
  var vowelAlt = mbchr(0xF701)+mbchr(0xF702)+mbchr(0xF703)+mbchr(0xF704)+mbchr(0xF710)+mbchr(0xF711)+mbchr(0xF712);
  // ตัวอักษรหางยาว ปฟฝ
  var longTail = mbchr(0x0E1B)+mbchr(0x0E1D)+mbchr(0x0E1F);
 
  var vowelPos = vowel.indexOf(char);
  // ถ้ามากกว่า -1 แสดงว่าเป็นสระ และสระอะไรต้องดูที่ค่า ถ้าเท่ากับ 0 จะเท่ากับสระอิหรือ mbchr(0x0E34) เป็นต้น
  var afterLongTail = (longTail.indexOf(target.charAt(i-1)) > -1) && (i > 0);
  // String.indexOf(character) ถ้าไม่มีตัวอักษรหรือ character อยู่ใน String จะตีกลับมาเป็น -1
  if ((vowelPos > -1) && afterLongTail) {
    var myVar = vowelAlt.charAt(vowelPos);
    // เนื่องจากตัวอักษรตัวที่ 1 ของ vowel คือสระอิธรรมดา และตัวอักษรตัวที่ 1 ของ vowelAlt คือสระอิหลบหาง ปฟฝ
    resultString += myVar;
  }
  else {
    resultString += char;
  }
}
return (resultString);
}

จะสั่งให้สระที่อยู่ด้านบนหลบหาง ปฝฟ เสีย

ยกตัวอย่างการนำไปใช้
สร้าง Dynamic TextField ขึ้นมาอันหนึ่ง
เสร็จแล้วตั้ง Instant Name ให้ สมมุติคือ ex
ใส่ ActionScript ประมาณนี้ลงไป

โค้ด:
var myTxt = fixFloat("ปิิปีปึปืปัปํป็"); // กำหนดตัวแปร myTxt ซึ่งมีค่าเป็น ปิิปีปึปืปัปํป็ ที่ปรับให้หลบหาง ปฝฟ แล้ว
ex.text = myTxt; // กำหนดให้ข้อความใน ex เป็นตัวแปร myTxt

สรุปแนวคิดคือ พิจารณาตัวอักษรแต่ละตัวและถ้าจำเป็น ตัวก่อนหน้าและตัวหลัง กำหนดตัวแปรใหม่มาหนึ่งตัว แล้วถ้าเป็นไปตามเงื่อนไขที่กำหนด ให้เพิ่มตัวอักษรที่ต้องการให้เปลี่ยนไปเป็นหากเป็นไปตามเงื่อนไขเข้าในตัวแปรที่กำหนดขึ้นมาใหม่นั้น ถ้าไม่เป็นไปตามเงื่อนไข ให้เพิ่มตัวอักษรตัวนั้นแหละเข้าในตัวแปรที่กำหนดขึ้นมาใหม่

ครับ  (เหงื่อแตกพลั่ก)
บันทึกการเข้า
ส่วนฟังก์ชั่น replace ที่ว่า
คือประมาณนี้ครับ

addr_str = "402 My Street";
addr_str =
addr_str.split("My").join("18th");

เอามาจากที่นี่
http://flash-creations.com/notes/servercomm_asphptable.php
บันทึกการเข้า
 งง
บันทึกการเข้า
 มึนตึ้บ
บันทึกการเข้า
อืมมม

แบบนี้นี่เอง
บันทึกการเข้า

I ROCK , THEREFORE I AM
สคริปต์ของ SleepyDesign สามารถเข้าไปดาวน์โหลดได้ที่ http://www.sleepydesign.com หมวด exp ครับ
(รู้สึกว่ามันจะไม่ work กับคำว่าปู่ปู้ปู๊ปู๋)

ส่วนสคริปต์ที่แยกออกมาเป็นเฉพาะฟังก์ชั่น (สำหรับฟอนต์ยูนิโคด) ที่ผมนำมาใช้กับ sIFR ก็มีดังนี้ครับ
โค้ด:
function reType(target) {

// วรรณยุกต์
var reAccent = new String(mbchr(0x0E48)+mbchr(0x0E49)+mbchr(0x0E4A)+mbchr(0x0E4B)+mbchr(0x0E4C));
var reAccentLowLeft = new String(mbchr(0xF705)+mbchr(0xF706)+mbchr(0xF707)+mbchr(0xF708)+mbchr(0xF709));
var reAccentLowRight = new String(mbchr(0xF70A)+mbchr(0xF70B)+mbchr(0xF70C)+mbchr(0xF70D)+mbchr(0xF70E));
var reAccentUpperLeft = new String(mbchr(0xF713)+mbchr(0xF714)+mbchr(0xF715)+mbchr(0xF716)+mbchr(0xF717));

// สระที่อยู่ด้านบน
var reVowelUpper = new String(mbchr(0x0E34)+mbchr(0x0E35)+mbchr(0x0E36)+mbchr(0x0E37)+mbchr(0x0E31)+mbchr(0x0E4D)+mbchr(0x0E47));
var reVowelUpperLeft = new String(mbchr(0xF701)+mbchr(0xF702)+mbchr(0xF703)+mbchr(0xF704)+mbchr(0xF710)+mbchr(0xF711)+mbchr(0xF712));

// สระที่อยู่ด้านล่าง
var reVowelLow = new String(mbchr(0x0E38)+mbchr(0x0E39)+mbchr(0x0E3A));
var reVowelLower = new String(mbchr(0xF718)+mbchr(0xF719)+mbchr(0xF71A));

// ญ หญิง
var reYoying = new String(mbchr(0x0E0D));
var reYoyingNoBase = new String(mbchr(0xF70F));

// ฐ ฐาน
var reThothan = new String(mbchr(0x0E10));
var reThothanNoBase = new String(mbchr(0xF700));

// ตัวอักษรพิเศษ ยาวบนกับยาวล่าง
var reAlphabetLongTail = new String(mbchr(0x0E1B)+mbchr(0x0E1D)+mbchr(0x0E1F));
var reAlphabetLongBase = new String(mbchr(0x0E0E)+mbchr(0x0E0F));

// สระอำ
var reSaraAm = new String(mbchr(0x0E33));
var reSaraAmLeft = new String(mbchr(0xF711)+mbchr(0x0E32));

// กำหนด resultString
var resultString:String = "";

// ทำ Loop เพื่อพิจารณาตัวอักษรทีละตัว
for (var i = 0; i < target.length; i++) {

var char = target.charAt(i);
//var charCode = target.charCodeAt(i);

var isBeforeVowelLow = (reVowelLow.indexOf(target.charAt(i+1)) > -1) && (i+1 < target.length);
// มี ญ หญิง ?
var hasYoying = (reYoying == char);
// มี ฐ ฐาน ?
var hasThothan = (reThothan == char);
// มีสระอำ ?
var hasAm = (reSaraAm == char);
// ตำแหน่งวรรณยุกต์
var atAccent = reAccent.indexOf(char);
// ตำแหน่งสระบน
var atVowelUpper = reVowelUpper.indexOf(char);
// ตำแหน่งสระล่าง
var atVowelLow = reVowelLow.indexOf(char);
// อยู่หน้าสระล่าง ?
var isBeforeVowelLow = (reVowelLow.indexOf(target.charAt(i+1)) > -1) && (i+1 < target.length);
// ตามหลัง ปฝฟ ?
var isAfterLongTail = (reAlphabetLongTail.indexOf(target.charAt(i-1)) > -1) && (i >= 1);
// ตามหลัง ปฝฟ สองตัว ?
var isDoubleAfterLongTail = (reAlphabetLongTail.indexOf(target.charAt(i-2)) > -1) && (i > 1);
// อยู่ก่อนหน้าสระอำ ?
var isBeforeAm = (reSaraAm.indexOf(target.charAt(i+1)) > -1) && (i+1 < target.length);
// อยู่หลังสระบน ?
var isAfterVowelUpper = (reVowelUpper.indexOf(target.charAt(i-1)) > -1) && (i > 0);
// อยู่หลังสระล่าง ?
var isAfterVowelLow = (reVowelLow.indexOf(target.charAt(i-1)) > -1) && (i > 0);
// อยู่หลังฐานยาว ?
var isAfterLongBase = (reAlphabetLongBase.indexOf(target.charAt(i-1)) > -1) && (i > 0);
// อยู่หลังวรรณยุกต์ ?
var isAfterAccent = (reAccent.indexOf(target.charAt(i-1)) > -1) && (i > 0);
// ขึ้นบรรทัดใหม่ ?
var isNewLine = (char == newline);

// ญ หญิง
if (!isNewLine && hasYoying && isBeforeVowelLow) { // MAJ
resultString += reYoyingNoBase;
}
// ฐ ฐาน
else if (!isNewLine && hasThothan && isBeforeVowelLow) { // MAJ
resultString += reThothanNoBase;
}
// สระอำ
else if (!isNewLine && hasAm && (isAfterLongTail || (isDoubleAfterLongTail && isAfterAccent))) { // MAJ
resultString += reSaraAmLeft;
}
// วรรณยุกต์
else if (!isNewLine && (atAccent > -1)) { // MAJ
var addedVar = new String();
// ล่างซ้าย
if ((isAfterLongTail && !isBeforeAm) || (isDoubleAfterLongTail && isAfterVowelLow)) {
var addedVar = reAccentLowLeft.charAt(atAccent);
}
// บนขวา
else if ((!isDoubleAfterLongTail && isAfterVowelUpper) || (!isAfterLongTail && isBeforeAm)) {
var addedVar = char;
}
// บนซ้าย
else if ((isDoubleAfterLongTail && isAfterVowelUpper) || (isAfterLongTail && isBeforeAm)) {
var addedVar = reAccentUpperLeft.charAt(atAccent);
}
// ล่างขวา
else {
var addedVar = reAccentLowRight.charAt(atAccent);
}
resultString += addedVar;
}
// สระบนหลบซ้าย
else if (!isNewLine && (atVowelUpper > -1) && (isAfterLongTail || isDoubleAfterLongTail)) { // MAJ
var vowelVar = reVowelUpperLeft.charAt(atVowelUpper);
resultString += vowelVar;
}
// สระล่างกว่า
else if (!isNewline && (atVowelLow > -1) && isAfterLongBase) { // MAJ
var lowVar = reVowelLower.charAt(atVowelLow);
resultString += lowVar;
}
// นอกเหนือจากนี้ถือว่า ...
else { // MAJ
resultString += char;
}
}

return resultString;

}

function openType(target) {

// fi
var fi = new String(mbchr(0xFB01));
// f & i
var fRe = "f";
var iRe = "i";

var resultString = "";

for (var i = 0; i < target.length; i++) {
char = target.charAt(i);
isF = (fRe == char);
isBeforeI = (target.charAt(i+1) == iRe) && (i+1 < target.length);
isAfterF = (target.charAt(i-1) == fRe) && (i >= 1);
isntNewLine = (char != newline);

if (isntNewLine && isBeforeI) {
resultString += fi;
}
else if (isntNewLine && isAfterF) {
resultString += "";
}
else {
resultString += char;
}
}

return resultString;

}

ส่วนจะเป็นประโยชน์ยังไงนั้น
เหมือนกับพิมพ์พรีวิวให้สระไม่ลอยประมาณนั้นแหละครับ

<a href="http://zf.f0nt.com/stor/Thai.swf" target="_blank">http://zf.f0nt.com/stor/Thai.swf</a>

(เคยเห็นป้ามิตรเอามาโพสต์แล้วครั้งหนึ่ง)
บันทึกการเข้า
เก่งจริงๆ เร่  เจ๋ง

สามารถแกะ source code แล้วแยกแนวคิดออกมาสรุปได้ เจ๋งจริงๆ
เคยเอา source code ของ katopz มาแปลงเป็น delphi เหมือนกัน
แล้วก็เปลี่ยนวิธีการจัดการอักษรเพราะของเดิมมีบักอยู่เยอะเอาการเลย
(หมายถึงตัวเก่านะ ตัวใหม่ไม่รู้ แต่คาดว่าคงจักการไปได้เยอะแล้ว)
ก็เกือบจะเสร็จแล้วล่ะ แต่ติดตรงสระอำมั้ง บวกกับขี้เกียจ หมดไฟ เลยทิ้งเอาดื้อๆ  ฮิ้ววว

สระอำมันจะเป็นการรวม   ํ กับ า เข้ามาเป็น   ำ  ตอนนั้นมึนเลยเลิก
« แก้ไขครั้งสุดท้าย: 04 มิ.ย. 2006, 18:33 น. โดย นายโอ้เอ้ » บันทึกการเข้า

Today you , Tomorrow me.
+1 เร่ไม่ได้

รอตูเป็นหมูก่อนนะ
บันทึกการเข้า
เจ๋ง

วันนี้ตอนขับรถไปส่งเสื้อ
นั่งนึกถึงบทความใน blognone ที่ว่า Adobe จะเลิกผลิต Golive แล้วก็ Freehand
แล้วก็หันมาดัดให้ Dream อะไรงี้ หน้าตาคล้ายๆ Adobe เข้าไปทุกที
ก็เลยนึกต่อไปว่า ยังงี้พวก OpenType ใน Flash ก็คงไม่ใช่อนาคตที่ำไกลเกินเอื้อม


เผลอๆ จะมีในรุ่นต่อไปด้วยซ้ำ - Adobe Flash CS3 เอือม
บันทึกการเข้า

ทำมาหากินด้วยการเปิดร้านสกรีนเสื้อยืด จ้ะ
CS3
เอือม
บันทึกการเข้า
ไม่ใช่ๆ

ต้องเป็น

Lantom  Flash CSaam

  กร๊าก
บันทึกการเข้า
เหรอ
บันทึกการเข้า

สะพรึบสะพรั่ง ณหน้าและหลัง ณซ้ายและขวา ละหมู่ละหมวด ก็ตรวจก็ตรา ประมวลกะมา สิมากประมาณ
โอ้วส์ จอร์จ มันยอดมาก  กรี๊ดดดดด

นี่ก็เป็นอีกหนึ่ง ของบุคคลที่น่าเอาเยี่ยงอย่างครับ

จากคนที่ไม่มีอะไรเลย ทำอะไรไม่เป็น
เก่งก็ไม่เก่ง ห่วย แย่ สำมะเลเทเมา มั่ว ชุ่ย

วันนี้เขากลายเป็นคนๆหนึ่ง ที่โปรมาก

ขอตบกบาลตัวเองให้ในความพยายามครับ  เจ๋ง

ปล1. ตูอ่านไม่จบ เพราะ 15 บรรทัดแรกก็ไม่รู้เรื่องเสียแล้ว
ปล2. ขอ +1 งามๆ (ชอบบวกให้คนที่ทำเพื่อส่วนรวมครับ
แต่ไม่ค่อยจะมาโพสบอกว่า "บวกให้นะ" เพราะส่วนตัวไม่ค่อยชอบวัฒนธรรมนี้)
บันทึกการเข้า
ดีจัง เค้าบวกให้นะตัวเอง
บันทึกการเข้า

สะพรึบสะพรั่ง ณหน้าและหลัง ณซ้ายและขวา ละหมู่ละหมวด ก็ตรวจก็ตรา ประมวลกะมา สิมากประมาณ
จากคนที่ไม่มีอะไรเลย ทำอะไรไม่เป็น
เก่งก็ไม่เก่ง ห่วย แย่ สำมะเลเทเมา มั่ว ชุ่ย
เฮ้ย อย่าเน้น  โวย
บันทึกการเข้า
หน้า: [1] 2
 
 
Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2007, Simple Machines | Thai language by ThaiSMF Valid XHTML 1.0! Valid CSS!