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