X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/af3c30cb283811135d9a1136fa5072e6922410a9..0b381c7eb83c635f39159168a48c869d632d8081:/src/composite.c diff --git a/src/composite.c b/src/composite.c index ab9ec3f5a0..885e026267 100644 --- a/src/composite.c +++ b/src/composite.c @@ -142,10 +142,10 @@ Lisp_Object Qcomposition; struct composition **composition_table; /* The current size of `composition_table'. */ -static int composition_table_size; +static ptrdiff_t composition_table_size; /* Number of compositions currently made. */ -int n_compositions; +ptrdiff_t n_compositions; /* Hash table for compositions. The key is COMPONENTS-VEC of `composition' property. The value is the corresponding @@ -172,19 +172,30 @@ Lisp_Object composition_temp; If the composition is invalid, return -1. */ -int +ptrdiff_t get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, Lisp_Object prop, Lisp_Object string) { Lisp_Object id, length, components, key, *key_contents; - int glyph_len; + ptrdiff_t glyph_len; struct Lisp_Hash_Table *hash_table = XHASH_TABLE (composition_hash_table); - EMACS_INT hash_index; + ptrdiff_t hash_index; EMACS_UINT hash_code; + enum composition_method method; struct composition *cmp; EMACS_INT i; int ch; + /* Maximum length of a string of glyphs. XftGlyphExtents limits + this to INT_MAX, and Emacs limits it further. Divide INT_MAX - 1 + by 2 because x_produce_glyphs computes glyph_len * 2 + 1. Divide + the size by MAX_MULTIBYTE_LENGTH because encode_terminal_code + multiplies glyph_len by MAX_MULTIBYTE_LENGTH. */ + enum { + GLYPH_LEN_MAX = min ((INT_MAX - 1) / 2, + min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH) + }; + /* PROP should be Form-A: ((LENGTH . COMPONENTS) . MODIFICATION-FUNC) or @@ -258,21 +269,9 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, /* This composition is a new one. We must register it. */ /* Check if we have sufficient memory to store this information. */ - if (composition_table_size == 0) - { - composition_table_size = 256; - composition_table - = (struct composition **) xmalloc (sizeof (composition_table[0]) - * composition_table_size); - } - else if (composition_table_size <= n_compositions) - { - composition_table_size += 256; - composition_table - = (struct composition **) xrealloc (composition_table, - sizeof (composition_table[0]) - * composition_table_size); - } + if (composition_table_size <= n_compositions) + composition_table = xpalloc (composition_table, &composition_table_size, + 1, -1, sizeof *composition_table); key_contents = XVECTOR (key)->contents; @@ -285,7 +284,7 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, && VECTORP (AREF (components, 0))) { /* COMPONENTS is a glyph-string. */ - EMACS_UINT len = ASIZE (key); + EMACS_INT len = ASIZE (key); for (i = 1; i < len; i++) if (! VECTORP (AREF (key, i))) @@ -293,7 +292,7 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, } else if (VECTORP (components) || CONSP (components)) { - EMACS_UINT len = ASIZE (key); + EMACS_INT len = ASIZE (key); /* The number of elements should be odd. */ if ((len % 2) == 0) @@ -316,20 +315,26 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, /* Register the composition in composition_hash_table. */ hash_index = hash_put (hash_table, key, id, hash_code); + method = (NILP (components) + ? COMPOSITION_RELATIVE + : ((INTEGERP (components) || STRINGP (components)) + ? COMPOSITION_WITH_ALTCHARS + : COMPOSITION_WITH_RULE_ALTCHARS)); + + glyph_len = (method == COMPOSITION_WITH_RULE_ALTCHARS + ? (ASIZE (key) + 1) / 2 + : ASIZE (key)); + + if (GLYPH_LEN_MAX < glyph_len) + memory_full (SIZE_MAX); + /* Register the composition in composition_table. */ cmp = (struct composition *) xmalloc (sizeof (struct composition)); - cmp->method = (NILP (components) - ? COMPOSITION_RELATIVE - : ((INTEGERP (components) || STRINGP (components)) - ? COMPOSITION_WITH_ALTCHARS - : COMPOSITION_WITH_RULE_ALTCHARS)); + cmp->method = method; cmp->hash_index = hash_index; - glyph_len = (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS - ? (ASIZE (key) + 1) / 2 - : ASIZE (key)); cmp->glyph_len = glyph_len; - cmp->offsets = (short *) xmalloc (sizeof (short) * glyph_len * 2); + cmp->offsets = xnmalloc (glyph_len, 2 * sizeof *cmp->offsets); cmp->font = NULL; if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS) @@ -340,6 +345,8 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, { int this_width; ch = XINT (key_contents[i]); + /* TAB in a composition means display glyphs with padding + space on the left or right. */ this_width = (ch == '\t' ? 1 : CHAR_WIDTH (ch)); if (cmp->width < this_width) cmp->width = this_width; @@ -656,7 +663,7 @@ static Lisp_Object gstring_lookup_cache (Lisp_Object header) { struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); - EMACS_INT i = hash_lookup (h, header, NULL); + ptrdiff_t i = hash_lookup (h, header, NULL); return (i >= 0 ? HASH_VALUE (h, i) : Qnil); } @@ -673,13 +680,14 @@ composition_gstring_put_cache (Lisp_Object gstring, EMACS_INT len) hash = h->hashfn (h, header); if (len < 0) { - EMACS_UINT j, glyph_len = LGSTRING_GLYPH_LEN (gstring); + EMACS_INT j, glyph_len = LGSTRING_GLYPH_LEN (gstring); for (j = 0; j < glyph_len; j++) if (NILP (LGSTRING_GLYPH (gstring, j))) break; len = j; } + lint_assume (len <= TYPE_MAXIMUM (EMACS_INT) - 2); copy = Fmake_vector (make_number (len + 2), Qnil); LGSTRING_SET_HEADER (copy, Fcopy_sequence (header)); for (i = 0; i < len; i++) @@ -690,7 +698,7 @@ composition_gstring_put_cache (Lisp_Object gstring, EMACS_INT len) } Lisp_Object -composition_gstring_from_id (int id) +composition_gstring_from_id (ptrdiff_t id) { struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); @@ -705,7 +713,7 @@ int composition_gstring_p (Lisp_Object gstring) { Lisp_Object header; - int i; + EMACS_INT i; if (! VECTORP (gstring) || ASIZE (gstring) < 2) return 0; @@ -858,7 +866,7 @@ fill_gstring_body (Lisp_Object gstring) for (i = 0; i < len; i++) { Lisp_Object g = LGSTRING_GLYPH (gstring, i); - EMACS_INT c = XINT (AREF (header, i + 1)); + int c = XFASTINT (AREF (header, i + 1)); if (NILP (g)) { @@ -959,14 +967,11 @@ autocmp_chars (Lisp_Object rule, EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT args[4] = font_object; args[5] = string; lgstring = safe_call (6, args); - if (NILP (string)) - TEMP_SET_PT_BOTH (pt, pt_byte); } return unbind_to (count, lgstring); } static Lisp_Object _work_val; -static int _work_char; /* 1 iff the character C is composable. Characters of general category Z? or C? are not composable except for ZWNJ and ZWJ. */ @@ -975,9 +980,8 @@ static int _work_char; ((C) > ' ' \ && ((C) == 0x200C || (C) == 0x200D \ || (_work_val = CHAR_TABLE_REF (Vunicode_category_table, (C)), \ - (SYMBOLP (_work_val) \ - && (_work_char = SDATA (SYMBOL_NAME (_work_val))[0]) != 'C' \ - && _work_char != 'Z')))) + (INTEGERP (_work_val) \ + && (XINT (_work_val) <= UNICODE_CATEGORY_So))))) /* Update cmp_it->stop_pos to the next position after CHARPOS (and BYTEPOS) where character composition may happen. If BYTEPOS is @@ -995,7 +999,8 @@ static int _work_char; void composition_compute_stop_pos (struct composition_it *cmp_it, EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT endpos, Lisp_Object string) { - EMACS_INT start, end, c; + EMACS_INT start, end; + int c; Lisp_Object prop, val; /* This is from forward_to_next_line_start in xdisp.c. */ const int MAX_NEWLINE_DISTANCE = 500; @@ -1025,6 +1030,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, EMACS_INT charpos, /* FIXME: Bidi is not yet handled well in static composition. */ if (charpos < endpos && find_composition (charpos, endpos, &start, &end, &prop, string) + && start >= charpos && COMPOSITION_VALID_P (start, end, prop)) { cmp_it->stop_pos = endpos = start; @@ -1251,7 +1257,7 @@ composition_reseat_it (struct composition_it *cmp_it, EMACS_INT charpos, EMACS_I { Lisp_Object lgstring = Qnil; Lisp_Object val, elt; - int i; + EMACS_INT i; val = CHAR_TABLE_REF (Vcomposition_function_table, cmp_it->ch); for (i = 0; i < cmp_it->rule_idx; i++, val = XCDR (val)); @@ -1301,7 +1307,7 @@ composition_reseat_it (struct composition_it *cmp_it, EMACS_INT charpos, EMACS_I if (cmp_it->lookback == 0) goto no_composition; lgstring = Qnil; - /* Try to find a shorter compostion that starts after CPOS. */ + /* Try to find a shorter composition that starts after CPOS. */ composition_compute_stop_pos (cmp_it, charpos, bytepos, cpos, string); if (cmp_it->ch == -2 || cmp_it->stop_pos < charpos) @@ -1380,6 +1386,8 @@ composition_update_it (struct composition_it *cmp_it, EMACS_INT charpos, EMACS_I else { for (i = 0; i < cmp->glyph_len; i++) + /* TAB in a composition means display glyphs with padding + space on the left or right. */ if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t') break; if (c == '\t') @@ -1675,7 +1683,6 @@ find_automatic_composition (EMACS_INT pos, EMACS_INT limit, } BACKWARD_CHAR (cur, stop); } - return 0; } /* Return the adjusted point provided that point is moved from LAST_PT @@ -1684,9 +1691,8 @@ find_automatic_composition (EMACS_INT pos, EMACS_INT limit, EMACS_INT composition_adjust_point (EMACS_INT last_pt, EMACS_INT new_pt) { - EMACS_INT beg, end; + EMACS_INT i, beg, end; Lisp_Object val; - int i; if (new_pt == BEGV || new_pt == ZV) return new_pt; @@ -1937,8 +1943,7 @@ syms_of_composite (void) { int i; - Qcomposition = intern_c_string ("composition"); - staticpro (&Qcomposition); + DEFSYM (Qcomposition, "composition"); /* Make a hash table for static composition. */ { @@ -1997,11 +2002,8 @@ valid. The default value is the function `compose-chars-after'. */); Vcompose_chars_after_function = intern_c_string ("compose-chars-after"); - Qauto_composed = intern_c_string ("auto-composed"); - staticpro (&Qauto_composed); - - Qauto_composition_function = intern_c_string ("auto-composition-function"); - staticpro (&Qauto_composition_function); + DEFSYM (Qauto_composed, "auto-composed"); + DEFSYM (Qauto_composition_function, "auto-composition-function"); DEFVAR_LISP ("auto-composition-mode", Vauto_composition_mode, doc: /* Non-nil if Auto-Composition mode is enabled.