Real length of a Thai UTF-8 encoded string in Delphi

Viewed 919

Thai is a very special language. You can write vowels (32 in total) as in any other languages right after the consonant, or IN FRONT of it, or ON TOP of it, or ON THE BOTTOM of it (ok, just the short and long "u" sound can go on the bottom, but anyway...).

Furthermore, there are other modifiers (the 4 tone markers, the ga-ran, the mai-tai-ku and other ones) that can go ON TOP of an already existing vowel!

For example:

 ที่ดีที่สุด (the best)

As you can see, if I try to print it with a monospaced font, the "real length" would be of 5 characters, but all the UTF-8 strlen routines give me back 11 characters - which is TOTALLY CORRECT, but I need to know the "actual space" that the string will use on screen/on printer, when printed monospaced.

Sure, an easy solution would be to list all the special characters that can go on the top or on the bottom of the word, and remove them from the total count.

Since I am not sure I can find all the special characters, is there already a routine made in any language so that I can translate it in Delphi?

Thank you

1 Answers

In C++:

    /*---------------------------------------------------------------------------*/
    /*                              thai_tcslen                                  */
    /*---------------------------------------------------------------------------*/
    long thai_tcslen(_TCHAR *buff)
    {
      long bufpos = 0;
      long normal_length = _tcslen(buff);
      long thai_length = 0;

      for (bufpos = 0; bufpos < normal_length; ++bufpos) {
        if (   *(buff+bufpos) != _T('Ñ')/*mai han na kaad*//*-047*/
            && *(buff+bufpos) != _T('Ô')/*sara ee        *//*-044*/
            && *(buff+bufpos) != _T('Õ')/*sara eeeee     *//*-043*/
            && *(buff+bufpos) != _T('Ö')/*sara uu        *//*-042*/
            && *(buff+bufpos) != _T('×')/*sara uuuuu     *//*-041*/
            && *(buff+bufpos) != _T('Ø')/*sara oo        *//*-040*/
            && *(buff+bufpos) != _T('Ù')/*sara ooooo     *//*-039*/
            && *(buff+bufpos) != _T('ç')/*mai tai khoo   *//*-025*/
            && *(buff+bufpos) != _T('è')/*mai aek        *//*-024*/
            && *(buff+bufpos) != _T('é')/*mai toe        *//*-023*/
            && *(buff+bufpos) != _T('ê')/*mai cha ta wah *//*-022*/
            && *(buff+bufpos) != _T('ë')/*mai tree       *//*-021*/
            && *(buff+bufpos) != _T('ì')/*ka ran         *//*-020*/
            ) {
          ++thai_length;
        }
      }

      return thai_length;
    } /* thai_tcslen */

in VB6:

    Public Function ThaiStringLength(ByRef ThaiString As String) As Long
      Dim b As String, noLengthChars(13) As Byte
      b = ThaiString

      noLengthChars(0) = 209
      noLengthChars(1) = 212
      noLengthChars(2) = 213
      noLengthChars(3) = 214
      noLengthChars(4) = 215
      noLengthChars(5) = 216
      noLengthChars(6) = 217
      noLengthChars(7) = 231
      noLengthChars(8) = 232
      noLengthChars(9) = 233
      noLengthChars(10) = 234
      noLengthChars(11) = 235
      noLengthChars(12) = 236

      Dim o As Long
      For o = 0 To 12
        If InStr(b, Chr(noLengthChars(o))) > 0 Then
          b = Replace(b, Chr(noLengthChars(o)), "")
        End If
      Next
      ThaiStringLength = Len(b)
    End Function
Related