summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/fonts/amiri/sources/quran.fea
blob: 39a22179d538b06885e425f1190df2268d103d54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#
# dagger alef
#

# In Quranic orthography, there are two forms of dagger alef; a superscript one
# that is a combining mark and a spacing one that is regular alef letter, the
# later is not encoded in Unicode yet. The spacing dagger alef is almost always
# preceded by a fatha mark and we use this fact to replace the combing dagger
# alef by a spacing one when preceded by fatha, a hack but should do the job
# until the proper character get encoded.

# substitute combining dagger alef preceded by fatha with the spacing one
feature calt {
  sub [uni064E] uni0670' by uni0670.isol;
} calt;

#
# floats
#

# Some Arabic characters are shaping transparent, just like combining marks,
# but are not combining marks, I call them float because they "float" between
# adjacent characters. When a float comes between two characters that would
# normally join, it will be placed between them over a connecting stroke, else
# it will just set on the baseline.
#
# This concept is not recognized by Unicode, so we have to hack our way in the
# font to override shaping decisions by OpenType engine.
#
# This includes:
# * the dagger alef above
# * standalone hamza (U+0621)
# * small waw and yaa (U+06E5, U+06E6)
#
# Since the layout engine will consider those characters non-joiners, it will
# break shaping between them, so we simply override this by replacing glyphs
# around the float with forms that they would normally take if it was not
# there, and replace the float wit its medial glyph that has a connecting
# stroke.

# do dagger alef first since in Unicode it is a combining mark so it does not
# break shaping, we just need to substitute it with the medial alternate
@before = [@aAyn.init @aAyn.medi @aBaa.init @aBaa.medi @aFaa.init @aFaa.medi
           @aHaa.init @aHaa.medi @aHeh.init @aHeh.medi @aKaf.init @aKaf.medi
           @aLam.init @aLam.medi @aMem.init @aMem.medi @aSad.init @aSad.medi
           @aSen.init @aSen.medi @aTaa.init @aTaa.medi];
@after  = [@aAlf.fina @aAyn.fina @aAyn.medi @aBaa.fina @aBaa.medi @aDal.fina
           @aFaa.fina @aFaa.medi @aHaa.fina @aHaa.medi @aHeh.fina @aHeh.medi
           @aKaf.fina @aKaf.medi @aLam.fina @aLam.medi @aMem.fina @aMem.medi
           @aNon.fina @aQaf.fina @aRaa.fina @aSad.fina @aSad.medi @aSen.fina
           @aSen.medi @aTaa.fina @aTaa.medi @aWaw.fina @aYaa.fina uni0640];

lookup MedialSmallAlef {
  sub uni0670.isol by uni0670.medi;
} MedialSmallAlef;

feature calt {
  lookupflag IgnoreMarks;
    sub @before'
        uni0670.isol' lookup MedialSmallAlef
        @after;
} calt;

@before.isol = [uni0626 uni0628 uni062A uni062B uni062C uni062D uni062E uni0633
                uni0634 uni0635 uni0636 uni0637 uni0638 uni0639 uni063A uni0641
                uni0642 uni0643 uni0644 uni0645 uni0646 uni0647 uni0649 uni064A
                uni06CC];
@before.init = [uni0626.init uni0628.init uni062A.init uni062B.init uni062C.init
                uni062D.init uni062E.init uni0633.init uni0634.init uni0635.init
                uni0636.init uni0637.init uni0638.init uni0639.init uni063A.init
                uni0641.init uni0642.init uni0643.init uni0644.init uni0645.init
                uni0646.init uni0647.init uni0649.init uni064A.init uni06CC.init];
@before.medi = [uni0626.medi uni0628.medi uni062A.medi uni062B.medi uni062C.medi
                uni062D.medi uni062E.medi uni0633.medi uni0634.medi uni0635.medi
                uni0636.medi uni0637.medi uni0638.medi uni0639.medi uni063A.medi
                uni0641.medi uni0642.medi uni0643.medi uni0644.medi uni0645.medi
                uni0646.medi uni0647.medi uni0649.medi uni064A.medi uni06CC.medi];
