contrib/OWB: add correct SDL dependency, fix compilers used
[AROS-Contrib.git] / freetype1 / test / arabic.c
blob76b9b2b24024612ab7c97428664acb18dc6a4903
1 /****************************************************************************/
2 /* */
3 /* The FreeType project -- a free and portable quality TrueType renderer. */
4 /* */
5 /* Copyright 1996-1999 by */
6 /* D. Turner, R.Wilhelm, and W. Lemberg */
7 /* */
8 /* arabic -- An implementation of the contextual algorithm given in the */
9 /* Unicode 2.0 book to assign the `isolated', `initial', `medial', and */
10 /* `final' properties to an input string of character codes for the Arabic */
11 /* script. */
12 /* */
13 /****************************************************************************/
15 #include <stdio.h>
16 #include <stdlib.h>
18 #include "arabic.h"
19 #include "freetype.h"
20 #include "ftxopen.h"
25 Here a table of the joining classes for characters in the range
26 U+0620 - U+06FF.
28 The following character also has a joining class:
30 U+200C ZERO WIDTH NON-JOINER -> causing
32 All other characters are given the joining class `none'.
36 joining_class arabic[] =
38 /* U+0620 */
39 none, none, right, right,
40 right, right, dual, right,
41 dual, right, dual, dual,
42 dual, dual, dual, right,
44 /* U+0630 */
45 right, right, right, dual,
46 dual, dual, dual, dual,
47 dual, dual, dual, none,
48 none, none, none, none,
50 /* U+0640 */
51 causing, dual, dual, dual,
52 dual, dual, dual, dual,
53 right, right, dual, transparent,
54 transparent, transparent, transparent, transparent,
56 /* U+0650 */
57 transparent, transparent, transparent, none,
58 none, none, none, none,
59 none, none, none, none,
60 none, none, none, none,
62 /* U+0660 */
63 none, none, none, none,
64 none, none, none, none,
65 none, none, none, none,
66 none, none, none, none,
68 /* U+0670 */
69 transparent, none, right, right,
70 none, right, right, right,
71 dual, dual, dual, dual,
72 dual, dual, dual, dual,
74 /* U+0680 */
75 dual, dual, dual, dual,
76 dual, dual, dual, dual,
77 right, right, right, right,
78 right, right, right, right,
80 /* U+0690 */
81 right, right, right, right,
82 right, right, right, right,
83 right, right, dual, dual,
84 dual, dual, dual, dual,
86 /* U+06A0 */
87 dual, dual, dual, dual,
88 dual, dual, dual, dual,
89 dual, dual, dual, dual,
90 dual, dual, dual, dual,
92 /* U+06B0 */
93 dual, dual, dual, dual,
94 dual, dual, dual, dual,
95 dual, dual, dual, dual,
96 dual, dual, dual, dual,
98 /* U+06C0 */
99 right, dual, right, right,
100 right, right, right, right,
101 right, right, right, right,
102 dual, right, dual, right,
104 /* U+06D0 */
105 dual, dual, right, right,
106 none, none, none, transparent,
107 transparent, transparent, transparent, transparent,
108 transparent, transparent, transparent, transparent,
110 /* U+06E0 */
111 transparent, transparent, transparent, transparent,
112 transparent, none, none, transparent,
113 transparent, none, transparent, transparent,
114 transparent, transparent, none, none,
116 /* U+06F0 */
117 none, none, none, none,
118 none, none, none, none,
119 none, none, dual, dual,
120 dual, none, none, none
124 struct cgc_
126 TT_UShort char_code;
127 TT_UShort glyph_index;
128 TT_UShort class;
131 typedef struct cgc_ cgc;
134 int compare_cgc( const void* a,
135 const void* b )
137 return ( ((cgc*)a)->glyph_index > ((cgc*)b)->glyph_index ) ?
138 1 : ( ( ((cgc*)a)->glyph_index == ((cgc*)b)->glyph_index ) ?
139 0 : -1 );
143 TT_Error Build_Arabic_Glyph_Properties( TT_CharMap char_map,
144 TT_UShort max_glyphs,
145 TTO_GDEFHeader** gdef )
147 TT_UShort i, j, num_glyphs;
149 cgc Arabic[0x0700 - 0x0620];
151 TT_UShort glyph_indices[0x700 - 0x0620];
152 TT_UShort classes[0x700 - 0x0620];
154 if ( !gdef )
155 return TT_Err_Invalid_Argument;
157 j = 0;
159 for ( i = 0x0620; i < 0x0700; i++ )
161 Arabic[j].char_code = i;
162 Arabic[j].class = ( arabic[i - 0x0620] == transparent ) ?
163 MARK_GLYPH : SIMPLE_GLYPH;
164 Arabic[j].glyph_index = TT_Char_Index( char_map, i );
165 if ( Arabic[j].glyph_index )
166 j++;
168 num_glyphs = j;
170 if ( !num_glyphs )
172 /* no Arabic font */
173 *gdef = NULL;
174 return TT_Err_Ok;
177 /* sort it */
179 qsort( Arabic, num_glyphs, sizeof ( cgc ), compare_cgc );
181 /* write it to the arrays, removing duplicates */
183 glyph_indices[0] = Arabic[0].glyph_index;
184 classes[0] = Arabic[0].class;
186 j = 1;
188 for ( i = 1; i < num_glyphs; i++ )
190 glyph_indices[j] = Arabic[i].glyph_index;
191 classes[j] = Arabic[i].class;
193 if ( glyph_indices[j - 1] != glyph_indices[j] )
194 j++;
196 num_glyphs = j;
198 TT_GDEF_Build_ClassDefinition( *gdef, max_glyphs, num_glyphs,
199 glyph_indices, classes );
201 return TT_Err_Ok;
205 /* The joining rules as given in the Unicode 2.0 book (characters are
206 here specified as appearing in the byte stream, i.e. *not* in
207 visual order). Joining classes are given in angle brackets, glyph
208 forms in square brackets. Glyphs affected by a specific rule are
209 enclosed with vertical bars.
211 Note: The description of the joining algorithm in the book is
212 severely broken. You can get a corrected version from
213 www.unicode.org (as of 29-Jun-1999, this hasn't appeared).
215 R1: <anything1> <transparent> <anything2>
217 apply joining rules for
218 <anything1> <anything2> -> [shape1] [shape2]
220 -> [shape1] [isolated] [shape2]
222 R2: <causing|left|dual> |<right>|
224 -> [final]
226 R3: |<left>| <causing|right|dual>
228 -> [initial]
230 R4: <causing|left|dual> |<dual>| <causing|right|dual>
232 -> [medial]
234 R5: <causing|left|dual> |<dual>| <!(causing|right|dual)>
236 -> [final]
238 R6: <!(causing|left|dual)> |<dual>| <causing|right|dual>
240 -> [initial]
242 R7: If R1-R6 fail:
244 <anything> -> [isolated] */
247 /* `direction' can be -1, 0, or 1 to indicate the last non-transparent
248 glyph, the current glyph, and the next non-transparent glyph,
249 respectively. */
251 static joining_class Get_Joining_Class( TT_UShort* string,
252 TT_UShort pos,
253 TT_UShort length,
254 int direction )
256 joining_class j;
259 while ( 1 )
261 if ( pos == 0 && direction < 0 )
262 return none;
264 pos += direction;
266 if ( pos >= length )
267 return none;
269 if ( string[pos] < 0x0620 ||
270 string[pos] >= 0x0700 )
272 if ( string[pos] == 0x200C )
273 return causing;
274 else
275 return none;
277 else
278 j = arabic[string[pos] - 0x0620];
280 if ( !direction || j != transparent )
281 return j;
286 TT_Error Assign_Arabic_Properties( TT_UShort* string,
287 TT_UShort* properties,
288 TT_UShort length )
290 joining_class previous, current, next;
292 TT_UShort i;
295 if ( !string || !properties || length == 0 )
296 return TT_Err_Invalid_Argument;
298 for ( i = 0; i < length; i++ )
300 previous = Get_Joining_Class( string, i, length, -1 );
301 current = Get_Joining_Class( string, i, length, 0 );
302 next = Get_Joining_Class( string, i, length, 1 );
304 /* R1 */
306 if ( current == transparent )
308 properties[i] |= isolated_p;
309 continue;
312 /* R2 */
314 if ( previous == causing ||
315 previous == left ||
316 previous == dual )
317 if ( current == right )
319 properties[i] |= final_p;
320 continue;
323 /* R3 */
325 if ( current == left )
326 if ( next == causing ||
327 next == right ||
328 next == dual )
330 properties[i] |= initial_p;
331 continue;
334 /* R4 */
336 if ( previous == causing ||
337 previous == left ||
338 previous == dual )
339 if ( current == dual )
340 if ( next == causing ||
341 next == right ||
342 next == dual )
344 properties[i] |= medial_p;
345 continue;
348 /* R5 */
350 if ( previous == causing ||
351 previous == left ||
352 previous == dual )
353 if ( current == dual )
354 if ( !( next == causing ||
355 next == right ||
356 next == dual ) )
358 properties[i] |= final_p;
359 continue;
362 /* R6 */
364 if ( !( previous == causing ||
365 previous == left ||
366 previous == dual ) )
367 if ( current == dual )
368 if ( next == causing ||
369 next == right ||
370 next == dual )
372 properties[i] |= initial_p;
373 continue;
376 /* R7 */
378 if ( current != none )
379 properties[i] |= isolated_p;
382 return TT_Err_Ok;
386 /* End */