--- /dev/null
+;; KHMR-OTF.flt -- Font Layout Table for Khmer OpenType fonts
+;; Copyright (C) 2005
+;; National Institute of Advanced Industrial Science and Technology (AIST)
+;; Registration Number H15PRO112
+
+;; This file is part of the m17n database; a sub-part of the m17n
+;; library.
+
+;; The m17n library is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU Lesser General Public License
+;; as published by the Free Software Foundation; either version 2.1 of
+;; the License, or (at your option) any later version.
+
+;; The m17n library is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; Lesser General Public License for more details.
+
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with the m17n library; if not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+;; 02111-1307, USA.
+
+;;; <li> KHMR-OTF.flt
+;;;
+;;; For Khmer OpenType fonts to draw Khmer.
+;;; A Font is available from
+;;; <http://www.khmeros.info/drupal/?q=en/download/fonts>.
+
+(category
+ ;; E : else
+ ;; C : consonant & independent vowel
+ ;; R : RO
+ ;; r : ROBAT
+ ;; m : vowel sign (pre)
+ ;; b : vowel sign (below)
+ ;; a : vowel sign (above)
+ ;; A : vowel sign (two-part, above)
+ ;; p : vowel sign (post)
+ ;; P : vowel sign (two-part, post)
+ ;; s : sign (above)
+ ;; S : sign (post)
+ ;; c : consonant shifter
+ ;; H : COENG
+ ;; N : ZERO WIDTH NON-JOINER
+ ;; J : ZERO WIDTH JOINER
+ (0x1780 0x17FF ?E)
+ (0x19E0 0x19FF ?E)
+ (0x1780 0x17B3 ?C)
+ (0x179A ?R)
+;; (0x17A3 0x17B3 ?V)
+ (0x17B6 ?p)
+ (0x17B7 0x17BA ?a)
+ (0x17BB 0x17BD ?b)
+ (0x17BE ?A)
+ (0x17BF 0x17C0 ?P)
+ (0x17C1 0x17C3 ?m)
+ (0x17C4 0x17C5 ?P)
+ (0x17C6 ?s)
+ (0x17C7 0x17C8 ?S)
+ (0x17C9 0x17CA ?c)
+ (0x17CB 0x17D1 ?s)
+ (0x17CC ?r)
+ (0x17D2 ?H)
+ (0x17D3 ?s)
+ (0x17DD ?s)
+ (0x200C ?N)
+ (0x200D ?J)
+ )
+
+;; Generic syllable pattern is as follows.
+;; [CR](r|N?c)?(HCr?)*(HR)?(HCr?)*[NJ]?(m|b|a|A|p|P)?s*S?(H[CR])?
+
+;; Step 0.
+;; Move m to the beginning.
+;; Split A and P.
+;; Exchange the order of pP and s.
+;; Move HR before the base.
+
+(generator
+ (0
+ (cond
+
+ ;; pre vowel sign
+ ;;1 2 3 4 56 7 8 9
+ ("([CR](r|N?c)?(HCr?)*)(HR)?((HCr?)*[NJ]?)(m)(s*S?(H[CR])?)"
+ < |
+ (7 =)
+ (4 = =)
+ (1 = *)
+ (5 = *)
+ (8 = *)
+ | > )
+
+ ;; two-part above vowel sign
+ ;;1 2 3 4 56 7
+ ("([CR](r|N?c)?(HCr?)*)(HR)?((HCr?)*[NJ]?As*S?(H[CR])?)"
+ < |
+ 0x17C1
+ (4 = =)
+ (1 = *)
+ (5 = *)
+ | > )
+
+ ;; post vowel sign
+ ;;1 2 3 4 56 7 8 9 10
+ ("([CR](r|N?c)?(HCr?)*)(HR)?((HCr?)*[NJ]?)(p)(s*)(S?(H[CR])?)"
+ < |
+ (4 = =)
+ (1 = *)
+ (5 = *)
+ (8 = *)
+ (7 =)
+ (9 = *)
+ | > )
+
+ ;; two-part post vowel sign
+ ;;1 2 3 4 56 7 8 9 10
+ ("([CR](r|N?c)?(HCr?)*)(HR)?((HCr?)*[NJ]?)(P)(s*)(S?(H[CR])?)"
+ < |
+ 0x17C1
+ (4 = =)
+ (1 = *)
+ (5 = *)
+ (8 = *)
+ (7 =)
+ (9 = *)
+ | > )
+
+ ;; other vowel signs or no vowel sign
+ ;;1 2 3 4 56 7
+ ("([CR](r|N?c)?(HCr?)*)(HR)?((HCr?)*[NJ]?[b|a]?s*S?(H[CR])?)"
+ < |
+ (4 = =)
+ (1 = *)
+ (5 = *)
+ | > )
+
+ ("." =))
+ *))
+
+;; Now a syllable looks like below.
+;; m?(HR)?[CR](r|N?c)?(HCr?)*[NJ]?(b|a|A)?s*(p|P)?S?(H[CR])?
+
+;; Step 1.
+;; Set the form of consonant shifter.
+
+(generator
+ (0
+ (cond
+ ;; shifter + above vowel sign without ZWNJ
+ ;; Shifter take blwf. HR takes pref. HC's take blwf or pstf.
+ ;; 1 2 3 4 5 6 7 8
+ (" (m)?(HR)?([CR]c(HCr?)*(N|J)?(a|A))(s*S?)(H[CR])? "
+ |
+ (1 =)
+ (2 otf:khmr=pref+)
+ (3 otf:khmr=blwf,abvf,pstf+)
+ (7 = *)
+ (8 otf:khmr=blwf,pstf+)
+ | )
+
+ ;; shifter + ZWNJ + above vowel sign, or, shifter without above vowel sign
+ ;; Shifter stays above. HR takes pref. HC's take blwf or pstf.
+ ;; 1 2 3 45 6 7 8 9 10 11
+ (" (m)?(HR)?([CR]N?c)((HCr?)*)([NJ]?[ba]?)(A)?(s*p?)(P)?(S)?(H[CR])? "
+ |
+ (1 =)
+ (2 otf:khmr=pref+)
+ (3 = *)
+ (4 otf:khmr=blwf,pstf+)
+ (6 = *)
+ (7 otf:khmr=abvf+)
+ (8 = *)
+ (9 otf:khmr=pstf+)
+ (10 =)
+ (11 otf:khmr=blwf,pstf+)
+ | )
+
+ ;; no shifter
+ ;; 1 2 3 45 6 7 8 9 10 11
+ (" (m)?(HR)?([CR]r?)((HCr?)*)([NJ]?[ba]?)(A)?(s*p?)(P)?(S)?(H[CR])? "
+ |
+ (1 =)
+ (2 otf:khmr=pref+)
+ (3 = *)
+ (4 otf:khmr=blwf,pstf+)
+ (6 = *)
+ (7 otf:khmr=abvf+)
+ (8 = *)
+ (9 otf:khmr=pstf+)
+ (10 =)
+ (11 otf:khmr=blwf,pstf+)
+ | )
+
+ ("." =))
+ *))
+
+;; Now a syllable looks like below. ~ characters are OTF feature applied.
+;; m?(HR)?[CR](r|c)?(HCr?)*[NJ]?(b|a|A)?s*(p|P)?S?(H[CR])?
+;; ~~ ~~ ~ ~~~~ ~ ~ ~~~~~
+
+;; Step 2.
+;; Concatenate adjacent Khmer syllables.
+;; Remove J. Retain N to prevent ligature.
+
+(generator
+ (0
+ (cond
+ (" ")
+ ("J")
+ ("." =))
+ *))
+
+;; Step 3.
+;; Apply other OTF features.
+
+(generator
+ (0
+ (cond
+ (" ([^ ]*) "
+ (1 otf:khmr=pres,blws,abvs,psts,clig))
+ ("."
+ [ otf:sinh=+ ]))
+ *))
+
+;; Step 4.
+;; Remove N to clean up.
+(generator
+ (0
+ (cond
+ ("N")
+ ("." =))
+ *))
+
+;; Local Variables:
+;; mode: emacs-lisp
+;; End: