Mailbox support for texture layers.
[chromium-blink-merge.git] / third_party / harfbuzz / contrib / harfbuzz-unicode.c
blobf8302167246a8ffb24acbee8dd6221a73120dd33
1 #include <stdint.h>
2 #include <stdlib.h>
4 #include <harfbuzz-external.h>
5 #include <harfbuzz-impl.h>
6 #include <harfbuzz-shaper.h>
7 #include "harfbuzz-unicode.h"
9 #include "tables/grapheme-break-properties.h"
10 #include "tables/mirroring-properties.h"
11 #include "tables/script-properties.h"
13 uint32_t
14 utf16_to_code_point(const uint16_t *chars, size_t len, ssize_t *iter) {
15 const uint16_t v = chars[(*iter)++];
16 if (HB_IsHighSurrogate(v)) {
17 // surrogate pair
18 if (*iter >= len) {
19 // the surrogate is incomplete.
20 return HB_InvalidCodePoint;
22 const uint16_t v2 = chars[(*iter)++];
23 if (!HB_IsLowSurrogate(v2)) {
24 // invalidate surrogate pair.
25 return HB_InvalidCodePoint;
28 return HB_SurrogateToUcs4(v, v2);
31 if (HB_IsLowSurrogate(v)) {
32 // this isn't a valid code point
33 return HB_InvalidCodePoint;
36 return v;
39 uint32_t
40 utf16_to_code_point_prev(const uint16_t *chars, size_t len, ssize_t *iter) {
41 const uint16_t v = chars[(*iter)--];
42 if (HB_IsLowSurrogate(v)) {
43 // surrogate pair
44 if (*iter < 0) {
45 // the surrogate is incomplete.
46 return HB_InvalidCodePoint;
48 const uint16_t v2 = chars[(*iter)--];
49 if (!HB_IsHighSurrogate(v2)) {
50 // invalidate surrogate pair.
51 return HB_InvalidCodePoint;
54 return HB_SurrogateToUcs4(v2, v);
57 if (HB_IsHighSurrogate(v)) {
58 // this isn't a valid code point
59 return HB_InvalidCodePoint;
62 return v;
65 static int
66 script_property_cmp(const void *vkey, const void *vcandidate) {
67 const uint32_t key = (uint32_t) (intptr_t) vkey;
68 const struct script_property *candidate = vcandidate;
70 if (key < candidate->range_start) {
71 return -1;
72 } else if (key > candidate->range_end) {
73 return 1;
74 } else {
75 return 0;
79 HB_Script
80 code_point_to_script(uint32_t cp) {
81 const void *vprop = bsearch((void *) (intptr_t) cp, script_properties,
82 script_properties_count,
83 sizeof(struct script_property),
84 script_property_cmp);
85 if (!vprop)
86 return HB_Script_Common;
88 return ((const struct script_property *) vprop)->script;
91 char
92 hb_utf16_script_run_next(unsigned *num_code_points, HB_ScriptItem *output,
93 const uint16_t *chars, size_t len, ssize_t *iter) {
94 if (*iter == len)
95 return 0;
97 output->pos = *iter;
98 const uint32_t init_cp = utf16_to_code_point(chars, len, iter);
99 unsigned cps = 1;
100 if (init_cp == HB_InvalidCodePoint)
101 return 0;
102 const HB_Script init_script = code_point_to_script(init_cp);
103 HB_Script current_script = init_script;
104 output->script = init_script;
106 for (;;) {
107 if (*iter == len)
108 break;
109 const ssize_t prev_iter = *iter;
110 const uint32_t cp = utf16_to_code_point(chars, len, iter);
111 if (cp == HB_InvalidCodePoint)
112 return 0;
113 cps++;
114 const HB_Script script = code_point_to_script(cp);
116 if (script != current_script) {
117 if (current_script == HB_Script_Inherited && init_script == HB_Script_Inherited) {
118 // If we started off as inherited, we take whatever we can find.
119 output->script = script;
120 current_script = script;
121 continue;
122 } else if (script == HB_Script_Inherited) {
123 continue;
124 } else {
125 *iter = prev_iter;
126 cps--;
127 break;
132 if (output->script == HB_Script_Inherited)
133 output->script = HB_Script_Common;
135 output->length = *iter - output->pos;
136 if (num_code_points)
137 *num_code_points = cps;
138 return 1;
141 char
142 hb_utf16_script_run_prev(unsigned *num_code_points, HB_ScriptItem *output,
143 const uint16_t *chars, size_t len, ssize_t *iter) {
144 if (*iter == (size_t) -1)
145 return 0;
147 const size_t ending_index = *iter;
148 const uint32_t init_cp = utf16_to_code_point_prev(chars, len, iter);
149 unsigned cps = 1;
150 if (init_cp == HB_InvalidCodePoint)
151 return 0;
152 const HB_Script init_script = code_point_to_script(init_cp);
153 HB_Script current_script = init_script;
154 output->script = init_script;
156 for (;;) {
157 if (*iter < 0)
158 break;
159 const ssize_t prev_iter = *iter;
160 const uint32_t cp = utf16_to_code_point_prev(chars, len, iter);
161 if (cp == HB_InvalidCodePoint)
162 return 0;
163 cps++;
164 const HB_Script script = code_point_to_script(cp);
166 if (script != current_script) {
167 if (current_script == init_script == HB_Script_Inherited) {
168 // If we started off as inherited, we take whatever we can find.
169 output->script = script;
170 current_script = script;
171 continue;
172 } else if (script == HB_Script_Inherited) {
173 // Just assume that whatever follows this combining character is within
174 // the same script. This is incorrect if you had language1 + combining
175 // char + language 2, but that is rare and this code is suspicious
176 // anyway.
177 continue;
178 } else {
179 *iter = prev_iter;
180 cps--;
181 break;
186 if (output->script == HB_Script_Inherited)
187 output->script = HB_Script_Common;
189 output->pos = *iter + 1;
190 output->length = ending_index - *iter;
191 if (num_code_points)
192 *num_code_points = cps;
193 return 1;
196 static int
197 grapheme_break_property_cmp(const void *vkey, const void *vcandidate) {
198 const uint32_t key = (uint32_t) (intptr_t) vkey;
199 const struct grapheme_break_property *candidate = vcandidate;
201 if (key < candidate->range_start) {
202 return -1;
203 } else if (key > candidate->range_end) {
204 return 1;
205 } else {
206 return 0;
210 HB_GraphemeClass
211 HB_GetGraphemeClass(HB_UChar32 ch) {
212 const void *vprop = bsearch((void *) (intptr_t) ch, grapheme_break_properties,
213 grapheme_break_properties_count,
214 sizeof(struct grapheme_break_property),
215 grapheme_break_property_cmp);
216 if (!vprop)
217 return HB_Grapheme_Other;
219 return ((const struct grapheme_break_property *) vprop)->klass;
222 HB_WordClass
223 HB_GetWordClass(HB_UChar32 ch) {
224 abort();
225 return 0;
228 HB_SentenceClass
229 HB_GetSentenceClass(HB_UChar32 ch) {
230 abort();
231 return 0;
234 void
235 HB_GetGraphemeAndLineBreakClass(HB_UChar32 ch, HB_GraphemeClass *gclass, HB_LineBreakClass *breakclass) {
236 *gclass = HB_GetGraphemeClass(ch);
237 *breakclass = HB_GetLineBreakClass(ch);
240 static int
241 mirroring_property_cmp(const void *vkey, const void *vcandidate) {
242 const uint32_t key = (uint32_t) (intptr_t) vkey;
243 const struct mirroring_property *candidate = vcandidate;
245 if (key < candidate->a) {
246 return -1;
247 } else if (key > candidate->a) {
248 return 1;
249 } else {
250 return 0;
254 HB_UChar16
255 HB_GetMirroredChar(HB_UChar16 ch) {
256 const void *mprop = bsearch((void *) (intptr_t) ch, mirroring_properties,
257 mirroring_properties_count,
258 sizeof(struct mirroring_property),
259 mirroring_property_cmp);
260 if (!mprop)
261 return ch;
263 return ((const struct mirroring_property *) mprop)->b;
266 void *
267 HB_Library_Resolve(const char *library, int version, const char *symbol) {
268 abort();
269 return NULL;