Whether East Asian double-width characters are treated as such is just as
much a relevant console attribute as its coding-system, IMO. It should also
be part of the user’s language environment, somehow, but that needs code a
long hard look generally before it’s updated to deal with this.
src/ChangeLog addition:
2006-08-06 Aidan Kehoe <kehoea(a)parhasard.net>
* console-tty-impl.h (struct tty_console):
New flag; multiple_width, specifying whether East Asian characters
take up two columns on this terminal. The macro to access it
expands to a constant under non-Mule, so anything conditionalising
on it will be optimised away.
* console-tty.c:
* console-tty.c (tty_init_console):
Initialise tty_con->multiple_width; zero on non-Mule, one on Mule.
* console-tty.c (Fconsole_tty_multiple_width): New.
* console-tty.c (Fset_console_tty_multiple_width): New.
* console-tty.c (syms_of_console_tty): Make them available outside
console-tty.c.
* redisplay-tty.c (tty_text_width):
* redisplay-tty.c (tty_output_ibyte_string):
Check that the relevant console has multiple-width characters
before using something other than the number of characters in a
string for the text width of that string.
* text.c:
* text.c (ibyte_string_displayed_columns):
* text.c (ichar_string_displayed_columns):
Remove some Mule conditionals; add some sanity-checking.
XEmacs Trunk source patch:
Diff command: cvs -q diff -Nu
Files affected: src/text.c src/redisplay-tty.c src/console-tty.c src/console-tty-impl.h
Index: src/console-tty-impl.h
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/console-tty-impl.h,v
retrieving revision 1.2
diff -u -u -r1.2 console-tty-impl.h
--- src/console-tty-impl.h 2005/11/25 01:41:57 1.2
+++ src/console-tty-impl.h 2006/08/06 19:58:43
@@ -200,6 +200,8 @@
/* Is this TTY our controlling terminal? */
unsigned int controlling_terminal :1;
unsigned int is_stdio :1;
+ /* Do East Asian chars take up two columns? */
+ unsigned int multiple_width :1;
};
#ifdef NEW_GC
@@ -220,6 +222,12 @@
#define CONSOLE_TTY_REAL_CURSOR_Y(c) (CONSOLE_TTY_DATA (c)->real_cursor_y)
#define CONSOLE_TTY_FINAL_CURSOR_X(c) (CONSOLE_TTY_DATA (c)->final_cursor_x)
#define CONSOLE_TTY_FINAL_CURSOR_Y(c) (CONSOLE_TTY_DATA (c)->final_cursor_y)
+
+#ifdef MULE
+#define CONSOLE_TTY_MULTIPLE_WIDTH(c) (CONSOLE_TTY_DATA (c)->multiple_width)
+#else /* MULE */
+#define CONSOLE_TTY_MULTIPLE_WIDTH(c) (0)
+#endif /* MULE */
#define TTY_CM(c) (CONSOLE_TTY_DATA (c)->cm)
#define TTY_SE(c) (CONSOLE_TTY_DATA (c)->se)
Index: src/console-tty.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/console-tty.c,v
retrieving revision 1.34
diff -u -u -r1.34 console-tty.c
--- src/console-tty.c 2005/11/25 01:41:58 1.34
+++ src/console-tty.c 2006/08/06 19:58:43
@@ -158,6 +158,11 @@
tty_con->terminal_type = terminal_type;
tty_con->controlling_process = controlling_process;
+ /* multiple_width is not actually read or changed if Mule support isn't
+ available--the macro to access it expands to a constant--so this is
+ mainly for consistency. */
+ tty_con->multiple_width = !(Vcharset_ascii == ichar_charset(0xFF));
+
if (NILP (CONSOLE_NAME (con)))
CONSOLE_NAME (con) = Ffile_name_nondirectory (tty);
{
@@ -319,6 +324,46 @@
return Qnil;
}
+DEFUN ("console-tty-multiple-width", Fconsole_tty_multiple_width,
+ 0, 1, 0, /*
+Return whether CONSOLE treats East Asian double-width chars as such.
+
+CONSOLE defaults to the selected console. Without Mule support,
+this always gives nil.
+*/
+ (console))
+{
+ return CONSOLE_TTY_MULTIPLE_WIDTH (decode_tty_console(console))
+ ? Qt : Qnil;
+}
+
+DEFUN ("set-console-tty-multiple-width", Fset_console_tty_multiple_width,
+ 0, 2, 0, /*
+Set whether CONSOLE treats East Asian double-width characters as such.
+
+CONSOLE defaults to the selected console, and VALUE defaults to nil.
+Without Mule support, this throws an error if VALUE is non-nil.
+*/
+ (console, value))
+{
+ if (!CONSOLE_TTY_MULTIPLE_WIDTH (decode_tty_console (console))
+ && NILP(value))
+
+ {
+ return Qnil;
+ }
+
+#ifndef MULE
+ invalid_change
+ ("Non-nil change to console-tty-multiple-width' needs Mule.", value);
+#endif
+
+ CONSOLE_TTY_MULTIPLE_WIDTH (decode_tty_console (console))
+ = NILP(value) ? 0 : 1;
+
+ return Qnil;
+}
+
/* #### Move this function to lisp */
DEFUN ("set-console-tty-coding-system", Fset_console_tty_coding_system,
0, 2, 0, /*
@@ -431,6 +476,8 @@
DEFSUBR (Fconsole_tty_input_coding_system);
DEFSUBR (Fset_console_tty_input_coding_system);
DEFSUBR (Fset_console_tty_coding_system);
+ DEFSUBR (Fconsole_tty_multiple_width);
+ DEFSUBR (Fset_console_tty_multiple_width);
}
void
Index: src/redisplay-tty.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/redisplay-tty.c,v
retrieving revision 1.26
diff -u -u -r1.26 redisplay-tty.c
--- src/redisplay-tty.c 2006/06/27 22:59:40 1.26
+++ src/redisplay-tty.c 2006/08/06 19:58:43
@@ -100,16 +100,23 @@
/*****************************************************************************
tty_text_width
- Non-Mule tty's don't have fonts (that we use at least), so everything
+ Non-Mule TTYs don't have fonts (that we use at least), so everything
is considered to be fixed width -- in other words, we return LEN.
Under Mule, however, a character can still cover more than one
column, so we use ichar_string_displayed_columns().
****************************************************************************/
static int
-tty_text_width (struct frame *UNUSED (f), struct face_cachel *UNUSED (cachel),
+tty_text_width (struct frame *f, struct face_cachel *UNUSED (cachel),
const Ichar *str, Charcount len)
{
- return ichar_string_displayed_columns (str, len);
+ struct console *c = XCONSOLE(FRAME_CONSOLE (f));
+
+ if (CONSOLE_TTY_MULTIPLE_WIDTH (c))
+ {
+ return ichar_string_displayed_columns (str, len);
+ }
+
+ return len;
}
/*****************************************************************************
@@ -533,6 +540,8 @@
{
struct frame *f = XFRAME (w->frame);
struct console *c = XCONSOLE (FRAME_CONSOLE (f));
+ int incing = CONSOLE_TTY_MULTIPLE_WIDTH (c) ?
+ ibyte_string_displayed_columns (str, len) : len;
/* First position the cursor. */
cmgoto (f, dl->ypos - 1, xpos);
@@ -541,7 +550,7 @@
tty_turn_on_face (w, findex);
send_string_to_tty_console (c, str, len);
- TTY_INC_CURSOR_X (c, ibyte_string_displayed_columns (str, len));
+ TTY_INC_CURSOR_X (c, incing);
/* Turn the face properties back off. */
tty_turn_off_face (w, findex);
Index: src/text.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/text.c,v
retrieving revision 1.28
diff -u -u -r1.28 text.c
--- src/text.c 2006/07/08 16:15:57 1.28
+++ src/text.c 2006/08/06 19:58:45
@@ -1998,20 +1998,25 @@
#endif
}
+/* A couple of these functions should only be called on a non-Mule build. */
+#ifdef MULE
+#define ASSERT_BUILT_WITH_MULE() assert(1)
+#else /* MULE */
+#define ASSERT_BUILT_WITH_MULE() assert(0)
+#endif /* MULE */
+
int
ibyte_string_displayed_columns (const Ibyte *str, Bytecount len)
{
int cols = 0;
const Ibyte *end = str + len;
+ ASSERT_BUILT_WITH_MULE();
+
while (str < end)
{
-#ifdef MULE
Ichar ch = itext_ichar (str);
cols += XCHARSET_COLUMNS (ichar_charset (ch));
-#else
- cols++;
-#endif
INC_IBYTEPTR (str);
}
@@ -2019,19 +2024,17 @@
}
int
-ichar_string_displayed_columns (const Ichar *USED_IF_MULE (str), Charcount len)
+ichar_string_displayed_columns (const Ichar * str, Charcount len)
{
-#ifdef MULE
int cols = 0;
int i;
+ ASSERT_BUILT_WITH_MULE();
+
for (i = 0; i < len; i++)
cols += XCHARSET_COLUMNS (ichar_charset (str[i]));
return cols;
-#else /* not MULE */
- return len;
-#endif
}
Charcount
--
Santa Maradona, priez pour moi!