OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2009,2010 Red Hat, Inc. | 2 * Copyright © 2009,2010 Red Hat, Inc. |
3 * Copyright © 2011,2012 Google, Inc. | 3 * Copyright © 2011,2012 Google, Inc. |
4 * | 4 * |
5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
6 * | 6 * |
7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 char *c = getenv ("HB_OPTIONS"); | 50 char *c = getenv ("HB_OPTIONS"); |
51 u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible"); | 51 u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible"); |
52 | 52 |
53 /* This is idempotent and threadsafe. */ | 53 /* This is idempotent and threadsafe. */ |
54 _hb_options = u; | 54 _hb_options = u; |
55 } | 55 } |
56 | 56 |
57 | 57 |
58 /* hb_tag_t */ | 58 /* hb_tag_t */ |
59 | 59 |
| 60 /** |
| 61 * hb_tag_from_string: |
| 62 * @str: (array length=len): |
| 63 * @len: |
| 64 * |
| 65 * |
| 66 * |
| 67 * Return value: |
| 68 * |
| 69 * Since: 1.0 |
| 70 **/ |
60 hb_tag_t | 71 hb_tag_t |
61 hb_tag_from_string (const char *s, int len) | 72 hb_tag_from_string (const char *str, int len) |
62 { | 73 { |
63 char tag[4]; | 74 char tag[4]; |
64 unsigned int i; | 75 unsigned int i; |
65 | 76 |
66 if (!s || !len || !*s) | 77 if (!str || !len || !*str) |
67 return HB_TAG_NONE; | 78 return HB_TAG_NONE; |
68 | 79 |
69 if (len < 0 || len > 4) | 80 if (len < 0 || len > 4) |
70 len = 4; | 81 len = 4; |
71 for (i = 0; i < (unsigned) len && s[i]; i++) | 82 for (i = 0; i < (unsigned) len && str[i]; i++) |
72 tag[i] = s[i]; | 83 tag[i] = str[i]; |
73 for (; i < 4; i++) | 84 for (; i < 4; i++) |
74 tag[i] = ' '; | 85 tag[i] = ' '; |
75 | 86 |
76 return HB_TAG_CHAR4 (tag); | 87 return HB_TAG_CHAR4 (tag); |
77 } | 88 } |
78 | 89 |
| 90 /** |
| 91 * hb_tag_to_string: |
| 92 * @tag: |
| 93 * @buf: (array fixed-size=4): |
| 94 * |
| 95 * |
| 96 * |
| 97 * Since: 1.0 |
| 98 **/ |
79 void | 99 void |
80 hb_tag_to_string (hb_tag_t tag, char *buf) | 100 hb_tag_to_string (hb_tag_t tag, char *buf) |
81 { | 101 { |
82 buf[0] = (char) (uint8_t) (tag >> 24); | 102 buf[0] = (char) (uint8_t) (tag >> 24); |
83 buf[1] = (char) (uint8_t) (tag >> 16); | 103 buf[1] = (char) (uint8_t) (tag >> 16); |
84 buf[2] = (char) (uint8_t) (tag >> 8); | 104 buf[2] = (char) (uint8_t) (tag >> 8); |
85 buf[3] = (char) (uint8_t) (tag >> 0); | 105 buf[3] = (char) (uint8_t) (tag >> 0); |
86 } | 106 } |
87 | 107 |
88 | 108 |
89 /* hb_direction_t */ | 109 /* hb_direction_t */ |
90 | 110 |
91 const char direction_strings[][4] = { | 111 const char direction_strings[][4] = { |
92 "ltr", | 112 "ltr", |
93 "rtl", | 113 "rtl", |
94 "ttb", | 114 "ttb", |
95 "btt" | 115 "btt" |
96 }; | 116 }; |
97 | 117 |
| 118 /** |
| 119 * hb_direction_from_string: |
| 120 * @str: (array length=len): |
| 121 * @len: |
| 122 * |
| 123 * |
| 124 * |
| 125 * Return value: |
| 126 * |
| 127 * Since: 1.0 |
| 128 **/ |
98 hb_direction_t | 129 hb_direction_t |
99 hb_direction_from_string (const char *str, int len) | 130 hb_direction_from_string (const char *str, int len) |
100 { | 131 { |
101 if (unlikely (!str || !len || !*str)) | 132 if (unlikely (!str || !len || !*str)) |
102 return HB_DIRECTION_INVALID; | 133 return HB_DIRECTION_INVALID; |
103 | 134 |
104 /* Lets match loosely: just match the first letter, such that | 135 /* Lets match loosely: just match the first letter, such that |
105 * all of "ltr", "left-to-right", etc work! | 136 * all of "ltr", "left-to-right", etc work! |
106 */ | 137 */ |
107 char c = TOLOWER (str[0]); | 138 char c = TOLOWER (str[0]); |
108 for (unsigned int i = 0; i < ARRAY_LENGTH (direction_strings); i++) | 139 for (unsigned int i = 0; i < ARRAY_LENGTH (direction_strings); i++) |
109 if (c == direction_strings[i][0]) | 140 if (c == direction_strings[i][0]) |
110 return (hb_direction_t) (HB_DIRECTION_LTR + i); | 141 return (hb_direction_t) (HB_DIRECTION_LTR + i); |
111 | 142 |
112 return HB_DIRECTION_INVALID; | 143 return HB_DIRECTION_INVALID; |
113 } | 144 } |
114 | 145 |
| 146 /** |
| 147 * hb_direction_to_string: |
| 148 * @direction: |
| 149 * |
| 150 * |
| 151 * |
| 152 * Return value: (transfer none): |
| 153 * |
| 154 * Since: 1.0 |
| 155 **/ |
115 const char * | 156 const char * |
116 hb_direction_to_string (hb_direction_t direction) | 157 hb_direction_to_string (hb_direction_t direction) |
117 { | 158 { |
118 if (likely ((unsigned int) (direction - HB_DIRECTION_LTR) | 159 if (likely ((unsigned int) (direction - HB_DIRECTION_LTR) |
119 < ARRAY_LENGTH (direction_strings))) | 160 < ARRAY_LENGTH (direction_strings))) |
120 return direction_strings[direction - HB_DIRECTION_LTR]; | 161 return direction_strings[direction - HB_DIRECTION_LTR]; |
121 | 162 |
122 return "invalid"; | 163 return "invalid"; |
123 } | 164 } |
124 | 165 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 } | 221 } |
181 | 222 |
182 inline hb_language_item_t & operator = (const char *s) { | 223 inline hb_language_item_t & operator = (const char *s) { |
183 lang = (hb_language_t) strdup (s); | 224 lang = (hb_language_t) strdup (s); |
184 for (unsigned char *p = (unsigned char *) lang; *p; p++) | 225 for (unsigned char *p = (unsigned char *) lang; *p; p++) |
185 *p = canon_map[*p]; | 226 *p = canon_map[*p]; |
186 | 227 |
187 return *this; | 228 return *this; |
188 } | 229 } |
189 | 230 |
190 void finish (void) { free (lang); } | 231 void finish (void) { free ((void *) lang); } |
191 }; | 232 }; |
192 | 233 |
193 | 234 |
194 /* Thread-safe lock-free language list */ | 235 /* Thread-safe lock-free language list */ |
195 | 236 |
196 static hb_language_item_t *langs; | 237 static hb_language_item_t *langs; |
197 | 238 |
198 static inline | 239 static inline |
199 void free_langs (void) | 240 void free_langs (void) |
200 { | 241 { |
(...skipping 29 matching lines...) Expand all Loading... |
230 | 271 |
231 #ifdef HAVE_ATEXIT | 272 #ifdef HAVE_ATEXIT |
232 if (!first_lang) | 273 if (!first_lang) |
233 atexit (free_langs); /* First person registers atexit() callback. */ | 274 atexit (free_langs); /* First person registers atexit() callback. */ |
234 #endif | 275 #endif |
235 | 276 |
236 return lang; | 277 return lang; |
237 } | 278 } |
238 | 279 |
239 | 280 |
| 281 /** |
| 282 * hb_language_from_string: |
| 283 * @str: (array length=len): |
| 284 * @len: |
| 285 * |
| 286 * |
| 287 * |
| 288 * Return value: |
| 289 * |
| 290 * Since: 1.0 |
| 291 **/ |
240 hb_language_t | 292 hb_language_t |
241 hb_language_from_string (const char *str, int len) | 293 hb_language_from_string (const char *str, int len) |
242 { | 294 { |
| 295 char strbuf[64]; |
| 296 |
243 if (!str || !len || !*str) | 297 if (!str || !len || !*str) |
244 return HB_LANGUAGE_INVALID; | 298 return HB_LANGUAGE_INVALID; |
245 | 299 |
246 char strbuf[32]; | 300 if (len >= 0) |
247 if (len >= 0) { | 301 { |
248 len = MIN (len, (int) sizeof (strbuf) - 1); | 302 len = MIN (len, (int) sizeof (strbuf) - 1); |
249 str = (char *) memcpy (strbuf, str, len); | 303 str = (char *) memcpy (strbuf, str, len); |
250 strbuf[len] = '\0'; | 304 strbuf[len] = '\0'; |
251 } | 305 } |
252 | 306 |
253 hb_language_item_t *item = lang_find_or_insert (str); | 307 hb_language_item_t *item = lang_find_or_insert (str); |
254 | 308 |
255 return likely (item) ? item->lang : HB_LANGUAGE_INVALID; | 309 return likely (item) ? item->lang : HB_LANGUAGE_INVALID; |
256 } | 310 } |
257 | 311 |
| 312 /** |
| 313 * hb_language_to_string: |
| 314 * @language: |
| 315 * |
| 316 * |
| 317 * |
| 318 * Return value: (transfer none): |
| 319 * |
| 320 * Since: 1.0 |
| 321 **/ |
258 const char * | 322 const char * |
259 hb_language_to_string (hb_language_t language) | 323 hb_language_to_string (hb_language_t language) |
260 { | 324 { |
261 /* This is actually NULL-safe! */ | 325 /* This is actually NULL-safe! */ |
262 return language->s; | 326 return language->s; |
263 } | 327 } |
264 | 328 |
| 329 /** |
| 330 * hb_language_get_default: |
| 331 * |
| 332 * |
| 333 * |
| 334 * Return value: |
| 335 * |
| 336 * Since: 1.0 |
| 337 **/ |
265 hb_language_t | 338 hb_language_t |
266 hb_language_get_default (void) | 339 hb_language_get_default (void) |
267 { | 340 { |
268 static hb_language_t default_language = HB_LANGUAGE_INVALID; | 341 static hb_language_t default_language = HB_LANGUAGE_INVALID; |
269 | 342 |
270 hb_language_t language = (hb_language_t) hb_atomic_ptr_get (&default_language)
; | 343 hb_language_t language = (hb_language_t) hb_atomic_ptr_get (&default_language)
; |
271 if (unlikely (language == HB_LANGUAGE_INVALID)) { | 344 if (unlikely (language == HB_LANGUAGE_INVALID)) { |
272 language = hb_language_from_string (setlocale (LC_CTYPE, NULL), -1); | 345 language = hb_language_from_string (setlocale (LC_CTYPE, NULL), -1); |
273 hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language); | 346 hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language); |
274 } | 347 } |
275 | 348 |
276 return default_language; | 349 return default_language; |
277 } | 350 } |
278 | 351 |
279 | 352 |
280 /* hb_script_t */ | 353 /* hb_script_t */ |
281 | 354 |
| 355 /** |
| 356 * hb_script_from_iso15924_tag: |
| 357 * @tag: |
| 358 * |
| 359 * |
| 360 * |
| 361 * Return value: |
| 362 * |
| 363 * Since: 1.0 |
| 364 **/ |
282 hb_script_t | 365 hb_script_t |
283 hb_script_from_iso15924_tag (hb_tag_t tag) | 366 hb_script_from_iso15924_tag (hb_tag_t tag) |
284 { | 367 { |
285 if (unlikely (tag == HB_TAG_NONE)) | 368 if (unlikely (tag == HB_TAG_NONE)) |
286 return HB_SCRIPT_INVALID; | 369 return HB_SCRIPT_INVALID; |
287 | 370 |
288 /* Be lenient, adjust case (one capital letter followed by three small letters
) */ | 371 /* Be lenient, adjust case (one capital letter followed by three small letters
) */ |
289 tag = (tag & 0xDFDFDFDF) | 0x00202020; | 372 tag = (tag & 0xDFDFDFDF) | 0x00202020; |
290 | 373 |
291 switch (tag) { | 374 switch (tag) { |
(...skipping 14 matching lines...) Expand all Loading... |
306 } | 389 } |
307 | 390 |
308 /* If it looks right, just use the tag as a script */ | 391 /* If it looks right, just use the tag as a script */ |
309 if (((uint32_t) tag & 0xE0E0E0E0) == 0x40606060) | 392 if (((uint32_t) tag & 0xE0E0E0E0) == 0x40606060) |
310 return (hb_script_t) tag; | 393 return (hb_script_t) tag; |
311 | 394 |
312 /* Otherwise, return unknown */ | 395 /* Otherwise, return unknown */ |
313 return HB_SCRIPT_UNKNOWN; | 396 return HB_SCRIPT_UNKNOWN; |
314 } | 397 } |
315 | 398 |
| 399 /** |
| 400 * hb_script_from_string: |
| 401 * @s: (array length=len): |
| 402 * @len: |
| 403 * |
| 404 * |
| 405 * |
| 406 * Return value: |
| 407 * |
| 408 * Since: 1.0 |
| 409 **/ |
316 hb_script_t | 410 hb_script_t |
317 hb_script_from_string (const char *s, int len) | 411 hb_script_from_string (const char *s, int len) |
318 { | 412 { |
319 return hb_script_from_iso15924_tag (hb_tag_from_string (s, len)); | 413 return hb_script_from_iso15924_tag (hb_tag_from_string (s, len)); |
320 } | 414 } |
321 | 415 |
| 416 /** |
| 417 * hb_script_to_iso15924_tag: |
| 418 * @script: |
| 419 * |
| 420 * |
| 421 * |
| 422 * Return value: |
| 423 * |
| 424 * Since: 1.0 |
| 425 **/ |
322 hb_tag_t | 426 hb_tag_t |
323 hb_script_to_iso15924_tag (hb_script_t script) | 427 hb_script_to_iso15924_tag (hb_script_t script) |
324 { | 428 { |
325 return (hb_tag_t) script; | 429 return (hb_tag_t) script; |
326 } | 430 } |
327 | 431 |
| 432 /** |
| 433 * hb_script_get_horizontal_direction: |
| 434 * @script: |
| 435 * |
| 436 * |
| 437 * |
| 438 * Return value: |
| 439 * |
| 440 * Since: 1.0 |
| 441 **/ |
328 hb_direction_t | 442 hb_direction_t |
329 hb_script_get_horizontal_direction (hb_script_t script) | 443 hb_script_get_horizontal_direction (hb_script_t script) |
330 { | 444 { |
331 /* http://goo.gl/x9ilM */ | 445 /* http://goo.gl/x9ilM */ |
332 switch ((hb_tag_t) script) | 446 switch ((hb_tag_t) script) |
333 { | 447 { |
334 /* Unicode-1.1 additions */ | 448 /* Unicode-1.1 additions */ |
335 case HB_SCRIPT_ARABIC: | 449 case HB_SCRIPT_ARABIC: |
336 case HB_SCRIPT_HEBREW: | 450 case HB_SCRIPT_HEBREW: |
337 | 451 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 hb_user_data_array_t::get (hb_user_data_key_t *key) | 516 hb_user_data_array_t::get (hb_user_data_key_t *key) |
403 { | 517 { |
404 hb_user_data_item_t item = {NULL }; | 518 hb_user_data_item_t item = {NULL }; |
405 | 519 |
406 return items.find (key, &item, lock) ? item.data : NULL; | 520 return items.find (key, &item, lock) ? item.data : NULL; |
407 } | 521 } |
408 | 522 |
409 | 523 |
410 /* hb_version */ | 524 /* hb_version */ |
411 | 525 |
| 526 /** |
| 527 * hb_version: |
| 528 * @major: (out): Library major version component. |
| 529 * @minor: (out): Library minor version component. |
| 530 * @micro: (out): Library micro version component. |
| 531 * |
| 532 * Returns library version as three integer components. |
| 533 * |
| 534 * Since: 1.0 |
| 535 **/ |
412 void | 536 void |
413 hb_version (unsigned int *major, | 537 hb_version (unsigned int *major, |
414 unsigned int *minor, | 538 unsigned int *minor, |
415 unsigned int *micro) | 539 unsigned int *micro) |
416 { | 540 { |
417 *major = HB_VERSION_MAJOR; | 541 *major = HB_VERSION_MAJOR; |
418 *minor = HB_VERSION_MINOR; | 542 *minor = HB_VERSION_MINOR; |
419 *micro = HB_VERSION_MICRO; | 543 *micro = HB_VERSION_MICRO; |
420 } | 544 } |
421 | 545 |
| 546 /** |
| 547 * hb_version_string: |
| 548 * |
| 549 * Returns library version as a string with three components. |
| 550 * |
| 551 * Return value: library version string. |
| 552 * |
| 553 * Since: 1.0 |
| 554 **/ |
422 const char * | 555 const char * |
423 hb_version_string (void) | 556 hb_version_string (void) |
424 { | 557 { |
425 return HB_VERSION_STRING; | 558 return HB_VERSION_STRING; |
426 } | 559 } |
427 | 560 |
| 561 /** |
| 562 * hb_version_check: |
| 563 * @major: |
| 564 * @minor: |
| 565 * @micro: |
| 566 * |
| 567 * |
| 568 * |
| 569 * Return value: |
| 570 * |
| 571 * Since: 1.0 |
| 572 **/ |
428 hb_bool_t | 573 hb_bool_t |
429 hb_version_check (unsigned int major, | 574 hb_version_check (unsigned int major, |
430 unsigned int minor, | 575 unsigned int minor, |
431 unsigned int micro) | 576 unsigned int micro) |
432 { | 577 { |
433 return HB_VERSION_CHECK (major, minor, micro); | 578 return HB_VERSION_CHECK (major, minor, micro); |
434 } | 579 } |
OLD | NEW |