add explicit freetype2 linking
[charfbuzz.git] / hb-unicode.c
blob53862e6db7e90afb058efbc0f0bad27cd25b28c1
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
6 #include <stdlib.h>
8 #include "hb.h"
9 #include "hb-private.h"
10 #include "hb-atomic-private.h"
11 #include "hb-unicode-private.h"
13 static hb_unicode_combining_class_t
14 hb_unicode_combining_class_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,
15 hb_codepoint_t unicode HB_UNUSED,
16 void *user_data HB_UNUSED)
18 return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
21 static unsigned int hb_unicode_eastasian_width_nil(hb_unicode_funcs_t *
22 ufuncs HB_UNUSED,
23 hb_codepoint_t unicode
24 HB_UNUSED,
25 void *user_data HB_UNUSED)
27 return 1;
30 static hb_unicode_general_category_t
31 hb_unicode_general_category_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,
32 hb_codepoint_t unicode HB_UNUSED,
33 void *user_data HB_UNUSED)
35 return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
38 static hb_codepoint_t hb_unicode_mirroring_nil(hb_unicode_funcs_t *
39 ufuncs HB_UNUSED,
40 hb_codepoint_t unicode HB_UNUSED,
41 void *user_data HB_UNUSED)
43 return unicode;
46 static hb_script_t hb_unicode_script_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,
47 hb_codepoint_t unicode HB_UNUSED,
48 void *user_data HB_UNUSED)
50 return HB_SCRIPT_UNKNOWN;
53 static hb_bool_t hb_unicode_compose_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,
54 hb_codepoint_t a HB_UNUSED,
55 hb_codepoint_t b HB_UNUSED,
56 hb_codepoint_t * ab HB_UNUSED,
57 void *user_data HB_UNUSED)
59 return FALSE;
62 static hb_bool_t hb_unicode_decompose_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,
63 hb_codepoint_t ab HB_UNUSED,
64 hb_codepoint_t * a HB_UNUSED,
65 hb_codepoint_t * b HB_UNUSED,
66 void *user_data HB_UNUSED)
68 return FALSE;
71 static unsigned int hb_unicode_decompose_compatibility_nil(hb_unicode_funcs_t *
72 ufuncs HB_UNUSED,
73 hb_codepoint_t u
74 HB_UNUSED,
75 hb_codepoint_t *
76 decomposed HB_UNUSED,
77 void *user_data
78 HB_UNUSED)
80 return 0;
83 /*must be public*/
84 hb_unicode_funcs_t _hb_unicode_funcs_nil = {
85 REF_CNT_INVALID_VAL, /*ref_cnt */
86 NULL, /*parent */
87 TRUE, /*immutable */
88 { /*func */
89 hb_unicode_combining_class_nil,
90 hb_unicode_eastasian_width_nil,
91 hb_unicode_general_category_nil,
92 hb_unicode_mirroring_nil,
93 hb_unicode_script_nil,
94 hb_unicode_compose_nil,
95 hb_unicode_decompose_nil,
96 hb_unicode_decompose_compatibility_nil}
98 { /*user_data */
99 NULL, /*combining_class */
100 NULL, /*eastasian_width */
101 NULL, /*general_category */
102 NULL, /*mirroring */
103 NULL, /*script */
104 NULL, /*compose */
105 NULL, /*decompose */
106 NULL /*decompose_compatibility */
109 { /*destroy */
110 NULL, /*combining_class */
111 NULL, /*eastasian_width */
112 NULL, /*general_category */
113 NULL, /*mirroring */
114 NULL, /*script */
115 NULL, /*compose */
116 NULL, /*decompose */
117 NULL /*decompose_compatibility */
122 Default_Ignorable codepoints:
124 Note that as of Oct 2012 (Unicode 6.2), U+180E MONGOLIAN VOWEL SEPARATOR
125 is NOT Default_Ignorable, but it really behaves in a way that it should
126 be. That has been reported to the Unicode Technical Committee for
127 consideration. As such, we include it here, since Uniscribe removes it.
128 It *is* in Unicode 6.3 however. U+061C ARABIC LETTER MARK from Unicode
129 6.3 is also added manually. The new Unicode 6.3 bidi formatting
130 characters are encoded in a block that was Default_Ignorable already.
132 Note: While U+115F and U+1160 are Default_Ignorable, we do NOT want to
133 hide them, as the way Uniscribe has implemented them is with regular
134 spacing glyphs, and that's the way fonts are made to work. As such,
135 we make exceptions for those two.
137 Gathered from:
138 http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:DI:]&abb=on&ucd=on&esc=on
140 Last updated to the page with the following versions:
141 Version 3.6; ICU version: 50.0.1.0; Unicode version: 6.1.0.0
143 4,167 Code Points
145 [\u00AD\u034F\u115F\u1160\u17B4\u17B5\u180B-\u180D\u200B-\u200F\u202A-\u202E\u2060-\u206F\u3164\uFE00-\uFE0F\uFEFF\uFFA0\uFFF0-\uFFF8\U0001D173-\U0001D17A\U000E0000-\U000E0FFF]
147 00AD ;SOFT HYPHEN
148 034F ;COMBINING GRAPHEME JOINER
149 #115F ;HANGUL CHOSEONG FILLER
150 #1160 ;HANGUL JUNGSEONG FILLER
151 17B4 ;KHMER VOWEL INHERENT AQ
152 17B5 ;KHMER VOWEL INHERENT AA
153 180B..180D ;MONGOLIAN FREE VARIATION SELECTOR THREE
154 200B..200F ;RIGHT-TO-LEFT MARK
155 202A..202E ;RIGHT-TO-LEFT OVERRIDE
156 2060..206F ;NOMINAL DIGIT SHAPES
157 3164 ;HANGUL FILLER
158 FE00..FE0F ;VARIATION SELECTOR-16
159 FEFF ;ZERO WIDTH NO-BREAK SPACE
160 FFA0 ;HALFWIDTH HANGUL FILLER
161 FFF0..FFF8 ;<unassigned-FFF8>
162 1D173..1D17A ;MUSICAL SYMBOL END PHRASE
163 E0000..E0FFF ;<unassigned-E0FFF>
166 hb_bool_t hb_unicode_is_default_ignorable(hb_codepoint_t ch)
168 hb_codepoint_t plane;
170 plane = ch >> 16;
171 if (plane == 0) {
172 hb_codepoint_t page;
173 /*BMP*/ page = ch >> 8;
174 switch (page) {
175 case 0x00:
176 return ch == 0x00AD;
177 case 0x03:
178 return ch == 0x034F;
179 case 0x06:
180 return ch == 0x061C;
181 case 0x17:
182 return hb_codepoint_in_range(ch, 0x17B4, 0x17B5);
183 case 0x18:
184 return hb_codepoint_in_range(ch, 0x180B, 0x180E);
185 case 0x20:
186 return hb_codepoint_in_ranges(ch, 0x200B, 0x200F,
187 0x202A, 0x202E, 0x2060,
188 0x206F);
189 case 0x31:
190 return ch == 0x3164;
191 case 0xFE:
192 return hb_codepoint_in_range(ch, 0xFE00, 0xFE0F)
193 || ch == 0xFEFF;
194 case 0xFF:
195 return hb_codepoint_in_range(ch, 0xFFF0, 0xFFF8)
196 || ch == 0xFFA0;
197 default:
198 return FALSE;
200 } else {
201 /*Other planes */
202 switch (plane) {
203 case 0x01:
204 return hb_codepoint_in_range(ch, 0x0001D173,
205 0x0001D17A);
206 case 0x0E:
207 return hb_codepoint_in_range(ch, 0x000E0000,
208 0x000E0FFF);
209 default:
210 return FALSE;
215 hb_unicode_funcs_t *hb_unicode_funcs_get_empty(void)
217 return &_hb_unicode_funcs_nil;
220 hb_unicode_funcs_t *hb_unicode_funcs_reference(hb_unicode_funcs_t * ufuncs)
222 if (hb_atomic_int32_get(&ufuncs->ref_cnt) != REF_CNT_INVALID_VAL)
223 hb_atomic_int32_add(&ufuncs->ref_cnt, 1);
224 return ufuncs;
227 extern hb_unicode_funcs_t *hb_glib_get_unicode_funcs(void);
228 extern hb_unicode_funcs_t *hb_nil_get_unicode_funcs(void);
230 hb_unicode_funcs_t *hb_unicode_funcs_get_default(void)
232 #ifdef HAVE_GLIB
233 return hb_glib_get_unicode_funcs();
234 #else
235 return hb_unicode_funcs_get_empty();
236 #endif
239 void hb_unicode_funcs_destroy(hb_unicode_funcs_t * ufuncs)
241 if (!ufuncs)
242 return;
243 if (hb_atomic_int32_get(&ufuncs->ref_cnt) == REF_CNT_INVALID_VAL)
244 return;
245 hb_atomic_int32_add(&ufuncs->ref_cnt, -1);
246 if (hb_atomic_int32_get(&ufuncs->ref_cnt) > 0)
247 return;
248 hb_atomic_int32_set(&ufuncs->ref_cnt, REF_CNT_INVALID_VAL);
250 if (ufuncs->destroy.combining_class)
251 ufuncs->destroy.combining_class(ufuncs->user_data.
252 combining_class);
253 if (ufuncs->destroy.eastasian_width)
254 ufuncs->destroy.eastasian_width(ufuncs->user_data.
255 eastasian_width);
256 if (ufuncs->destroy.general_category)
257 ufuncs->destroy.general_category(ufuncs->user_data.
258 general_category);
259 if (ufuncs->destroy.mirroring)
260 ufuncs->destroy.mirroring(ufuncs->user_data.mirroring);
261 if (ufuncs->destroy.script)
262 ufuncs->destroy.script(ufuncs->user_data.script);
263 if (ufuncs->destroy.compose)
264 ufuncs->destroy.compose(ufuncs->user_data.compose);
265 if (ufuncs->destroy.decompose)
266 ufuncs->destroy.decompose(ufuncs->user_data.decompose);
267 if (ufuncs->destroy.decompose_compatibility)
268 ufuncs->destroy.decompose_compatibility(ufuncs->user_data.
269 decompose_compatibility);
271 hb_unicode_funcs_destroy(ufuncs->parent);
272 free(ufuncs);