[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/src/composite.c,v
From: |
Kenichi Handa |
Subject: |
[Emacs-diffs] Changes to emacs/src/composite.c,v |
Date: |
Fri, 05 Sep 2008 00:46:58 +0000 |
CVSROOT: /cvsroot/emacs
Module name: emacs
Changes by: Kenichi Handa <handa> 08/09/05 00:46:57
Index: composite.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/composite.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -b -r1.53 -r1.54
--- composite.c 31 Aug 2008 00:57:00 -0000 1.53
+++ composite.c 5 Sep 2008 00:46:57 -0000 1.54
@@ -402,8 +402,8 @@
}
-/* Find a composition at or nearest to position POS of OBJECT (buffer
- or string).
+/* Find a static composition at or nearest to position POS of OBJECT
+ (buffer or string).
OBJECT defaults to the current buffer. If there's a composition at
POS, set *START and *END to the start and end of the sequence,
@@ -916,9 +916,10 @@
FRAME_PTR f = XFRAME (win->frame);
Lisp_Object pos = make_number (charpos);
EMACS_INT pt = PT, pt_byte = PT_BYTE;
+ int lookback;
record_unwind_save_match_data ();
- for (; CONSP (cft_element); cft_element = XCDR (cft_element))
+ for (lookback = -1; CONSP (cft_element); cft_element = XCDR (cft_element))
{
Lisp_Object elt = XCAR (cft_element);
Lisp_Object re;
@@ -927,6 +928,10 @@
if (! VECTORP (elt) || ASIZE (elt) != 3)
continue;
+ if (lookback < 0)
+ lookback = XFASTINT (AREF (elt, 1));
+ else if (lookback != XFASTINT (AREF (elt, 1)))
+ break;
re = AREF (elt, 0);
if (NILP (string))
TEMP_SET_PT_BOTH (charpos, bytepos);
@@ -1029,7 +1034,8 @@
}
if (CONSP (val))
{
- cmp_it->stop_pos = charpos - 1 - XFASTINT (AREF (elt, 1));
+ cmp_it->lookback = XFASTINT (AREF (elt, 1));
+ cmp_it->stop_pos = charpos - 1 - cmp_it->lookback;
cmp_it->ch = c;
break;
}
@@ -1072,12 +1078,19 @@
}
else
{
- Lisp_Object val;
+ Lisp_Object val, elt;
int i;
val = CHAR_TABLE_REF (Vcomposition_function_table, cmp_it->ch);
+ for (; CONSP (val); val = XCDR (val))
+ {
+ elt = XCAR (val);
+ if (cmp_it->lookback == XFASTINT (AREF (elt, 1)))
+ break;
+ }
if (NILP (val))
goto no_composition;
+
val = autocmp_chars (val, charpos, bytepos, endpos, w, face, string);
if (! composition_gstring_p (val))
goto no_composition;
@@ -1167,120 +1180,240 @@
}
-int
-composition_adjust_point (last_pt)
- EMACS_INT last_pt;
+struct position_record
{
- /* Now check the automatic composition. */
- EMACS_INT charpos, bytepos, startpos, beg, end, pos;
- Lisp_Object val, cat;
- EMACS_INT limit;
+ EMACS_INT pos, pos_byte;
+ unsigned char *p;
+};
+
+/* Update the members of POSTION to the next character boundary. */
+#define FORWARD_CHAR(POSITION, STOP) \
+ do { \
+ if ((POSITION).pos == (STOP)) \
+ (POSITION).p = GAP_END_ADDR; \
+ (POSITION).pos++; \
+ (POSITION).pos_byte += BYTES_BY_CHAR_HEAD (*((POSITION).p)); \
+ (POSITION).p += BYTES_BY_CHAR_HEAD (*((POSITION).p)); \
+ } while (0)
+
+/* Update the members of POSTION to the previous character boundary. */
+#define BACKWARD_CHAR(POSITION, STOP) \
+ do { \
+ if ((POSITION).pos == STOP) \
+ (POSITION).p = GPT_ADDR; \
+ do { \
+ (POSITION).pos_byte--; \
+ (POSITION).p--; \
+ } while (! CHAR_HEAD_P (*((POSITION).p))); \
+ (POSITION).pos--; \
+ } while (0)
+
+static Lisp_Object _work_val;
+static int _work_char;
+
+/* 1 iff the character C is composable. */
+#define CHAR_COMPOSABLE_P(C) \
+ (_work_val = CHAR_TABLE_REF (Vunicode_category_table, (C)), \
+ (SYMBOLP (_work_val) \
+ && (_work_char = SDATA (SYMBOL_NAME (_work_val))[0]) != 'C' \
+ && _work_char != 'Z'))
+
+/* This is like find_composition, but find an automatic composition
+ instead. If found, set *GSTRING to the glyph-string representing
+ the composition, and return 1. Otherwise, return 0. */
+
+static int
+find_automatic_composition (pos, limit, start, end, gstring, string)
+ EMACS_INT pos, limit, *start, *end;
+ Lisp_Object *gstring, string;
+{
+ EMACS_INT head, tail, stop;
+ struct position_record orig, cur, check, prev;
+ Lisp_Object check_val, val, elt;
+ int check_lookback;
int c;
+ struct window *w;
- if (PT == BEGV || PT == ZV)
- return PT;
-
- if (get_property_and_range (PT, Qcomposition, &val, &beg, &end, Qnil)
- && COMPOSITION_VALID_P (beg, end, val)
- && beg < PT /* && end > PT <- It's always the case. */
- && (last_pt <= beg || last_pt >= end))
- return (PT < last_pt ? beg : end);
-
- if (NILP (current_buffer->enable_multibyte_characters)
- || ! FUNCTIONP (Vauto_composition_function))
- return PT;
-
- c = FETCH_MULTIBYTE_CHAR (PT_BYTE);
- cat = CHAR_TABLE_REF (Vunicode_category_table, c);
- if (SYMBOLP (cat)
- && ((c = SDATA (SYMBOL_NAME (cat))[0]) == 'C' || c == 'Z'))
- /* A control character is never composed. */
- return PT;
-
- charpos = PT;
- bytepos = PT_BYTE;
- limit = (last_pt < PT ? last_pt : BEGV);
- do {
- DEC_BOTH (charpos, bytepos);
- c = FETCH_MULTIBYTE_CHAR (bytepos);
- cat = CHAR_TABLE_REF (Vunicode_category_table, c);
- if (SYMBOLP (cat)
- && ((c = SDATA (SYMBOL_NAME (cat))[0]) == 'C' || c == 'Z'))
+ orig.pos = pos;
+ if (NILP (string))
{
- INC_BOTH (charpos, bytepos);
- break;
+ head = BEGV, tail = ZV, stop = GPT;
+ orig.pos_byte = CHAR_TO_BYTE (orig.pos);
+ orig.p = BYTE_POS_ADDR (orig.pos_byte);
}
- } while (charpos > limit);
-
-
- limit = (last_pt < PT ? ZV : last_pt);
- if (limit > PT + 3)
- limit = PT + 3;
- startpos = charpos;
- while (charpos < limit)
+ else
+ {
+ head = 0, tail = SCHARS (string), stop = -1;
+ orig.pos_byte = string_char_to_byte (string, orig.pos);
+ orig.p = SDATA (string) + orig.pos_byte;
+ }
+ if (limit < pos)
{
- c = FETCH_MULTIBYTE_CHAR (bytepos);
- if (charpos > PT)
+ head = max (head, limit);
+ tail = min (tail, pos + 3);
+ }
+ else
{
- int ch;
+ tail = min (tail, limit + 3);
+ }
+ w = XWINDOW (selected_window);
+ cur = orig;
- cat = CHAR_TABLE_REF (Vunicode_category_table, c);
- if (SYMBOLP (cat)
- && ((ch = SDATA (SYMBOL_NAME (cat))[0]) == 'C' || ch == 'Z'))
- return PT;
+ retry:
+ check_val = Qnil;
+ /* At first, check if POS is compoable. */
+ c = STRING_CHAR (cur.p, 0);
+ if (! CHAR_COMPOSABLE_P (c))
+ {
+ if (limit < 0)
+ return 0;
+ if (limit >= cur.pos)
+ goto search_forward;
}
+ else
+ {
val = CHAR_TABLE_REF (Vcomposition_function_table, c);
- if (! CONSP (val))
+ if (! NILP (val))
+ check_val = val, check = cur;
+ else
+ while (cur.pos + 1 < tail)
{
- INC_BOTH (charpos, bytepos);
+ FORWARD_CHAR (cur, stop);
+ c = STRING_CHAR (cur.p, 0);
+ if (! CHAR_COMPOSABLE_P (c))
+ break;
+ val = CHAR_TABLE_REF (Vcomposition_function_table, c);
+ if (NILP (val))
continue;
+ check_val = val, check = cur;
+ break;
}
- for (; CONSP (val); val = XCDR (val))
+ cur = orig;
+ }
+ /* Rewind back to the position where we can safely search forward
+ for compositions. */
+ while (cur.pos > head)
+ {
+ BACKWARD_CHAR (cur, stop);
+ c = STRING_CHAR (cur.p, 0);
+ if (! CHAR_COMPOSABLE_P (c))
+ break;
+ val = CHAR_TABLE_REF (Vcomposition_function_table, c);
+ if (! NILP (val))
+ check_val = val, check = cur;
+ }
+ prev = cur;
+ /* Now search forward. */
+ search_forward:
+ *gstring = Qnil;
+ if (! NILP (check_val) || limit >= orig.pos)
+ {
+ if (NILP (check_val))
+ cur = orig;
+ else
+ cur = check;
+ while (cur.pos < tail)
{
- Lisp_Object elt = XCAR (val);
+ int need_adjustment = 0;
+ if (NILP (check_val))
+ {
+ c = STRING_CHAR (cur.p, 0);
+ check_val = CHAR_TABLE_REF (Vcomposition_function_table, c);
+ }
+ for (; CONSP (check_val); check_val = XCDR (check_val))
+ {
+ elt = XCAR (check_val);
if (VECTORP (elt) && ASIZE (elt) == 3 && NATNUMP (AREF (elt, 1))
- && (pos = charpos - XFASTINT (AREF (elt, 1))) < PT
- && pos >= startpos)
+ && cur.pos - XFASTINT (AREF (elt, 1)) >= head)
{
- Lisp_Object gstring;
- EMACS_INT pos_byte;
-
- if (XFASTINT (AREF (elt, 1)) == 0)
- pos_byte = bytepos;
+ check.pos = cur.pos - XFASTINT (AREF (elt, 1));
+ if (check.pos == cur.pos)
+ check.pos_byte = cur.pos_byte;
else
- pos_byte = CHAR_TO_BYTE (pos);
- gstring = autocmp_chars (val, pos, pos_byte, Z,
- XWINDOW (selected_window), NULL, Qnil);
- if (composition_gstring_p (gstring))
+ check.pos_byte = CHAR_TO_BYTE (check.pos);
+ val = autocmp_chars (check_val, check.pos, check.pos_byte,
+ tail, w, NULL, string);
+ need_adjustment = 1;
+ if (! NILP (val))
{
- if (pos + LGSTRING_CHAR_LEN (gstring) > PT)
+ *gstring = val;
+ *start = check.pos;
+ *end = check.pos + LGSTRING_CHAR_LEN (*gstring);
+ if (*start <= orig.pos ? *end > orig.pos
+ : limit >= orig.pos)
+ return 1;
+ cur.pos = *end;
+ cur.pos_byte = CHAR_TO_BYTE (cur.pos);
+ break;
+ }
+ }
+ }
+ if (need_adjustment)
{
+ /* As we have called Lisp, there's a possibilily that
+ buffer/string is relocated. */
+ if (NILP (string))
+ cur.p = BYTE_POS_ADDR (cur.pos_byte);
+ else
+ cur.p = SDATA (string) + cur.pos_byte;
+ }
+ if (! CONSP (check_val))
+ FORWARD_CHAR (cur, stop);
+ check_val = Qnil;
+ }
+ }
+ if (! NILP (*gstring))
+ return (limit >= 0 || (*start <= orig.pos && *end > orig.pos));
+ if (limit >= 0 && limit < orig.pos && prev.pos > head)
+ {
+ cur = prev;
+ BACKWARD_CHAR (cur, stop);
+ orig = cur;
+ tail = orig.pos;
+ goto retry;
+ }
+ return 0;
+}
+
+int
+composition_adjust_point (last_pt)
+ EMACS_INT last_pt;
+{
+ EMACS_INT charpos, bytepos, startpos, beg, end, pos;
+ Lisp_Object val;
int i;
- for (i = 0; i < LGSTRING_GLYPH_LEN (gstring); i++)
+ if (PT == BEGV || PT == ZV)
+ return PT;
+
+ /* At first check the static composition. */
+ if (get_property_and_range (PT, Qcomposition, &val, &beg, &end, Qnil)
+ && COMPOSITION_VALID_P (beg, end, val)
+ && beg < PT /* && end > PT <- It's always the case. */
+ && (last_pt <= beg || last_pt >= end))
+ return (PT < last_pt ? beg : end);
+
+ if (NILP (current_buffer->enable_multibyte_characters)
+ || ! FUNCTIONP (Vauto_composition_function))
+ return PT;
+
+ /* Next check the automatic composition. */
+ if (! find_automatic_composition (PT, -1, &beg, &end, &val, Qnil)
+ || beg == PT)
+ return PT;
+ for (i = 0; i < LGSTRING_GLYPH_LEN (val); i++)
{
- Lisp_Object glyph = LGSTRING_GLYPH (gstring, i);
+ Lisp_Object glyph = LGSTRING_GLYPH (val, i);
if (NILP (glyph))
break;
- if (pos + LGLYPH_FROM (glyph) == PT)
+ if (beg + LGLYPH_FROM (glyph) == PT)
return PT;
- if (pos + LGLYPH_TO (glyph) + 1 > PT)
+ if (beg + LGLYPH_TO (glyph) >= PT)
return (PT < last_pt
- ? pos + LGLYPH_FROM (glyph)
- : pos + LGLYPH_TO (glyph) + 1);
- }
- return PT;
- }
- charpos = startpos = pos + LGSTRING_CHAR_LEN (gstring);
- bytepos = CHAR_TO_BYTE (charpos);
- break;
- }
- }
- }
- if (! CONSP (val))
- INC_BOTH (charpos, bytepos);
+ ? beg + LGLYPH_FROM (glyph)
+ : beg + LGLYPH_TO (glyph) + 1);
}
return PT;
}
@@ -1395,19 +1528,19 @@
(pos, limit, string, detail_p)
Lisp_Object pos, limit, string, detail_p;
{
- Lisp_Object prop, tail;
- EMACS_INT start, end;
+ Lisp_Object prop, tail, gstring;
+ EMACS_INT start, end, from, to;
int id;
CHECK_NUMBER_COERCE_MARKER (pos);
- start = XINT (pos);
+ from = XINT (pos);
if (!NILP (limit))
{
CHECK_NUMBER_COERCE_MARKER (limit);
- end = XINT (limit);
+ to = XINT (limit);
}
else
- end = -1;
+ to = -1;
if (!NILP (string))
{
@@ -1421,8 +1554,23 @@
args_out_of_range (Fcurrent_buffer (), pos);
}
- if (!find_composition (start, end, &start, &end, &prop, string))
+ if (!find_composition (from, to, &start, &end, &prop, string))
+ {
+ if (!NILP (current_buffer->enable_multibyte_characters)
+ && FUNCTIONP (Vauto_composition_function)
+ && find_automatic_composition (from, to, &start, &end, &gstring,
+ string))
+ return list3 (make_number (start), make_number (end), gstring);
return Qnil;
+ }
+ if ((end <= XINT (pos) || start > XINT (pos)))
+ {
+ EMACS_INT s, e;
+
+ if (find_automatic_composition (from, to, &s, &e, &gstring, string)
+ && (e <= XINT (pos) ? e > end : s < start))
+ return list3 (make_number (start), make_number (end), gstring);
+ }
if (!COMPOSITION_VALID_P (start, end, prop))
return Fcons (make_number (start), Fcons (make_number (end),
Fcons (Qnil, Qnil)));
- [Emacs-diffs] Changes to emacs/src/composite.c,v,
Kenichi Handa <=
- [Emacs-diffs] Changes to emacs/src/composite.c,v, Kenichi Handa, 2008/09/06
- [Emacs-diffs] Changes to emacs/src/composite.c,v, Kenichi Handa, 2008/09/08
- [Emacs-diffs] Changes to emacs/src/composite.c,v, Kenichi Handa, 2008/09/09
- [Emacs-diffs] Changes to emacs/src/composite.c,v, Kenichi Handa, 2008/09/09
- [Emacs-diffs] Changes to emacs/src/composite.c,v, Kenichi Handa, 2008/09/10
- [Emacs-diffs] Changes to emacs/src/composite.c,v, Kenichi Handa, 2008/09/12
- [Emacs-diffs] Changes to emacs/src/composite.c,v, Kenichi Handa, 2008/09/12
- [Emacs-diffs] Changes to emacs/src/composite.c,v, Kenichi Handa, 2008/09/12
- [Emacs-diffs] Changes to emacs/src/composite.c,v, Kenichi Handa, 2008/09/16
- [Emacs-diffs] Changes to emacs/src/composite.c,v, Romain Francoise, 2008/09/17