tv-util.el 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. ;;; tv-util.el --- support for Tai Viet -*- coding: utf-8 -*-
  2. ;; Copyright (C) 2007, 2008, 2009, 2010, 2011
  3. ;; National Institute of Advanced Industrial Science and Technology (AIST)
  4. ;; Registration Number H13PRO009
  5. ;; Keywords: multilingual, Tai Viet, i18n
  6. ;; This file is part of GNU Emacs.
  7. ;; GNU Emacs is free software: you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation, either version 3 of the License, or
  10. ;; (at your option) any later version.
  11. ;; GNU Emacs is distributed in the hope that it will be useful,
  12. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;; GNU General Public License for more details.
  15. ;; You should have received a copy of the GNU General Public License
  16. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  17. ;;; Code
  18. ;; Regexp matching with a sequence of Tai Viet characters.
  19. (defconst tai-viet-re "[\xaa80-\xaac2\xaadb-\xaadf]+")
  20. ;; Char-table of information about glyph type of Tai Viet characters.
  21. (defconst tai-viet-glyph-info
  22. (let ((table (make-char-table nil))
  23. (specials '((right-overhang . "ꪊꪋꪌꪍꪏꪓꪖꪜꪞꪡꪤꪨ")
  24. (left-overhang . "ꫂ")
  25. (combining-vowel . "ꪴꪰꪲꪳꪷꪸꪾ")
  26. (combining-tone . "꪿꫁")
  27. (misc . "-"))))
  28. ;; Set all TaiViet characters to `t'.
  29. (set-char-table-range table (cons #xaa80 #xaac2) t)
  30. (set-char-table-range table (cons #xaadb #xaadf) t)
  31. ;; Overwrite it for special characters.
  32. (dolist (elt specials)
  33. (let ((category (car elt))
  34. (chars (cdr elt)))
  35. (dotimes (i (length chars))
  36. (aset table (aref chars i) category))))
  37. table))
  38. (defun tai-viet-compose-string (from to string)
  39. "Compose Tai Viet characters in STRING between indices FROM and TO."
  40. (let* ((ch (aref string from))
  41. (info (aref tai-viet-glyph-info ch))
  42. prev-info)
  43. (if (eq info 'non-spacing)
  44. (compose-string string from (1+ from) (string ch ?\t)))
  45. (setq from (1+ from) prev-info info)
  46. (while (and (< from to)
  47. (>= #xaa80 (setq ch (aref string from)))
  48. (<= #xaaDF ch))
  49. (setq info (aref tai-viet-glyph-info ch))
  50. (if (and (eq info 'non-spacing)
  51. (eq prev-info 'non-spacing))
  52. (compose-string from (1+ from) (string ?\t ch)))
  53. (setq from (1+ from) prev-info info))
  54. (if (eq info 'right-overhang)
  55. (compose-string string (1- from) from (string ch ?\t)))
  56. from))
  57. (defun tai-viet-compose-region (from to)
  58. "Compose Tai Viet characters in the region between FROM and TO."
  59. (decompose-region from to)
  60. (let ((normal-rule '(Br . Bl))
  61. (tone-rule '(tr . bl))
  62. (prev-viet nil)
  63. ch info pos components overhang)
  64. (while (< from to)
  65. (or ch
  66. (setq ch (char-after from)
  67. info (aref tai-viet-glyph-info ch)))
  68. (setq from (1+ from))
  69. (if (not info)
  70. (setq prev-viet nil
  71. ch nil)
  72. (if (memq info '(combining-vowel combining-tone))
  73. (progn
  74. ;; Display this as a spacing glyph.
  75. (compose-region (1- from) from (string ?\t ch))
  76. (setq prev-viet t
  77. ch nil))
  78. (setq pos (1- from)
  79. components ch
  80. overhang (if (eq info 'right-overhang)
  81. 'right-overhang
  82. (if (and (not prev-viet) (eq info 'left-overhang))
  83. 'left-overhang))
  84. prev-viet t
  85. ch nil)
  86. (if (and (< from to)
  87. (setq ch (char-after from)
  88. info (aref tai-viet-glyph-info ch)))
  89. (if (memq info '(combining-vowel combining-tone))
  90. (progn
  91. (setq components
  92. (list components normal-rule ch)
  93. from (1+ from)
  94. ch nil)
  95. (if (and (< from to)
  96. (setq ch (char-after from)
  97. info (aref tai-viet-glyph-info ch))
  98. (eq info 'combining-tone))
  99. (setq components (nconc components
  100. (list tone-rule ch))
  101. from (1+ from)))
  102. (if (eq overhang 'left-overhang)
  103. (setq components (cons ?\t
  104. (cons normal-rule components)))
  105. (if (and (eq overhang 'right-overhang)
  106. (>= from to))
  107. (setq components (nconc components
  108. (list normal-rule ?\t)))))
  109. (compose-region pos from components))
  110. (if (eq overhang 'left-overhang)
  111. (compose-region pos from (string ?\t components))))
  112. (if (eq overhang 'left-overhang)
  113. (compose-region pos from (string ?\t components))
  114. (if (and (eq overhang 'right-overhang) (>= from to))
  115. (compose-region pos from (string components ?\t))))))))
  116. from))
  117. ;;;###autoload
  118. (defun tai-viet-composition-function (from to font-object string)
  119. (if string
  120. (if (string-match tai-viet-re string from)
  121. (tai-viet-compose-string from (match-end 0) string))
  122. (goto-char from)
  123. (if (looking-at tai-viet-re)
  124. (tai-viet-compose-region from (match-end 0)))))
  125. ;;
  126. (provide 'tai-viet-util)