Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright © 2009,2010 Red Hat, Inc. |
michael@0 | 3 | * Copyright © 2011,2012 Google, Inc. |
michael@0 | 4 | * |
michael@0 | 5 | * This is part of HarfBuzz, a text shaping library. |
michael@0 | 6 | * |
michael@0 | 7 | * Permission is hereby granted, without written agreement and without |
michael@0 | 8 | * license or royalty fees, to use, copy, modify, and distribute this |
michael@0 | 9 | * software and its documentation for any purpose, provided that the |
michael@0 | 10 | * above copyright notice and the following two paragraphs appear in |
michael@0 | 11 | * all copies of this software. |
michael@0 | 12 | * |
michael@0 | 13 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
michael@0 | 14 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
michael@0 | 15 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
michael@0 | 16 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
michael@0 | 17 | * DAMAGE. |
michael@0 | 18 | * |
michael@0 | 19 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
michael@0 | 20 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
michael@0 | 21 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
michael@0 | 22 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
michael@0 | 23 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
michael@0 | 24 | * |
michael@0 | 25 | * Red Hat Author(s): Behdad Esfahbod |
michael@0 | 26 | * Google Author(s): Behdad Esfahbod |
michael@0 | 27 | */ |
michael@0 | 28 | |
michael@0 | 29 | #include "hb-private.hh" |
michael@0 | 30 | |
michael@0 | 31 | #include "hb-mutex-private.hh" |
michael@0 | 32 | #include "hb-object-private.hh" |
michael@0 | 33 | |
michael@0 | 34 | #include <locale.h> |
michael@0 | 35 | |
michael@0 | 36 | |
michael@0 | 37 | /* hb_options_t */ |
michael@0 | 38 | |
michael@0 | 39 | hb_options_union_t _hb_options; |
michael@0 | 40 | |
michael@0 | 41 | void |
michael@0 | 42 | _hb_options_init (void) |
michael@0 | 43 | { |
michael@0 | 44 | hb_options_union_t u; |
michael@0 | 45 | u.i = 0; |
michael@0 | 46 | u.opts.initialized = 1; |
michael@0 | 47 | |
michael@0 | 48 | char *c = getenv ("HB_OPTIONS"); |
michael@0 | 49 | u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible"); |
michael@0 | 50 | |
michael@0 | 51 | /* This is idempotent and threadsafe. */ |
michael@0 | 52 | _hb_options = u; |
michael@0 | 53 | } |
michael@0 | 54 | |
michael@0 | 55 | |
michael@0 | 56 | /* hb_tag_t */ |
michael@0 | 57 | |
michael@0 | 58 | /** |
michael@0 | 59 | * hb_tag_from_string: |
michael@0 | 60 | * @str: (array length=len): |
michael@0 | 61 | * @len: |
michael@0 | 62 | * |
michael@0 | 63 | * |
michael@0 | 64 | * |
michael@0 | 65 | * Return value: |
michael@0 | 66 | * |
michael@0 | 67 | * Since: 1.0 |
michael@0 | 68 | **/ |
michael@0 | 69 | hb_tag_t |
michael@0 | 70 | hb_tag_from_string (const char *str, int len) |
michael@0 | 71 | { |
michael@0 | 72 | char tag[4]; |
michael@0 | 73 | unsigned int i; |
michael@0 | 74 | |
michael@0 | 75 | if (!str || !len || !*str) |
michael@0 | 76 | return HB_TAG_NONE; |
michael@0 | 77 | |
michael@0 | 78 | if (len < 0 || len > 4) |
michael@0 | 79 | len = 4; |
michael@0 | 80 | for (i = 0; i < (unsigned) len && str[i]; i++) |
michael@0 | 81 | tag[i] = str[i]; |
michael@0 | 82 | for (; i < 4; i++) |
michael@0 | 83 | tag[i] = ' '; |
michael@0 | 84 | |
michael@0 | 85 | return HB_TAG_CHAR4 (tag); |
michael@0 | 86 | } |
michael@0 | 87 | |
michael@0 | 88 | /** |
michael@0 | 89 | * hb_tag_to_string: |
michael@0 | 90 | * @tag: |
michael@0 | 91 | * @buf: (array fixed-size=4): |
michael@0 | 92 | * |
michael@0 | 93 | * |
michael@0 | 94 | * |
michael@0 | 95 | * Since: 1.0 |
michael@0 | 96 | **/ |
michael@0 | 97 | void |
michael@0 | 98 | hb_tag_to_string (hb_tag_t tag, char *buf) |
michael@0 | 99 | { |
michael@0 | 100 | buf[0] = (char) (uint8_t) (tag >> 24); |
michael@0 | 101 | buf[1] = (char) (uint8_t) (tag >> 16); |
michael@0 | 102 | buf[2] = (char) (uint8_t) (tag >> 8); |
michael@0 | 103 | buf[3] = (char) (uint8_t) (tag >> 0); |
michael@0 | 104 | } |
michael@0 | 105 | |
michael@0 | 106 | |
michael@0 | 107 | /* hb_direction_t */ |
michael@0 | 108 | |
michael@0 | 109 | const char direction_strings[][4] = { |
michael@0 | 110 | "ltr", |
michael@0 | 111 | "rtl", |
michael@0 | 112 | "ttb", |
michael@0 | 113 | "btt" |
michael@0 | 114 | }; |
michael@0 | 115 | |
michael@0 | 116 | /** |
michael@0 | 117 | * hb_direction_from_string: |
michael@0 | 118 | * @str: (array length=len): |
michael@0 | 119 | * @len: |
michael@0 | 120 | * |
michael@0 | 121 | * |
michael@0 | 122 | * |
michael@0 | 123 | * Return value: |
michael@0 | 124 | * |
michael@0 | 125 | * Since: 1.0 |
michael@0 | 126 | **/ |
michael@0 | 127 | hb_direction_t |
michael@0 | 128 | hb_direction_from_string (const char *str, int len) |
michael@0 | 129 | { |
michael@0 | 130 | if (unlikely (!str || !len || !*str)) |
michael@0 | 131 | return HB_DIRECTION_INVALID; |
michael@0 | 132 | |
michael@0 | 133 | /* Lets match loosely: just match the first letter, such that |
michael@0 | 134 | * all of "ltr", "left-to-right", etc work! |
michael@0 | 135 | */ |
michael@0 | 136 | char c = TOLOWER (str[0]); |
michael@0 | 137 | for (unsigned int i = 0; i < ARRAY_LENGTH (direction_strings); i++) |
michael@0 | 138 | if (c == direction_strings[i][0]) |
michael@0 | 139 | return (hb_direction_t) (HB_DIRECTION_LTR + i); |
michael@0 | 140 | |
michael@0 | 141 | return HB_DIRECTION_INVALID; |
michael@0 | 142 | } |
michael@0 | 143 | |
michael@0 | 144 | /** |
michael@0 | 145 | * hb_direction_to_string: |
michael@0 | 146 | * @direction: |
michael@0 | 147 | * |
michael@0 | 148 | * |
michael@0 | 149 | * |
michael@0 | 150 | * Return value: (transfer none): |
michael@0 | 151 | * |
michael@0 | 152 | * Since: 1.0 |
michael@0 | 153 | **/ |
michael@0 | 154 | const char * |
michael@0 | 155 | hb_direction_to_string (hb_direction_t direction) |
michael@0 | 156 | { |
michael@0 | 157 | if (likely ((unsigned int) (direction - HB_DIRECTION_LTR) |
michael@0 | 158 | < ARRAY_LENGTH (direction_strings))) |
michael@0 | 159 | return direction_strings[direction - HB_DIRECTION_LTR]; |
michael@0 | 160 | |
michael@0 | 161 | return "invalid"; |
michael@0 | 162 | } |
michael@0 | 163 | |
michael@0 | 164 | |
michael@0 | 165 | /* hb_language_t */ |
michael@0 | 166 | |
michael@0 | 167 | struct hb_language_impl_t { |
michael@0 | 168 | const char s[1]; |
michael@0 | 169 | }; |
michael@0 | 170 | |
michael@0 | 171 | static const char canon_map[256] = { |
michael@0 | 172 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
michael@0 | 173 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
michael@0 | 174 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, |
michael@0 | 175 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0, |
michael@0 | 176 | '-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', |
michael@0 | 177 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-', |
michael@0 | 178 | 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', |
michael@0 | 179 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0 |
michael@0 | 180 | }; |
michael@0 | 181 | |
michael@0 | 182 | static hb_bool_t |
michael@0 | 183 | lang_equal (hb_language_t v1, |
michael@0 | 184 | const void *v2) |
michael@0 | 185 | { |
michael@0 | 186 | const unsigned char *p1 = (const unsigned char *) v1; |
michael@0 | 187 | const unsigned char *p2 = (const unsigned char *) v2; |
michael@0 | 188 | |
michael@0 | 189 | while (*p1 && *p1 == canon_map[*p2]) |
michael@0 | 190 | p1++, p2++; |
michael@0 | 191 | |
michael@0 | 192 | return *p1 == canon_map[*p2]; |
michael@0 | 193 | } |
michael@0 | 194 | |
michael@0 | 195 | #if 0 |
michael@0 | 196 | static unsigned int |
michael@0 | 197 | lang_hash (const void *key) |
michael@0 | 198 | { |
michael@0 | 199 | const unsigned char *p = key; |
michael@0 | 200 | unsigned int h = 0; |
michael@0 | 201 | while (canon_map[*p]) |
michael@0 | 202 | { |
michael@0 | 203 | h = (h << 5) - h + canon_map[*p]; |
michael@0 | 204 | p++; |
michael@0 | 205 | } |
michael@0 | 206 | |
michael@0 | 207 | return h; |
michael@0 | 208 | } |
michael@0 | 209 | #endif |
michael@0 | 210 | |
michael@0 | 211 | |
michael@0 | 212 | struct hb_language_item_t { |
michael@0 | 213 | |
michael@0 | 214 | struct hb_language_item_t *next; |
michael@0 | 215 | hb_language_t lang; |
michael@0 | 216 | |
michael@0 | 217 | inline bool operator == (const char *s) const { |
michael@0 | 218 | return lang_equal (lang, s); |
michael@0 | 219 | } |
michael@0 | 220 | |
michael@0 | 221 | inline hb_language_item_t & operator = (const char *s) { |
michael@0 | 222 | lang = (hb_language_t) strdup (s); |
michael@0 | 223 | for (unsigned char *p = (unsigned char *) lang; *p; p++) |
michael@0 | 224 | *p = canon_map[*p]; |
michael@0 | 225 | |
michael@0 | 226 | return *this; |
michael@0 | 227 | } |
michael@0 | 228 | |
michael@0 | 229 | void finish (void) { free ((void *) lang); } |
michael@0 | 230 | }; |
michael@0 | 231 | |
michael@0 | 232 | |
michael@0 | 233 | /* Thread-safe lock-free language list */ |
michael@0 | 234 | |
michael@0 | 235 | static hb_language_item_t *langs; |
michael@0 | 236 | |
michael@0 | 237 | static inline |
michael@0 | 238 | void free_langs (void) |
michael@0 | 239 | { |
michael@0 | 240 | while (langs) { |
michael@0 | 241 | hb_language_item_t *next = langs->next; |
michael@0 | 242 | langs->finish (); |
michael@0 | 243 | free (langs); |
michael@0 | 244 | langs = next; |
michael@0 | 245 | } |
michael@0 | 246 | } |
michael@0 | 247 | |
michael@0 | 248 | static hb_language_item_t * |
michael@0 | 249 | lang_find_or_insert (const char *key) |
michael@0 | 250 | { |
michael@0 | 251 | retry: |
michael@0 | 252 | hb_language_item_t *first_lang = (hb_language_item_t *) hb_atomic_ptr_get (&langs); |
michael@0 | 253 | |
michael@0 | 254 | for (hb_language_item_t *lang = first_lang; lang; lang = lang->next) |
michael@0 | 255 | if (*lang == key) |
michael@0 | 256 | return lang; |
michael@0 | 257 | |
michael@0 | 258 | /* Not found; allocate one. */ |
michael@0 | 259 | hb_language_item_t *lang = (hb_language_item_t *) calloc (1, sizeof (hb_language_item_t)); |
michael@0 | 260 | if (unlikely (!lang)) |
michael@0 | 261 | return NULL; |
michael@0 | 262 | lang->next = first_lang; |
michael@0 | 263 | *lang = key; |
michael@0 | 264 | |
michael@0 | 265 | if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) { |
michael@0 | 266 | free (lang); |
michael@0 | 267 | goto retry; |
michael@0 | 268 | } |
michael@0 | 269 | |
michael@0 | 270 | #ifdef HAVE_ATEXIT |
michael@0 | 271 | if (!first_lang) |
michael@0 | 272 | atexit (free_langs); /* First person registers atexit() callback. */ |
michael@0 | 273 | #endif |
michael@0 | 274 | |
michael@0 | 275 | return lang; |
michael@0 | 276 | } |
michael@0 | 277 | |
michael@0 | 278 | |
michael@0 | 279 | /** |
michael@0 | 280 | * hb_language_from_string: |
michael@0 | 281 | * @str: (array length=len): |
michael@0 | 282 | * @len: |
michael@0 | 283 | * |
michael@0 | 284 | * |
michael@0 | 285 | * |
michael@0 | 286 | * Return value: |
michael@0 | 287 | * |
michael@0 | 288 | * Since: 1.0 |
michael@0 | 289 | **/ |
michael@0 | 290 | hb_language_t |
michael@0 | 291 | hb_language_from_string (const char *str, int len) |
michael@0 | 292 | { |
michael@0 | 293 | char strbuf[64]; |
michael@0 | 294 | |
michael@0 | 295 | if (!str || !len || !*str) |
michael@0 | 296 | return HB_LANGUAGE_INVALID; |
michael@0 | 297 | |
michael@0 | 298 | if (len >= 0) |
michael@0 | 299 | { |
michael@0 | 300 | len = MIN (len, (int) sizeof (strbuf) - 1); |
michael@0 | 301 | str = (char *) memcpy (strbuf, str, len); |
michael@0 | 302 | strbuf[len] = '\0'; |
michael@0 | 303 | } |
michael@0 | 304 | |
michael@0 | 305 | hb_language_item_t *item = lang_find_or_insert (str); |
michael@0 | 306 | |
michael@0 | 307 | return likely (item) ? item->lang : HB_LANGUAGE_INVALID; |
michael@0 | 308 | } |
michael@0 | 309 | |
michael@0 | 310 | /** |
michael@0 | 311 | * hb_language_to_string: |
michael@0 | 312 | * @language: |
michael@0 | 313 | * |
michael@0 | 314 | * |
michael@0 | 315 | * |
michael@0 | 316 | * Return value: (transfer none): |
michael@0 | 317 | * |
michael@0 | 318 | * Since: 1.0 |
michael@0 | 319 | **/ |
michael@0 | 320 | const char * |
michael@0 | 321 | hb_language_to_string (hb_language_t language) |
michael@0 | 322 | { |
michael@0 | 323 | /* This is actually NULL-safe! */ |
michael@0 | 324 | return language->s; |
michael@0 | 325 | } |
michael@0 | 326 | |
michael@0 | 327 | /** |
michael@0 | 328 | * hb_language_get_default: |
michael@0 | 329 | * |
michael@0 | 330 | * |
michael@0 | 331 | * |
michael@0 | 332 | * Return value: |
michael@0 | 333 | * |
michael@0 | 334 | * Since: 1.0 |
michael@0 | 335 | **/ |
michael@0 | 336 | hb_language_t |
michael@0 | 337 | hb_language_get_default (void) |
michael@0 | 338 | { |
michael@0 | 339 | static hb_language_t default_language = HB_LANGUAGE_INVALID; |
michael@0 | 340 | |
michael@0 | 341 | hb_language_t language = (hb_language_t) hb_atomic_ptr_get (&default_language); |
michael@0 | 342 | if (unlikely (language == HB_LANGUAGE_INVALID)) { |
michael@0 | 343 | language = hb_language_from_string (setlocale (LC_CTYPE, NULL), -1); |
michael@0 | 344 | hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language); |
michael@0 | 345 | } |
michael@0 | 346 | |
michael@0 | 347 | return default_language; |
michael@0 | 348 | } |
michael@0 | 349 | |
michael@0 | 350 | |
michael@0 | 351 | /* hb_script_t */ |
michael@0 | 352 | |
michael@0 | 353 | /** |
michael@0 | 354 | * hb_script_from_iso15924_tag: |
michael@0 | 355 | * @tag: |
michael@0 | 356 | * |
michael@0 | 357 | * |
michael@0 | 358 | * |
michael@0 | 359 | * Return value: |
michael@0 | 360 | * |
michael@0 | 361 | * Since: 1.0 |
michael@0 | 362 | **/ |
michael@0 | 363 | hb_script_t |
michael@0 | 364 | hb_script_from_iso15924_tag (hb_tag_t tag) |
michael@0 | 365 | { |
michael@0 | 366 | if (unlikely (tag == HB_TAG_NONE)) |
michael@0 | 367 | return HB_SCRIPT_INVALID; |
michael@0 | 368 | |
michael@0 | 369 | /* Be lenient, adjust case (one capital letter followed by three small letters) */ |
michael@0 | 370 | tag = (tag & 0xDFDFDFDF) | 0x00202020; |
michael@0 | 371 | |
michael@0 | 372 | switch (tag) { |
michael@0 | 373 | |
michael@0 | 374 | /* These graduated from the 'Q' private-area codes, but |
michael@0 | 375 | * the old code is still aliased by Unicode, and the Qaai |
michael@0 | 376 | * one in use by ICU. */ |
michael@0 | 377 | case HB_TAG('Q','a','a','i'): return HB_SCRIPT_INHERITED; |
michael@0 | 378 | case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC; |
michael@0 | 379 | |
michael@0 | 380 | /* Script variants from http://unicode.org/iso15924/ */ |
michael@0 | 381 | case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC; |
michael@0 | 382 | case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN; |
michael@0 | 383 | case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN; |
michael@0 | 384 | case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC; |
michael@0 | 385 | case HB_TAG('S','y','r','j'): return HB_SCRIPT_SYRIAC; |
michael@0 | 386 | case HB_TAG('S','y','r','n'): return HB_SCRIPT_SYRIAC; |
michael@0 | 387 | } |
michael@0 | 388 | |
michael@0 | 389 | /* If it looks right, just use the tag as a script */ |
michael@0 | 390 | if (((uint32_t) tag & 0xE0E0E0E0) == 0x40606060) |
michael@0 | 391 | return (hb_script_t) tag; |
michael@0 | 392 | |
michael@0 | 393 | /* Otherwise, return unknown */ |
michael@0 | 394 | return HB_SCRIPT_UNKNOWN; |
michael@0 | 395 | } |
michael@0 | 396 | |
michael@0 | 397 | /** |
michael@0 | 398 | * hb_script_from_string: |
michael@0 | 399 | * @s: (array length=len): |
michael@0 | 400 | * @len: |
michael@0 | 401 | * |
michael@0 | 402 | * |
michael@0 | 403 | * |
michael@0 | 404 | * Return value: |
michael@0 | 405 | * |
michael@0 | 406 | * Since: 1.0 |
michael@0 | 407 | **/ |
michael@0 | 408 | hb_script_t |
michael@0 | 409 | hb_script_from_string (const char *s, int len) |
michael@0 | 410 | { |
michael@0 | 411 | return hb_script_from_iso15924_tag (hb_tag_from_string (s, len)); |
michael@0 | 412 | } |
michael@0 | 413 | |
michael@0 | 414 | /** |
michael@0 | 415 | * hb_script_to_iso15924_tag: |
michael@0 | 416 | * @script: |
michael@0 | 417 | * |
michael@0 | 418 | * |
michael@0 | 419 | * |
michael@0 | 420 | * Return value: |
michael@0 | 421 | * |
michael@0 | 422 | * Since: 1.0 |
michael@0 | 423 | **/ |
michael@0 | 424 | hb_tag_t |
michael@0 | 425 | hb_script_to_iso15924_tag (hb_script_t script) |
michael@0 | 426 | { |
michael@0 | 427 | return (hb_tag_t) script; |
michael@0 | 428 | } |
michael@0 | 429 | |
michael@0 | 430 | /** |
michael@0 | 431 | * hb_script_get_horizontal_direction: |
michael@0 | 432 | * @script: |
michael@0 | 433 | * |
michael@0 | 434 | * |
michael@0 | 435 | * |
michael@0 | 436 | * Return value: |
michael@0 | 437 | * |
michael@0 | 438 | * Since: 1.0 |
michael@0 | 439 | **/ |
michael@0 | 440 | hb_direction_t |
michael@0 | 441 | hb_script_get_horizontal_direction (hb_script_t script) |
michael@0 | 442 | { |
michael@0 | 443 | /* http://goo.gl/x9ilM */ |
michael@0 | 444 | switch ((hb_tag_t) script) |
michael@0 | 445 | { |
michael@0 | 446 | /* Unicode-1.1 additions */ |
michael@0 | 447 | case HB_SCRIPT_ARABIC: |
michael@0 | 448 | case HB_SCRIPT_HEBREW: |
michael@0 | 449 | |
michael@0 | 450 | /* Unicode-3.0 additions */ |
michael@0 | 451 | case HB_SCRIPT_SYRIAC: |
michael@0 | 452 | case HB_SCRIPT_THAANA: |
michael@0 | 453 | |
michael@0 | 454 | /* Unicode-4.0 additions */ |
michael@0 | 455 | case HB_SCRIPT_CYPRIOT: |
michael@0 | 456 | |
michael@0 | 457 | /* Unicode-4.1 additions */ |
michael@0 | 458 | case HB_SCRIPT_KHAROSHTHI: |
michael@0 | 459 | |
michael@0 | 460 | /* Unicode-5.0 additions */ |
michael@0 | 461 | case HB_SCRIPT_PHOENICIAN: |
michael@0 | 462 | case HB_SCRIPT_NKO: |
michael@0 | 463 | |
michael@0 | 464 | /* Unicode-5.1 additions */ |
michael@0 | 465 | case HB_SCRIPT_LYDIAN: |
michael@0 | 466 | |
michael@0 | 467 | /* Unicode-5.2 additions */ |
michael@0 | 468 | case HB_SCRIPT_AVESTAN: |
michael@0 | 469 | case HB_SCRIPT_IMPERIAL_ARAMAIC: |
michael@0 | 470 | case HB_SCRIPT_INSCRIPTIONAL_PAHLAVI: |
michael@0 | 471 | case HB_SCRIPT_INSCRIPTIONAL_PARTHIAN: |
michael@0 | 472 | case HB_SCRIPT_OLD_SOUTH_ARABIAN: |
michael@0 | 473 | case HB_SCRIPT_OLD_TURKIC: |
michael@0 | 474 | case HB_SCRIPT_SAMARITAN: |
michael@0 | 475 | |
michael@0 | 476 | /* Unicode-6.0 additions */ |
michael@0 | 477 | case HB_SCRIPT_MANDAIC: |
michael@0 | 478 | |
michael@0 | 479 | /* Unicode-6.1 additions */ |
michael@0 | 480 | case HB_SCRIPT_MEROITIC_CURSIVE: |
michael@0 | 481 | case HB_SCRIPT_MEROITIC_HIEROGLYPHS: |
michael@0 | 482 | |
michael@0 | 483 | return HB_DIRECTION_RTL; |
michael@0 | 484 | } |
michael@0 | 485 | |
michael@0 | 486 | return HB_DIRECTION_LTR; |
michael@0 | 487 | } |
michael@0 | 488 | |
michael@0 | 489 | |
michael@0 | 490 | /* hb_user_data_array_t */ |
michael@0 | 491 | |
michael@0 | 492 | bool |
michael@0 | 493 | hb_user_data_array_t::set (hb_user_data_key_t *key, |
michael@0 | 494 | void * data, |
michael@0 | 495 | hb_destroy_func_t destroy, |
michael@0 | 496 | hb_bool_t replace) |
michael@0 | 497 | { |
michael@0 | 498 | if (!key) |
michael@0 | 499 | return false; |
michael@0 | 500 | |
michael@0 | 501 | if (replace) { |
michael@0 | 502 | if (!data && !destroy) { |
michael@0 | 503 | items.remove (key, lock); |
michael@0 | 504 | return true; |
michael@0 | 505 | } |
michael@0 | 506 | } |
michael@0 | 507 | hb_user_data_item_t item = {key, data, destroy}; |
michael@0 | 508 | bool ret = !!items.replace_or_insert (item, lock, replace); |
michael@0 | 509 | |
michael@0 | 510 | return ret; |
michael@0 | 511 | } |
michael@0 | 512 | |
michael@0 | 513 | void * |
michael@0 | 514 | hb_user_data_array_t::get (hb_user_data_key_t *key) |
michael@0 | 515 | { |
michael@0 | 516 | hb_user_data_item_t item = {NULL }; |
michael@0 | 517 | |
michael@0 | 518 | return items.find (key, &item, lock) ? item.data : NULL; |
michael@0 | 519 | } |
michael@0 | 520 | |
michael@0 | 521 | |
michael@0 | 522 | /* hb_version */ |
michael@0 | 523 | |
michael@0 | 524 | /** |
michael@0 | 525 | * hb_version: |
michael@0 | 526 | * @major: (out): Library major version component. |
michael@0 | 527 | * @minor: (out): Library minor version component. |
michael@0 | 528 | * @micro: (out): Library micro version component. |
michael@0 | 529 | * |
michael@0 | 530 | * Returns library version as three integer components. |
michael@0 | 531 | * |
michael@0 | 532 | * Since: 1.0 |
michael@0 | 533 | **/ |
michael@0 | 534 | void |
michael@0 | 535 | hb_version (unsigned int *major, |
michael@0 | 536 | unsigned int *minor, |
michael@0 | 537 | unsigned int *micro) |
michael@0 | 538 | { |
michael@0 | 539 | *major = HB_VERSION_MAJOR; |
michael@0 | 540 | *minor = HB_VERSION_MINOR; |
michael@0 | 541 | *micro = HB_VERSION_MICRO; |
michael@0 | 542 | } |
michael@0 | 543 | |
michael@0 | 544 | /** |
michael@0 | 545 | * hb_version_string: |
michael@0 | 546 | * |
michael@0 | 547 | * Returns library version as a string with three components. |
michael@0 | 548 | * |
michael@0 | 549 | * Return value: library version string. |
michael@0 | 550 | * |
michael@0 | 551 | * Since: 1.0 |
michael@0 | 552 | **/ |
michael@0 | 553 | const char * |
michael@0 | 554 | hb_version_string (void) |
michael@0 | 555 | { |
michael@0 | 556 | return HB_VERSION_STRING; |
michael@0 | 557 | } |
michael@0 | 558 | |
michael@0 | 559 | /** |
michael@0 | 560 | * hb_version_check: |
michael@0 | 561 | * @major: |
michael@0 | 562 | * @minor: |
michael@0 | 563 | * @micro: |
michael@0 | 564 | * |
michael@0 | 565 | * |
michael@0 | 566 | * |
michael@0 | 567 | * Return value: |
michael@0 | 568 | * |
michael@0 | 569 | * Since: 1.0 |
michael@0 | 570 | **/ |
michael@0 | 571 | hb_bool_t |
michael@0 | 572 | hb_version_check (unsigned int major, |
michael@0 | 573 | unsigned int minor, |
michael@0 | 574 | unsigned int micro) |
michael@0 | 575 | { |
michael@0 | 576 | return HB_VERSION_CHECK (major, minor, micro); |
michael@0 | 577 | } |