@before.fina = [uni0626.fina uni0628.fina uni062A.fina uni062B.fina uni062C.fina
                uni062D.fina uni062E.fina uni0633.fina uni0634.fina uni0635.fina
                uni0636.fina uni0637.fina uni0638.fina uni0639.fina uni063A.fina
                uni0641.fina uni0642.fina uni0643.fina uni0644.fina uni0645.fina
                uni0646.fina uni0647.fina uni0649.fina uni064A.fina uni06CC.fina];

@after.isol =  [uni0622 uni0623 uni0624 uni0625 uni0627 uni0629 uni062F uni0630
                uni0631 uni0632 uni0648];
@after.fina =  [uni0622.fina uni0623.fina uni0624.fina uni0625.fina uni0627.fina
                uni0629.fina uni062F.fina uni0630.fina uni0631.fina uni0632.fina
                uni0648.fina];

@before = [@before.isol @before.fina];
@after  = [@after.isol @before.isol @before.init];

@floats.isol = [uni0621 uni06E5 uni06E6 uni0670.isol];
@floats.medi = [uni0621.medi uni06E5.medi uni06E6.medi uni0670.medi];

lookup Before {
  sub @before.isol by @before.init;
  sub @before.fina by @before.medi;
} Before;

lookup After {
  sub @before.isol by @before.fina;
  sub @after.isol  by @after.fina;
  sub @before.init by @before.medi;
} After;

lookup MedialFloats {
  sub @floats.isol by @floats.medi;
} MedialFloats;

lookup FloatHamza {
  sub uni0621 by uni0621.float;
} FloatHamza;

lookup LamAlefIsol {
  sub uni0644 by uni0644.init_LamAlfIsol;
  sub uni0627 by uni0627.fina_LamAlfIsol;
} LamAlefIsol;

lookup LamAlefFina {
  sub uni0644.fina by uni0644.medi_LamAlfFina;
  sub uni0627      by uni0627.fina_LamAlfFina;
} LamAlefFina;

feature calt {
  lookupflag IgnoreMarks;
    # hamza between lam and alef needs special treatment as it should not have
    # a connecting stroke to avoid breaking lam-alef. Other floats don't
    # normally occur between lam and alef so we don't bothe handling them
    sub uni0644'      lookup LamAlefIsol
        uni0621'      lookup FloatHamza
        uni0627'      lookup LamAlefIsol;

    sub uni0644.fina' lookup LamAlefFina
        uni0621'      lookup FloatHamza
        uni0627'      lookup LamAlefFina;

    # everything else
    sub @before'      lookup Before
        @floats.isol' lookup MedialFloats
        @after'       lookup After;

    # handle two successive floats
    sub @before'      lookup Before
        @floats.isol' lookup MedialFloats
        @floats.isol' lookup MedialFloats
        @after'       lookup After;
} calt;

#
# sequential tanween
#
# The following marks are proposed for inclusion in Unicode 6.1:
# http://std.dkuug.dk/jtc1/sc2/wg2/docs/n3791.pdf
#
# We can use this temporary ligature hack for now.

# rlig as we want it to be applied before calt
feature rlig {
  sub uni064E uni064E by uni08F0; # fathatan
  sub uni064F uni064F by uni08F1; # dammatan
  sub uni0650 uni0650 by uni08F2; # kasratan
} rlig;


# small waw after isolated/final heh is lower than usual, so we use an
# alternate glyph for that
feature calt {
  lookupflag IgnoreMarks;
    sub [@aHeh.isol @aHeh.fina] [uni06E5]' by [uni06E5.low];
} calt;

# some glyphs need more room to accomodate madda mark, so we change the advance
# width on fly.
feature mark {
  # small waw
  pos [uni06E5.low]' <50 0 350 0> [uni06E4];

  # alef
  pos [uni0627.fina_Wide uni0627.fina_KafMemAlf uni0627.fina_MemAlfFina]' <250 0 250 0> [uni06E4];
  pos [uni0627]' <150 0 300 0> [uni06E4];
} mark;