-;; MLYM-OTF.flt -- Font Layout Table for Malayalam OpenType font
-;; Copyright (C) 2003, 2004, 2005, 2007 AIST (H15PRO112)
+;; MLYM-OTF.flt -- Font Layout Table for Malayalam OpenType fonts
+;; Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010 AIST (H15PRO112)
;; See the end for copying conditions.
(font layouter mlym-otf nil
- (font (nil nil unicode-bmp :otf=mlym=akhn)))
+ (version "1.6.0")
+ (font (nil nil unicode-bmp :otf=mlym)))
;;; <li> MLYM-OTF.flt
;;;
;;; For Malayalam OpenType fonts to draw the reformed Malayalam script.
+;; AnjaliOldLipi.ttf, Dyuthi3.ttf, Meera_04.ttf, Rachana_04.ttf, suruma2.ttf
+;; blwf: 0d32
+;; pstf: 0d2f 0d30 0d35
+
+;; RaghuMalayalamSans2.ttf
+;; blwf: 0d32
+;; pstf: 0d2f 0d30 0d35 0d41
+
+;; lohit_ml.ttf
+;; blwf: 0d32
+;; pstf: 0d2f 0d30 0d31 0d35 0d41
+
+;; Kalyani121.ttf
+;; blwf: N/A
+;; pstf: 0d2f 0d30 0d32 0d35 0d41
+
(category
- ;; C: consonant (except for R, B, and P)
- ;; R: consonant RA
- ;; B: consonant (below)
- ;; P: consonant (post)
- ;; H: HALANT
- ;; m: vowel sign (pre)
- ;; p: vowel sign (post)
- ;; A: vowel modifier (post)
- ;; V: independent vowel
- ;; N: ZWNJ (ZERO WIDTH NON-JOINER)
- ;; J: ZWJ (ZERO WIDTH JOINER)
- ;; X: generic
- ;; Z: internal use
(0x0D00 0x0D7F ?X) ; generic
- (0x0D00 ?Z) ; internal use
(0x0D02 0x0D03 ?A) ; SIGN ANUSVARA .. VISARGA
(0x0D05 0x0D14 ?V) ; LETTER A .. AU
(0x0D15 0x0D39 ?C) ; LETTER KA .. HA
(0x0D30 ?R) ; LETTER RA
(0x0D32 ?B) ; LETTER LA
(0x0D35 ?P) ; LETTER VA
- (0x0D3E 0x0D43 ?p) ; VOWEL SIGN AA .. VOCALIC R
+ (0x0D3E 0x0D44 ?p) ; VOWEL SIGN AA .. VOCALIC RR
(0x0D46 0x0D48 ?m) ; VOWEL SIGN E .. AI
(0x0D4D ?H) ; SIGN VIRAMA
(0x0D57 ?p) ; AU LENGTH MARK
(0x0D60 0x0D61 ?V) ; LETTER VOCALIC RR .. VOCALIC LL
- (0x0964 0x0965 ?X) ; DANDA .. DOUBLE DANDA
+ (0x0D62 0x0D63 ?b) ; VOWEL SIGN VOCALIC L .. LL
+
(0x200C ?N) ; ZWNJ
(0x200D ?J) ; ZWJ
+ (0x25CC ?X) ; DOTTED CIRCLE
+
+ (pstf ?r)
)
-;; Decompose two-part vowels.
+;; Stage 0
+;; Preprocessing
(generator
(0
(cond
- ((0x0D4A)
- 0x0D46 0x0D3E)
- ((0x0D4B)
- 0x0D47 0x0D3E)
- ((0x0D4C)
- 0x0D46 0x0D57)
+ ;; Decompose two-part vowel signs
+ ((0x0D4A) 0x0D46 0x0D3E)
+ ((0x0D4B) 0x0D47 0x0D3E)
+ ((0x0D4C) 0x0D46 0x0D57)
+
("." =))
*))
-;; Syllable identification and reordering.
-;; Put the mark 0x0D00 before the first pre-base consonant and after
-;; the base consonant.
+;; Stage 1
+;; Syllable identification
(generator
(0
(cond
- ;; A syllable with a left vowel sign.
- ;;1 2 3 4
- ("([CRBP](H[CRBP])*)(m)(p?A?)"
- < | (3 =) (1 get-rh) 0x0D00 (1 move-h) (4 = *) | >)
-
- ;; A syllable with a right vowel sign and/or a vowel modifier.
- ;;1 2 3
- ("([CRBP](H[CRBP])*)(pA?|A)"
- < | (1 get-rh) 0x0D00 (1 move-h) (3 = *) | >)
+ ;; Consonant-based syllables
+ ;;1 23 4
+ ("([CBPR]((J?H|HJ?)[CBPR])*)(H[NJ]?|m?p?A?)"
+ < |
+ (cond
+ (".+HJ$" :otf=mlym=nukt,akhn+)
+ ("(.+)(H)N?$" (1 :otf=mlym=nukt,akhn+) (2 =) 0x200C)
+ (".+" :otf=mlym=nukt,akhn+))
+ | >)
+
+ ;; Syllables with an independent vowel
+ ("V(J?H[BPR])?m?p?A?"
+ < | = * | >)
+
+ ;; Two-part vowel signs
+ ((0x0D46 0x0D3E)
+ (cond
+ ((font-facility 0x25CC) < = 0x25CC = >)
+ (".+" [ 0x0D4A ])))
+ ((0x0D47 0x0D3E)
+ (cond
+ ((font-facility 0x25CC) < = 0x25CC = >)
+ (".+" [ 0x0D4B ])))
+ ((0x0D46 0x0D57)
+ (cond
+ ((font-facility 0x25CC) < = 0x25CC = >)
+ (".+" [ 0x0D4C ])))
+
+ ;; Combining marks are displayed with a DOTTED CIRCLE.
+ ("m"
+ (cond
+ ((font-facility 0x25CC) < = 0x25CC >)
+ ("." [ = ])))
+ ("[HbpA]"
+ (cond
+ ((font-facility 0x25CC) < 0x25CC = >)
+ ("." [ = ])))
+
+ ;; Isolated blwf and pstf are displayed with a DOTTED CIRCLE in the
+ ;; next stage.
+ ("(J)(H)([BPR])"
+ < | (1 =) (3 =) (2 =) | >)
- ;; Explicit Halant / forced chillu form is cut off from the preceders.
- ("(([CRBP]H)*)([CRBP]H[NJ])"
- (1 cut-off) (3 < | = * | >))
-
- ;; A syllable with no vowel signs/modifiers.
- ("([CRBP](H[CRBP])*H?)"
- < | (1 get-rh) 0x0D00 (1 move-h) | >)
+ ("." =))
+ *))
- ;; Starting with an independent vowel.
- ("(VA?)"
- < | (1 = *) | >)
+;; Stage 2
+;; Reorder halant for blwf and pstf
+(generator
+ (0
+ (cond
+ ;; Isolated blwf and pstf
+ (" J([BP]H) "
+ (cond
+ ((font-facility 0x25CC) < 0x25CC (1 :otf=mlym=blwf,pstf+) >)
+ (" J([BP]H) " [ (1 :otf=mlym=blwf,pstf+) ])))
+
+ ;; Isolated pref
+ (" J(RH) "
+ (cond
+ ((font-facility 0x25CC) < (1 :otf=mlym=pstf+) 0x25CC >)
+ (" J(RH) " [ (1 :otf=mlym=pstf+) ])))
+
+ ;; Overt halnt forms
+ (" ([^ ]+)(HN) "
+ | (1 reorder) (2 = =) |)
+
+ ;; Ordinary syllables
+ (" ([^mbpA ]+)(m?p?A?) "
+ | (1 reorder) (2 = *) |)
("." =))
*)
- ;; Extract RH that will be moved to the left.
- (get-rh
+ (reorder
(cond
- (".+HR$"
- 0x0D30 0x0D4D)))
-
- ;; Move the halant after the base consonant to the end.
- ;; Fill the resulting gap with 0x0D00.
- ;; Remove final RH if any.
- (move-h
+ ;; pref after pstf
+ ("(.|.+([^PJ]|JP))((J?HP)*J?HR)$"
+ (1 reorder-B *) (3 reorder-any *))
+ ;; pref between blwf and pstf
+ ("(.*[^J])(J?HR(J?HP)+)$"
+ (1 reorder-B *) (2 reorder-any *))
+ ;; pref before blwf
+ ("(.*[^J])(J?HR(J?HB)+(J?HP)*)$"
+ (1 reorder-B *) (2 reorder-any *))
+ ;; no pref
+ ("(.|.+([^PJ]|JP|HJ))((J?HP)*)$"
+ (1 reorder-B *) (3 reorder-any *))))
+
+ (reorder-B
(cond
- ;; There is a C and the syllable ends with an R. Remove final RH.
- ("([CRBPH]*C)H([RBPH]*)R$"
- (1 = *) 0x0D00 (2 = *))
+ ("J?(H)(B)"
+ (2 =) (1 =))
+ ("." =)))
- ;; The syllable ends other than R. Move H.
- ("([CRBPH]*C)(H)([RBPH]+)$"
- (1 = *) 0x0D00 (3 = *) (2 =))
-
- ;; No C and end with R. The first consonant will be the base. Remove RH.
- ("([RBP])H([RBPH]*)R$"
- (1 =) 0x0D00 (2 = *))
-
- ;; No C and not end with R. Move H.
- ("([RBP])(H)([RBPH]+)$"
- (1 =) 0x0D00 (3 = *) (2 =))
-
- ;; Otherwise, no need to move H.
- (".+"
- = * 0x0D00)))
-
- ;; If there are some letters make them a separate syllable.
- (cut-off
- (cond
- (".+"
- < | = * | >)))
+ (reorder-any
+ ("J?(H)(.)"
+ (2 =) (1 =)))
)
-;; Apply GSUB features.
-;; According to Microsoft Typography
-;; <http://www.microsoft.com/typography/otfntdev/malayot/features.htm>
-;; 'chillu' are generated with the 'haln' feature. However, some
-;; fonts generate them with 'half'.
+;; Stage 3
+;; Language forms and matra reordering
(generator
(0
(cond
- ;; Ordinary syllable. We must avoid applying 'blwf' and 'pstf' to
- ;; the first consonant. Also 'haln' and 'half' must be avoided
- ;; because chillu does not appear at the beginning of a word. Thus
- ;; we apply only 'akhn' here and postpone applying other features
- ;; to the next stage.
- ;; 1 2 3 4 5
- (" (m?(RH)?Z)([CRBPH]+)(Z)([RBPHpA]*) "
- | (1 = *) (3 otf:mlym=akhn+) (4 =) (5 otf:mlym=blwf,pstf+) |)
-
- ;; Explicit Halant.
- (" [CRBP]HN "
- = *)
+ ;; Overt halant forms
+ (" ([^ ]+)(HN) "
+ | (1 blwf-pstf) (2 = =) |)
- ;; Forced chillu form.
- (" ([CRBP]H)(J) "
- | (1 otf:mlym=haln,half+) (2 =) |)
-
- ;; Sequence that was cut off from a forced form. Again we apply
- ;; only 'akhn' here.
- (" ([CRBPH]+) "
- | (1 otf:mlym=akhn+) |)
+ ;; Other syllables
+ ;; 1 2 3
+ (" ([^mpA ]+)(m)?(p?A?) "
+ | (2 =) (1 blwf-pstf) (3 = *) |)
("." =))
- *))
+ *)
+
+ (blwf-pstf
+ (cond
+ ;;1 23 4
+ ("(.|.+BH|.+[^H])((PH)*)(RH)$"
+ (4 :otf=mlym=pstf) (1 :otf=mlym=blwf+) (2 :otf=mlym=pstf+))
+ ;;1 2 3
+ ("(.*)(RH)((PH)+)$"
+ (2 :otf=mlym=pstf+) (1 :otf=mlym=blwf+) (3 :otf=mlym=pstf+))
+ ;;1 2 34 5
+ ("(.*)(RH)((BH)+)((PH)*)$"
+ (2 :otf=mlym=pstf+) (1 :otf=mlym=blwf+) (3 :otf=mlym=blwf+)
+ (5 :otf=mlym=pstf+))
+ ;;1 2
+ ("(.|.+BH|.+[^H])((PH)*)$"
+ (1 :otf=mlym=blwf+) (2 :otf=mlym=pstf+))))
+ )
-;; Apply postoponed GSUB features to ordinary syllables.
+;; Stage 4
+;; Final reordering (Move pre-base matra and pref after the last halant)
(generator
(0
(cond
- ;; Ordinary syllable.
- ;; 1 2 3 4
- (" (m?(RH)?Z[^Z])([^Z]*)(Z[^ ]*) "
- | (1 = *) (3 otf:mlym=blwf,half,pstf,haln+) (4 = *) |)
+ ;; With a pref, one or more intermediate- and a final overt halant forms.
+ ;; 1 2 3
+ (" (r)([^ ]+HJ?)([^H ]+HN) "
+ | (2 = *) (1 =) (3 = *) |)
- ;; Explicit Halant / Forced chillu must not change to others.
- (" ([^ ]+)[NJ] "
- | (1 = *) |)
+ ;; With a pref and a final overt halant form. Don't move the pref.
+ (" r[^H ]+HN "
+ = *)
- ;; Cut off sequence.
- (" ([^ ])([^ ]*) "
- | (1 =) (2 otf:mlym=blwf,half,pstf,haln+) |)
+ ;; 1 2 3
+ (" (m?r?)([^ ]+HJ?)([^H ]+) "
+ | (2 = *) (1 = *) (3 = *) |)
("." =))
*))
-;; Second reordering. If there are glyphs before the base, move left
-;; vowel sign and RH to the left of the base.
+;; Stage 5
+;; Remove ZWNJ/ZWJ
(generator
(0
(cond
- ;; 1 2 3 4 5
- (" (m)?(RH)?Z([^Z]*)([^Z])Z([^ ]*) "
- | (3 = *) (1 =) (2 otf:mlym=pstf+) (4 =) (5 = *) |)
+ ("[NJ]")
("." =))
*))
-;; Apply substitutions and GPOS features.
+;; Stage 6
+;; GPOS processing
(generator
(0
(cond
(" ([^ ]+) "
- (1 otf:mlym=pres,abvs,blws,psts+abvm,blwm,dist))
- ("."
- [ = ]))
+ (1 :otf=mlym=+abvm,blwm,dist))
+
+ ("." =))
*))
-;; Copyright (C) 2003, 2004, 2005, 2007
+;; Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010
;; National Institute of Advanced Industrial Science and Technology (AIST)
;; Registration Number H15PRO112