changeset 111526:5c986eef8f0d

Fix and document display of glyphless characters. src/xdisp.c (set_cursor_from_row): Fix cursor positioning on zero-width characters. (syms_of_xdisp) <glyphless-char-display>: Doc fix. src/.gdbinit (pgx): Adapt to latest changes in `struct glyph'. src/w32term.c (x_draw_glyphless_glyph_string_foreground): Draw the box before drawing the glyphs inside it. src/dispextern.h (enum glyphless_display_method): Rename GLYPHLESS_DISPLAY_HEXA_CODE to GLYPHLESS_DISPLAY_HEX_CODE. All users changed. src/term.c (append_glyphless_glyph, produce_glyphless_glyph): Fix comments. (produce_glyphless_glyph): Enclose "U+nnnn" and "empty box" whitespace in "[]", to simulate a box. Don't use uninitialized variable `width'. lisp/international/characters.el (glyphless-char-display-control): Renamed from glyphless-char-control; all users changed. Doc fix. Signal an error if display method is not one of the recognized symbols. doc/emacs/rmail.texi (Rmail Coding): Characters with no fonts are not necessarily displayed as empty boxes. doc/emacs/mule.texi (Language Environments, Fontsets): Characters with no fonts are not necessarily displayed as empty boxes. doc/emacs/display.texi (Text Display): Document display of glyphless characters. doc/lispref/display.texi (Usual Display): Characters with no fonts are not necessarily displayed as empty boxes. etc/NEWS: Document display of glyphless characters.
author Eli Zaretskii <eliz@gnu.org>
date Sat, 13 Nov 2010 15:29:31 +0200
parents 49c1b16ca6b1
children e48ae521359f
files doc/emacs/ChangeLog doc/emacs/display.texi doc/emacs/mule.texi doc/emacs/rmail.texi doc/lispref/ChangeLog doc/lispref/display.texi etc/ChangeLog etc/NEWS lisp/ChangeLog lisp/international/characters.el src/.gdbinit src/ChangeLog src/dispextern.h src/term.c src/w32term.c src/xdisp.c src/xterm.c
diffstat 17 files changed, 215 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/doc/emacs/ChangeLog	Sat Nov 13 11:42:32 2010 +0100
+++ b/doc/emacs/ChangeLog	Sat Nov 13 15:29:31 2010 +0200
@@ -1,3 +1,14 @@
+2010-11-13  Eli Zaretskii  <eliz@gnu.org>
+
+	* rmail.texi (Rmail Coding): Characters with no fonts are not
+	necessarily displayed as empty boxes.
+
+	* mule.texi (Language Environments, Fontsets): Characters with no
+	fonts are not necessarily displayed as empty boxes.
+
+	* display.texi (Text Display): Document display of glyphless
+	characters.
+
 2010-11-13  Glenn Morris  <rgm@gnu.org>
 
 	* basic.texi (Position Info): Add M-x count-words-region.
--- a/doc/emacs/display.texi	Sat Nov 13 11:42:32 2010 +0100
+++ b/doc/emacs/display.texi	Sat Nov 13 15:29:31 2010 +0200
@@ -1136,6 +1136,48 @@
 by means of a display table.  @xref{Display Tables,, Display Tables,
 elisp, The Emacs Lisp Reference Manual}.
 
+@cindex glyphless characters
+@cindex characters with no font glyphs
+  On graphics displays, some characters could have no glyphs in any of
+the fonts available to Emacs.  On text terminals, some characters
+could be impossible to encode with the terminal coding system
+(@pxref{Terminal Coding}).  Emacs can display such @dfn{glyphless}
+characters using one of the following methods:
+
+@table @code
+@item zero-width
+Don't display the character.
+
+@item thin-space
+Display a thin space, 1-pixel wide on graphics displays or 1-character
+wide on text terminals.
+
+@item empty-box
+Display an empty box.
+
+@item acronym
+Display the acronym of the character's name (such as @sc{zwnj} or
+@sc{rlm}) in a box.
+
+@item hex-code
+Display the Unicode codepoint of the character in hexadecimal
+notation, in a box.
+@end table
+
+@noindent
+@cindex @code{glyphless-char} face
+With the exception of @code{zero-width}, all other methods draw these
+characters in a special face @code{glyphless-char}, which you can
+customize.
+
+@vindex glyphless-char-display-control
+@vindex char-acronym-table
+To control what glyphless characters are displayed using which method,
+customize the variable @code{glyphless-char-display-control}; see its
+doc string for the details.  For even finer control, set the elements
+of 2 char-tables: @code{glyphless-char-display} and
+@code{char-acronym-table}.
+
 @node Cursor Display
 @section Displaying the Cursor
 
