diff options
Diffstat (limited to 'src/composite.c')
| -rw-r--r-- | src/composite.c | 78 |
1 files changed, 42 insertions, 36 deletions
diff --git a/src/composite.c b/src/composite.c index cf1e053f027..c44c8e565d0 100644 --- a/src/composite.c +++ b/src/composite.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Composite sequence support. | 1 | /* Composite sequence support. |
| 2 | Copyright (C) 2001-2011 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2012 Free Software Foundation, Inc. |
| 3 | Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 3 | Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
| 4 | National Institute of Advanced Industrial Science and Technology (AIST) | 4 | National Institute of Advanced Industrial Science and Technology (AIST) |
| 5 | Registration Number H14PRO021 | 5 | Registration Number H14PRO021 |
| @@ -142,10 +142,10 @@ Lisp_Object Qcomposition; | |||
| 142 | struct composition **composition_table; | 142 | struct composition **composition_table; |
| 143 | 143 | ||
| 144 | /* The current size of `composition_table'. */ | 144 | /* The current size of `composition_table'. */ |
| 145 | static int composition_table_size; | 145 | static ptrdiff_t composition_table_size; |
| 146 | 146 | ||
| 147 | /* Number of compositions currently made. */ | 147 | /* Number of compositions currently made. */ |
| 148 | int n_compositions; | 148 | ptrdiff_t n_compositions; |
| 149 | 149 | ||
| 150 | /* Hash table for compositions. The key is COMPONENTS-VEC of | 150 | /* Hash table for compositions. The key is COMPONENTS-VEC of |
| 151 | `composition' property. The value is the corresponding | 151 | `composition' property. The value is the corresponding |
| @@ -172,19 +172,30 @@ Lisp_Object composition_temp; | |||
| 172 | 172 | ||
| 173 | If the composition is invalid, return -1. */ | 173 | If the composition is invalid, return -1. */ |
| 174 | 174 | ||
| 175 | int | 175 | ptrdiff_t |
| 176 | get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, | 176 | get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, |
| 177 | Lisp_Object prop, Lisp_Object string) | 177 | Lisp_Object prop, Lisp_Object string) |
| 178 | { | 178 | { |
| 179 | Lisp_Object id, length, components, key, *key_contents; | 179 | Lisp_Object id, length, components, key, *key_contents; |
| 180 | int glyph_len; | 180 | ptrdiff_t glyph_len; |
| 181 | struct Lisp_Hash_Table *hash_table = XHASH_TABLE (composition_hash_table); | 181 | struct Lisp_Hash_Table *hash_table = XHASH_TABLE (composition_hash_table); |
| 182 | EMACS_INT hash_index; | 182 | ptrdiff_t hash_index; |
| 183 | EMACS_UINT hash_code; | 183 | EMACS_UINT hash_code; |
| 184 | enum composition_method method; | ||
| 184 | struct composition *cmp; | 185 | struct composition *cmp; |
| 185 | EMACS_INT i; | 186 | EMACS_INT i; |
| 186 | int ch; | 187 | int ch; |
| 187 | 188 | ||
| 189 | /* Maximum length of a string of glyphs. XftGlyphExtents limits | ||
| 190 | this to INT_MAX, and Emacs limits it further. Divide INT_MAX - 1 | ||
| 191 | by 2 because x_produce_glyphs computes glyph_len * 2 + 1. Divide | ||
| 192 | the size by MAX_MULTIBYTE_LENGTH because encode_terminal_code | ||
| 193 | multiplies glyph_len by MAX_MULTIBYTE_LENGTH. */ | ||
| 194 | enum { | ||
| 195 | GLYPH_LEN_MAX = min ((INT_MAX - 1) / 2, | ||
| 196 | min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH) | ||
| 197 | }; | ||
| 198 | |||
| 188 | /* PROP should be | 199 | /* PROP should be |
| 189 | Form-A: ((LENGTH . COMPONENTS) . MODIFICATION-FUNC) | 200 | Form-A: ((LENGTH . COMPONENTS) . MODIFICATION-FUNC) |
| 190 | or | 201 | or |
| @@ -258,21 +269,9 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, | |||
| 258 | /* This composition is a new one. We must register it. */ | 269 | /* This composition is a new one. We must register it. */ |
| 259 | 270 | ||
| 260 | /* Check if we have sufficient memory to store this information. */ | 271 | /* Check if we have sufficient memory to store this information. */ |
| 261 | if (composition_table_size == 0) | 272 | if (composition_table_size <= n_compositions) |
| 262 | { | 273 | composition_table = xpalloc (composition_table, &composition_table_size, |
| 263 | composition_table_size = 256; | 274 | 1, -1, sizeof *composition_table); |
| 264 | composition_table | ||
| 265 | = (struct composition **) xmalloc (sizeof (composition_table[0]) | ||
| 266 | * composition_table_size); | ||
| 267 | } | ||
| 268 | else if (composition_table_size <= n_compositions) | ||
| 269 | { | ||
| 270 | composition_table_size += 256; | ||
| 271 | composition_table | ||
| 272 | = (struct composition **) xrealloc (composition_table, | ||
| 273 | sizeof (composition_table[0]) | ||
| 274 | * composition_table_size); | ||
| 275 | } | ||
| 276 | 275 | ||
| 277 | key_contents = XVECTOR (key)->contents; | 276 | key_contents = XVECTOR (key)->contents; |
| 278 | 277 | ||
| @@ -316,20 +315,26 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, | |||
| 316 | /* Register the composition in composition_hash_table. */ | 315 | /* Register the composition in composition_hash_table. */ |
| 317 | hash_index = hash_put (hash_table, key, id, hash_code); | 316 | hash_index = hash_put (hash_table, key, id, hash_code); |
| 318 | 317 | ||
| 318 | method = (NILP (components) | ||
| 319 | ? COMPOSITION_RELATIVE | ||
| 320 | : ((INTEGERP (components) || STRINGP (components)) | ||
| 321 | ? COMPOSITION_WITH_ALTCHARS | ||
| 322 | : COMPOSITION_WITH_RULE_ALTCHARS)); | ||
| 323 | |||
| 324 | glyph_len = (method == COMPOSITION_WITH_RULE_ALTCHARS | ||
| 325 | ? (ASIZE (key) + 1) / 2 | ||
| 326 | : ASIZE (key)); | ||
| 327 | |||
| 328 | if (GLYPH_LEN_MAX < glyph_len) | ||
| 329 | memory_full (SIZE_MAX); | ||
| 330 | |||
| 319 | /* Register the composition in composition_table. */ | 331 | /* Register the composition in composition_table. */ |
| 320 | cmp = (struct composition *) xmalloc (sizeof (struct composition)); | 332 | cmp = (struct composition *) xmalloc (sizeof (struct composition)); |
| 321 | 333 | ||
| 322 | cmp->method = (NILP (components) | 334 | cmp->method = method; |
| 323 | ? COMPOSITION_RELATIVE | ||
| 324 | : ((INTEGERP (components) || STRINGP (components)) | ||
| 325 | ? COMPOSITION_WITH_ALTCHARS | ||
| 326 | : COMPOSITION_WITH_RULE_ALTCHARS)); | ||
| 327 | cmp->hash_index = hash_index; | 335 | cmp->hash_index = hash_index; |
| 328 | glyph_len = (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS | ||
| 329 | ? (ASIZE (key) + 1) / 2 | ||
| 330 | : ASIZE (key)); | ||
| 331 | cmp->glyph_len = glyph_len; | 336 | cmp->glyph_len = glyph_len; |
| 332 | cmp->offsets = (short *) xmalloc (sizeof (short) * glyph_len * 2); | 337 | cmp->offsets = xnmalloc (glyph_len, 2 * sizeof *cmp->offsets); |
| 333 | cmp->font = NULL; | 338 | cmp->font = NULL; |
| 334 | 339 | ||
| 335 | if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS) | 340 | if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS) |
| @@ -340,6 +345,8 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, | |||
| 340 | { | 345 | { |
| 341 | int this_width; | 346 | int this_width; |
| 342 | ch = XINT (key_contents[i]); | 347 | ch = XINT (key_contents[i]); |
| 348 | /* TAB in a composition means display glyphs with padding | ||
| 349 | space on the left or right. */ | ||
| 343 | this_width = (ch == '\t' ? 1 : CHAR_WIDTH (ch)); | 350 | this_width = (ch == '\t' ? 1 : CHAR_WIDTH (ch)); |
| 344 | if (cmp->width < this_width) | 351 | if (cmp->width < this_width) |
| 345 | cmp->width = this_width; | 352 | cmp->width = this_width; |
| @@ -656,7 +663,7 @@ static Lisp_Object | |||
| 656 | gstring_lookup_cache (Lisp_Object header) | 663 | gstring_lookup_cache (Lisp_Object header) |
| 657 | { | 664 | { |
| 658 | struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); | 665 | struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); |
| 659 | EMACS_INT i = hash_lookup (h, header, NULL); | 666 | ptrdiff_t i = hash_lookup (h, header, NULL); |
| 660 | 667 | ||
| 661 | return (i >= 0 ? HASH_VALUE (h, i) : Qnil); | 668 | return (i >= 0 ? HASH_VALUE (h, i) : Qnil); |
| 662 | } | 669 | } |
| @@ -691,7 +698,7 @@ composition_gstring_put_cache (Lisp_Object gstring, EMACS_INT len) | |||
| 691 | } | 698 | } |
| 692 | 699 | ||
| 693 | Lisp_Object | 700 | Lisp_Object |
| 694 | composition_gstring_from_id (int id) | 701 | composition_gstring_from_id (ptrdiff_t id) |
| 695 | { | 702 | { |
| 696 | struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); | 703 | struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); |
| 697 | 704 | ||
| @@ -960,14 +967,11 @@ autocmp_chars (Lisp_Object rule, EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT | |||
| 960 | args[4] = font_object; | 967 | args[4] = font_object; |
| 961 | args[5] = string; | 968 | args[5] = string; |
| 962 | lgstring = safe_call (6, args); | 969 | lgstring = safe_call (6, args); |
| 963 | if (NILP (string)) | ||
| 964 | TEMP_SET_PT_BOTH (pt, pt_byte); | ||
| 965 | } | 970 | } |
| 966 | return unbind_to (count, lgstring); | 971 | return unbind_to (count, lgstring); |
| 967 | } | 972 | } |
| 968 | 973 | ||
| 969 | static Lisp_Object _work_val; | 974 | static Lisp_Object _work_val; |
| 970 | static int _work_char; | ||
| 971 | 975 | ||
| 972 | /* 1 iff the character C is composable. Characters of general | 976 | /* 1 iff the character C is composable. Characters of general |
| 973 | category Z? or C? are not composable except for ZWNJ and ZWJ. */ | 977 | category Z? or C? are not composable except for ZWNJ and ZWJ. */ |
| @@ -1303,7 +1307,7 @@ composition_reseat_it (struct composition_it *cmp_it, EMACS_INT charpos, EMACS_I | |||
| 1303 | if (cmp_it->lookback == 0) | 1307 | if (cmp_it->lookback == 0) |
| 1304 | goto no_composition; | 1308 | goto no_composition; |
| 1305 | lgstring = Qnil; | 1309 | lgstring = Qnil; |
| 1306 | /* Try to find a shorter compostion that starts after CPOS. */ | 1310 | /* Try to find a shorter composition that starts after CPOS. */ |
| 1307 | composition_compute_stop_pos (cmp_it, charpos, bytepos, cpos, | 1311 | composition_compute_stop_pos (cmp_it, charpos, bytepos, cpos, |
| 1308 | string); | 1312 | string); |
| 1309 | if (cmp_it->ch == -2 || cmp_it->stop_pos < charpos) | 1313 | if (cmp_it->ch == -2 || cmp_it->stop_pos < charpos) |
| @@ -1382,6 +1386,8 @@ composition_update_it (struct composition_it *cmp_it, EMACS_INT charpos, EMACS_I | |||
| 1382 | else | 1386 | else |
| 1383 | { | 1387 | { |
| 1384 | for (i = 0; i < cmp->glyph_len; i++) | 1388 | for (i = 0; i < cmp->glyph_len; i++) |
| 1389 | /* TAB in a composition means display glyphs with padding | ||
| 1390 | space on the left or right. */ | ||
| 1385 | if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t') | 1391 | if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t') |
| 1386 | break; | 1392 | break; |
| 1387 | if (c == '\t') | 1393 | if (c == '\t') |