gfx/harfbuzz/src/hb-glib.cc

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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 Red Hat, Inc.
michael@0 3 * Copyright © 2011 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-glib.h"
michael@0 32
michael@0 33 #include "hb-unicode-private.hh"
michael@0 34
michael@0 35
michael@0 36 #if !GLIB_CHECK_VERSION(2,29,14)
michael@0 37 static const hb_script_t
michael@0 38 glib_script_to_script[] =
michael@0 39 {
michael@0 40 HB_SCRIPT_COMMON,
michael@0 41 HB_SCRIPT_INHERITED,
michael@0 42 HB_SCRIPT_ARABIC,
michael@0 43 HB_SCRIPT_ARMENIAN,
michael@0 44 HB_SCRIPT_BENGALI,
michael@0 45 HB_SCRIPT_BOPOMOFO,
michael@0 46 HB_SCRIPT_CHEROKEE,
michael@0 47 HB_SCRIPT_COPTIC,
michael@0 48 HB_SCRIPT_CYRILLIC,
michael@0 49 HB_SCRIPT_DESERET,
michael@0 50 HB_SCRIPT_DEVANAGARI,
michael@0 51 HB_SCRIPT_ETHIOPIC,
michael@0 52 HB_SCRIPT_GEORGIAN,
michael@0 53 HB_SCRIPT_GOTHIC,
michael@0 54 HB_SCRIPT_GREEK,
michael@0 55 HB_SCRIPT_GUJARATI,
michael@0 56 HB_SCRIPT_GURMUKHI,
michael@0 57 HB_SCRIPT_HAN,
michael@0 58 HB_SCRIPT_HANGUL,
michael@0 59 HB_SCRIPT_HEBREW,
michael@0 60 HB_SCRIPT_HIRAGANA,
michael@0 61 HB_SCRIPT_KANNADA,
michael@0 62 HB_SCRIPT_KATAKANA,
michael@0 63 HB_SCRIPT_KHMER,
michael@0 64 HB_SCRIPT_LAO,
michael@0 65 HB_SCRIPT_LATIN,
michael@0 66 HB_SCRIPT_MALAYALAM,
michael@0 67 HB_SCRIPT_MONGOLIAN,
michael@0 68 HB_SCRIPT_MYANMAR,
michael@0 69 HB_SCRIPT_OGHAM,
michael@0 70 HB_SCRIPT_OLD_ITALIC,
michael@0 71 HB_SCRIPT_ORIYA,
michael@0 72 HB_SCRIPT_RUNIC,
michael@0 73 HB_SCRIPT_SINHALA,
michael@0 74 HB_SCRIPT_SYRIAC,
michael@0 75 HB_SCRIPT_TAMIL,
michael@0 76 HB_SCRIPT_TELUGU,
michael@0 77 HB_SCRIPT_THAANA,
michael@0 78 HB_SCRIPT_THAI,
michael@0 79 HB_SCRIPT_TIBETAN,
michael@0 80 HB_SCRIPT_CANADIAN_SYLLABICS,
michael@0 81 HB_SCRIPT_YI,
michael@0 82 HB_SCRIPT_TAGALOG,
michael@0 83 HB_SCRIPT_HANUNOO,
michael@0 84 HB_SCRIPT_BUHID,
michael@0 85 HB_SCRIPT_TAGBANWA,
michael@0 86
michael@0 87 /* Unicode-4.0 additions */
michael@0 88 HB_SCRIPT_BRAILLE,
michael@0 89 HB_SCRIPT_CYPRIOT,
michael@0 90 HB_SCRIPT_LIMBU,
michael@0 91 HB_SCRIPT_OSMANYA,
michael@0 92 HB_SCRIPT_SHAVIAN,
michael@0 93 HB_SCRIPT_LINEAR_B,
michael@0 94 HB_SCRIPT_TAI_LE,
michael@0 95 HB_SCRIPT_UGARITIC,
michael@0 96
michael@0 97 /* Unicode-4.1 additions */
michael@0 98 HB_SCRIPT_NEW_TAI_LUE,
michael@0 99 HB_SCRIPT_BUGINESE,
michael@0 100 HB_SCRIPT_GLAGOLITIC,
michael@0 101 HB_SCRIPT_TIFINAGH,
michael@0 102 HB_SCRIPT_SYLOTI_NAGRI,
michael@0 103 HB_SCRIPT_OLD_PERSIAN,
michael@0 104 HB_SCRIPT_KHAROSHTHI,
michael@0 105
michael@0 106 /* Unicode-5.0 additions */
michael@0 107 HB_SCRIPT_UNKNOWN,
michael@0 108 HB_SCRIPT_BALINESE,
michael@0 109 HB_SCRIPT_CUNEIFORM,
michael@0 110 HB_SCRIPT_PHOENICIAN,
michael@0 111 HB_SCRIPT_PHAGS_PA,
michael@0 112 HB_SCRIPT_NKO,
michael@0 113
michael@0 114 /* Unicode-5.1 additions */
michael@0 115 HB_SCRIPT_KAYAH_LI,
michael@0 116 HB_SCRIPT_LEPCHA,
michael@0 117 HB_SCRIPT_REJANG,
michael@0 118 HB_SCRIPT_SUNDANESE,
michael@0 119 HB_SCRIPT_SAURASHTRA,
michael@0 120 HB_SCRIPT_CHAM,
michael@0 121 HB_SCRIPT_OL_CHIKI,
michael@0 122 HB_SCRIPT_VAI,
michael@0 123 HB_SCRIPT_CARIAN,
michael@0 124 HB_SCRIPT_LYCIAN,
michael@0 125 HB_SCRIPT_LYDIAN,
michael@0 126
michael@0 127 /* Unicode-5.2 additions */
michael@0 128 HB_SCRIPT_AVESTAN,
michael@0 129 HB_SCRIPT_BAMUM,
michael@0 130 HB_SCRIPT_EGYPTIAN_HIEROGLYPHS,
michael@0 131 HB_SCRIPT_IMPERIAL_ARAMAIC,
michael@0 132 HB_SCRIPT_INSCRIPTIONAL_PAHLAVI,
michael@0 133 HB_SCRIPT_INSCRIPTIONAL_PARTHIAN,
michael@0 134 HB_SCRIPT_JAVANESE,
michael@0 135 HB_SCRIPT_KAITHI,
michael@0 136 HB_SCRIPT_TAI_THAM,
michael@0 137 HB_SCRIPT_LISU,
michael@0 138 HB_SCRIPT_MEETEI_MAYEK,
michael@0 139 HB_SCRIPT_OLD_SOUTH_ARABIAN,
michael@0 140 HB_SCRIPT_OLD_TURKIC,
michael@0 141 HB_SCRIPT_SAMARITAN,
michael@0 142 HB_SCRIPT_TAI_VIET,
michael@0 143
michael@0 144 /* Unicode-6.0 additions */
michael@0 145 HB_SCRIPT_BATAK,
michael@0 146 HB_SCRIPT_BRAHMI,
michael@0 147 HB_SCRIPT_MANDAIC,
michael@0 148
michael@0 149 /* Unicode-6.1 additions */
michael@0 150 HB_SCRIPT_CHAKMA,
michael@0 151 HB_SCRIPT_MEROITIC_CURSIVE,
michael@0 152 HB_SCRIPT_MEROITIC_HIEROGLYPHS,
michael@0 153 HB_SCRIPT_MIAO,
michael@0 154 HB_SCRIPT_SHARADA,
michael@0 155 HB_SCRIPT_SORA_SOMPENG,
michael@0 156 HB_SCRIPT_TAKRI
michael@0 157 };
michael@0 158 #endif
michael@0 159
michael@0 160 hb_script_t
michael@0 161 hb_glib_script_to_script (GUnicodeScript script)
michael@0 162 {
michael@0 163 #if GLIB_CHECK_VERSION(2,29,14)
michael@0 164 return (hb_script_t) g_unicode_script_to_iso15924 (script);
michael@0 165 #else
michael@0 166 if (likely ((unsigned int) script < ARRAY_LENGTH (glib_script_to_script)))
michael@0 167 return glib_script_to_script[script];
michael@0 168
michael@0 169 if (unlikely (script == G_UNICODE_SCRIPT_INVALID_CODE))
michael@0 170 return HB_SCRIPT_INVALID;
michael@0 171
michael@0 172 return HB_SCRIPT_UNKNOWN;
michael@0 173 #endif
michael@0 174 }
michael@0 175
michael@0 176 GUnicodeScript
michael@0 177 hb_glib_script_from_script (hb_script_t script)
michael@0 178 {
michael@0 179 #if GLIB_CHECK_VERSION(2,29,14)
michael@0 180 return g_unicode_script_from_iso15924 (script);
michael@0 181 #else
michael@0 182 unsigned int count = ARRAY_LENGTH (glib_script_to_script);
michael@0 183 for (unsigned int i = 0; i < count; i++)
michael@0 184 if (glib_script_to_script[i] == script)
michael@0 185 return (GUnicodeScript) i;
michael@0 186
michael@0 187 if (unlikely (script == HB_SCRIPT_INVALID))
michael@0 188 return G_UNICODE_SCRIPT_INVALID_CODE;
michael@0 189
michael@0 190 return G_UNICODE_SCRIPT_UNKNOWN;
michael@0 191 #endif
michael@0 192 }
michael@0 193
michael@0 194
michael@0 195 static hb_unicode_combining_class_t
michael@0 196 hb_glib_unicode_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED,
michael@0 197 hb_codepoint_t unicode,
michael@0 198 void *user_data HB_UNUSED)
michael@0 199
michael@0 200 {
michael@0 201 return (hb_unicode_combining_class_t) g_unichar_combining_class (unicode);
michael@0 202 }
michael@0 203
michael@0 204 static unsigned int
michael@0 205 hb_glib_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED,
michael@0 206 hb_codepoint_t unicode,
michael@0 207 void *user_data HB_UNUSED)
michael@0 208 {
michael@0 209 return g_unichar_iswide (unicode) ? 2 : 1;
michael@0 210 }
michael@0 211
michael@0 212 static hb_unicode_general_category_t
michael@0 213 hb_glib_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
michael@0 214 hb_codepoint_t unicode,
michael@0 215 void *user_data HB_UNUSED)
michael@0 216
michael@0 217 {
michael@0 218 /* hb_unicode_general_category_t and GUnicodeType are identical */
michael@0 219 return (hb_unicode_general_category_t) g_unichar_type (unicode);
michael@0 220 }
michael@0 221
michael@0 222 static hb_codepoint_t
michael@0 223 hb_glib_unicode_mirroring (hb_unicode_funcs_t *ufuncs HB_UNUSED,
michael@0 224 hb_codepoint_t unicode,
michael@0 225 void *user_data HB_UNUSED)
michael@0 226 {
michael@0 227 g_unichar_get_mirror_char (unicode, &unicode);
michael@0 228 return unicode;
michael@0 229 }
michael@0 230
michael@0 231 static hb_script_t
michael@0 232 hb_glib_unicode_script (hb_unicode_funcs_t *ufuncs HB_UNUSED,
michael@0 233 hb_codepoint_t unicode,
michael@0 234 void *user_data HB_UNUSED)
michael@0 235 {
michael@0 236 return hb_glib_script_to_script (g_unichar_get_script (unicode));
michael@0 237 }
michael@0 238
michael@0 239 static hb_bool_t
michael@0 240 hb_glib_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
michael@0 241 hb_codepoint_t a,
michael@0 242 hb_codepoint_t b,
michael@0 243 hb_codepoint_t *ab,
michael@0 244 void *user_data HB_UNUSED)
michael@0 245 {
michael@0 246 #if GLIB_CHECK_VERSION(2,29,12)
michael@0 247 return g_unichar_compose (a, b, ab);
michael@0 248 #endif
michael@0 249
michael@0 250 /* We don't ifdef-out the fallback code such that compiler always
michael@0 251 * sees it and makes sure it's compilable. */
michael@0 252
michael@0 253 gchar utf8[12];
michael@0 254 gchar *normalized;
michael@0 255 int len;
michael@0 256 hb_bool_t ret;
michael@0 257
michael@0 258 len = g_unichar_to_utf8 (a, utf8);
michael@0 259 len += g_unichar_to_utf8 (b, utf8 + len);
michael@0 260 normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFC);
michael@0 261 len = g_utf8_strlen (normalized, -1);
michael@0 262 if (unlikely (!len))
michael@0 263 return false;
michael@0 264
michael@0 265 if (len == 1) {
michael@0 266 *ab = g_utf8_get_char (normalized);
michael@0 267 ret = true;
michael@0 268 } else {
michael@0 269 ret = false;
michael@0 270 }
michael@0 271
michael@0 272 g_free (normalized);
michael@0 273 return ret;
michael@0 274 }
michael@0 275
michael@0 276 static hb_bool_t
michael@0 277 hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
michael@0 278 hb_codepoint_t ab,
michael@0 279 hb_codepoint_t *a,
michael@0 280 hb_codepoint_t *b,
michael@0 281 void *user_data HB_UNUSED)
michael@0 282 {
michael@0 283 #if GLIB_CHECK_VERSION(2,29,12)
michael@0 284 return g_unichar_decompose (ab, a, b);
michael@0 285 #endif
michael@0 286
michael@0 287 /* We don't ifdef-out the fallback code such that compiler always
michael@0 288 * sees it and makes sure it's compilable. */
michael@0 289
michael@0 290 gchar utf8[6];
michael@0 291 gchar *normalized;
michael@0 292 int len;
michael@0 293 hb_bool_t ret;
michael@0 294
michael@0 295 len = g_unichar_to_utf8 (ab, utf8);
michael@0 296 normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFD);
michael@0 297 len = g_utf8_strlen (normalized, -1);
michael@0 298 if (unlikely (!len))
michael@0 299 return false;
michael@0 300
michael@0 301 if (len == 1) {
michael@0 302 *a = g_utf8_get_char (normalized);
michael@0 303 *b = 0;
michael@0 304 ret = *a != ab;
michael@0 305 } else if (len == 2) {
michael@0 306 *a = g_utf8_get_char (normalized);
michael@0 307 *b = g_utf8_get_char (g_utf8_next_char (normalized));
michael@0 308 /* Here's the ugly part: if ab decomposes to a single character and
michael@0 309 * that character decomposes again, we have to detect that and undo
michael@0 310 * the second part :-(. */
michael@0 311 gchar *recomposed = g_utf8_normalize (normalized, -1, G_NORMALIZE_NFC);
michael@0 312 hb_codepoint_t c = g_utf8_get_char (recomposed);
michael@0 313 if (c != ab && c != *a) {
michael@0 314 *a = c;
michael@0 315 *b = 0;
michael@0 316 }
michael@0 317 g_free (recomposed);
michael@0 318 ret = true;
michael@0 319 } else {
michael@0 320 /* If decomposed to more than two characters, take the last one,
michael@0 321 * and recompose the rest to get the first component. */
michael@0 322 gchar *end = g_utf8_offset_to_pointer (normalized, len - 1);
michael@0 323 gchar *recomposed;
michael@0 324 *b = g_utf8_get_char (end);
michael@0 325 recomposed = g_utf8_normalize (normalized, end - normalized, G_NORMALIZE_NFC);
michael@0 326 /* We expect that recomposed has exactly one character now. */
michael@0 327 *a = g_utf8_get_char (recomposed);
michael@0 328 g_free (recomposed);
michael@0 329 ret = true;
michael@0 330 }
michael@0 331
michael@0 332 g_free (normalized);
michael@0 333 return ret;
michael@0 334 }
michael@0 335
michael@0 336 static unsigned int
michael@0 337 hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
michael@0 338 hb_codepoint_t u,
michael@0 339 hb_codepoint_t *decomposed,
michael@0 340 void *user_data HB_UNUSED)
michael@0 341 {
michael@0 342 #if GLIB_CHECK_VERSION(2,29,12)
michael@0 343 return g_unichar_fully_decompose (u, TRUE, decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN);
michael@0 344 #endif
michael@0 345
michael@0 346 /* If the user doesn't have GLib >= 2.29.12 we have to perform
michael@0 347 * a round trip to UTF-8 and the associated memory management dance. */
michael@0 348 gchar utf8[6];
michael@0 349 gchar *utf8_decomposed, *c;
michael@0 350 gsize utf8_len, utf8_decomposed_len, i;
michael@0 351
michael@0 352 /* Convert @u to UTF-8 and normalise it in NFKD mode. This performs the compatibility decomposition. */
michael@0 353 utf8_len = g_unichar_to_utf8 (u, utf8);
michael@0 354 utf8_decomposed = g_utf8_normalize (utf8, utf8_len, G_NORMALIZE_NFKD);
michael@0 355 utf8_decomposed_len = g_utf8_strlen (utf8_decomposed, -1);
michael@0 356
michael@0 357 assert (utf8_decomposed_len <= HB_UNICODE_MAX_DECOMPOSITION_LEN);
michael@0 358
michael@0 359 for (i = 0, c = utf8_decomposed; i < utf8_decomposed_len; i++, c = g_utf8_next_char (c))
michael@0 360 *decomposed++ = g_utf8_get_char (c);
michael@0 361
michael@0 362 g_free (utf8_decomposed);
michael@0 363
michael@0 364 return utf8_decomposed_len;
michael@0 365 }
michael@0 366
michael@0 367 hb_unicode_funcs_t *
michael@0 368 hb_glib_get_unicode_funcs (void)
michael@0 369 {
michael@0 370 static const hb_unicode_funcs_t _hb_glib_unicode_funcs = {
michael@0 371 HB_OBJECT_HEADER_STATIC,
michael@0 372
michael@0 373 NULL, /* parent */
michael@0 374 true, /* immutable */
michael@0 375 {
michael@0 376 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_glib_unicode_##name,
michael@0 377 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
michael@0 378 #undef HB_UNICODE_FUNC_IMPLEMENT
michael@0 379 }
michael@0 380 };
michael@0 381
michael@0 382 return const_cast<hb_unicode_funcs_t *> (&_hb_glib_unicode_funcs);
michael@0 383 }
michael@0 384

mercurial