--- a/doc/emacs/mule.texi	Sat Nov 13 11:42:32 2010 +0100
+++ b/doc/emacs/mule.texi	Sat Nov 13 15:29:31 2010 +0200
@@ -351,10 +351,11 @@
 @cindex Intlfonts package, installation
   To display the script(s) used by your language environment on a
 graphical display, you need to have a suitable font.  If some of the
-characters appear as empty boxes, you should install the GNU Intlfonts
-package, which includes fonts for most supported scripts.@footnote{If
-you run Emacs on X, you need to inform the X server about the location
-of the newly installed fonts with the following commands:
+characters appear as empty boxes or hex codes, you should install the
+GNU Intlfonts package, which includes fonts for most supported
+scripts.@footnote{If you run Emacs on X, you need to inform the X
+server about the location of the newly installed fonts with the
+following commands:
 
 @example
  xset fp+ /usr/local/share/emacs/fonts
@@ -1314,10 +1315,11 @@
 explicitly requested, despite its name.
 
   A fontset does not necessarily specify a font for every character
-code.  If a fontset specifies no font for a certain character, or if it
-specifies a font that does not exist on your system, then it cannot
-display that character properly.  It will display that character as an
-empty box instead.
+code.  If a fontset specifies no font for a certain character, or if
+it specifies a font that does not exist on your system, then it cannot
+display that character properly.  It will display that character as a
+hex code or thin space or an empty box instead.  (@xref{Text Display,
+glyphless characters}, for details.)
 
 @node Defining Fontsets
 @section Defining fontsets
--- a/doc/emacs/rmail.texi	Sat Nov 13 11:42:32 2010 +0100
+++ b/doc/emacs/rmail.texi	Sat Nov 13 15:29:31 2010 +0200
@@ -1192,7 +1192,8 @@
 example, a misconfigured mailer could send a message with a
 @samp{charset=iso-8859-1} header when the message is actually encoded
 in @code{koi8-r}.  When you see the message text garbled, or some of
-its characters displayed as empty boxes, this may have happened.
+its characters displayed as hex codes or empty boxes, this may have
+happened.
 
 @findex rmail-redecode-body
   You can correct the problem by decoding the message again using the
--- a/doc/lispref/ChangeLog	Sat Nov 13 11:42:32 2010 +0100
+++ b/doc/lispref/ChangeLog	Sat Nov 13 15:29:31 2010 +0200
@@ -1,3 +1,8 @@
+2010-11-13  Eli Zaretskii  <eliz@gnu.org>
+
+	* display.texi (Usual Display): Characters with no fonts are not
+	necessarily displayed as empty boxes.
+
 2010-10-31  Glenn Morris  <rgm@gnu.org>
 
 	* maps.texi (Standard Keymaps): Update File menu description.
--- a/doc/lispref/display.texi	Sat Nov 13 11:42:32 2010 +0100
+++ b/doc/lispref/display.texi	Sat Nov 13 15:29:31 2010 +0200
@@ -5579,9 +5579,9 @@
 table can specify a glyph to use instead of @samp{\}.)
 
 @item
-Multibyte character codes above 256 are displayed as themselves, or as a
-question mark or empty box if the terminal cannot display that
-character.
+Multibyte character codes above 256 are displayed as themselves, or as
+a question mark or a hex code or an empty box if the terminal cannot
+display that character.
 @end itemize
 
   The usual display conventions apply even when there is a display
--- a/etc/ChangeLog	Sat Nov 13 11:42:32 2010 +0100
+++ b/etc/ChangeLog	Sat Nov 13 15:29:31 2010 +0200
@@ -1,3 +1,7 @@
+2010-11-13  Eli Zaretskii  <eliz@gnu.org>
+
+	* NEWS: Document display of glyphless characters.
+
 2010-11-11  Eric Schulte  <schulte.eric@gmail.com>
 
 	* refcards/orgcard.tex: Add new Babel key sequences.
--- a/etc/NEWS	Sat Nov 13 11:42:32 2010 +0100
+++ b/etc/NEWS	Sat Nov 13 15:29:31 2010 +0200
@@ -138,6 +138,18 @@
 Emacs.pane.menubar.faceName:  Courier-12
 Set faceName to none and use font to use the old X fonts.
 
++++
+** Enhanced support for characters that have no glyphs in available fonts
+If a character has no glyphs in any of the available fonts, Emacs by
+default will display it either as a hexadecimal code in a box or as a
+thin 1-pixel space.  In addition to these two methods, Emacs can
+display these characters as empty box, as an acronym, or not display
+them at all.  To change how these characters are displayed, customize
+the variable `glyphless-char-display-control'.
+
+On character terminals these methods are used for characters that
+cannot be encoded by the `terminal-coding-system'.
+
 ** On graphical displays, the mode-line no longer ends in dashes.
 
 ** Basic SELinux support has been added.
--- a/lisp/ChangeLog	Sat Nov 13 11:42:32 2010 +0100
+++ b/lisp/ChangeLog	Sat Nov 13 15:29:31 2010 +0200
@@ -1,3 +1,9 @@
+2010-11-13  Eli Zaretskii  <eliz@gnu.org>
+
+	* international/characters.el (glyphless-char-display-control):
+	Doc fix.  Signal an error if display method is not one of the
+	recognized symbols.
+
 2010-11-13  Michael Albinus  <michael.albinus@gmx.de>
 
 	* net/tramp-compat.el (tramp-compat-line-beginning-position)
--- a/lisp/international/characters.el	Sat Nov 13 11:42:32 2010 +0100
+++ b/lisp/international/characters.el	Sat Nov 13 15:29:31 2010 +0200
@@ -1294,40 +1294,48 @@
 (aset char-acronym-table #xE007F "->|TAG") ; CANCEL TAG
 
 ;;; Control of displaying glyphless characters.
-(defvar glyphless-char-control
+(defvar glyphless-char-display-control
   '((format-control . thin-space)
-    (no-font . hexa-code))
-  "List of directives to control displaying of glyphless characters.
+    (no-font . hex-code))
+  "List of directives to control display of glyphless characters.
+
+Each element has the form (GROUP . METHOD), where GROUP is a
+symbol specifying the character group, and METHOD is a symbol
+specifying the method of displaying characters belonging to that
+group.
 
-Each element has the form (TARGET . METHOD), where TARGET is a
-symbol specifying the target character group to control, and
-METHOD is a symbol specifying the method of displaying them.
-
-TARGET must be one of these symbols:
-  `c0-control': U+0000..U+001F.
-  `c1-control': U+0080..U+009F.
-  `format-control': Characters of Unicode General Category `Cf'.
-     Ex: U+200C (ZWNJ), U+200E (LRM)), but don't include characters
-     that have graphic image such as U+00AD (SHY).
-  `no-font': characters for which no suitable font is found.
+GROUP must be one of these symbols:
+  `c0-control':     U+0000..U+001F.
+  `c1-control':     U+0080..U+009F.
+  `format-control': Characters of Unicode General Category `Cf',
+                    such as U+200C (ZWNJ), U+200E (LRM), but
+                    excluding characters that have graphic images,
+                    such as U+00AD (SHY).
+  `no-font':        characters for which no suitable font is found.
+                    For character terminals, characters that cannot
+                    be encoded by `terminal-coding-system'.
 
 METHOD must be one of these symbols:
   `zero-width': don't display.
-  `thin-space': display a thin space (1-pixel width).
-  `empty-box': display an empty box.
-  `acronym': display an acronum string in a box.
-  `hexa-code': display a hexadecimal character code in a box.
+  `thin-space': display a thin (1-pixel width) space.  On character
+                terminals, display as 1-character space.
+  `empty-box':  display an empty box.
+  `acronym':    display an acronym of the character in a box.  The
+                acronym is taken from `char-acronym-table', which see.
+  `hex-code':   display the hexadecimal character code in a box.
 
 Just setting this variable does not take effect.  Call the
 function `update-glyphless-char-display' (which see) after
 setting this variable.")
 
 (defun update-glyphless-char-display ()
-  "Make the setting of `glyphless-char-control' take effect.
+  "Make the setting of `glyphless-char-display-control' take effect.
 This function updates the char-table `glyphless-char-display'."
-  (dolist (elt glyphless-char-control)
+  (dolist (elt glyphless-char-display-control)
     (let ((target (car elt))
 	  (method (cdr elt)))
+      (or (memq method '(zero-width thin-space empty-box acronym hex-code))
+	  (error "Invalid glyphless character display method: %s" method))
       (cond ((eq target 'c0-control)
 	     (set-char-table-range glyphless-char-display '(#x00 . #x1F)
 				   method))
@@ -1346,7 +1354,7 @@
 			(while (<= from to)
 			  (when (/= from #xAD)
 			    (if (eq method 'acronym)
-				(setq this-method 
+				(setq this-method
 				      (aref char-acronym-table from)))
 			    (set-char-table-range glyphless-char-display
 						  from this-method))
@@ -1355,7 +1363,7 @@
 	    ((eq target 'no-font)
 	     (set-char-table-extra-slot glyphless-char-display 0 method))
 	    (t
-	     (error "Invalid target character group: %s" target))))))
+	     (error "Invalid glyphless character group: %s" target))))))
 
 (update-glyphless-char-display)
 
--- a/src/.gdbinit	Sat Nov 13 11:42:32 2010 +0100
+++ b/src/.gdbinit	Sat Nov 13 15:29:31 2010 +0200
@@ -494,14 +494,30 @@
   end
   # COMPOSITE_GLYPH
   if ($g->type == 1)
-    printf "COMP[%d (%d..%d)]", $g->u.cmp.id, $g->u.cmp.from, $g->u.cmp.to
+    printf "COMP[%d (%d..%d)]", $g->u.cmp.id, $g->slice.cmp.from, $g->slice.cmp.to
+  end
+  # GLYPHLESS_GLYPH
+  if ($g->type == 2)
+    printf "GLYPHLESS["
+    if ($g->u.glyphless.method == 0)
+      printf "THIN]"
+    end
+    if ($g->u.glyphless.method == 1)
+      printf "EMPTY]"
+    end
+    if ($g->u.glyphless.method == 2)
+      printf "ACRO]"
+    end
+    if ($g->u.glyphless.method == 3)
+      printf "HEX]"
+    end
   end
   # IMAGE_GLYPH
-  if ($g->type == 2)
+  if ($g->type == 3)
     printf "IMAGE[%d]", $g->u.img_id
   end
   # STRETCH_GLYPH
-  if ($g->type == 3)
+  if ($g->type == 4)
     printf "STRETCH[%d+%d]", $g->u.stretch.height, $g->u.stretch.ascent
   end
   xgettype ($g->object)
@@ -544,8 +560,8 @@
   if ($g->right_box_line_p)
     printf " ]"
   end
-  if ($g->slice.x || $g->slice.y || $g->slice.width || $g->slice.height)
-    printf " slice=%d,%d,%d,%d" ,$g->slice.x, $g->slice.y, $g->slice.width, $g->slice.height
+  if ($g->slice.img.x || $g->slice.img.y || $g->slice.img.width || $g->slice.img.height)
+    printf " slice=%d,%d,%d,%d" ,$g->slice.img.x, $g->slice.img.y, $g->slice.img.width, $g->slice.img.height
   end
   printf "\n"
 end
--- a/src/ChangeLog	Sat Nov 13 11:42:32 2010 +0100
+++ b/src/ChangeLog	Sat Nov 13 15:29:31 2010 +0200
@@ -1,3 +1,25 @@
+2010-11-13  Eli Zaretskii  <eliz@gnu.org>
+
+	* xdisp.c (set_cursor_from_row): Fix cursor positioning on
+	zero-width characters.
+
+	* .gdbinit (pgx): Adapt to latest changes in `struct glyph'.
+
+	* w32term.c (x_draw_glyphless_glyph_string_foreground): Draw the
+	box before drawing the glyphs inside it.
+
+	* xdisp.c (syms_of_xdisp) <glyphless-char-display>: Doc fix.
+
+	* dispextern.h (enum glyphless_display_method): Rename
+	GLYPHLESS_DISPLAY_HEXA_CODE to GLYPHLESS_DISPLAY_HEX_CODE.  All
+	users changed.
+
+	* term.c (append_glyphless_glyph, produce_glyphless_glyph): Fix
+	comments.
+	(produce_glyphless_glyph): Enclose "U+nnnn" and "empty box"
+	whitespace in "[]", to simulate a box.  Don't use uninitialized
+	variable `width'.
+
 2010-11-11  Julien Danjou  <julien@danjou.info>
 
 	* xsettings.c (init_xsettings): Use already fetch atoms.
--- a/src/dispextern.h	Sat Nov 13 11:42:32 2010 +0100
+++ b/src/dispextern.h	Sat Nov 13 15:29:31 2010 +0200
@@ -371,12 +371,11 @@
      displaying.  The member `pixel_width' above is set to 1.  */
   unsigned padding_p : 1;
 
-  /* 1 means the actual glyph is not available, draw a box instead.
-     This can happen when a font couldn't be loaded, or a character
-     doesn't have a glyph in a font.  */
+  /* 1 means the actual glyph is not available, draw using `struct
+     glyphless' below instead.  This can happen when a font couldn't
+     be loaded, or a character doesn't have a glyph in a font.  */
   unsigned glyph_not_available_p : 1;
 
- 
   /* Non-zero means don't display cursor here.  */
   unsigned avoid_cursor_p : 1;
 
@@ -1997,14 +1996,15 @@
 
 enum glyphless_display_method
   {
-    /* Display a thin (1-pixel width) space.  */
+    /* Display a thin (1-pixel width) space.  On a TTY, display a
+       1-character width space.  */
     GLYPHLESS_DISPLAY_THIN_SPACE,
     /* Display an empty box of proper width.  */
     GLYPHLESS_DISPLAY_EMPTY_BOX,
     /* Display an acronym string in a box.  */
     GLYPHLESS_DISPLAY_ACRONYM,
-    /* Display a hexadecimal character code in a box.  */
-    GLYPHLESS_DISPLAY_HEXA_CODE
+    /* Display the hexadecimal code of the character in a box.  */
+    GLYPHLESS_DISPLAY_HEX_CODE
   };
 
 struct it_slice
--- a/src/term.c	Sat Nov 13 11:42:32 2010 +0100
+++ b/src/term.c	Sat Nov 13 15:29:31 2010 +0200
@@ -1850,9 +1850,9 @@
 
 
 /* Append a glyph for a glyphless character to IT->glyph_row.  FACE_ID
-   is a face ID to be used for the glyph.  What actually appended are
-   glyphs of type CHAR_GLYPH of which characters are in STR
-   (it->nglyphs bytes).  */
+   is a face ID to be used for the glyph.  What is actually appended
+   are glyphs of type CHAR_GLYPH whose characters are in STR (which
+   comes from it->nglyphs bytes).  */
 
 static void
 append_glyphless_glyph (struct it *it, int face_id, char *str)
@@ -1923,7 +1923,7 @@
 /* Produce glyphs for a glyphless character for iterator IT.
    IT->glyphless_method specifies which method to use for displaying
    the character.  See the description of enum
-   glyphless_display_method in dispextern.h for the detail.
+   glyphless_display_method in dispextern.h for the details.
 
    FOR_NO_FONT is nonzero if and only if this is for a character that
    is not supproted by the coding system of the terminal.  ACRONYM, if
@@ -1935,11 +1935,11 @@
 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
 {
   int face_id;
-  int width, len;
-  char buf[9], *str = "    ";
+  int len;
+  char buf[11], *str = "    ";
 
   /* Get a face ID for the glyph by utilizing a cache (the same way as
-     doen for `escape-glyph' in get_next_display_element).  */
+     done for `escape-glyph' in get_next_display_element).  */
   if (it->f == last_glyphless_glyph_frame
       && it->face_id == last_glyphless_glyph_face_id)
     {
@@ -1956,8 +1956,8 @@
 
   if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
     {
-      /* As there's no way to produce a thin space, we produce
-	 a space of canonical width..  */
+      /* As there's no way to produce a thin space, we produce a space
+	 of canonical width.  */
       len = 1;
     }
   else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
@@ -1965,8 +1965,11 @@
       len = CHAR_WIDTH (it->c);
       if (len == 0)
 	len = 1;
-      else if (width > 4)
+      else if (len > 4)
 	len = 4;
+      sprintf (buf, "[%.*s]", len, str);
+      len += 2;
+      str = buf;
     }
   else
     {
@@ -1983,11 +1986,11 @@
 	}
       else
 	{
-	  xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEXA_CODE);
-	  len = (it->c < 0x100 ? sprintf (buf, "U+%02X", it->c)
-		 : it->c < 0x10000 ? sprintf (buf, "U+%04X", it->c)
-		 : it->c <= MAX_UNICODE_CHAR ? sprintf (buf, "U+%06X", it->c)
-		 : sprintf (buf, "E+%06X", it->c));
+	  xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
+	  len = (it->c < 0x100 ? sprintf (buf, "[U+%02X]", it->c)
+		 : it->c < 0x10000 ? sprintf (buf, "[U+%04X]", it->c)
+		 : it->c <= MAX_UNICODE_CHAR ? sprintf (buf, "[U+%06X]", it->c)
+		 : sprintf (buf, "[E+%06X]", it->c));
 	}
       str = buf;
     }
--- a/src/w32term.c	Sat Nov 13 11:42:32 2010 +0100
+++ b/src/w32term.c	Sat Nov 13 15:29:31 2010 +0200
@@ -1440,7 +1440,7 @@
 		str = (char *) SDATA (acronym);
 	    }
 	}
-      else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEXA_CODE)
+      else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
 	{
 	  sprintf ((char *) buf, "%0*X",
 		   glyph->u.glyphless.ch < 0x10000 ? 4 : 6,
@@ -1448,6 +1448,11 @@
 	  str = buf;
 	}
 
+      if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
+	w32_draw_rectangle (s->hdc, s->gc,
+			    x, s->ybase - glyph->ascent,
+			    glyph->pixel_width - 1,
+			    glyph->ascent + glyph->descent - 1);
       if (str)
 	{
 	  struct font *font = s->font;
@@ -1456,7 +1461,7 @@
 	  HFONT old_font;
 
 	  old_font = SelectObject (s->hdc, FONT_HANDLE (font));
-	  /* It is assured that all LEN characters in STR is ASCII.  */
+	  /* It is certain that all LEN characters in STR are ASCII.  */
 	  for (j = 0; j < len; j++)
 	    {
 	      code = font->driver->encode_char (font, str[j]);
@@ -1472,11 +1477,6 @@
 			      with_background);
 	  SelectObject (s->hdc, old_font);
 	}
-      if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
-	w32_draw_rectangle (s->hdc, s->gc,
-			    x, s->ybase - glyph->ascent,
-			    glyph->pixel_width - 1,
-			    glyph->ascent + glyph->descent - 1);
       x += glyph->pixel_width;
    }
 }
--- a/src/xdisp.c	Sat Nov 13 11:42:32 2010 +0100
+++ b/src/xdisp.c	Sat Nov 13 15:29:31 2010 +0200
@@ -971,7 +971,7 @@
 Lisp_Object Qglyphless_char_display;
 
 /* Method symbols for Vglyphless_char_display.  */
-static Lisp_Object Qhexa_code, Qempty_box, Qthin_space, Qzero_width;
+static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
 
 /* Default pixel width of `thin-space' display method.  */
 #define THIN_SPACE_WIDTH 1
@@ -5813,8 +5813,8 @@
     it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
   else if (EQ (glyphless_method, Qempty_box))
     it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
-  else if (EQ (glyphless_method, Qhexa_code))
-    it->glyphless_method = GLYPHLESS_DISPLAY_HEXA_CODE;
+  else if (EQ (glyphless_method, Qhex_code))
+    it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
   else if (STRINGP (glyphless_method))
     it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
   else
@@ -12871,10 +12871,10 @@
 	       || (row->truncated_on_left_p && pt_old < bpos_min)
 	       || (row->truncated_on_right_p && pt_old > bpos_max)
 	       /* Zero-width characters produce no glyphs.  */
-	       || ((row->reversed_p
-		    ? glyph_after > glyphs_end
-		    : glyph_after < glyphs_end)
-		   && eabs (glyph_after - glyph_before) == 1))
+	       || (!string_seen
+		   && (row->reversed_p
+		       ? glyph_after > glyphs_end
+		       : glyph_after < glyphs_end)))
 	{
 	  cursor = glyph_after;
 	  x = -1;
@@ -22292,7 +22292,7 @@
    and only if this is for a character for which no font was found.
 
    If the display method (it->glyphless_method) is
-   GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEXA_CODE, LEN is a
+   GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
    length of the acronym or the hexadecimal string, UPPER_XOFF and
    UPPER_YOFF are pixel offsets for the upper part of the string,
    LOWER_XOFF and LOWER_YOFF are for the lower part.
@@ -22441,7 +22441,7 @@
 	}
       else
 	{
-	  xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEXA_CODE);
+	  xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
 	  sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
 	  str = buf;
 	}
