Mercurial > emacs
annotate src/composite.c @ 88054:eae3aec0f807
2008-01-29 John Wiegley <johnw@newartisans.com>
* url-auth.el (url-digest-auth): If the 'opaque' argument is not
being used, don't add it to the response text. Also, changed an
if so that the interaction between the PROMPT and OVERWRITE
arguments can no longer result in the user being queried twice for
the same login and password information.
author | John Wiegley <johnw@newartisans.com> |
---|---|
date | Tue, 29 Jan 2008 03:52:05 +0000 |
parents | 107ccd98fa12 |
children | 606f2d163a64 |
rev | line source |
---|---|
26848 | 1 /* Composite sequence support. |
68651
3bd95f4f2941
Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
67658
diff
changeset
|
2 Copyright (C) 2001, 2002, 2003, 2004, 2005, |
79759 | 3 2006, 2007, 2008 Free Software Foundation, Inc. |
4 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 | |
67658 | 5 National Institute of Advanced Industrial Science and Technology (AIST) |
6 Registration Number H14PRO021 | |
26848 | 7 |
8 This file is part of GNU Emacs. | |
9 | |
10 GNU Emacs is free software; you can redistribute it and/or modify | |
11 it under the terms of the GNU General Public License as published by | |
78313
2b9404c2f01f
Remove license from trivial file.
Glenn Morris <rgm@gnu.org>
parents:
78011
diff
changeset
|
12 the Free Software Foundation; either version 3, or (at your option) |
26848 | 13 any later version. |
14 | |
15 GNU Emacs is distributed in the hope that it will be useful, | |
16 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 GNU General Public License for more details. | |
19 | |
20 You should have received a copy of the GNU General Public License | |
21 along with GNU Emacs; see the file COPYING. If not, write to | |
64084 | 22 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
23 Boston, MA 02110-1301, USA. */ | |
26848 | 24 |
25 #include <config.h> | |
26 #include "lisp.h" | |
27 #include "buffer.h" | |
28 #include "charset.h" | |
29 #include "intervals.h" | |
30 | |
31 /* Emacs uses special text property `composition' to support character | |
32 composition. A sequence of characters that have the same (i.e. eq) | |
33 `composition' property value is treated as a single composite | |
34 sequence (we call it just `composition' here after). Characters in | |
35 a composition are all composed somehow on the screen. | |
36 | |
37 The property value has this form when the composition is made: | |
38 ((LENGTH . COMPONENTS) . MODIFICATION-FUNC) | |
39 then turns to this form: | |
40 (COMPOSITION-ID . (LENGTH COMPONENTS-VEC . MODIFICATION-FUNC)) | |
41 when the composition is registered in composition_hash_table and | |
42 composition_table. These rather peculiar structures were designed | |
43 to make it easy to distinguish them quickly (we can do that by | |
44 checking only the first element) and to extract LENGTH (from the | |
45 former form) and COMPOSITION-ID (from the latter form). | |
46 | |
47 We register a composition when it is displayed, or when the width | |
48 is required (for instance, to calculate columns). | |
49 | |
50 LENGTH -- Length of the composition. This information is used to | |
51 check the validity of the composition. | |
52 | |
53 COMPONENTS -- Character, string, vector, list, or nil. | |
54 | |
55 If it is nil, characters in the text are composed relatively | |
56 according to their metrics in font glyphs. | |
57 | |
58 If it is a character or a string, the character or characters | |
59 in the string are composed relatively. | |
60 | |
61 If it is a vector or list of integers, the element is a | |
62 character or an encoded composition rule. The characters are | |
63 composed according to the rules. (2N)th elements are | |
64 characters to be composed and (2N+1)th elements are | |
65 composition rules to tell how to compose (2N+2)th element with | |
66 the previously composed 2N glyphs. | |
67 | |
68 COMPONENTS-VEC -- Vector of integers. In relative composition, the | |
69 elements are characters to be composed. In rule-base | |
70 composition, the elements are characters or encoded | |
71 composition rules. | |
72 | |
73 MODIFICATION-FUNC -- If non nil, it is a function to call when the | |
74 composition gets invalid after a modification in a buffer. If | |
75 it is nil, a function in `composition-function-table' of the | |
76 first character in the sequence is called. | |
77 | |
78 COMPOSITION-ID --Identification number of the composition. It is | |
79 used as an index to composition_table for the composition. | |
80 | |
81 When Emacs has to display a composition or has to know its | |
82 displaying width, the function get_composition_id is called. It | |
83 returns COMPOSITION-ID so that the caller can access the | |
84 information about the composition through composition_table. If a | |
85 COMPOSITION-ID has not yet been assigned to the composition, | |
86 get_composition_id checks the validity of `composition' property, | |
87 and, if valid, assigns a new ID, registers the information in | |
88 composition_hash_table and composition_table, and changes the form | |
89 of the property value. If the property is invalid, return -1 | |
90 without changing the property value. | |
91 | |
92 We use two tables to keep information about composition; | |
93 composition_hash_table and composition_table. | |
94 | |
95 The former is a hash table in which keys are COMPONENTS-VECs and | |
96 values are the corresponding COMPOSITION-IDs. This hash table is | |
49136
6a4a30f1c2cb
(syms_of_composite): Make composition_hash_table
Dave Love <fx@gnu.org>
parents:
48318
diff
changeset
|
97 weak, but as each key (COMPONENTS-VEC) is also kept as a value of the |
26848 | 98 `composition' property, it won't be collected as garbage until all |
49136
6a4a30f1c2cb
(syms_of_composite): Make composition_hash_table
Dave Love <fx@gnu.org>
parents:
48318
diff
changeset
|
99 bits of text that have the same COMPONENTS-VEC are deleted. |
26848 | 100 |
101 The latter is a table of pointers to `struct composition' indexed | |
49136
6a4a30f1c2cb
(syms_of_composite): Make composition_hash_table
Dave Love <fx@gnu.org>
parents:
48318
diff
changeset
|
102 by COMPOSITION-ID. This structure keeps the other information (see |
26848 | 103 composite.h). |
104 | |
105 In general, a text property holds information about individual | |
106 characters. But, a `composition' property holds information about | |
49136
6a4a30f1c2cb
(syms_of_composite): Make composition_hash_table
Dave Love <fx@gnu.org>
parents:
48318
diff
changeset
|
107 a sequence of characters (in this sense, it is like the `intangible' |
26848 | 108 property). That means that we should not share the property value |
49136
6a4a30f1c2cb
(syms_of_composite): Make composition_hash_table
Dave Love <fx@gnu.org>
parents:
48318
diff
changeset
|
109 in adjacent compositions -- we can't distinguish them if they have the |
26848 | 110 same property. So, after any changes, we call |
111 `update_compositions' and change a property of one of adjacent | |
112 compositions to a copy of it. This function also runs a proper | |
113 composition modification function to make a composition that gets | |
114 invalid by the change valid again. | |
115 | |
49136
6a4a30f1c2cb
(syms_of_composite): Make composition_hash_table
Dave Love <fx@gnu.org>
parents:
48318
diff
changeset
|
116 As the value of the `composition' property holds information about a |
26848 | 117 specific range of text, the value gets invalid if we change the |
49136
6a4a30f1c2cb
(syms_of_composite): Make composition_hash_table
Dave Love <fx@gnu.org>
parents:
48318
diff
changeset
|
118 text in the range. We treat the `composition' property as always |
26848 | 119 rear-nonsticky (currently by setting default-text-properties to |
120 (rear-nonsticky (composition))) and we never make properties of | |
121 adjacent compositions identical. Thus, any such changes make the | |
49136
6a4a30f1c2cb
(syms_of_composite): Make composition_hash_table
Dave Love <fx@gnu.org>
parents:
48318
diff
changeset
|
122 range just shorter. So, we can check the validity of the `composition' |
26848 | 123 property by comparing LENGTH information with the actual length of |
124 the composition. | |
125 | |
126 */ | |
127 | |
128 | |
129 Lisp_Object Qcomposition; | |
130 | |
131 /* Table of pointers to the structure `composition' indexed by | |
132 COMPOSITION-ID. This structure is for storing information about | |
133 each composition except for COMPONENTS-VEC. */ | |
134 struct composition **composition_table; | |
135 | |
136 /* The current size of `composition_table'. */ | |
137 static int composition_table_size; | |
138 | |
139 /* Number of compositions currently made. */ | |
140 int n_compositions; | |
141 | |
142 /* Hash table for compositions. The key is COMPONENTS-VEC of | |
143 `composition' property. The value is the corresponding | |
144 COMPOSITION-ID. */ | |
145 Lisp_Object composition_hash_table; | |
146 | |
147 /* Function to call to adjust composition. */ | |
148 Lisp_Object Vcompose_chars_after_function; | |
149 | |
33240
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
150 /* Char-table of patterns and functions to make a composition. */ |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
151 Lisp_Object Vcomposition_function_table; |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
152 Lisp_Object Qcomposition_function_table; |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
153 |
26848 | 154 /* Temporary variable used in macros COMPOSITION_XXX. */ |
155 Lisp_Object composition_temp; | |
156 | |
157 /* Return how many columns C will occupy on the screen. It always | |
158 returns 1 for control characters and 8-bit characters because those | |
159 are just ignored in a composition. */ | |
160 #define CHAR_WIDTH(c) \ | |
161 (SINGLE_BYTE_CHAR_P (c) ? 1 : CHARSET_WIDTH (CHAR_CHARSET (c))) | |
162 | |
163 /* Return COMPOSITION-ID of a composition at buffer position | |
164 CHARPOS/BYTEPOS and length NCHARS. The `composition' property of | |
165 the sequence is PROP. STRING, if non-nil, is a string that | |
166 contains the composition instead of the current buffer. | |
167 | |
168 If the composition is invalid, return -1. */ | |
169 | |
170 int | |
171 get_composition_id (charpos, bytepos, nchars, prop, string) | |
172 int charpos, bytepos, nchars; | |
173 Lisp_Object prop, string; | |
174 { | |
175 Lisp_Object id, length, components, key, *key_contents; | |
176 int glyph_len; | |
177 struct Lisp_Hash_Table *hash_table = XHASH_TABLE (composition_hash_table); | |
178 int hash_index; | |
179 unsigned hash_code; | |
180 struct composition *cmp; | |
181 int i, ch; | |
182 | |
183 /* PROP should be | |
184 Form-A: ((LENGTH . COMPONENTS) . MODIFICATION-FUNC) | |
185 or | |
186 Form-B: (COMPOSITION-ID . (LENGTH COMPONENTS-VEC . MODIFICATION-FUNC)) | |
187 */ | |
188 if (nchars == 0 || !CONSP (prop)) | |
189 goto invalid_composition; | |
190 | |
191 id = XCAR (prop); | |
192 if (INTEGERP (id)) | |
193 { | |
194 /* PROP should be Form-B. */ | |
195 if (XINT (id) < 0 || XINT (id) >= n_compositions) | |
196 goto invalid_composition; | |
197 return XINT (id); | |
198 } | |
199 | |
200 /* PROP should be Form-A. | |
201 Thus, ID should be (LENGTH . COMPONENTS). */ | |
202 if (!CONSP (id)) | |
203 goto invalid_composition; | |
204 length = XCAR (id); | |
205 if (!INTEGERP (length) || XINT (length) != nchars) | |
206 goto invalid_composition; | |
207 | |
208 components = XCDR (id); | |
209 | |
210 /* Check if the same composition has already been registered or not | |
211 by consulting composition_hash_table. The key for this table is | |
212 COMPONENTS (converted to a vector COMPONENTS-VEC) or, if it is | |
213 nil, vector of characters in the composition range. */ | |
214 if (INTEGERP (components)) | |
215 key = Fmake_vector (make_number (1), components); | |
216 else if (STRINGP (components) || CONSP (components)) | |
217 key = Fvconcat (1, &components); | |
218 else if (VECTORP (components)) | |
219 key = components; | |
220 else if (NILP (components)) | |
221 { | |
222 key = Fmake_vector (make_number (nchars), Qnil); | |
223 if (STRINGP (string)) | |
224 for (i = 0; i < nchars; i++) | |
225 { | |
226 FETCH_STRING_CHAR_ADVANCE (ch, string, charpos, bytepos); | |
227 XVECTOR (key)->contents[i] = make_number (ch); | |
228 } | |
229 else | |
230 for (i = 0; i < nchars; i++) | |
231 { | |
232 FETCH_CHAR_ADVANCE (ch, charpos, bytepos); | |
233 XVECTOR (key)->contents[i] = make_number (ch); | |
234 } | |
235 } | |
236 else | |
237 goto invalid_composition; | |
238 | |
239 hash_index = hash_lookup (hash_table, key, &hash_code); | |
240 if (hash_index >= 0) | |
241 { | |
242 /* We have already registered the same composition. Change PROP | |
243 from Form-A above to Form-B while replacing COMPONENTS with | |
244 COMPONENTS-VEC stored in the hash table. We can directly | |
245 modify the cons cell of PROP because it is not shared. */ | |
246 key = HASH_KEY (hash_table, hash_index); | |
247 id = HASH_VALUE (hash_table, hash_index); | |
39973
579177964efa
Avoid (most) uses of XCAR/XCDR as lvalues, for flexibility in experimenting
Ken Raeburn <raeburn@raeburn.org>
parents:
39046
diff
changeset
|
248 XSETCAR (prop, id); |
579177964efa
Avoid (most) uses of XCAR/XCDR as lvalues, for flexibility in experimenting
Ken Raeburn <raeburn@raeburn.org>
parents:
39046
diff
changeset
|
249 XSETCDR (prop, Fcons (make_number (nchars), Fcons (key, XCDR (prop)))); |
26848 | 250 return XINT (id); |
251 } | |
252 | |
253 /* This composition is a new one. We must register it. */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49136
diff
changeset
|
254 |
26848 | 255 /* Check if we have sufficient memory to store this information. */ |
256 if (composition_table_size == 0) | |
257 { | |
258 composition_table_size = 256; | |
259 composition_table | |
260 = (struct composition **) xmalloc (sizeof (composition_table[0]) | |
261 * composition_table_size); | |
262 } | |
263 else if (composition_table_size <= n_compositions) | |
264 { | |
265 composition_table_size += 256; | |
266 composition_table | |
267 = (struct composition **) xrealloc (composition_table, | |
268 sizeof (composition_table[0]) | |
269 * composition_table_size); | |
270 } | |
271 | |
272 key_contents = XVECTOR (key)->contents; | |
273 | |
274 /* Check if the contents of COMPONENTS are valid if COMPONENTS is a | |
275 vector or a list. It should be a sequence of: | |
276 char1 rule1 char2 rule2 char3 ... ruleN charN+1 */ | |
277 if (VECTORP (components) || CONSP (components)) | |
278 { | |
279 int len = XVECTOR (key)->size; | |
280 | |
281 /* The number of elements should be odd. */ | |
282 if ((len % 2) == 0) | |
283 goto invalid_composition; | |
284 /* All elements should be integers (character or encoded | |
285 composition rule). */ | |
286 for (i = 0; i < len; i++) | |
287 { | |
288 if (!INTEGERP (key_contents[i])) | |
289 goto invalid_composition; | |
290 } | |
291 } | |
292 | |
293 /* Change PROP from Form-A above to Form-B. We can directly modify | |
294 the cons cell of PROP because it is not shared. */ | |
295 XSETFASTINT (id, n_compositions); | |
39973
579177964efa
Avoid (most) uses of XCAR/XCDR as lvalues, for flexibility in experimenting
Ken Raeburn <raeburn@raeburn.org>
parents:
39046
diff
changeset
|
296 XSETCAR (prop, id); |
579177964efa
Avoid (most) uses of XCAR/XCDR as lvalues, for flexibility in experimenting
Ken Raeburn <raeburn@raeburn.org>
parents:
39046
diff
changeset
|
297 XSETCDR (prop, Fcons (make_number (nchars), Fcons (key, XCDR (prop)))); |
26848 | 298 |
299 /* Register the composition in composition_hash_table. */ | |
300 hash_index = hash_put (hash_table, key, id, hash_code); | |
301 | |
302 /* Register the composition in composition_table. */ | |
303 cmp = (struct composition *) xmalloc (sizeof (struct composition)); | |
304 | |
305 cmp->method = (NILP (components) | |
306 ? COMPOSITION_RELATIVE | |
307 : ((INTEGERP (components) || STRINGP (components)) | |
308 ? COMPOSITION_WITH_ALTCHARS | |
309 : COMPOSITION_WITH_RULE_ALTCHARS)); | |
310 cmp->hash_index = hash_index; | |
311 glyph_len = (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS | |
312 ? (XVECTOR (key)->size + 1) / 2 | |
313 : XVECTOR (key)->size); | |
314 cmp->glyph_len = glyph_len; | |
315 cmp->offsets = (short *) xmalloc (sizeof (short) * glyph_len * 2); | |
316 cmp->font = NULL; | |
317 | |
318 /* Calculate the width of overall glyphs of the composition. */ | |
319 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS) | |
320 { | |
321 /* Relative composition. */ | |
322 cmp->width = 0; | |
323 for (i = 0; i < glyph_len; i++) | |
324 { | |
325 int this_width; | |
326 ch = XINT (key_contents[i]); | |
327 this_width = CHAR_WIDTH (ch); | |
328 if (cmp->width < this_width) | |
329 cmp->width = this_width; | |
330 } | |
331 } | |
332 else | |
333 { | |
334 /* Rule-base composition. */ | |
335 float leftmost = 0.0, rightmost; | |
336 | |
337 ch = XINT (key_contents[0]); | |
338 rightmost = CHAR_WIDTH (ch); | |
339 | |
340 for (i = 1; i < glyph_len; i += 2) | |
341 { | |
342 int rule, gref, nref; | |
343 int this_width; | |
344 float this_left; | |
345 | |
346 rule = XINT (key_contents[i]); | |
347 ch = XINT (key_contents[i + 1]); | |
348 this_width = CHAR_WIDTH (ch); | |
349 | |
350 /* A composition rule is specified by an integer value | |
351 that encodes global and new reference points (GREF and | |
352 NREF). GREF and NREF are specified by numbers as | |
353 below: | |
354 0---1---2 -- ascent | |
355 | | | |
356 | | | |
357 | | | |
358 9--10--11 -- center | |
359 | | | |
360 ---3---4---5--- baseline | |
361 | | | |
362 6---7---8 -- descent | |
363 */ | |
364 COMPOSITION_DECODE_RULE (rule, gref, nref); | |
365 this_left = (leftmost | |
366 + (gref % 3) * (rightmost - leftmost) / 2.0 | |
367 - (nref % 3) * this_width / 2.0); | |
368 | |
369 if (this_left < leftmost) | |
370 leftmost = this_left; | |
371 if (this_left + this_width > rightmost) | |
372 rightmost = this_left + this_width; | |
373 } | |
374 | |
375 cmp->width = rightmost - leftmost; | |
376 if (cmp->width < (rightmost - leftmost)) | |
377 /* To get a ceiling integer value. */ | |
378 cmp->width++; | |
379 } | |
380 | |
381 composition_table[n_compositions] = cmp; | |
382 | |
383 return n_compositions++; | |
384 | |
385 invalid_composition: | |
386 /* Would it be better to remove this `composition' property? */ | |
387 return -1; | |
388 } | |
389 | |
390 | |
391 /* Find a composition at or nearest to position POS of OBJECT (buffer | |
392 or string). | |
393 | |
394 OBJECT defaults to the current buffer. If there's a composition at | |
395 POS, set *START and *END to the start and end of the sequence, | |
396 *PROP to the `composition' property, and return 1. | |
397 | |
398 If there's no composition at POS and LIMIT is negative, return 0. | |
399 | |
400 Otherwise, search for a composition forward (LIMIT > POS) or | |
401 backward (LIMIT < POS). In this case, LIMIT bounds the search. | |
402 | |
403 If a composition is found, set *START, *END, and *PROP as above, | |
404 and return 1, else return 0. | |
405 | |
406 This doesn't check the validity of composition. */ | |
407 | |
408 int | |
409 find_composition (pos, limit, start, end, prop, object) | |
410 int pos, limit, *start, *end; | |
411 Lisp_Object *prop, object; | |
412 { | |
413 Lisp_Object val; | |
414 | |
415 if (get_property_and_range (pos, Qcomposition, prop, start, end, object)) | |
416 return 1; | |
417 | |
418 if (limit < 0 || limit == pos) | |
419 return 0; | |
420 | |
421 if (limit > pos) /* search forward */ | |
34933
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
422 { |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
423 val = Fnext_single_property_change (make_number (pos), Qcomposition, |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
424 object, make_number (limit)); |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
425 pos = XINT (val); |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
426 if (pos == limit) |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
427 return 0; |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
428 } |
26848 | 429 else /* search backward */ |
34933
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
430 { |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
431 if (get_property_and_range (pos - 1, Qcomposition, prop, start, end, |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
432 object)) |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
433 return 1; |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
434 val = Fprevious_single_property_change (make_number (pos), Qcomposition, |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
435 object, make_number (limit)); |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
436 pos = XINT (val); |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
437 if (pos == limit) |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
438 return 0; |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
439 pos--; |
414310d24f52
(find_composition): Fix a code for searching a composition backward.
Kenichi Handa <handa@m17n.org>
parents:
34241
diff
changeset
|
440 } |
26848 | 441 get_property_and_range (pos, Qcomposition, prop, start, end, object); |
442 return 1; | |
443 } | |
444 | |
445 /* Run a proper function to adjust the composition sitting between | |
446 FROM and TO with property PROP. */ | |
447 | |
448 static void | |
449 run_composition_function (from, to, prop) | |
450 int from, to; | |
451 Lisp_Object prop; | |
452 { | |
34958
e3133339e30c
(run_composition_function): Remove unused variable
Eli Zaretskii <eliz@gnu.org>
parents:
34933
diff
changeset
|
453 Lisp_Object func; |
26848 | 454 int start, end; |
455 | |
456 func = COMPOSITION_MODIFICATION_FUNC (prop); | |
457 /* If an invalid composition precedes or follows, try to make them | |
458 valid too. */ | |
459 if (from > BEGV | |
460 && find_composition (from - 1, -1, &start, &end, &prop, Qnil) | |
461 && !COMPOSITION_VALID_P (start, end, prop)) | |
462 from = start; | |
463 if (to < ZV | |
464 && find_composition (to, -1, &start, &end, &prop, Qnil) | |
465 && !COMPOSITION_VALID_P (start, end, prop)) | |
466 to = end; | |
46940 | 467 if (!NILP (Ffboundp (func))) |
26848 | 468 call2 (func, make_number (from), make_number (to)); |
28472
bae9218986ac
* composite.c (run_composite_function): Use NILP when checking for nil.
Ken Raeburn <raeburn@raeburn.org>
parents:
26848
diff
changeset
|
469 else if (!NILP (Ffboundp (Vcompose_chars_after_function))) |
33240
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
470 call3 (Vcompose_chars_after_function, |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
471 make_number (from), make_number (to), Qnil); |
26848 | 472 } |
473 | |
474 /* Make invalid compositions adjacent to or inside FROM and TO valid. | |
475 CHECK_MASK is bitwise `or' of mask bits defined by macros | |
476 CHECK_XXX (see the comment in composite.h). | |
477 | |
478 This function is called when a buffer text is changed. If the | |
479 change is deletion, FROM == TO. Otherwise, FROM < TO. */ | |
480 | |
481 void | |
482 update_compositions (from, to, check_mask) | |
48318
5c1be14cbcac
(calccost, cmgoto): Declare all args (per C99).
Dave Love <fx@gnu.org>
parents:
47275
diff
changeset
|
483 int from, to, check_mask; |
26848 | 484 { |
34958
e3133339e30c
(run_composition_function): Remove unused variable
Eli Zaretskii <eliz@gnu.org>
parents:
34933
diff
changeset
|
485 Lisp_Object prop; |
26848 | 486 int start, end; |
487 | |
39046
a61b3d907098
(update_compositions): Do nothing if
Gerd Moellmann <gerd@gnu.org>
parents:
38116
diff
changeset
|
488 if (inhibit_modification_hooks) |
a61b3d907098
(update_compositions): Do nothing if
Gerd Moellmann <gerd@gnu.org>
parents:
38116
diff
changeset
|
489 return; |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49136
diff
changeset
|
490 |
28581
151b7ae3b21f
(update_compositions): If FROM and TO is not in a
Kenichi Handa <handa@m17n.org>
parents:
28472
diff
changeset
|
491 /* If FROM and TO are not in a valid range, do nothing. */ |
151b7ae3b21f
(update_compositions): If FROM and TO is not in a
Kenichi Handa <handa@m17n.org>
parents:
28472
diff
changeset
|
492 if (! (BEGV <= from && from <= to && to <= ZV)) |
151b7ae3b21f
(update_compositions): If FROM and TO is not in a
Kenichi Handa <handa@m17n.org>
parents:
28472
diff
changeset
|
493 return; |
151b7ae3b21f
(update_compositions): If FROM and TO is not in a
Kenichi Handa <handa@m17n.org>
parents:
28472
diff
changeset
|
494 |
26848 | 495 if (check_mask & CHECK_HEAD) |
496 { | |
497 /* FROM should be at composition boundary. But, insertion or | |
498 deletion will make two compositions adjacent and | |
499 indistinguishable when they have same (eq) property. To | |
500 avoid it, in such a case, we change the property of the | |
501 latter to the copy of it. */ | |
502 if (from > BEGV | |
78011
f6d5dccc38c9
(update_compositions): Check validity of compositions.
Chong Yidong <cyd@stupidchicken.com>
parents:
75348
diff
changeset
|
503 && find_composition (from - 1, -1, &start, &end, &prop, Qnil) |
f6d5dccc38c9
(update_compositions): Check validity of compositions.
Chong Yidong <cyd@stupidchicken.com>
parents:
75348
diff
changeset
|
504 && COMPOSITION_VALID_P (start, end, prop)) |
26848 | 505 { |
506 if (from < end) | |
507 Fput_text_property (make_number (from), make_number (end), | |
508 Qcomposition, | |
509 Fcons (XCAR (prop), XCDR (prop)), Qnil); | |
510 run_composition_function (start, end, prop); | |
511 from = end; | |
512 } | |
37242
029c8c1b451d
(update_compositions) <check_mask & CHECK_HEAD>: Fix
Dave Love <fx@gnu.org>
parents:
34958
diff
changeset
|
513 else if (from < ZV |
78011
f6d5dccc38c9
(update_compositions): Check validity of compositions.
Chong Yidong <cyd@stupidchicken.com>
parents:
75348
diff
changeset
|
514 && find_composition (from, -1, &start, &from, &prop, Qnil) |
f6d5dccc38c9
(update_compositions): Check validity of compositions.
Chong Yidong <cyd@stupidchicken.com>
parents:
75348
diff
changeset
|
515 && COMPOSITION_VALID_P (start, from, prop)) |
26848 | 516 run_composition_function (start, from, prop); |
517 } | |
518 | |
519 if (check_mask & CHECK_INSIDE) | |
520 { | |
521 /* In this case, we are sure that (check & CHECK_TAIL) is also | |
522 nonzero. Thus, here we should check only compositions before | |
523 (to - 1). */ | |
524 while (from < to - 1 | |
525 && find_composition (from, to, &start, &from, &prop, Qnil) | |
78011
f6d5dccc38c9
(update_compositions): Check validity of compositions.
Chong Yidong <cyd@stupidchicken.com>
parents:
75348
diff
changeset
|
526 && COMPOSITION_VALID_P (start, from, prop) |
26848 | 527 && from < to - 1) |
528 run_composition_function (start, from, prop); | |
529 } | |
530 | |
531 if (check_mask & CHECK_TAIL) | |
532 { | |
533 if (from < to | |
78011
f6d5dccc38c9
(update_compositions): Check validity of compositions.
Chong Yidong <cyd@stupidchicken.com>
parents:
75348
diff
changeset
|
534 && find_composition (to - 1, -1, &start, &end, &prop, Qnil) |
f6d5dccc38c9
(update_compositions): Check validity of compositions.
Chong Yidong <cyd@stupidchicken.com>
parents:
75348
diff
changeset
|
535 && COMPOSITION_VALID_P (start, end, prop)) |
26848 | 536 { |
537 /* TO should be also at composition boundary. But, | |
538 insertion or deletion will make two compositions adjacent | |
539 and indistinguishable when they have same (eq) property. | |
540 To avoid it, in such a case, we change the property of | |
541 the former to the copy of it. */ | |
542 if (to < end) | |
543 Fput_text_property (make_number (start), make_number (to), | |
544 Qcomposition, | |
545 Fcons (XCAR (prop), XCDR (prop)), Qnil); | |
546 run_composition_function (start, end, prop); | |
547 } | |
548 else if (to < ZV | |
78011
f6d5dccc38c9
(update_compositions): Check validity of compositions.
Chong Yidong <cyd@stupidchicken.com>
parents:
75348
diff
changeset
|
549 && find_composition (to, -1, &start, &end, &prop, Qnil) |
f6d5dccc38c9
(update_compositions): Check validity of compositions.
Chong Yidong <cyd@stupidchicken.com>
parents:
75348
diff
changeset
|
550 && COMPOSITION_VALID_P (start, end, prop)) |
26848 | 551 run_composition_function (start, end, prop); |
552 } | |
553 } | |
554 | |
30022
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
555 |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
556 /* Modify composition property values in LIST destructively. LIST is |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
557 a list as returned from text_property_list. Change values to the |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
558 top-level copies of them so that none of them are `eq'. */ |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
559 |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
560 void |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
561 make_composition_value_copy (list) |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
562 Lisp_Object list; |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
563 { |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
564 Lisp_Object plist, val; |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
565 |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
566 for (; CONSP (list); list = XCDR (list)) |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
567 { |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
568 plist = XCAR (XCDR (XCDR (XCAR (list)))); |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
569 while (CONSP (plist) && CONSP (XCDR (plist))) |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
570 { |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
571 if (EQ (XCAR (plist), Qcomposition) |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
572 && (val = XCAR (XCDR (plist)), CONSP (val))) |
39973
579177964efa
Avoid (most) uses of XCAR/XCDR as lvalues, for flexibility in experimenting
Ken Raeburn <raeburn@raeburn.org>
parents:
39046
diff
changeset
|
573 XSETCAR (XCDR (plist), Fcons (XCAR (val), XCDR (val))); |
30022
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
574 plist = XCDR (XCDR (plist)); |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
575 } |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
576 } |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
577 } |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
578 |
6a52904a743b
(make_composition_value_copy): New function.
Kenichi Handa <handa@m17n.org>
parents:
28581
diff
changeset
|
579 |
26848 | 580 /* Make text in the region between START and END a composition that |
581 has COMPONENTS and MODIFICATION-FUNC. | |
582 | |
583 If STRING is non-nil, then operate on characters contained between | |
584 indices START and END in STRING. */ | |
585 | |
586 void | |
587 compose_text (start, end, components, modification_func, string) | |
588 int start, end; | |
589 Lisp_Object components, modification_func, string; | |
590 { | |
591 Lisp_Object prop; | |
592 | |
593 prop = Fcons (Fcons (make_number (end - start), components), | |
594 modification_func); | |
595 Fput_text_property (make_number (start), make_number (end), | |
596 Qcomposition, prop, string); | |
597 } | |
598 | |
599 | |
600 /* Emacs Lisp APIs. */ | |
601 | |
602 DEFUN ("compose-region-internal", Fcompose_region_internal, | |
603 Scompose_region_internal, 2, 4, 0, | |
41001
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
604 doc: /* Internal use only. |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
605 |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
606 Compose text in the region between START and END. |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
607 Optional 3rd and 4th arguments are COMPONENTS and MODIFICATION-FUNC |
47275
49ac77cddafb
(Fcompose_region_internal, Fcompose_string_internal): Fix spacing.
Juanma Barranquero <lekktu@gmail.com>
parents:
46940
diff
changeset
|
608 for the composition. See `compose-region' for more detail. */) |
64574
5c90d9a42573
(Fcompose_region_internal, Fcompose_string_internal):
Juanma Barranquero <lekktu@gmail.com>
parents:
64084
diff
changeset
|
609 (start, end, components, modification_func) |
5c90d9a42573
(Fcompose_region_internal, Fcompose_string_internal):
Juanma Barranquero <lekktu@gmail.com>
parents:
64084
diff
changeset
|
610 Lisp_Object start, end, components, modification_func; |
26848 | 611 { |
612 validate_region (&start, &end); | |
613 if (!NILP (components) | |
614 && !INTEGERP (components) | |
615 && !CONSP (components) | |
616 && !STRINGP (components)) | |
40656
cdfd4d09b79a
Update usage of CHECK_ macros (remove unused second argument).
Pavel Janík <Pavel@Janik.cz>
parents:
39973
diff
changeset
|
617 CHECK_VECTOR (components); |
26848 | 618 |
64574
5c90d9a42573
(Fcompose_region_internal, Fcompose_string_internal):
Juanma Barranquero <lekktu@gmail.com>
parents:
64084
diff
changeset
|
619 compose_text (XINT (start), XINT (end), components, modification_func, Qnil); |
26848 | 620 return Qnil; |
621 } | |
622 | |
623 DEFUN ("compose-string-internal", Fcompose_string_internal, | |
624 Scompose_string_internal, 3, 5, 0, | |
41001
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
625 doc: /* Internal use only. |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
626 |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
627 Compose text between indices START and END of STRING. |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
628 Optional 4th and 5th arguments are COMPONENTS and MODIFICATION-FUNC |
47275
49ac77cddafb
(Fcompose_region_internal, Fcompose_string_internal): Fix spacing.
Juanma Barranquero <lekktu@gmail.com>
parents:
46940
diff
changeset
|
629 for the composition. See `compose-string' for more detail. */) |
64574
5c90d9a42573
(Fcompose_region_internal, Fcompose_string_internal):
Juanma Barranquero <lekktu@gmail.com>
parents:
64084
diff
changeset
|
630 (string, start, end, components, modification_func) |
5c90d9a42573
(Fcompose_region_internal, Fcompose_string_internal):
Juanma Barranquero <lekktu@gmail.com>
parents:
64084
diff
changeset
|
631 Lisp_Object string, start, end, components, modification_func; |
26848 | 632 { |
40656
cdfd4d09b79a
Update usage of CHECK_ macros (remove unused second argument).
Pavel Janík <Pavel@Janik.cz>
parents:
39973
diff
changeset
|
633 CHECK_STRING (string); |
cdfd4d09b79a
Update usage of CHECK_ macros (remove unused second argument).
Pavel Janík <Pavel@Janik.cz>
parents:
39973
diff
changeset
|
634 CHECK_NUMBER (start); |
cdfd4d09b79a
Update usage of CHECK_ macros (remove unused second argument).
Pavel Janík <Pavel@Janik.cz>
parents:
39973
diff
changeset
|
635 CHECK_NUMBER (end); |
26848 | 636 |
637 if (XINT (start) < 0 || | |
638 XINT (start) > XINT (end) | |
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
parents:
46293
diff
changeset
|
639 || XINT (end) > SCHARS (string)) |
26848 | 640 args_out_of_range (start, end); |
641 | |
64574
5c90d9a42573
(Fcompose_region_internal, Fcompose_string_internal):
Juanma Barranquero <lekktu@gmail.com>
parents:
64084
diff
changeset
|
642 compose_text (XINT (start), XINT (end), components, modification_func, string); |
26848 | 643 return string; |
644 } | |
645 | |
646 DEFUN ("find-composition-internal", Ffind_composition_internal, | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49136
diff
changeset
|
647 Sfind_composition_internal, 4, 4, 0, |
41001
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
648 doc: /* Internal use only. |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
649 |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
650 Return information about composition at or nearest to position POS. |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
651 See `find-composition' for more detail. */) |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
652 (pos, limit, string, detail_p) |
26848 | 653 Lisp_Object pos, limit, string, detail_p; |
654 { | |
655 Lisp_Object prop, tail; | |
656 int start, end; | |
657 int id; | |
658 | |
40656
cdfd4d09b79a
Update usage of CHECK_ macros (remove unused second argument).
Pavel Janík <Pavel@Janik.cz>
parents:
39973
diff
changeset
|
659 CHECK_NUMBER_COERCE_MARKER (pos); |
26848 | 660 start = XINT (pos); |
661 if (!NILP (limit)) | |
662 { | |
40656
cdfd4d09b79a
Update usage of CHECK_ macros (remove unused second argument).
Pavel Janík <Pavel@Janik.cz>
parents:
39973
diff
changeset
|
663 CHECK_NUMBER_COERCE_MARKER (limit); |
26848 | 664 end = XINT (limit); |
665 } | |
666 else | |
667 end = -1; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49136
diff
changeset
|
668 |
26848 | 669 if (!NILP (string)) |
38097
8757fe98656e
(Ffind_composition_internal): Check POS
Gerd Moellmann <gerd@gnu.org>
parents:
37242
diff
changeset
|
670 { |
40656
cdfd4d09b79a
Update usage of CHECK_ macros (remove unused second argument).
Pavel Janík <Pavel@Janik.cz>
parents:
39973
diff
changeset
|
671 CHECK_STRING (string); |
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
parents:
46293
diff
changeset
|
672 if (XINT (pos) < 0 || XINT (pos) > SCHARS (string)) |
38097
8757fe98656e
(Ffind_composition_internal): Check POS
Gerd Moellmann <gerd@gnu.org>
parents:
37242
diff
changeset
|
673 args_out_of_range (string, pos); |
8757fe98656e
(Ffind_composition_internal): Check POS
Gerd Moellmann <gerd@gnu.org>
parents:
37242
diff
changeset
|
674 } |
8757fe98656e
(Ffind_composition_internal): Check POS
Gerd Moellmann <gerd@gnu.org>
parents:
37242
diff
changeset
|
675 else |
8757fe98656e
(Ffind_composition_internal): Check POS
Gerd Moellmann <gerd@gnu.org>
parents:
37242
diff
changeset
|
676 { |
38116
a85b9df3dffb
(Ffind_composition_internal): Accept ZV
Gerd Moellmann <gerd@gnu.org>
parents:
38098
diff
changeset
|
677 if (XINT (pos) < BEGV || XINT (pos) > ZV) |
38097
8757fe98656e
(Ffind_composition_internal): Check POS
Gerd Moellmann <gerd@gnu.org>
parents:
37242
diff
changeset
|
678 args_out_of_range (Fcurrent_buffer (), pos); |
8757fe98656e
(Ffind_composition_internal): Check POS
Gerd Moellmann <gerd@gnu.org>
parents:
37242
diff
changeset
|
679 } |
26848 | 680 |
681 if (!find_composition (start, end, &start, &end, &prop, string)) | |
682 return Qnil; | |
683 if (!COMPOSITION_VALID_P (start, end, prop)) | |
684 return Fcons (make_number (start), Fcons (make_number (end), | |
685 Fcons (Qnil, Qnil))); | |
686 if (NILP (detail_p)) | |
687 return Fcons (make_number (start), Fcons (make_number (end), | |
688 Fcons (Qt, Qnil))); | |
689 | |
690 if (COMPOSITION_REGISTERD_P (prop)) | |
691 id = COMPOSITION_ID (prop); | |
692 else | |
693 { | |
694 int start_byte = (NILP (string) | |
695 ? CHAR_TO_BYTE (start) | |
696 : string_char_to_byte (string, start)); | |
697 id = get_composition_id (start, start_byte, end - start, prop, string); | |
698 } | |
699 | |
700 if (id >= 0) | |
701 { | |
702 Lisp_Object components, relative_p, mod_func; | |
703 enum composition_method method = COMPOSITION_METHOD (prop); | |
704 int width = composition_table[id]->width; | |
705 | |
706 components = Fcopy_sequence (COMPOSITION_COMPONENTS (prop)); | |
707 relative_p = (method == COMPOSITION_WITH_RULE_ALTCHARS | |
708 ? Qnil : Qt); | |
709 mod_func = COMPOSITION_MODIFICATION_FUNC (prop); | |
710 tail = Fcons (components, | |
711 Fcons (relative_p, | |
712 Fcons (mod_func, | |
713 Fcons (make_number (width), Qnil)))); | |
714 } | |
715 else | |
716 tail = Qnil; | |
717 | |
718 return Fcons (make_number (start), Fcons (make_number (end), tail)); | |
719 } | |
720 | |
721 | |
722 void | |
723 syms_of_composite () | |
724 { | |
725 Qcomposition = intern ("composition"); | |
726 staticpro (&Qcomposition); | |
727 | |
728 /* Make a hash table for composition. */ | |
729 { | |
28472
bae9218986ac
* composite.c (run_composite_function): Use NILP when checking for nil.
Ken Raeburn <raeburn@raeburn.org>
parents:
26848
diff
changeset
|
730 Lisp_Object args[6]; |
26848 | 731 extern Lisp_Object QCsize; |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49136
diff
changeset
|
732 |
26848 | 733 args[0] = QCtest; |
734 args[1] = Qequal; | |
53316 | 735 /* We used to make the hash table weak so that unreferenced |
736 compostions can be garbage-collected. But, usually once | |
737 created compositions are repeatedly used in an Emacs session, | |
738 and thus it's not worth to save memory in such a way. So, we | |
739 make the table not weak. */ | |
26848 | 740 args[2] = QCweakness; |
53221
94ae4d74b7e0
(syms_of_composite): Don't make the compostion hash table week.
Kenichi Handa <handa@m17n.org>
parents:
52401
diff
changeset
|
741 args[3] = Qnil; |
26848 | 742 args[4] = QCsize; |
743 args[5] = make_number (311); | |
28472
bae9218986ac
* composite.c (run_composite_function): Use NILP when checking for nil.
Ken Raeburn <raeburn@raeburn.org>
parents:
26848
diff
changeset
|
744 composition_hash_table = Fmake_hash_table (6, args); |
26848 | 745 staticpro (&composition_hash_table); |
746 } | |
747 | |
748 /* Text property `composition' should be nonsticky by default. */ | |
749 Vtext_property_default_nonsticky | |
750 = Fcons (Fcons (Qcomposition, Qt), Vtext_property_default_nonsticky); | |
751 | |
752 DEFVAR_LISP ("compose-chars-after-function", &Vcompose_chars_after_function, | |
41001
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
753 doc: /* Function to adjust composition of buffer text. |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
754 |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
755 The function is called with three arguments FROM, TO, and OBJECT. |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
756 FROM and TO specify the range of text of which composition should be |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
757 adjusted. OBJECT, if non-nil, is a string that contains the text. |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
758 |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
759 This function is called after a text with `composition' property is |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
760 inserted or deleted to keep `composition' property of buffer text |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
761 valid. |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
762 |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
763 The default value is the function `compose-chars-after'. */); |
26848 | 764 Vcompose_chars_after_function = intern ("compose-chars-after"); |
765 | |
33240
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
766 Qcomposition_function_table = intern ("composition-function-table"); |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
767 staticpro (&Qcomposition_function_table); |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
768 |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
769 /* Intern this now in case it isn't already done. |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
770 Setting this variable twice is harmless. |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
771 But don't staticpro it here--that is done in alloc.c. */ |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
772 Qchar_table_extra_slots = intern ("char-table-extra-slots"); |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
773 |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
774 Fput (Qcomposition_function_table, Qchar_table_extra_slots, make_number (0)); |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
775 |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
776 DEFVAR_LISP ("composition-function-table", &Vcomposition_function_table, |
41001
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
777 doc: /* Char table of patterns and functions to make a composition. |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
778 |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
779 Each element is nil or an alist of PATTERNs vs FUNCs, where PATTERNs |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
780 are regular expressions and FUNCs are functions. FUNC is responsible |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
781 for composing text matching the corresponding PATTERN. FUNC is called |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
782 with three arguments FROM, TO, and PATTERN. See the function |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
783 `compose-chars-after' for more detail. |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
784 |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
785 This table is looked up by the first character of a composition when |
a17c8b15ef1b
Change doc-string comments to `new style' [w/`doc:' keyword].
Pavel Janík <Pavel@Janik.cz>
parents:
40656
diff
changeset
|
786 the composition gets invalid after a change in a buffer. */); |
33240
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
787 Vcomposition_function_table |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
788 = Fmake_char_table (Qcomposition_function_table, Qnil); |
aaa42106f0da
(Vcomposition_function_table): New variable.
Kenichi Handa <handa@m17n.org>
parents:
30171
diff
changeset
|
789 |
26848 | 790 defsubr (&Scompose_region_internal); |
791 defsubr (&Scompose_string_internal); | |
792 defsubr (&Sfind_composition_internal); | |
793 } | |
52401 | 794 |
795 /* arch-tag: 79cefaf8-ca48-4eed-97e5-d5afb290d272 | |
796 (do not change this comment) */ |