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
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
/* 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;
/* 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)
{
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;
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);
}
}
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);
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. */
/* 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;
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)
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')
{
int i;
- Qcomposition = intern_c_string ("composition");
- staticpro (&Qcomposition);
+ DEFSYM (Qcomposition, "composition");
/* Make a hash table for static composition. */
{
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.