@@ -27057,7 +27057,7 @@
   hourglass_shown_p = 0;
 
   DEFSYM (Qglyphless_char, "glyphless-char");
-  DEFSYM (Qhexa_code, "hexa-code");
+  DEFSYM (Qhex_code, "hex-code");
   DEFSYM (Qempty_box, "empty-box");
   DEFSYM (Qthin_space, "thin-space");
   DEFSYM (Qzero_width, "zero-width");
@@ -27073,13 +27073,13 @@
 	       doc: /* Char-table to control displaying of glyphless characters.
 Each element, if non-nil, is an ASCII acronym string (displayed in a box)
 or one of these symbols:
-  hexa-code: display with hexadecimal character code in a box
-  empty-box: display with an empty box
-  thin-space: display with 1-pixel width space
+  hex-code:   display the hexadecimal code of a character in a box
+  empty-box:  display as an empty box
+  thin-space: display as 1-pixel width space
   zero-width: don't display
 
 It has one extra slot to control the display of a character for which
-no font is found.  The value of the slot is `hexa-code' or `empty-box'.
+no font is found.  The value of the slot is `hex-code' or `empty-box'.
 The default is `empty-box'.  */);
   Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
   Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
--- a/src/xterm.c	Sat Nov 13 11:42:32 2010 +0100
+++ b/src/xterm.c	Sat Nov 13 15:29:31 2010 +0200
@@ -1369,7 +1369,7 @@
 		str = (char *) SDATA (acronym);
 	    }
 	}
-      else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEXA_CODE)
+      else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
 	{
 	  sprintf ((char *) buf, "%0*X",
 		   glyph->u.glyphless.ch < 0x10000 ? 4 : 6,