qemacs-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemacs-commit] qemacs qe.c qe.h qeconfig.h tty.c unicode_join.c


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs qe.c qe.h qeconfig.h tty.c unicode_join.c
Date: Sat, 01 Feb 2014 12:49:07 +0000

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        14/02/01 12:49:06

Modified files:
        .              : qe.c qe.h qeconfig.h tty.c unicode_join.c 

Log message:
        add support for combining marks (accents)
        
        * add qe_isaccent() to test for combining marks
        * add do_combine_char() command to insert or remove combining marks
        * fix some display glitches involving combining marks
        * add expand_ligature() and combine_accent() to handle simple ligatures
        * change do_what_cursor_position() to display combining marks

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.139&r2=1.140
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.132&r2=1.133
http://cvs.savannah.gnu.org/viewcvs/qemacs/qeconfig.h?cvsroot=qemacs&r1=1.43&r2=1.44
http://cvs.savannah.gnu.org/viewcvs/qemacs/tty.c?cvsroot=qemacs&r1=1.57&r2=1.58
http://cvs.savannah.gnu.org/viewcvs/qemacs/unicode_join.c?cvsroot=qemacs&r1=1.14&r2=1.15

Patches:
Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.139
retrieving revision 1.140
diff -u -b -r1.139 -r1.140
--- qe.c        31 Jan 2014 14:50:13 -0000      1.139
+++ qe.c        1 Feb 2014 12:49:06 -0000       1.140
@@ -1263,6 +1263,31 @@
     }
 }
 
+#ifdef CONFIG_UNICODE_JOIN
+void do_combine_char(EditState *s, int accent)
+{
+    int offset0, len, c;
+    unsigned int g[2];
+    char buf[MAX_CHAR_BYTES];
+
+    if (s->b->flags & BF_READONLY)
+        return;
+
+    c = eb_prevc(s->b, s->offset, &offset0);
+    if (c == accent) {
+        eb_delete(s->b, offset0, s->offset - offset0);
+    } else
+    if (((expand_ligature(g, c) && g[1] == accent)
+    ||   (c != '\n' && combine_accent(g, c, accent)))
+    &&  (len = unicode_to_charset(buf, g[0], s->b->charset)) > 0) {
+        eb_replace(s->b, offset0, s->offset - offset0, buf, len);
+        s->offset = offset0 + len;
+    } else {
+        do_char(s, accent, 1);
+    }
+}
+#endif
+
 void text_write_char(EditState *s, int key)
 {
     int cur_ch, len, cur_len, offset1, ret, insert;
@@ -2003,43 +2028,53 @@
     buf_t outbuf, *out;
     unsigned char cc;
     int line_num, col_num;
-    int c, offset1, off;
+    int c, c2, offset1, offset2, off;
 
     out = buf_init(&outbuf, buf, sizeof(buf));
     if (s->offset < s->b->total_size) {
         c = eb_nextc(s->b, s->offset, &offset1);
-        buf_puts(out, "char: ");
+        c2 = eb_nextc(s->b, offset1, &offset2);
+        if (c == '\n' || !qe_isaccent(c2)) {
+            c2 = 0;
+            offset2 = offset1;
+        }
+        buf_puts(out, "char:");
         if (c < 32 || c == 127) {
-            buf_printf(out, "^%c ", (c + '@') & 127);
+            buf_printf(out, " ^%c", (c + '@') & 127);
         } else
         if (c < 127 || c >= 160) {
+            buf_put_byte(out, ' ');
             buf_put_byte(out, '\'');
             buf_putc_utf8(out, c);
+            if (c2)
+                buf_putc_utf8(out, c2);
             buf_put_byte(out, '\'');
-            buf_put_byte(out, ' ');
         }
-        if (c < 0x100)
-            buf_printf(out, "\\%03o ", c);
-        buf_printf(out, "%d 0x%02x ", c, c);
+        if (c < 0x100 && !c2)
+            buf_printf(out, " \\%03o", c);
+        buf_printf(out, " %d", c);
+        if (c2)
+            buf_printf(out, "/%d", c2);
+        buf_printf(out, " 0x%02x", c);
+        if (c2)
+            buf_printf(out, "/0x%02x", c2);
 
         /* Display buffer bytes if char is encoded */
         off = s->offset;
         eb_read(s->b, off++, &cc, 1);
-        if (cc != c || off != offset1) {
-            buf_printf(out, "[%02X", cc);
-            while (off < offset1) {
+        if (cc != c || c2 || off != offset2) {
+            buf_printf(out, " [%02X", cc);
+            while (off < offset2) {
                 eb_read(s->b, off++, &cc, 1);
                 buf_printf(out, " %02X", cc);
             }
             buf_put_byte(out, ']');
-            buf_put_byte(out, ' ');
         }
-        buf_put_byte(out, ' ');
     }
     eb_get_pos(s->b, &line_num, &col_num, s->offset);
-    put_status(s, "%spoint=%d col=%d mark=%d size=%d region=%d",
-               out->buf, s->offset, col_num, s->b->mark, s->b->total_size,
-               abs(s->offset - s->b->mark));
+    put_status(s, "%s  point=%d mark=%d size=%d region=%d col=%d",
+               out->buf, s->offset, s->b->mark, s->b->total_size,
+               abs(s->offset - s->b->mark), col_num);
 }
 
 void do_set_tab_width(EditState *s, int tab_width)

Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.132
retrieving revision 1.133
diff -u -b -r1.132 -r1.133
--- qe.h        31 Jan 2014 12:14:13 -0000      1.132
+++ qe.h        1 Feb 2014 12:49:06 -0000       1.133
@@ -265,6 +265,10 @@
     /* XXX: any unicode char >= 128 is considered as word. */
     return qe_isalnum_(c) || (c >= 128);
 }
+static inline int qe_isaccent(int c) {
+    /* XXX: only check Latin combining marks */
+    return qe_inrange(c, 0x300, 0x362);
+}
 static inline int qe_toupper(int c) {
     return (qe_inrange(c, 'a', 'z') ? c + 'A' - 'a' : c);
 }
@@ -561,6 +565,8 @@
 int unicode_to_glyphs(unsigned int *dst, unsigned int *char_to_glyph_pos,
                       int dst_size, unsigned int *src, int src_size,
                       int reverse);
+int combine_accent(unsigned int *buf, int c, int accent);
+int expand_ligature(unsigned int *buf, int c);
 int load_ligatures(void);
 void unload_ligatures(void);
 
@@ -1669,6 +1675,7 @@
                            int *offsetp, int line_num);
 
 void do_char(EditState *s, int key, int argval);
