Line data Source code
1 : /*
2 : Copyright: 2012 Barry Schwartz
3 : Create is_Ligature.c (using a python script) to test for Vulgar fractions
4 : Copyright: 2016 Joe Da Silva
5 : Re-write is_Ligature.c to test for ligatures, Vulgar and Other-fractions.
6 : Copyright: 2016 Gioele Barabucci
7 : Simplify makeutype.c code. Split is_Ligature.c, create is_Ligature_data.h
8 : License: BSD-3-clause
9 : Contributions:
10 : */
11 :
12 : #include "basics.h" /* for non-standard uint{16,32} typedefs */
13 : #include "is_Ligature_data.h"
14 : #include "utype.h"
15 : #include "chardata.h"
16 : #include <stdlib.h>
17 :
18 254 : static int compare_codepoints16(const void *uCode1, const void *uCode2) {
19 254 : const uint16 *cp1 = (const uint16 *)(uCode1);
20 254 : const uint16 *cp2 = (const uint16 *)(uCode2);
21 254 : return( (*cp1 < *cp2) ? -1 : ((*cp1 == *cp2) ? 0 : 1) );
22 : }
23 :
24 4 : static int compare_codepoints32(const void *uCode1, const void *uCode2) {
25 4 : const uint32 *cp1 = (const uint32 *)(uCode1);
26 4 : const uint32 *cp2 = (const uint32 *)(uCode2);
27 4 : return( (*cp1 < *cp2) ? -1 : ((*cp1 == *cp2) ? 0 : 1) );
28 : }
29 :
30 2 : int LigatureCount(void) {
31 2 : return( FF_ligatureTOTAL );
32 : }
33 :
34 2 : int VulgarFractionCount(void) {
35 2 : return( FF_vulgfracTOTAL );
36 : }
37 :
38 2 : int OtherFractionCount(void) {
39 2 : return( FF_fractionTOTAL );
40 : }
41 :
42 2 : int FractionCount(void) {
43 2 : return( FF_vulgfracTOTAL + FF_fractionTOTAL );
44 : }
45 :
46 14 : int32 Ligature_get_U(int n) {
47 14 : if ( n < 0 || n >= FF_ligatureTOTAL )
48 2 : return( -1 );
49 12 : if ( n < FF_ligatureTOTAL16 )
50 12 : return( (int32)(ligature16[n]) );
51 : else
52 0 : return( (int32)(ligature32[n-FF_ligatureTOTAL16]) );
53 : }
54 :
55 8 : int32 VulgFrac_get_U(int n) {
56 8 : if ( n < 0 || n >= FF_vulgfracTOTAL )
57 0 : return( -1 );
58 8 : if ( n < FF_vulgfracTOTAL16 )
59 8 : return( (int32)(vulgfrac16[n]) );
60 : else
61 0 : return( (int32)(vulgfrac32[n-FF_vulgfracTOTAL16]) );
62 : }
63 :
64 2 : int32 Fraction_get_U(int n) {
65 2 : if ( n < 0 || n >= FF_fractionTOTAL )
66 0 : return( -1 );
67 2 : if ( n < FF_fractionTOTAL16 )
68 0 : return( (int32)(fraction16[n]) );
69 : else
70 2 : return( (int32)(fraction32[n-FF_fractionTOTAL16]) );
71 : }
72 :
73 30 : int Ligature_find_N(uint32 uCode) {
74 : uint16 uCode16, *p16;
75 : uint32 *p32;
76 30 : int n=-1;
77 :
78 60 : if ( uCode < FF_ligature16FIRST || uCode > FF_ligature32LAST || \
79 56 : ((uCode < FF_UTYPE_MAXC) && (isligorfrac(uCode)==0)) )
80 4 : return( -1 );
81 26 : if ( uCode <= FF_ligature16LAST ) {
82 22 : uCode16 = uCode;
83 22 : p16 = (uint16 *)(bsearch(&uCode16, ligature16, FF_ligatureTOTAL16, \
84 : sizeof(uint16), compare_codepoints16));
85 22 : if ( p16 ) n = p16 - ligature16;
86 4 : } else if ( uCode >= FF_ligature32FIRST ) {
87 4 : p32 = (uint32 *)(bsearch(&uCode, ligature32, FF_ligatureTOTAL32, \
88 : sizeof(uint32), compare_codepoints32));
89 4 : if ( p32 ) n = p32 - ligature32 + FF_ligatureTOTAL16;
90 : }
91 26 : return( n );
92 : }
93 :
94 16 : int VulgFrac_find_N(uint32 uCode) {
95 : uint16 uCode16, *p16;
96 : uint32 *p32;
97 16 : int n=-1;
98 :
99 32 : if ( uCode < FF_vulgfrac16FIRST || uCode > FF_vulgfrac32LAST || \
100 32 : ((uCode < FF_UTYPE_MAXC) && (isligorfrac(uCode)==0)) )
101 0 : return( -1 );
102 16 : if (uCode <= FF_vulgfrac16LAST) {
103 16 : uCode16 = uCode;
104 16 : p16 = (uint16 *)(bsearch(&uCode16, vulgfrac16, FF_vulgfracTOTAL16, \
105 : sizeof(uint16), compare_codepoints16));
106 16 : if ( p16 ) n = p16 - vulgfrac16;
107 0 : } else if ( uCode >= FF_vulgfrac32FIRST ) {
108 0 : p32 = (uint32 *)(bsearch(&uCode, vulgfrac32, FF_vulgfracTOTAL32, \
109 : sizeof(uint32), compare_codepoints32));
110 0 : if (p32) n = p32 - vulgfrac32 + FF_vulgfracTOTAL16;
111 : }
112 16 : return( n );
113 : }
114 :
115 2 : int Fraction_find_N(uint32 uCode) {
116 : uint16 uCode16, *p16;
117 : uint32 *p32;
118 2 : int n=-1;
119 :
120 4 : if ( uCode < FF_fractionTOTAL16 || uCode > FF_fraction32LAST || \
121 4 : ((uCode < FF_UTYPE_MAXC) && (isligorfrac(uCode)==0)) )
122 0 : return( -1 );
123 2 : if ( uCode <= FF_fraction16LAST ) {
124 2 : uCode16 = uCode;
125 2 : p16 = (uint16 *)(bsearch(&uCode16, fraction16, FF_fractionTOTAL16, \
126 : sizeof(uint16), compare_codepoints16));
127 2 : if ( p16 ) n = p16 - fraction16;
128 0 : } else if ( uCode >= FF_fraction32FIRST ) {
129 0 : p32 = (uint32 *)(bsearch(&uCode, fraction32, FF_fractionTOTAL32, \
130 : sizeof(uint32), compare_codepoints32));
131 0 : if ( p32 ) n = p32 - fraction32 + FF_fractionTOTAL16;
132 : }
133 2 : return( n );
134 : }
135 :
136 : /* FontForge has a built-in internal table of ligatures. This function returns c */
137 : /* for ligature[n], so for example if ligature[n] is 'ae' then c is 2 {a=0,e=1}, */
138 : /* or if ligature[n] is 'ffi' then c is 3 {f=0,f=1,i=2}. Allowed range of n is 0 */
139 : /* to n < LigatureCount() (the size of the internal table), otherwise return -1. */
140 30 : int Ligature_alt_getC(int n) {
141 : int i,j;
142 :
143 30 : if ( n < 0 || n >= FF_ligatureTOTAL )
144 0 : return( -1 );
145 30 : if ( (i=ligatureAltI[n])&0x80 ) {
146 12 : j = i & 0x7f;
147 58 : for ( i=0; j; j=j>>1 )
148 46 : if ( j&1 ) ++i;
149 12 : return( i );
150 18 : } else if ( i < FF_ligatureTIS ) {
151 18 : return( ligatureAltIs[i+1] - ligatureAltIs[i] );
152 : } else {
153 0 : i -= FF_ligatureTIS;
154 0 : return( ligatureAltIl[i+1] - ligatureAltIl[i] );
155 : }
156 : }
157 :
158 : /* This function returns the unicode value for ligature[n][a]. Errors return -1. */
159 : /* allowed ranges: {0 <= n < LigatureCount()} & {0 <= a < Ligature_alt_getC(n)}. */
160 : /* For example, if ligature[n]='ae', then LigatureCount(n)=2 and the results are */
161 : /* alternate values of 'a'=Ligature_alt_getV(n,0) and 'e'=Ligature_alt_getV(n,1) */
162 20 : int32 Ligature_alt_getV(int n,int a) {
163 : int i,j;
164 : const unichar_t *upt;
165 : int32 u;
166 :
167 20 : if ( n < 0 || n >= FF_ligatureTOTAL || a<0 || a>=Ligature_alt_getC(n) )
168 4 : return( -1 );
169 16 : if ( (i=ligatureAltI[n])&0x80 ) {
170 4 : j = i & 0x7f;
171 18 : for ( i=0; a; ++i )
172 14 : if ( j&(1<<i) ) --a;
173 4 : u = Ligature_get_U(n);
174 4 : upt = unicode_alternates[u>>8][u&0xff];
175 4 : return( (int32)(upt[i]) );
176 12 : } else if ( i < FF_ligatureTIS ) {
177 12 : i = ligatureAltIs[i];
178 12 : u = ligatureAlt16[i+a];
179 12 : return( u );
180 : } else {
181 0 : i -= FF_ligatureTIS;
182 0 : i = ligatureAltIl[i];
183 0 : u = ligatureAlt32[i+a];
184 0 : return( u );
185 : }
186 : }
187 :
188 : /* This returns similar results like Ligature_alt_getC(n) but uses unicode input */
189 : /* uCode instead of ligature[n]. This isn't as speedy as c=Ligature_alt_getC(n). */
190 6 : int LigatureU_alt_getC(uint32 uCode) {
191 6 : return( Ligature_alt_getC(Ligature_find_N(uCode)) );
192 : }
193 :
194 6 : int32 LigatureU_alt_getV(uint32 uCode,int a) {
195 : int32 n;
196 :
197 6 : if ( (n=Ligature_find_N(uCode))<0 )
198 0 : return( -1 );
199 6 : return( Ligature_alt_getV(n,a) );
200 : }
201 :
202 14 : int VulgFrac_alt_getC(int n) {
203 : int i,j;
204 :
205 14 : if ( n < 0 || n >= FF_vulgfracTOTAL )
206 2 : return( -1 );
207 12 : if ( (i=vulgfracAltI[n])&0x80 ) {
208 12 : j = i & 0x7f;
209 54 : for ( i=0; j; j=j>>1 )
210 42 : if ( j&1 ) ++i;
211 12 : return( i );
212 0 : } else if ( i < FF_vulgfracTIS ) {
213 0 : return( vulgfracAltIs[i+1] - vulgfracAltIs[i] );
214 : } else {
215 0 : i -= FF_vulgfracTIS;
216 0 : return( vulgfracAltIl[i+1] - vulgfracAltIl[i] );
217 : }
218 : }
219 :
220 8 : int32 VulgFrac_alt_getV(int n,int a) {
221 : int i,j;
222 : const unichar_t *upt;
223 : int32 u;
224 :
225 8 : if ( n < 0 || n >= FF_vulgfracTOTAL || a<0 || a>=VulgFrac_alt_getC(n) )
226 0 : return( -1 );
227 8 : if ( (i=vulgfracAltI[n])&0x80 ) {
228 8 : j = i & 0x7f;
229 22 : for ( i=0; a; ++i )
230 14 : if ( j&(1<<i) ) --a;
231 8 : u = VulgFrac_get_U(n);
232 8 : upt = unicode_alternates[u>>8][u&0xff];
233 8 : return( (int32)(upt[i]) );
234 0 : } else if ( i < FF_vulgfracTIS ) {
235 0 : i = vulgfracAltIs[i];
236 0 : u = vulgfracAlt16[i+a];
237 0 : return( u );
238 : } else {
239 0 : i -= FF_vulgfracTIS;
240 0 : i = vulgfracAltIl[i];
241 0 : u = vulgfracAlt32[i+a];
242 0 : return( u );
243 : }
244 : }
245 :
246 0 : int VulgFracU_alt_getC(uint32 uCode) {
247 0 : return( VulgFrac_alt_getC(VulgFrac_find_N(uCode)) );
248 : }
249 :
250 0 : int32 VulgFracU_alt_getV(uint32 uCode,int a) {
251 : int32 n;
252 :
253 0 : if ( (n=VulgFrac_find_N(uCode))< 0 )
254 0 : return( -1 );
255 0 : return( VulgFrac_alt_getV(n,a) );
256 : }
257 :
258 0 : int Fraction_alt_getC(int n) {
259 : int i,j;
260 :
261 0 : if ( n < 0 || n >= FF_fractionTOTAL )
262 0 : return( -1 );
263 0 : if ( (i=fractionAltI[n])&0x80 ) {
264 0 : j = i & 0x7f;
265 0 : for ( i=0; j; j=j>>1 )
266 0 : if ( j&1 ) ++i;
267 0 : return( i );
268 0 : } else if ( i < FF_fractionTIS ) {
269 0 : return( fractionAltIs[i+1] - fractionAltIs[i] );
270 : } else {
271 0 : i -= FF_fractionTIS;
272 0 : return( fractionAltIl[i+1] - fractionAltIl[i] );
273 : }
274 : }
275 :
276 0 : int32 Fraction_alt_getV(int n,int a) {
277 : int i,j;
278 : const unichar_t *upt;
279 : int32 u;
280 :
281 0 : if ( n < 0 || n >= FF_fractionTOTAL || a<0 || a>=Fraction_alt_getC(n) )
282 0 : return( -1 );
283 0 : if ( (i=fractionAltI[n])&0x80 ) {
284 0 : j = i & 0x7f;
285 0 : for ( i=0; a; ++i )
286 0 : if ( j&(1<<i) ) --a;
287 0 : u = Fraction_get_U(n);
288 0 : upt = unicode_alternates[u>>8][u&0xff];
289 0 : return( (int32)(upt[i]) );
290 0 : } else if ( i < FF_fractionTIS ) {
291 0 : i = fractionAltIs[i];
292 0 : u = fractionAlt16[i+a];
293 0 : return( u );
294 : } else {
295 0 : i -= FF_fractionTIS;
296 0 : i = fractionAltIl[i];
297 0 : u = fractionAlt16[i+a];
298 0 : return( u );
299 : }
300 : }
301 :
302 0 : int FractionU_alt_getC(uint32 uCode) {
303 0 : return( Fraction_alt_getC(Fraction_find_N(uCode)) );
304 : }
305 :
306 0 : int32 FractionU_alt_getV(uint32 uCode,int a) {
307 : int32 n;
308 :
309 0 : if ( (n=Fraction_find_N(uCode))< 0 )
310 0 : return( -1 );
311 0 : return( Fraction_alt_getV(n,a) );
312 : }
313 : /* Boolean-style tests (found==0) to see if your codepoint value is listed */
314 : /* unicode.org codepoints for ligatures, vulgar fractions, other fractions */
315 :
316 4 : int is_LIGATURE(uint32 codepoint) {
317 4 : return( Ligature_find_N(codepoint)<0 );
318 : }
319 :
320 8 : int is_VULGAR_FRACTION(uint32 codepoint) {
321 8 : return( VulgFrac_find_N(codepoint)<0 );
322 : }
323 :
324 2 : int is_OTHER_FRACTION(uint32 codepoint) {
325 2 : return( Fraction_find_N(codepoint)<0 );
326 : }
327 :
328 0 : int is_FRACTION(uint32 codepoint) {
329 0 : return( VulgFrac_find_N(codepoint)<0 && Fraction_find_N(codepoint)<0 );
330 : }
331 :
332 0 : int is_LIGATURE_or_VULGAR_FRACTION(uint32 codepoint) {
333 0 : return( Ligature_find_N(codepoint)<0 && VulgFrac_find_N(codepoint)<0 );
334 : }
335 :
336 0 : int is_LIGATURE_or_OTHER_FRACTION(uint32 codepoint) {
337 0 : return( Ligature_find_N(codepoint)<0 && Fraction_find_N(codepoint)<0 );
338 : }
339 :
340 0 : int is_LIGATURE_or_FRACTION(uint32 codepoint) {
341 0 : return( Ligature_find_N(codepoint)<0 && VulgFrac_find_N(codepoint)<0 && Fraction_find_N(codepoint)<0 );
342 : }
343 :
|