diff options
| author | Kenichi Handa | 2008-09-05 00:47:23 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2008-09-05 00:47:23 +0000 |
| commit | 90b3fe912530f5170ae660f0a9a9a66f35714491 (patch) | |
| tree | 5f7a8e6a1eddb3200a5d5a018f45e1427c7a4525 /src | |
| parent | cbf21103d9fad16fe87d9affbc955c75cce657e4 (diff) | |
| download | emacs-90b3fe912530f5170ae660f0a9a9a66f35714491.tar.gz emacs-90b3fe912530f5170ae660f0a9a9a66f35714491.zip | |
(autocmp_chars): Check lookback count.
(composition_compute_stop_pos): Set cmp_it->lookback.
(composition_reseat_it): Check lookback count.
(struct position_record): New struct.
(FORWARD_CHAR, BACKWARD_CHAR, CHAR_COMPOSABLE_P): New macros.
(find_automatic_composition): New function.
(composition_adjust_point): Use find_automatic_composition.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 12 | ||||
| -rw-r--r-- | src/composite.c | 356 |
2 files changed, 264 insertions, 104 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 2cb1c7b8cb0..ff10dd9b61e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2008-09-05 Kenichi Handa <handa@m17n.org> | ||
| 2 | |||
| 3 | * composite.c (autocmp_chars): Check lookback count. | ||
| 4 | (composition_compute_stop_pos): Set cmp_it->lookback. | ||
| 5 | (composition_reseat_it): Check lookback count. | ||
| 6 | (struct position_record): New struct. | ||
| 7 | (FORWARD_CHAR, BACKWARD_CHAR, CHAR_COMPOSABLE_P): New macros. | ||
| 8 | (find_automatic_composition): New function. | ||
| 9 | (composition_adjust_point): Use find_automatic_composition. | ||
| 10 | |||
| 11 | * dispextern.h (struct composition_it): New member lookback. | ||
| 12 | |||
| 1 | 2008-09-02 Chong Yidong <cyd@stupidchicken.com> | 13 | 2008-09-02 Chong Yidong <cyd@stupidchicken.com> |
| 2 | 14 | ||
| 3 | * indent.c (Fvertical_motion): Don't call move_it_by_lines again | 15 | * indent.c (Fvertical_motion): Don't call move_it_by_lines again |
diff --git a/src/composite.c b/src/composite.c index 257ca66632d..6e9c823d8c1 100644 --- a/src/composite.c +++ b/src/composite.c | |||
| @@ -402,8 +402,8 @@ get_composition_id (charpos, bytepos, nchars, prop, string) | |||
| 402 | } | 402 | } |
| 403 | 403 | ||
| 404 | 404 | ||
| 405 | /* Find a composition at or nearest to position POS of OBJECT (buffer | 405 | /* Find a static composition at or nearest to position POS of OBJECT |
| 406 | or string). | 406 | (buffer or string). |
| 407 | 407 | ||
| 408 | OBJECT defaults to the current buffer. If there's a composition at | 408 | OBJECT defaults to the current buffer. If there's a composition at |
| 409 | POS, set *START and *END to the start and end of the sequence, | 409 | POS, set *START and *END to the start and end of the sequence, |
| @@ -916,9 +916,10 @@ autocmp_chars (cft_element, charpos, bytepos, limit, win, face, string) | |||
| 916 | FRAME_PTR f = XFRAME (win->frame); | 916 | FRAME_PTR f = XFRAME (win->frame); |
| 917 | Lisp_Object pos = make_number (charpos); | 917 | Lisp_Object pos = make_number (charpos); |
| 918 | EMACS_INT pt = PT, pt_byte = PT_BYTE; | 918 | EMACS_INT pt = PT, pt_byte = PT_BYTE; |
| 919 | int lookback; | ||
| 919 | 920 | ||
| 920 | record_unwind_save_match_data (); | 921 | record_unwind_save_match_data (); |
| 921 | for (; CONSP (cft_element); cft_element = XCDR (cft_element)) | 922 | for (lookback = -1; CONSP (cft_element); cft_element = XCDR (cft_element)) |
| 922 | { | 923 | { |
| 923 | Lisp_Object elt = XCAR (cft_element); | 924 | Lisp_Object elt = XCAR (cft_element); |
| 924 | Lisp_Object re; | 925 | Lisp_Object re; |
| @@ -927,6 +928,10 @@ autocmp_chars (cft_element, charpos, bytepos, limit, win, face, string) | |||
| 927 | 928 | ||
| 928 | if (! VECTORP (elt) || ASIZE (elt) != 3) | 929 | if (! VECTORP (elt) || ASIZE (elt) != 3) |
| 929 | continue; | 930 | continue; |
| 931 | if (lookback < 0) | ||
| 932 | lookback = XFASTINT (AREF (elt, 1)); | ||
| 933 | else if (lookback != XFASTINT (AREF (elt, 1))) | ||
| 934 | break; | ||
| 930 | re = AREF (elt, 0); | 935 | re = AREF (elt, 0); |
| 931 | if (NILP (string)) | 936 | if (NILP (string)) |
| 932 | TEMP_SET_PT_BOTH (charpos, bytepos); | 937 | TEMP_SET_PT_BOTH (charpos, bytepos); |
| @@ -1029,7 +1034,8 @@ composition_compute_stop_pos (cmp_it, charpos, bytepos, endpos, string) | |||
| 1029 | } | 1034 | } |
| 1030 | if (CONSP (val)) | 1035 | if (CONSP (val)) |
| 1031 | { | 1036 | { |
| 1032 | cmp_it->stop_pos = charpos - 1 - XFASTINT (AREF (elt, 1)); | 1037 | cmp_it->lookback = XFASTINT (AREF (elt, 1)); |
| 1038 | cmp_it->stop_pos = charpos - 1 - cmp_it->lookback; | ||
| 1033 | cmp_it->ch = c; | 1039 | cmp_it->ch = c; |
| 1034 | break; | 1040 | break; |
| 1035 | } | 1041 | } |
| @@ -1072,12 +1078,19 @@ composition_reseat_it (cmp_it, charpos, bytepos, endpos, w, face, string) | |||
| 1072 | } | 1078 | } |
| 1073 | else | 1079 | else |
| 1074 | { | 1080 | { |
| 1075 | Lisp_Object val; | 1081 | Lisp_Object val, elt; |
| 1076 | int i; | 1082 | int i; |
| 1077 | 1083 | ||
| 1078 | val = CHAR_TABLE_REF (Vcomposition_function_table, cmp_it->ch); | 1084 | val = CHAR_TABLE_REF (Vcomposition_function_table, cmp_it->ch); |
| 1085 | for (; CONSP (val); val = XCDR (val)) | ||
| 1086 | { | ||
| 1087 | elt = XCAR (val); | ||
| 1088 | if (cmp_it->lookback == XFASTINT (AREF (elt, 1))) | ||
| 1089 | break; | ||
| 1090 | } | ||
| 1079 | if (NILP (val)) | 1091 | if (NILP (val)) |
| 1080 | goto no_composition; | 1092 | goto no_composition; |
| 1093 | |||
| 1081 | val = autocmp_chars (val, charpos, bytepos, endpos, w, face, string); | 1094 | val = autocmp_chars (val, charpos, bytepos, endpos, w, face, string); |
| 1082 | if (! composition_gstring_p (val)) | 1095 | if (! composition_gstring_p (val)) |
| 1083 | goto no_composition; | 1096 | goto no_composition; |
| @@ -1167,19 +1180,214 @@ composition_update_it (cmp_it, charpos, bytepos, string) | |||
| 1167 | } | 1180 | } |
| 1168 | 1181 | ||
| 1169 | 1182 | ||
| 1183 | struct position_record | ||
| 1184 | { | ||
| 1185 | EMACS_INT pos, pos_byte; | ||
| 1186 | unsigned char *p; | ||
| 1187 | }; | ||
| 1188 | |||
| 1189 | /* Update the members of POSTION to the next character boundary. */ | ||
| 1190 | #define FORWARD_CHAR(POSITION, STOP) \ | ||
| 1191 | do { \ | ||
| 1192 | if ((POSITION).pos == (STOP)) \ | ||
| 1193 | (POSITION).p = GAP_END_ADDR; \ | ||
| 1194 | (POSITION).pos++; \ | ||
| 1195 | (POSITION).pos_byte += BYTES_BY_CHAR_HEAD (*((POSITION).p)); \ | ||
| 1196 | (POSITION).p += BYTES_BY_CHAR_HEAD (*((POSITION).p)); \ | ||
| 1197 | } while (0) | ||
| 1198 | |||
| 1199 | /* Update the members of POSTION to the previous character boundary. */ | ||
| 1200 | #define BACKWARD_CHAR(POSITION, STOP) \ | ||
| 1201 | do { \ | ||
| 1202 | if ((POSITION).pos == STOP) \ | ||
| 1203 | (POSITION).p = GPT_ADDR; \ | ||
| 1204 | do { \ | ||
| 1205 | (POSITION).pos_byte--; \ | ||
| 1206 | (POSITION).p--; \ | ||
| 1207 | } while (! CHAR_HEAD_P (*((POSITION).p))); \ | ||
| 1208 | (POSITION).pos--; \ | ||
| 1209 | } while (0) | ||
| 1210 | |||
| 1211 | static Lisp_Object _work_val; | ||
| 1212 | static int _work_char; | ||
| 1213 | |||
| 1214 | /* 1 iff the character C is composable. */ | ||
| 1215 | #define CHAR_COMPOSABLE_P(C) \ | ||
| 1216 | (_work_val = CHAR_TABLE_REF (Vunicode_category_table, (C)), \ | ||
| 1217 | (SYMBOLP (_work_val) \ | ||
| 1218 | && (_work_char = SDATA (SYMBOL_NAME (_work_val))[0]) != 'C' \ | ||
| 1219 | && _work_char != 'Z')) | ||
| 1220 | |||
| 1221 | /* This is like find_composition, but find an automatic composition | ||
| 1222 | instead. If found, set *GSTRING to the glyph-string representing | ||
| 1223 | the composition, and return 1. Otherwise, return 0. */ | ||
| 1224 | |||
| 1225 | static int | ||
| 1226 | find_automatic_composition (pos, limit, start, end, gstring, string) | ||
| 1227 | EMACS_INT pos, limit, *start, *end; | ||
| 1228 | Lisp_Object *gstring, string; | ||
| 1229 | { | ||
| 1230 | EMACS_INT head, tail, stop; | ||
| 1231 | struct position_record orig, cur, check, prev; | ||
| 1232 | Lisp_Object check_val, val, elt; | ||
| 1233 | int check_lookback; | ||
| 1234 | int c; | ||
| 1235 | struct window *w; | ||
| 1236 | |||
| 1237 | orig.pos = pos; | ||
| 1238 | if (NILP (string)) | ||
| 1239 | { | ||
| 1240 | head = BEGV, tail = ZV, stop = GPT; | ||
| 1241 | orig.pos_byte = CHAR_TO_BYTE (orig.pos); | ||
| 1242 | orig.p = BYTE_POS_ADDR (orig.pos_byte); | ||
| 1243 | } | ||
| 1244 | else | ||
| 1245 | { | ||
| 1246 | head = 0, tail = SCHARS (string), stop = -1; | ||
| 1247 | orig.pos_byte = string_char_to_byte (string, orig.pos); | ||
| 1248 | orig.p = SDATA (string) + orig.pos_byte; | ||
| 1249 | } | ||
| 1250 | if (limit < pos) | ||
| 1251 | { | ||
| 1252 | head = max (head, limit); | ||
| 1253 | tail = min (tail, pos + 3); | ||
| 1254 | } | ||
| 1255 | else | ||
| 1256 | { | ||
| 1257 | tail = min (tail, limit + 3); | ||
| 1258 | } | ||
| 1259 | w = XWINDOW (selected_window); | ||
| 1260 | cur = orig; | ||
| 1261 | |||
| 1262 | retry: | ||
| 1263 | check_val = Qnil; | ||
| 1264 | /* At first, check if POS is compoable. */ | ||
| 1265 | c = STRING_CHAR (cur.p, 0); | ||
| 1266 | if (! CHAR_COMPOSABLE_P (c)) | ||
| 1267 | { | ||
| 1268 | if (limit < 0) | ||
| 1269 | return 0; | ||
| 1270 | if (limit >= cur.pos) | ||
| 1271 | goto search_forward; | ||
| 1272 | } | ||
| 1273 | else | ||
| 1274 | { | ||
| 1275 | val = CHAR_TABLE_REF (Vcomposition_function_table, c); | ||
| 1276 | if (! NILP (val)) | ||
| 1277 | check_val = val, check = cur; | ||
| 1278 | else | ||
| 1279 | while (cur.pos + 1 < tail) | ||
| 1280 | { | ||
| 1281 | FORWARD_CHAR (cur, stop); | ||
| 1282 | c = STRING_CHAR (cur.p, 0); | ||
| 1283 | if (! CHAR_COMPOSABLE_P (c)) | ||
| 1284 | break; | ||
| 1285 | val = CHAR_TABLE_REF (Vcomposition_function_table, c); | ||
| 1286 | if (NILP (val)) | ||
| 1287 | continue; | ||
| 1288 | check_val = val, check = cur; | ||
| 1289 | break; | ||
| 1290 | } | ||
| 1291 | cur = orig; | ||
| 1292 | } | ||
| 1293 | /* Rewind back to the position where we can safely search forward | ||
| 1294 | for compositions. */ | ||
| 1295 | while (cur.pos > head) | ||
| 1296 | { | ||
| 1297 | BACKWARD_CHAR (cur, stop); | ||
| 1298 | c = STRING_CHAR (cur.p, 0); | ||
| 1299 | if (! CHAR_COMPOSABLE_P (c)) | ||
| 1300 | break; | ||
| 1301 | val = CHAR_TABLE_REF (Vcomposition_function_table, c); | ||
| 1302 | if (! NILP (val)) | ||
| 1303 | check_val = val, check = cur; | ||
| 1304 | } | ||
| 1305 | prev = cur; | ||
| 1306 | /* Now search forward. */ | ||
| 1307 | search_forward: | ||
| 1308 | *gstring = Qnil; | ||
| 1309 | if (! NILP (check_val) || limit >= orig.pos) | ||
| 1310 | { | ||
| 1311 | if (NILP (check_val)) | ||
| 1312 | cur = orig; | ||
| 1313 | else | ||
| 1314 | cur = check; | ||
| 1315 | while (cur.pos < tail) | ||
| 1316 | { | ||
| 1317 | int need_adjustment = 0; | ||
| 1318 | |||
| 1319 | if (NILP (check_val)) | ||
| 1320 | { | ||
| 1321 | c = STRING_CHAR (cur.p, 0); | ||
| 1322 | check_val = CHAR_TABLE_REF (Vcomposition_function_table, c); | ||
| 1323 | } | ||
| 1324 | for (; CONSP (check_val); check_val = XCDR (check_val)) | ||
| 1325 | { | ||
| 1326 | elt = XCAR (check_val); | ||
| 1327 | if (VECTORP (elt) && ASIZE (elt) == 3 && NATNUMP (AREF (elt, 1)) | ||
| 1328 | && cur.pos - XFASTINT (AREF (elt, 1)) >= head) | ||
| 1329 | { | ||
| 1330 | check.pos = cur.pos - XFASTINT (AREF (elt, 1)); | ||
| 1331 | if (check.pos == cur.pos) | ||
| 1332 | check.pos_byte = cur.pos_byte; | ||
| 1333 | else | ||
| 1334 | check.pos_byte = CHAR_TO_BYTE (check.pos); | ||
| 1335 | val = autocmp_chars (check_val, check.pos, check.pos_byte, | ||
| 1336 | tail, w, NULL, string); | ||
| 1337 | need_adjustment = 1; | ||
| 1338 | if (! NILP (val)) | ||
| 1339 | { | ||
| 1340 | *gstring = val; | ||
| 1341 | *start = check.pos; | ||
| 1342 | *end = check.pos + LGSTRING_CHAR_LEN (*gstring); | ||
| 1343 | if (*start <= orig.pos ? *end > orig.pos | ||
| 1344 | : limit >= orig.pos) | ||
| 1345 | return 1; | ||
| 1346 | cur.pos = *end; | ||
| 1347 | cur.pos_byte = CHAR_TO_BYTE (cur.pos); | ||
| 1348 | break; | ||
| 1349 | } | ||
| 1350 | } | ||
| 1351 | } | ||
| 1352 | if (need_adjustment) | ||
| 1353 | { | ||
| 1354 | /* As we have called Lisp, there's a possibilily that | ||
| 1355 | buffer/string is relocated. */ | ||
| 1356 | if (NILP (string)) | ||
| 1357 | cur.p = BYTE_POS_ADDR (cur.pos_byte); | ||
| 1358 | else | ||
| 1359 | cur.p = SDATA (string) + cur.pos_byte; | ||
| 1360 | } | ||
| 1361 | if (! CONSP (check_val)) | ||
| 1362 | FORWARD_CHAR (cur, stop); | ||
| 1363 | check_val = Qnil; | ||
| 1364 | } | ||
| 1365 | } | ||
| 1366 | if (! NILP (*gstring)) | ||
| 1367 | return (limit >= 0 || (*start <= orig.pos && *end > orig.pos)); | ||
| 1368 | if (limit >= 0 && limit < orig.pos && prev.pos > head) | ||
| 1369 | { | ||
| 1370 | cur = prev; | ||
| 1371 | BACKWARD_CHAR (cur, stop); | ||
| 1372 | orig = cur; | ||
| 1373 | tail = orig.pos; | ||
| 1374 | goto retry; | ||
| 1375 | } | ||
| 1376 | return 0; | ||
| 1377 | } | ||
| 1378 | |||
| 1170 | int | 1379 | int |
| 1171 | composition_adjust_point (last_pt) | 1380 | composition_adjust_point (last_pt) |
| 1172 | EMACS_INT last_pt; | 1381 | EMACS_INT last_pt; |
| 1173 | { | 1382 | { |
| 1174 | /* Now check the automatic composition. */ | ||
| 1175 | EMACS_INT charpos, bytepos, startpos, beg, end, pos; | 1383 | EMACS_INT charpos, bytepos, startpos, beg, end, pos; |
| 1176 | Lisp_Object val, cat; | 1384 | Lisp_Object val; |
| 1177 | EMACS_INT limit; | 1385 | int i; |
| 1178 | int c; | ||
| 1179 | 1386 | ||
| 1180 | if (PT == BEGV || PT == ZV) | 1387 | if (PT == BEGV || PT == ZV) |
| 1181 | return PT; | 1388 | return PT; |
| 1182 | 1389 | ||
| 1390 | /* At first check the static composition. */ | ||
| 1183 | if (get_property_and_range (PT, Qcomposition, &val, &beg, &end, Qnil) | 1391 | if (get_property_and_range (PT, Qcomposition, &val, &beg, &end, Qnil) |
| 1184 | && COMPOSITION_VALID_P (beg, end, val) | 1392 | && COMPOSITION_VALID_P (beg, end, val) |
| 1185 | && beg < PT /* && end > PT <- It's always the case. */ | 1393 | && beg < PT /* && end > PT <- It's always the case. */ |
| @@ -1190,97 +1398,22 @@ composition_adjust_point (last_pt) | |||
| 1190 | || ! FUNCTIONP (Vauto_composition_function)) | 1398 | || ! FUNCTIONP (Vauto_composition_function)) |
| 1191 | return PT; | 1399 | return PT; |
| 1192 | 1400 | ||
| 1193 | c = FETCH_MULTIBYTE_CHAR (PT_BYTE); | 1401 | /* Next check the automatic composition. */ |
| 1194 | cat = CHAR_TABLE_REF (Vunicode_category_table, c); | 1402 | if (! find_automatic_composition (PT, -1, &beg, &end, &val, Qnil) |
| 1195 | if (SYMBOLP (cat) | 1403 | || beg == PT) |
| 1196 | && ((c = SDATA (SYMBOL_NAME (cat))[0]) == 'C' || c == 'Z')) | ||
| 1197 | /* A control character is never composed. */ | ||
| 1198 | return PT; | 1404 | return PT; |
| 1199 | 1405 | for (i = 0; i < LGSTRING_GLYPH_LEN (val); i++) | |
| 1200 | charpos = PT; | ||
| 1201 | bytepos = PT_BYTE; | ||
| 1202 | limit = (last_pt < PT ? last_pt : BEGV); | ||
| 1203 | do { | ||
| 1204 | DEC_BOTH (charpos, bytepos); | ||
| 1205 | c = FETCH_MULTIBYTE_CHAR (bytepos); | ||
| 1206 | cat = CHAR_TABLE_REF (Vunicode_category_table, c); | ||
| 1207 | if (SYMBOLP (cat) | ||
| 1208 | && ((c = SDATA (SYMBOL_NAME (cat))[0]) == 'C' || c == 'Z')) | ||
| 1209 | { | ||
| 1210 | INC_BOTH (charpos, bytepos); | ||
| 1211 | break; | ||
| 1212 | } | ||
| 1213 | } while (charpos > limit); | ||
| 1214 | |||
| 1215 | |||
| 1216 | limit = (last_pt < PT ? ZV : last_pt); | ||
| 1217 | if (limit > PT + 3) | ||
| 1218 | limit = PT + 3; | ||
| 1219 | startpos = charpos; | ||
| 1220 | while (charpos < limit) | ||
| 1221 | { | 1406 | { |
| 1222 | c = FETCH_MULTIBYTE_CHAR (bytepos); | 1407 | Lisp_Object glyph = LGSTRING_GLYPH (val, i); |
| 1223 | if (charpos > PT) | ||
| 1224 | { | ||
| 1225 | int ch; | ||
| 1226 | |||
| 1227 | cat = CHAR_TABLE_REF (Vunicode_category_table, c); | ||
| 1228 | if (SYMBOLP (cat) | ||
| 1229 | && ((ch = SDATA (SYMBOL_NAME (cat))[0]) == 'C' || ch == 'Z')) | ||
| 1230 | return PT; | ||
| 1231 | } | ||
| 1232 | val = CHAR_TABLE_REF (Vcomposition_function_table, c); | ||
| 1233 | if (! CONSP (val)) | ||
| 1234 | { | ||
| 1235 | INC_BOTH (charpos, bytepos); | ||
| 1236 | continue; | ||
| 1237 | } | ||
| 1238 | for (; CONSP (val); val = XCDR (val)) | ||
| 1239 | { | ||
| 1240 | Lisp_Object elt = XCAR (val); | ||
| 1241 | 1408 | ||
| 1242 | if (VECTORP (elt) && ASIZE (elt) == 3 && NATNUMP (AREF (elt, 1)) | 1409 | if (NILP (glyph)) |
| 1243 | && (pos = charpos - XFASTINT (AREF (elt, 1))) < PT | 1410 | break; |
| 1244 | && pos >= startpos) | 1411 | if (beg + LGLYPH_FROM (glyph) == PT) |
| 1245 | { | 1412 | return PT; |
| 1246 | Lisp_Object gstring; | 1413 | if (beg + LGLYPH_TO (glyph) >= PT) |
| 1247 | EMACS_INT pos_byte; | 1414 | return (PT < last_pt |
| 1248 | 1415 | ? beg + LGLYPH_FROM (glyph) | |
| 1249 | if (XFASTINT (AREF (elt, 1)) == 0) | 1416 | : beg + LGLYPH_TO (glyph) + 1); |
| 1250 | pos_byte = bytepos; | ||
| 1251 | else | ||
| 1252 | pos_byte = CHAR_TO_BYTE (pos); | ||
| 1253 | gstring = autocmp_chars (val, pos, pos_byte, Z, | ||
| 1254 | XWINDOW (selected_window), NULL, Qnil); | ||
| 1255 | if (composition_gstring_p (gstring)) | ||
| 1256 | { | ||
| 1257 | if (pos + LGSTRING_CHAR_LEN (gstring) > PT) | ||
| 1258 | { | ||
| 1259 | int i; | ||
| 1260 | |||
| 1261 | for (i = 0; i < LGSTRING_GLYPH_LEN (gstring); i++) | ||
| 1262 | { | ||
| 1263 | Lisp_Object glyph = LGSTRING_GLYPH (gstring, i); | ||
| 1264 | |||
| 1265 | if (NILP (glyph)) | ||
| 1266 | break; | ||
| 1267 | if (pos + LGLYPH_FROM (glyph) == PT) | ||
| 1268 | return PT; | ||
| 1269 | if (pos + LGLYPH_TO (glyph) + 1 > PT) | ||
| 1270 | return (PT < last_pt | ||
| 1271 | ? pos + LGLYPH_FROM (glyph) | ||
| 1272 | : pos + LGLYPH_TO (glyph) + 1); | ||
| 1273 | } | ||
| 1274 | return PT; | ||
| 1275 | } | ||
| 1276 | charpos = startpos = pos + LGSTRING_CHAR_LEN (gstring); | ||
| 1277 | bytepos = CHAR_TO_BYTE (charpos); | ||
| 1278 | break; | ||
| 1279 | } | ||
| 1280 | } | ||
| 1281 | } | ||
| 1282 | if (! CONSP (val)) | ||
| 1283 | INC_BOTH (charpos, bytepos); | ||
| 1284 | } | 1417 | } |
| 1285 | return PT; | 1418 | return PT; |
| 1286 | } | 1419 | } |
| @@ -1395,19 +1528,19 @@ See `find-composition' for more detail. */) | |||
| 1395 | (pos, limit, string, detail_p) | 1528 | (pos, limit, string, detail_p) |
| 1396 | Lisp_Object pos, limit, string, detail_p; | 1529 | Lisp_Object pos, limit, string, detail_p; |
| 1397 | { | 1530 | { |
| 1398 | Lisp_Object prop, tail; | 1531 | Lisp_Object prop, tail, gstring; |
| 1399 | EMACS_INT start, end; | 1532 | EMACS_INT start, end, from, to; |
| 1400 | int id; | 1533 | int id; |
| 1401 | 1534 | ||
| 1402 | CHECK_NUMBER_COERCE_MARKER (pos); | 1535 | CHECK_NUMBER_COERCE_MARKER (pos); |
| 1403 | start = XINT (pos); | 1536 | from = XINT (pos); |
| 1404 | if (!NILP (limit)) | 1537 | if (!NILP (limit)) |
| 1405 | { | 1538 | { |
| 1406 | CHECK_NUMBER_COERCE_MARKER (limit); | 1539 | CHECK_NUMBER_COERCE_MARKER (limit); |
| 1407 | end = XINT (limit); | 1540 | to = XINT (limit); |
| 1408 | } | 1541 | } |
| 1409 | else | 1542 | else |
| 1410 | end = -1; | 1543 | to = -1; |
| 1411 | 1544 | ||
| 1412 | if (!NILP (string)) | 1545 | if (!NILP (string)) |
| 1413 | { | 1546 | { |
| @@ -1421,8 +1554,23 @@ See `find-composition' for more detail. */) | |||
| 1421 | args_out_of_range (Fcurrent_buffer (), pos); | 1554 | args_out_of_range (Fcurrent_buffer (), pos); |
| 1422 | } | 1555 | } |
| 1423 | 1556 | ||
| 1424 | if (!find_composition (start, end, &start, &end, &prop, string)) | 1557 | if (!find_composition (from, to, &start, &end, &prop, string)) |
| 1425 | return Qnil; | 1558 | { |
| 1559 | if (!NILP (current_buffer->enable_multibyte_characters) | ||
| 1560 | && FUNCTIONP (Vauto_composition_function) | ||
| 1561 | && find_automatic_composition (from, to, &start, &end, &gstring, | ||
| 1562 | string)) | ||
| 1563 | return list3 (make_number (start), make_number (end), gstring); | ||
| 1564 | return Qnil; | ||
| 1565 | } | ||
| 1566 | if ((end <= XINT (pos) || start > XINT (pos))) | ||
| 1567 | { | ||
| 1568 | EMACS_INT s, e; | ||
| 1569 | |||
| 1570 | if (find_automatic_composition (from, to, &s, &e, &gstring, string) | ||
| 1571 | && (e <= XINT (pos) ? e > end : s < start)) | ||
| 1572 | return list3 (make_number (start), make_number (end), gstring); | ||
| 1573 | } | ||
| 1426 | if (!COMPOSITION_VALID_P (start, end, prop)) | 1574 | if (!COMPOSITION_VALID_P (start, end, prop)) |
| 1427 | return Fcons (make_number (start), Fcons (make_number (end), | 1575 | return Fcons (make_number (start), Fcons (make_number (end), |
| 1428 | Fcons (Qnil, Qnil))); | 1576 | Fcons (Qnil, Qnil))); |