+void do_combine_char(EditState *s, int accent);
 void do_set_mode(EditState *s, const char *name);
 void text_move_left_right_visual(EditState *s, int dir);
 void text_move_word_left_right(EditState *s, int dir);

Index: qeconfig.h
===================================================================
RCS file: /sources/qemacs/qemacs/qeconfig.h,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -b -r1.43 -r1.44
--- qeconfig.h  21 Jan 2014 00:01:21 -0000      1.43
+++ qeconfig.h  1 Feb 2014 12:49:06 -0000       1.44
@@ -50,15 +50,19 @@
     CMD3( KEY_NONE, KEY_NONE,
           "insert-mode", do_overwrite_mode, ESi, 0, "v")
 
-    /* Insert combining accent: should combine with preceding letter */
+#ifdef CONFIG_UNICODE_JOIN
+    /* Insert combining accent: combine with letter if possible */
     CMD3( KEY_META('`'), KEY_NONE,
-          "insert-grave-accent", do_char, ESii, 0x300, "vui")
+          "combine-grave-accent", do_combine_char, ESi, 0x300, "*v")
     CMD3( KEY_META('\''), KEY_NONE,
-          "insert-acute-accent", do_char, ESii, 0x301, "vui")
+          "combine-acute-accent", do_combine_char, ESi, 0x301, "*v")
     CMD3( KEY_META('^'), KEY_NONE,
-          "insert-circumflex-accent", do_char, ESii, 0x302, "vui")
+          "combine-circumflex-accent", do_combine_char, ESi, 0x302, "*v")
     CMD3( KEY_META('"'), KEY_NONE,
-          "insert-diaeresis", do_char, ESii, 0x308, "vui")
+          "combine-diaeresis", do_combine_char, ESi, 0x308, "*v")
+    CMD3( KEY_META('~'), KEY_NONE,
+          "combine-tilde", do_combine_char, ESi, 0x303, "*v")
+#endif
 
     /* Moving around */
 

Index: tty.c
===================================================================
RCS file: /sources/qemacs/qemacs/tty.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -b -r1.57 -r1.58
--- tty.c       24 Jan 2014 00:46:27 -0000      1.57
+++ tty.c       1 Feb 2014 12:49:06 -0000       1.58
@@ -958,6 +958,8 @@
 
 static inline int tty_term_glyph_width(__unused__ QEditScreen *s, unsigned int 
ucs)
 {
+    /* XXX: should support combining marks */
+
     /* fast test for majority of non-wide scripts */
     if (ucs < 0x1100)
         return 1;
@@ -1089,6 +1091,12 @@
             if (ptr1 == ptr2)
                 continue;
 
+            /* if first modified char is an accent, backtrack on letter */
+            if (qe_isaccent(TTYCHAR_GETCH(*ptr1))
+            ||  qe_isaccent(TTYCHAR_GETCH(ptr1[shadow]))) {
+                ptr1--;
+            }
+
             /* quickly scan for last difference on row:
              * the first difference on row at ptr1 is before ptr2
              * so we do not need a test on ptr2 > ptr1
@@ -1171,7 +1179,9 @@
                                         40 + bgcolor);
                         }
                     }
-                    if (fgcolor != (int)TTYCHAR_GETFG(cc) && ch != ' ') {
+                    /* do not special case SPC on fg color change
+                     * because of combining marks */
+                    if (fgcolor != (int)TTYCHAR_GETFG(cc)) {
                         int lastfg = fgcolor;
                         fgcolor = TTYCHAR_GETFG(cc);
                         if (ts->term_flags & USE_BOLD_AS_BRIGHT) {

Index: unicode_join.c
===================================================================
RCS file: /sources/qemacs/qemacs/unicode_join.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- unicode_join.c      24 Jan 2014 00:46:27 -0000      1.14
+++ unicode_join.c      1 Feb 2014 12:49:06 -0000       1.15
@@ -122,6 +122,34 @@
     return -1;
 }
 
+int combine_accent(unsigned int *buf, int c, int accent)
+{
+    int lig = find_ligature(c, accent);
+    if (lig >= 0) {
+        *buf = lig;
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+/* No need for efficiency */
+int expand_ligature(unsigned int *buf, int c)
+{
+    unsigned short *a, *b;
+
+    if (c > 0x7f) {
+        for (a = ligature2, b = a + 3 * ligature2_count; a < b; a++) {
+            if (a[2] == c) {
+                buf[0] = a[0];
+                buf[1] = a[1];
+                return 1;
+            }
+        }
+    }
+    return 0;
+}
+
 /* apply all the ligature rules in logical order. Always return a
    smaller buffer */
 static int unicode_ligature(unsigned int *buf_out,



reply via email to

[Prev in Thread] Current Thread [Next in Thread]