92 |
|
|
93 |
The former is a hash table in which keys are COMPONENTS-VECs and |
The former is a hash table in which keys are COMPONENTS-VECs and |
94 |
values are the corresponding COMPOSITION-IDs. This hash table is |
values are the corresponding COMPOSITION-IDs. This hash table is |
95 |
weak, but as each key (COMPONENTS-VEC) is also kept as a value of |
weak, but as each key (COMPONENTS-VEC) is also kept as a value of the |
96 |
`composition' property, it won't be collected as garbage until all |
`composition' property, it won't be collected as garbage until all |
97 |
text that have the same COMPONENTS-VEC are deleted. |
bits of text that have the same COMPONENTS-VEC are deleted. |
98 |
|
|
99 |
The latter is a table of pointers to `struct composition' indexed |
The latter is a table of pointers to `struct composition' indexed |
100 |
by COMPOSITION-ID. This structure keep the other information (see |
by COMPOSITION-ID. This structure keeps the other information (see |
101 |
composite.h). |
composite.h). |
102 |
|
|
103 |
In general, a text property holds information about individual |
In general, a text property holds information about individual |
104 |
characters. But, a `composition' property holds information about |
characters. But, a `composition' property holds information about |
105 |
a sequence of characters (in this sense, it is like `intangible' |
a sequence of characters (in this sense, it is like the `intangible' |
106 |
property). That means that we should not share the property value |
property). That means that we should not share the property value |
107 |
in adjacent compositions we can't distinguish them if they have the |
in adjacent compositions -- we can't distinguish them if they have the |
108 |
same property. So, after any changes, we call |
same property. So, after any changes, we call |
109 |
`update_compositions' and change a property of one of adjacent |
`update_compositions' and change a property of one of adjacent |
110 |
compositions to a copy of it. This function also runs a proper |
compositions to a copy of it. This function also runs a proper |
111 |
composition modification function to make a composition that gets |
composition modification function to make a composition that gets |
112 |
invalid by the change valid again. |
invalid by the change valid again. |
113 |
|
|
114 |
As a value of `composition' property holds information about a |
As the value of the `composition' property holds information about a |
115 |
specific range of text, the value gets invalid if we change the |
specific range of text, the value gets invalid if we change the |
116 |
text in the range. We treat `composition' property always |
text in the range. We treat the `composition' property as always |
117 |
rear-nonsticky (currently by setting default-text-properties to |
rear-nonsticky (currently by setting default-text-properties to |
118 |
(rear-nonsticky (composition))) and we never make properties of |
(rear-nonsticky (composition))) and we never make properties of |
119 |
adjacent compositions identical. Thus, any such changes make the |
adjacent compositions identical. Thus, any such changes make the |
120 |
range just shorter. So, we can check the validity of `composition' |
range just shorter. So, we can check the validity of the `composition' |
121 |
property by comparing LENGTH information with the actual length of |
property by comparing LENGTH information with the actual length of |
122 |
the composition. |
the composition. |
123 |
|
|
158 |
#define CHAR_WIDTH(c) \ |
#define CHAR_WIDTH(c) \ |
159 |
(SINGLE_BYTE_CHAR_P (c) ? 1 : CHARSET_WIDTH (CHAR_CHARSET (c))) |
(SINGLE_BYTE_CHAR_P (c) ? 1 : CHARSET_WIDTH (CHAR_CHARSET (c))) |
160 |
|
|
|
/* The following macros for hash table are copied from fns.c. */ |
|
|
/* Value is the key part of entry IDX in hash table H. */ |
|
|
#define HASH_KEY(H, IDX) AREF ((H)->key_and_value, 2 * (IDX)) |
|
|
/* Value is the value part of entry IDX in hash table H. */ |
|
|
#define HASH_VALUE(H, IDX) AREF ((H)->key_and_value, 2 * (IDX) + 1) |
|
|
|
|
161 |
/* Return COMPOSITION-ID of a composition at buffer position |
/* Return COMPOSITION-ID of a composition at buffer position |
162 |
CHARPOS/BYTEPOS and length NCHARS. The `composition' property of |
CHARPOS/BYTEPOS and length NCHARS. The `composition' property of |
163 |
the sequence is PROP. STRING, if non-nil, is a string that |
the sequence is PROP. STRING, if non-nil, is a string that |
249 |
} |
} |
250 |
|
|
251 |
/* This composition is a new one. We must register it. */ |
/* This composition is a new one. We must register it. */ |
252 |
|
|
253 |
/* Check if we have sufficient memory to store this information. */ |
/* Check if we have sufficient memory to store this information. */ |
254 |
if (composition_table_size == 0) |
if (composition_table_size == 0) |
255 |
{ |
{ |
462 |
&& find_composition (to, -1, &start, &end, &prop, Qnil) |
&& find_composition (to, -1, &start, &end, &prop, Qnil) |
463 |
&& !COMPOSITION_VALID_P (start, end, prop)) |
&& !COMPOSITION_VALID_P (start, end, prop)) |
464 |
to = end; |
to = end; |
465 |
if (!NILP (func)) |
if (!NILP (Ffboundp (func))) |
466 |
call2 (func, make_number (from), make_number (to)); |
call2 (func, make_number (from), make_number (to)); |
467 |
else if (!NILP (Ffboundp (Vcompose_chars_after_function))) |
else if (!NILP (Ffboundp (Vcompose_chars_after_function))) |
468 |
call3 (Vcompose_chars_after_function, |
call3 (Vcompose_chars_after_function, |
478 |
|
|
479 |
void |
void |
480 |
update_compositions (from, to, check_mask) |
update_compositions (from, to, check_mask) |
481 |
int from, to; |
int from, to, check_mask; |
482 |
{ |
{ |
483 |
Lisp_Object prop; |
Lisp_Object prop; |
484 |
int start, end; |
int start, end; |
485 |
|
|
486 |
if (inhibit_modification_hooks) |
if (inhibit_modification_hooks) |
487 |
return; |
return; |
488 |
|
|
489 |
/* If FROM and TO are not in a valid range, do nothing. */ |
/* If FROM and TO are not in a valid range, do nothing. */ |
490 |
if (! (BEGV <= from && from <= to && to <= ZV)) |
if (! (BEGV <= from && from <= to && to <= ZV)) |
491 |
return; |
return; |
605 |
/* Set to nonzero if we don't have to compose ASCII characters. */ |
/* Set to nonzero if we don't have to compose ASCII characters. */ |
606 |
int skip_ascii; |
int skip_ascii; |
607 |
int i, len, stop, c; |
int i, len, stop, c; |
608 |
unsigned char *ptr, *pend; |
const unsigned char *ptr, *pend; |
609 |
|
|
610 |
if (! CHAR_TABLE_P (Vcomposition_function_table)) |
if (! CHAR_TABLE_P (Vcomposition_function_table)) |
611 |
return; |
return; |
612 |
|
|
613 |
if (STRINGP (string)) |
if (STRINGP (string)) |
614 |
{ |
{ |
615 |
count = specpdl_ptr - specpdl; |
count = SPECPDL_INDEX (); |
616 |
GCPRO1 (string); |
GCPRO1 (string); |
617 |
stop = end; |
stop = end; |
618 |
ptr = XSTRING (string)->data + string_char_to_byte (string, start); |
ptr = SDATA (string) + string_char_to_byte (string, start); |
619 |
pend = ptr + STRING_BYTES (XSTRING (string)); |
pend = ptr + SBYTES (string); |
620 |
} |
} |
621 |
else |
else |
622 |
{ |
{ |
650 |
break; |
break; |
651 |
stop = end; |
stop = end; |
652 |
if (STRINGP (string)) |
if (STRINGP (string)) |
653 |
ptr = XSTRING (string)->data + string_char_to_byte (string, start); |
ptr = SDATA (string) + string_char_to_byte (string, start); |
654 |
else |
else |
655 |
ptr = CHAR_POS_ADDR (start); |
ptr = CHAR_POS_ADDR (start); |
656 |
} |
} |
680 |
{ |
{ |
681 |
start += XINT (val); |
start += XINT (val); |
682 |
if (STRINGP (string)) |
if (STRINGP (string)) |
683 |
ptr = XSTRING (string)->data + string_char_to_byte (string, start); |
ptr = SDATA (string) + string_char_to_byte (string, start); |
684 |
else |
else |
685 |
ptr = CHAR_POS_ADDR (start); |
ptr = CHAR_POS_ADDR (start); |
686 |
} |
} |
715 |
|
|
716 |
Compose text in the region between START and END. |
Compose text in the region between START and END. |
717 |
Optional 3rd and 4th arguments are COMPONENTS and MODIFICATION-FUNC |
Optional 3rd and 4th arguments are COMPONENTS and MODIFICATION-FUNC |
718 |
for the composition. See `compose-region' for more detial. */) |
for the composition. See `compose-region' for more detail. */) |
719 |
(start, end, components, mod_func) |
(start, end, components, mod_func) |
720 |
Lisp_Object start, end, components, mod_func; |
Lisp_Object start, end, components, mod_func; |
721 |
{ |
{ |
736 |
|
|
737 |
Compose text between indices START and END of STRING. |
Compose text between indices START and END of STRING. |
738 |
Optional 4th and 5th arguments are COMPONENTS and MODIFICATION-FUNC |
Optional 4th and 5th arguments are COMPONENTS and MODIFICATION-FUNC |
739 |
for the composition. See `compose-string' for more detial. */) |
for the composition. See `compose-string' for more detail. */) |
740 |
(string, start, end, components, mod_func) |
(string, start, end, components, mod_func) |
741 |
Lisp_Object string, start, end, components, mod_func; |
Lisp_Object string, start, end, components, mod_func; |
742 |
{ |
{ |
746 |
|
|
747 |
if (XINT (start) < 0 || |
if (XINT (start) < 0 || |
748 |
XINT (start) > XINT (end) |
XINT (start) > XINT (end) |
749 |
|| XINT (end) > XSTRING (string)->size) |
|| XINT (end) > SCHARS (string)) |
750 |
args_out_of_range (start, end); |
args_out_of_range (start, end); |
751 |
|
|
752 |
compose_text (XINT (start), XINT (end), components, mod_func, string); |
compose_text (XINT (start), XINT (end), components, mod_func, string); |
754 |
} |
} |
755 |
|
|
756 |
DEFUN ("find-composition-internal", Ffind_composition_internal, |
DEFUN ("find-composition-internal", Ffind_composition_internal, |
757 |
Sfind_composition_internal, 4, 4, 0, |
Sfind_composition_internal, 4, 4, 0, |
758 |
doc: /* Internal use only. |
doc: /* Internal use only. |
759 |
|
|
760 |
Return information about composition at or nearest to position POS. |
Return information about composition at or nearest to position POS. |
775 |
} |
} |
776 |
else |
else |
777 |
end = -1; |
end = -1; |
778 |
|
|
779 |
if (!NILP (string)) |
if (!NILP (string)) |
780 |
{ |
{ |
781 |
CHECK_STRING (string); |
CHECK_STRING (string); |
782 |
if (XINT (pos) < 0 || XINT (pos) > XSTRING (string)->size) |
if (XINT (pos) < 0 || XINT (pos) > SCHARS (string)) |
783 |
args_out_of_range (string, pos); |
args_out_of_range (string, pos); |
784 |
} |
} |
785 |
else |
else |
839 |
{ |
{ |
840 |
Lisp_Object args[6]; |
Lisp_Object args[6]; |
841 |
extern Lisp_Object QCsize; |
extern Lisp_Object QCsize; |
842 |
|
|
843 |
args[0] = QCtest; |
args[0] = QCtest; |
844 |
args[1] = Qequal; |
args[1] = Qequal; |
845 |
args[2] = QCweakness; |
args[2] = QCweakness; |
846 |
args[3] = Qnil; |
args[3] = Qt; |
847 |
args[4] = QCsize; |
args[4] = QCsize; |
848 |
args[5] = make_number (311); |
args[5] = make_number (311); |
849 |
composition_hash_table = Fmake_hash_table (6, args); |
composition_hash_table = Fmake_hash_table (6, args); |