589 |
Qcomposition, prop, string); |
Qcomposition, prop, string); |
590 |
} |
} |
591 |
|
|
|
/* Compose sequences of characters in the region between START and END |
|
|
by functions registered in Vcomposition_function_table. If STRING |
|
|
is non-nil, operate on characters contained between indices START |
|
|
and END in STRING. */ |
|
|
|
|
|
void |
|
|
compose_chars_in_text (start, end, string) |
|
|
int start, end; |
|
|
Lisp_Object string; |
|
|
{ |
|
|
int count = 0; |
|
|
struct gcpro gcpro1; |
|
|
Lisp_Object tail, elt, val, to; |
|
|
/* Set to nonzero if we don't have to compose ASCII characters. */ |
|
|
int skip_ascii; |
|
|
int i, len, stop, c; |
|
|
const unsigned char *ptr, *pend; |
|
|
|
|
|
if (! CHAR_TABLE_P (Vcomposition_function_table)) |
|
|
return; |
|
|
|
|
|
if (STRINGP (string)) |
|
|
{ |
|
|
count = SPECPDL_INDEX (); |
|
|
GCPRO1 (string); |
|
|
stop = end; |
|
|
ptr = SDATA (string) + string_char_to_byte (string, start); |
|
|
pend = SDATA (string) + SBYTES (string); |
|
|
} |
|
|
else |
|
|
{ |
|
|
record_unwind_protect (save_excursion_restore, save_excursion_save ()); |
|
|
TEMP_SET_PT (start); |
|
|
stop = (start < GPT && GPT < end ? GPT : end); |
|
|
ptr = CHAR_POS_ADDR (start); |
|
|
pend = CHAR_POS_ADDR (end); |
|
|
} |
|
|
|
|
|
/* Preserve the match data. */ |
|
|
record_unwind_save_match_data (); |
|
|
|
|
|
/* If none of ASCII characters have composition functions, we can |
|
|
skip them quickly. */ |
|
|
for (i = 0; i < 128; i++) |
|
|
if (!NILP (CHAR_TABLE_REF (Vcomposition_function_table, i))) |
|
|
break; |
|
|
skip_ascii = (i == 128); |
|
|
|
|
|
|
|
|
while (1) |
|
|
{ |
|
|
if (skip_ascii) |
|
|
while (start < stop && ASCII_BYTE_P (*ptr)) |
|
|
start++, ptr++; |
|
|
|
|
|
if (start >= stop) |
|
|
{ |
|
|
if (stop == end || start >= end) |
|
|
break; |
|
|
stop = end; |
|
|
if (STRINGP (string)) |
|
|
ptr = SDATA (string) + string_char_to_byte (string, start); |
|
|
else |
|
|
ptr = CHAR_POS_ADDR (start); |
|
|
} |
|
|
|
|
|
c = STRING_CHAR_AND_LENGTH (ptr, pend - ptr, len); |
|
|
tail = CHAR_TABLE_REF (Vcomposition_function_table, c); |
|
|
while (CONSP (tail)) |
|
|
{ |
|
|
elt = XCAR (tail); |
|
|
if (CONSP (elt) |
|
|
&& STRINGP (XCAR (elt)) |
|
|
&& !NILP (Ffboundp (XCDR (elt)))) |
|
|
{ |
|
|
if (STRINGP (string)) |
|
|
val = Fstring_match (XCAR (elt), string, make_number (start)); |
|
|
else |
|
|
{ |
|
|
val = Flooking_at (XCAR (elt)); |
|
|
if (!NILP (val)) |
|
|
val = make_number (start); |
|
|
} |
|
|
if (INTEGERP (val) && XFASTINT (val) == start) |
|
|
{ |
|
|
to = Fmatch_end (make_number (0)); |
|
|
val = call4 (XCDR (elt), val, to, XCAR (elt), string); |
|
|
if (INTEGERP (val) && XINT (val) > 1) |
|
|
{ |
|
|
start += XINT (val); |
|
|
if (STRINGP (string)) |
|
|
{ |
|
|
ptr = SDATA (string) + string_char_to_byte (string, start); |
|
|
pend = SDATA (string) + SBYTES (string); |
|
|
} |
|
|
else |
|
|
ptr = CHAR_POS_ADDR (start); |
|
|
} |
|
|
else if (STRINGP (string)) |
|
|
{ |
|
|
start++; |
|
|
ptr = SDATA (string) + string_char_to_byte (string, start); |
|
|
pend = SDATA (string) + SBYTES (string); |
|
|
} |
|
|
else |
|
|
{ |
|
|
start++; |
|
|
ptr += len; |
|
|
} |
|
|
break; |
|
|
} |
|
|
} |
|
|
tail = XCDR (tail); |
|
|
} |
|
|
if (!CONSP (tail)) |
|
|
{ |
|
|
/* No composition done. Try the next character. */ |
|
|
start++; |
|
|
ptr += len; |
|
|
} |
|
|
} |
|
|
|
|
|
unbind_to (count, Qnil); |
|
|
if (STRINGP (string)) |
|
|
UNGCPRO; |
|
|
} |
|
592 |
|
|
593 |
/* Emacs Lisp APIs. */ |
/* Emacs Lisp APIs. */ |
594 |
|
|