| 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 |