Fix typo
[m17n/m17n-db.git] / BEN-OTF.flt
1 ;; BEN-OTF.flt -- Font Layout Table for Bengali OpenType font
2 ;; Copyright (C) 2004
3 ;;   National Institute of Advanced Industrial Science and Technology (AIST)
4 ;;   Registration Number H15PRO112
5
6 ;; This file is part of the m17n database; a sub-part of the m17n
7 ;; library.
8
9 ;; The m17n library is free software; you can redistribute it and/or
10 ;; modify it under the terms of the GNU Lesser General Public License
11 ;; as published by the Free Software Foundation; either version 2.1 of
12 ;; the License, or (at your option) any later version.
13
14 ;; The m17n library is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 ;; Lesser General Public License for more details.
18
19 ;; You should have received a copy of the GNU Lesser General Public
20 ;; License along with the m17n library; if not, write to the Free
21 ;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 ;; 02111-1307, USA.
23
24 ;;; <li> BEN-OTF.flt
25 ;;;
26 ;;; For Bengali OpenType fonts to draw Bengali script.  Tested with
27 ;;; MuktiNarrow.ttf <http://www.nongnu.org/freebangfont/index.html>
28 ;;; and
29 ;;; LikhanNormal.otf <http:http://www.stat.wisc.edu/~deepayan/Bengali/WebPage/Font/fonts.html>
30
31 (category
32  ;; C: consonant (excluding B, Y and R)
33  ;; B: consonant BA (below)
34  ;; Y: consonant YA (post)
35  ;; R: consonant RA (reph, below)
36  ;; n: NUKTA
37  ;; H: HALANT
38  ;; m: MATRA (pre)
39  ;; b: MATRA (below)
40  ;; p: MATRA (post)
41  ;; o: MATRA (two-part O)
42  ;; u: MATRA (two-part AU)
43  ;; U: AU LENGTH MARK
44  ;; A: vowel modifier (above)
45  ;; a: vowel modifier (post)
46  ;; V: independent vowel
47  ;; N: ZWNJ (ZERO WIDTH NON-JOINER)
48  ;; J: ZWJ (ZERO WIDTH JOINER)
49  ;; E: ELSE
50  ;;
51  (0x200C        ?N)                     ; ZWNJ
52  (0x200D        ?J)                     ; ZWJ
53  (0x0964 0x0965 ?E)                     ; DANDA, DOUBLE DANDA
54  (0x0980 0x09FF ?E)                     ; ELSE
55  (0x0981        ?A)                     ; SIGN CANDRABINDU (above)
56  (0x0982 0x0983 ?a)                     ; SIGN ANUSWAR, VISARGA (post)
57  (0x0985 0x098C ?V)                     ; LETTER A .. VOCALIC L
58  (0x098F 0x0990 ?V)                     ; LETTER E .. AI
59  (0x0993 0x0994 ?V)                     ; LETTER O .. AU
60  (0x0995 0x09B9 ?C)                     ; LETTER KA .. HA
61  (0x09AC        ?B)                     ; LETTER BA
62  (0x09AF        ?Y)                     ; LETTER YA
63  (0x09B0        ?R)                     ; LETTER RA
64  (0x09BC        ?n)                     ; SIGN NUKTA
65  (0x09BE        ?p)                     ; VOWEL SIGN AA (post)
66  (0x09BF        ?m)                     ; VOWEL SIGN I (pre)
67  (0x09C0        ?p)                     ; VOWEL SIGN II (post)
68  (0x09C1 0x09C4 ?b)                     ; VOWEL SIGN U, UU, R, RR (below)
69  (0x09C7 0x09C8 ?m)                     ; VOWEL SIGN E, AI (pre)
70  (0x09CB 0x09CC ?t)                     ; VOWEL SIGN O, AU (two-part)
71  (0x09CD        ?H)                     ; SIGN VIRAMA (HASANT)
72  (0x09D7        ?p)                     ; AU LENGTH MARK
73  (0x09DC 0x09DD ?C)                     ; LETTER RRA, RHA
74  (0x09DF        ?C)                     ; LETTER YYA
75  (0x09E0 0x09E1 ?V)                     ; LETTER VOCALIC RR, LL
76  (0x09E2 0x09E3 ?b)                     ; VOWEL SIGN L .. LL (below)
77  (0x09F1 0x09F2 ?C)                     ; LETTER RR', RR'' (assamese)
78  (0x09FE        ?x)                     ; mark #1 (internal use)
79  (0x09FF        ?y)                     ; mark #2 (internal use)
80  )
81
82 ;; Step 1 : Syllable identification.  Recognised syllables are quoted
83 ;; by the virtual character, which is generated by the command "|" and
84 ;; has the category " " (space).
85 (generator
86  (0
87   (cond
88    ;; Case A-C are for those syllables that end with an explicit vowel
89    ;; mark and/or a vowel modifier.  They are divided into three cases
90    ;; for the readability of regular expression.  The leading
91    ;; consonant-Hasant repetition is analysed for reordering in the
92    ;; next step.  Two-part vowel, if any, is split for
93    ;; canonicalisation.
94
95    ;; Case A : A syllable ending with a vowel modifier.
96    ("(([CRBY]n?H[NJ]?)*([CRBY]n?))([mbp]*)(t)?([Aa])"
97     < |
98     (1 set-marks)
99     (4 = *)
100     (5 split)
101     (6 =)
102     | >)
103
104    ;; Case B : A syllable ending with a two-part vowel.
105    ("(([CRBY]n?H[NJ]?)*([CRBY]n?))(t)"
106     < |
107     (1 set-marks)
108     (4 split)
109     | >)
110
111    ;; Case C : A syllable ending with other vowel.  Note that a
112    ;; two-part vowel may be expressed with two vowel marks for
113    ;; backward compatibility.
114    ("(([CRBY]n?H[NJ]?)*([CRBY]n?))([mbp]+)"
115     < |
116     (1 set-marks)
117     (4 = *)
118     | >)
119
120    ;; Case D : Ya-phalaa.  Reorder H and Y for the next step.
121    ;; The web page "Unicode FAQ for Indic Scripts and Languages"
122    ;; <http://www.unicode.org/faq/indic.html> says "it should be
123    ;; permissible for the Ya-phalla to be consistently formed by "ZWNJ
124    ;; + VIRAMA + YA".
125    ("([CBRY]N)(H)(Y)"
126     < |
127     (1 = =)
128     (3 =)
129     (2 =)
130     | >)
131
132    ;; Case E : No explicit vowel nor modifier.  If the syllable ends
133    ;; with a consonant, analyse it for reordering in the next step.
134    ;; Otherwise, just identify the syllable without changing anything.
135    ("([CRBY]n?H[NJ]?)*[CRBY]n?(HN|HJ|H)?"
136     (cond
137      (".+[^HNJ]$"
138       < | set-marks | >)
139      (".+"
140       < | = * | >)))
141
142    ;; Case F : Syllables that begin with an independent vowel.  An
143    ;; optional HYp sequence appears when this syllable represents the
144    ;; sound "a" in English "bat" (see the FAQ above).  If it appears,
145    ;; we reorder the H and Y for the next step.
146    ("(V)(HYp)?([aA])?"
147     < | (1 =) (2 ("HY(p)" 0x09AF 0x09CD (1 =))) (3 =) | >)
148
149    ("." =))
150   *)
151
152  ;; Set mark #1 (x) at the position where below consonants begin, and
153  ;; mark #2 (y) at the position to which below and above signs will be
154  ;; moved.
155  (set-marks
156   (cond
157    ;; At least one C and ends with Y.
158    ("(([CRBY]n?H[NJ]?)*Cn?)H(([BR]H)*)Y"
159     (1 = *)
160     0x09FE                              ; mark #1
161     (3 = *)                             ; below consonants
162     0x09FF                              ; mark #2
163     0x09AF 0x09CD)                      ; YA + moved HASANT
164    ;; At least one C and ends with B or R.
165    ("(([CRBY]n?H[NJ]?)*Cn?)H(([BR]H)*[BR])"
166     (1 = *)
167     0x09FE                              ; mark #1
168     (3 = *)                             ; below consonants 
169     0x09CD                              ; moved HASANT
170     0x09FF)                             ; mark #2
171    (".+"
172     = *
173     0x09FE                              ; mark #1
174     0x09FF)))                           ; mark #2
175
176  ;; Split two-part dependent vowel signs for canonicalisation.
177  (split
178   (cond
179    ((0x09CB)    0x09C7 0x09BE)
180    ((0x09CC)    0x09C7 0x09D7)))
181  )
182
183 ;; Step 2 : Move Reph and Matra if necessary.  From now on, we care
184 ;; for only those syllables that were identified in Step 1.
185 (generator
186  (0
187   (cond
188    ;; This is the most generic pattern.  It follows Case A-C and a
189    ;; part of Case E in Step 1.  Now Mark #1 is used to indicate the
190    ;; critical part that require pre-base substitution in the
191    ;; following steps.
192
193    ;; 1    2         3        4    5   6   7   8   9
194    (" (RH)?([^ xy]+)x([^ y]*)y(YH)?(m)?(b)?(p)?(A)?(a)? "
195     |
196     (5 =)                               ; [Mpre]
197     0x09FE
198     ;; Actually, the nukt feature is not necessary for Bengali because
199     ;; all the necessary Nukta forms are precomposed in the Unicode
200     ;; standard.  Even if a Nukta consonant is given in the form of
201     ;; the combination of the base consonant and a Nukta sign, we can
202     ;; safely perm the composition here because it does not affect
203     ;; surrounding letters in the syllable.  The Akhand ligature
204     ;; operation is also applied here, before applying the half form
205     ;; operation because the Mukti font generates Akhand ligatures
206     ;; directly from the "C H C" sequence, not via the half form.
207     (2 otf:beng=nukt,akhn)              ; {Cpre + H} + Cbase
208     0x09FE
209     (3 otf:beng=blwf)                   ; {Cbelow + H}
210     (6 =)                               ; [Mbelow]
211     (1 otf:beng=rphf)                   ; [Reph]
212     (8 =)                               ; [VMabove]
213     (4 otf:beng=pstf)                   ; [Cpost + H]
214     (7 =)                               ; [Mpost]
215     (9 =)                               ; [VMpost]
216     |)
217
218    ;; Syllables that begin with an independent vowel (following up
219    ;; Step 1, Case F).  If a YH sequence exist, it is changed to the
220    ;; post base form.  This type of syllables do not require further
221    ;; modification.
222    (" (V)(YH)(.*) "
223     |
224     (1 =)
225     (2 otf:beng=pstf)
226     (3 = *)
227     |)
228
229    ;; Ya-phalaa (following up Step 1, Case D).  Remove N and change YH
230    ;; to the post base form.  This type of syllables do not require
231    ;; further modification.
232    (" ([CBRY])N(YH) "
233     |
234     (1 =)
235     (2 otf:beng=pstf)
236     |)
237
238    ;; Syllables that end with H and an optional N or J (following up a
239    ;; part of Step 1, Case E).  This type of syllables also require
240    ;; pre-base substitution in the following steps.
241    (" ([^ ]+H[NJ]?) "
242     |
243     0x09FE
244     ;; Only Nukt and Akhn are applied here.  See the comment in the
245     ;; topmost sibling for explanation.
246     (1 otf:beng=nukt,akhn)
247     0x09FE
248     |)
249
250    ("." =))
251   *))
252
253 ;; Step 3 : Now only those syllables that contain the virtual
254 ;; character x require pre-base substition.  This is the most
255 ;; complicated part in this FLT.
256
257 ;; If the sequence "C1 H C2" makes ligature L12, L12 replaces the
258 ;; original sequence.
259
260 ;; To test the availability of such a ligature, we try to generate it
261 ;; using the pre-base substitute feature, then see whether succeeded
262 ;; or not.  In the case of failure, the pre-base feature does not
263 ;; change the original sequence.
264
265 ;; To create a ligature, the "C1 H" part must be first converted into
266 ;; the half form of C1.  Creating the half form of a consonant always
267 ;; succeeds.
268
269 ;; ligature(half(C1,H),C2)
270 ;; ==> ligature(C1half,C2)
271 ;; ==> L12         ; success
272 ;;     C1half C2   ; fail
273
274 ;; If the ligature is not available, the "C1 H" part must be converted
275 ;; into the _Halant_ (not half) form of C1.  However, there is no way
276 ;; to reconvert C1half into C1halant nor to revert back to "C1 H".
277 ;; Thus we duplicate the critical part in two different forms so that
278 ;; we can select the appropriate one in the next step.  The virtual
279 ;; character x is used to indicate the boundaries.
280
281 ;; ... C1 H C2 ...  ==>  ... x C1halant C2 x L12 x ...
282
283 ;; If the length of the L12 part is one, ligature generation was
284 ;; successful.  In this case we wipe out the duplicated C1halant and
285 ;; C2.  Otherwise we remove L12.
286
287 ;; In very few cases (I found only one in the Mukti font), the "C1 H"
288 ;; part need to be converted into C1halant to make a ligature with C2.
289 ;; So when try to generate a ligature form, we apply the GSUB features
290 ;; "half", "haln" and "pres" in this order.
291
292 (category
293  ;; C: consonant (excluding B, Y and R)
294  ;; H: HALANT
295  ;; N: ZWNJ (ZERO WIDTH NON-JOINER)
296  ;; J: ZWJ (ZERO WIDTH JOINER)
297  ;; E: ELSE
298  ;;
299  (0x200C        ?N)                     ; ZWNJ
300  (0x200D        ?J)                     ; ZWJ
301  (0x0964 0x0965 ?E)                     ; DANDA, DOUBLE DANDA
302  (0x0980 0x09FF ?E)                     ; ELSE
303  (0x09CD        ?H)                     ; SIGN VIRAMA (HASANT)
304  (0x0995        ?K)                     ; LETTER KA
305  (0x09B7        ?S)                     ; LETTER SSA
306  (0x09A8        ?M)                     ; LETTER NA
307  (0x09AE        ?M)                     ; LETTER MA
308  (0x09FE        ?x)                     ; mark #1 (internal use)
309  )
310
311 (generator
312  (0
313   (cond
314
315    ;; One pre-base and base.
316    ;; 1        23   4       5    6
317    (" ([^x ]*)x((.H)([^NJ]))(H)?x([^ ]*) "
318     |
319     (1 = *)
320     0x09FE                              ; x
321     (3 otf:beng=haln)                   ; C1halant
322     (4 =)                               ; C2
323     0x09FE                              ; x
324     (2 otf:beng=half,haln,pres)         ; ligature result
325     0x09FE                              ; x
326     (5 =)
327     (6 = *)
328     |)
329
330    ;; One pre-base with ZWJ.  According to the Unicode FAQ, the half
331    ;; form is forced in this case.  So we fake as if ligature
332    ;; generation was failed.
333    (" ([^x ]*)x(.H)J(.)?x([^ ]*) "
334     |
335     (1 = *)
336     0x09FE                              ; x
337     (2 otf:beng=half)                   ; C1half
338     (3 =)                               ; C2
339     0x09FE                              ; x
340     0x09FD                              ; pseudo result
341     0x09FD                              ; pseudo result
342     0x09FE                              ; x
343     (4 = *)
344     |)
345
346    ;; One pre-base possibly with ZWNJ.  Similar to above.
347    (" ([^x ]*)x(.H)N?(.)?x([^ ]*) "
348     |
349     (1 = *)
350     0x09FE                              ; x
351     (2 otf:beng=haln)                   ; C1halant
352     (3 =)                               ; C2
353     0x09FE                              ; x
354     0x09FD                              ; pseudo result
355     0x09FD                              ; pseudo result
356     0x09FE                              ; x
357     (4 = *)
358     |)
359
360    ;; Standalone base.  There is nothing more to do.
361    (" ([^x ]*)x(.)x([^ ]*) "
362     |
363     (1 = *)
364     (2 =)
365     (3 = *)
366     |)
367
368    ;; KA-SSA-NA and KA-SSA-MA are the only pre-base ligatures that
369    ;; consist of three consonants.
370    ;; 1        23   4   5   6    7
371    (" ([^x ]*)x((KH)(SH)(M))(H)?x([^ ]*) "
372     |
373     (1 = *)
374     0x09FE                              ; x
375     (3 otf:beng=haln)                   ; KAhalant
376     (4 otf:beng=haln)                   ; SSAhalant
377     (5 =)                               ; NA or MA
378     0x09FE                              ; x
379     (2 otf:beng=half,haln,pres)         ; ligature result
380     0x09FE                              ; x
381     (6 =)
382     (7 = *)
383     |)
384
385    ;; Two or more pre-bases plus base.  Give up.  Convert all
386    ;; pre-bases into halant form.
387    ;; 1        23             4       5
388    (" ([^x ]*)x(([^x]H[JN]?)+)([^x])?x([^ ]*) "
389     |
390     (1 = *)
391     0x09FE                              ; x
392     (2 force-haln)                      ; halant forms
393     (4 =)                               ; full form
394     0x09FE                              ; x
395     0x09FD                              ; pseudo result
396     0x09FD                              ; pseudo result
397     0x09FE                              ; x
398     (5 = *)
399     |)
400
401    ("." =))
402   *)
403
404  ;; This is to remove ZWNJ and ZWJ.  The half-form-force-effect of ZWJ
405  ;; is ignored.  Sorry.
406  (force-haln
407   (cond
408    ("([^JN]*)[JN](.*)"
409     (1 otf:beng=haln)
410     (2 force-haln))
411    (".+"
412     otf:beng=haln)))
413  )
414
415 ;; Step 4 : Select the appropriate representation.  Only those
416 ;; syllables that contain the virtual character x require
417 ;; modification.
418 (generator
419  (0
420   (cond
421    ;; Only one glyph in the ligature section (between the second and
422    ;; the third x).  It means a ligature was successfully generated.
423    ;; C1halant and C2 (between the first and second x) are removed.
424    (" ([^x ]*)x[^x]+x(.)x([^ ]*) "
425     |
426     (1 = *)
427     (2 =)
428     (3 = *)
429     |)
430
431    ;; Otherwise halant and base forms are used.  The failed ligature
432    ;; is removed.
433    (" ([^x ]*)x([^x]+)x[^x]+x([^ ]*) "
434     |
435     (1 = *)
436     (2 = *)
437     (3 = *)
438     |)
439
440    ;; No need to care the other cases.
441    ("." =))
442   *))
443
444 ;; Step 5 : Fine adjustments.  Select appropriate glyph variants and
445 ;; apply GPOS features.  Now the syllable boundary marks are removed
446 ;; so that the final step can find word boundaries.
447 (generator
448  (0
449   (cond
450    (" ([^ ]+) "
451     (1 otf:beng=blws,abvs,psts,vatu))
452    ("."
453     [ otf:beng=+ ] ))
454   *)
455  )
456
457 ;; Step 6 : Word initial substitute.  As the syllable boundaries has
458 ;; been eliminated in the previous step, this rule is applied to a run
459 ;; of Bengali glyphs, i.e. word by word.  We finally apply the init
460 ;; feature to the word initial gylphs and everything is over.
461 (generator
462  (0
463   ("(.)(.*)"
464    (1 otf:beng=init)
465    (2 = *))))
466
467 ;; Local Variables:
468 ;; mode: emacs-lisp
469 ;; End: