(analyse_bidi_level): Adjust a type (FriBidiParType).
[m17n/m17n-lib.git] / src / draw.c
index 4a7baa0..bc302b1 100644 (file)
@@ -1,5 +1,5 @@
 /* draw.c -- drawing module.
 /* draw.c -- drawing module.
-   Copyright (C) 2003, 2004
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
@@ -17,7 +17,7 @@
 
    You should have received a copy of the GNU Lesser General Public
    License along with the m17n library; if not, write to the Free
 
    You should have received a copy of the GNU Lesser General Public
    License along with the m17n library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    02111-1307, USA.  */
 
 /***en
    02111-1307, USA.  */
 
 /***en
@@ -31,7 +31,7 @@
     appearance of M-texts, i.e. font size, color, underline, etc.
 
     The drawing format of M-texts can be controlled in a variety of
     appearance of M-texts, i.e. font size, color, underline, etc.
 
     The drawing format of M-texts can be controlled in a variety of
-    ways, which provides powerful 2-dimensional layouting
+    ways, which provides powerful 2-dimensional layout
     facility.  */
 
 /***ja
     facility.  */
 
 /***ja
 
     m17n-gui API ¤Ë¤Ï¡¢M-text ¤òɽ¼¨¤¹¤ë¤¿¤á¤Î´Ø¿ô¤¬ÍÑ°Õ¤µ¤ì¤Æ¤¤¤ë¡£
 
 
     m17n-gui API ¤Ë¤Ï¡¢M-text ¤òɽ¼¨¤¹¤ë¤¿¤á¤Î´Ø¿ô¤¬ÍÑ°Õ¤µ¤ì¤Æ¤¤¤ë¡£
 
-    É½¼¨¤ËÍѤ¤¤é¤ì¤ë¥Õ¥©¥ó¥È¤Ï¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤È face ¥×¥í¥Ñ¥Æ¥£¤Ë´ð¤Å
-    ¤¤¤Æ¼«Æ°Åª¤Ë·èÄꤵ¤ì¤ë¡£¤Þ¤¿¡¢¥Õ¥©¥ó¥È¤Î¥µ¥¤¥º¤ä¿§¤ä²¼Àþ¤Ê¤É¤Î¸«±É
-    ¤¨¤â face ¤Ë¤è¤Ã¤Æ·è¤Þ¤ë¡£
+    É½¼¨¤ËÍѤ¤¤é¤ì¤ë¥Õ¥©¥ó¥È¤Ï¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤È face 
+    ¤Î¥×¥í¥Ñ¥Æ¥£¤Ë´ð¤Å¤¤¤Æ¼«Æ°Åª¤Ë·èÄꤵ¤ì¤ë¡£¤Þ¤¿¡¢¥Õ¥©¥ó¥È¤Î¥µ¥¤¥º¤ä¿§¤ä²¼Àþ¤Ê¤É¤Î¸«±É¤¨¤â
+    face ¤Ë¤è¤Ã¤Æ·è¤Þ¤ë¡£
 
 
-    M-text ¤ÎÉÁ²è¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï¿ÍͤÊÊýË¡¤ÇÀ©¸æ¤Ç¤­¤ë¤Î¤Ç¡¢¶¯ÎϤÊÆó¼¡
-    ¸µ¥ì¥¤¥¢¥¦¥Èµ¡Ç½¤¬¼Â¸½¤Ç¤­¤ë¡£
+    M-text ¤ÎÉÁ²è¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï¿ÍͤÊÊýË¡¤ÇÀ©¸æ¤Ç¤­¤ë¤Î¤Ç¡¢¶¯ÎϤÊÆ󼡸µ¥ì¥¤¥¢¥¦¥Èµ¡Ç½¤¬¼Â¸½¤Ç¤­¤ë¡£
     */
 
 /*=*/
     */
 
 /*=*/
 #include "m17n-misc.h"
 #include "internal.h"
 #include "symbol.h"
 #include "m17n-misc.h"
 #include "internal.h"
 #include "symbol.h"
+#include "mtext.h"
 #include "textprop.h"
 #include "internal-gui.h"
 #include "textprop.h"
 #include "internal-gui.h"
+#include "internal-flt.h"
 #include "face.h"
 #include "font.h"
 
 #include "face.h"
 #include "font.h"
 
 static MSymbol M_glyph_string;
 
 /* Special scripts */
 static MSymbol M_glyph_string;
 
 /* Special scripts */
-static MSymbol Mlatin, Minherited;
+static MSymbol Mcommon;
 /* Special categories */
 static MSymbol McatCc, McatCf;
 
 /* Special categories */
 static MSymbol McatCc, McatCf;
 
+static MCharTable *linebreak_table;
+static MSymbol M_break_at_space, M_break_at_word, M_break_at_any;
+static MSymbol M_kinsoku_bol, M_kinsoku_eol;
+
 \f
 /* Glyph-string composer.  */
 
 \f
 /* Glyph-string composer.  */
 
@@ -93,223 +98,406 @@ static MSymbol MbidiRLE;
 static MSymbol MbidiRLO;
 static MSymbol MbidiBN;
 static MSymbol MbidiS;
 static MSymbol MbidiRLO;
 static MSymbol MbidiBN;
 static MSymbol MbidiS;
+static MSymbol MbidiNSM;
 
 
-static void
-visual_order (MGlyphString *gstring)
+static int
+analyse_bidi_level (MGlyphString *gstring)
 {
   int len = gstring->used - 2;
 {
   int len = gstring->used - 2;
-  MGlyph *glyphs;
-  int *idx = alloca (sizeof (int) * len);
-  int gidx;
   int bidi_sensitive = gstring->control.orientation_reversed;
   int bidi_sensitive = gstring->control.orientation_reversed;
-  int size = 0;
-  MGlyph *g = MGLYPH (1);
+  int max_level;
+  MGlyph *g;
   int i;
 #ifdef HAVE_FRIBIDI
   int i;
 #ifdef HAVE_FRIBIDI
-  FriBidiCharType base = (gstring->control.orientation_reversed
-                         ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR);
+  FriBidiParType base = bidi_sensitive ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR;
   FriBidiChar *logical = alloca (sizeof (FriBidiChar) * len);
   FriBidiChar *logical = alloca (sizeof (FriBidiChar) * len);
-  FriBidiChar *visual;
+  FriBidiLevel *levels;
   FriBidiStrIndex *indices;
   FriBidiStrIndex *indices;
-  FriBidiLevel *levels = alloca (sizeof (FriBidiLevel) * len);
 #else  /* not HAVE_FRIBIDI */
   int *logical = alloca (sizeof (int) * len);
 #else  /* not HAVE_FRIBIDI */
   int *logical = alloca (sizeof (int) * len);
-  int *indices;
   char *levels = alloca (len);
   char *levels = alloca (len);
+
+  memset (levels, 0, sizeof (int) * len);
 #endif /* not HAVE_FRIBIDI */
 
 #endif /* not HAVE_FRIBIDI */
 
-  while (g->type != GLYPH_ANCHOR)
+  for (g = MGLYPH (1), i = 0; g->type != GLYPH_ANCHOR; g++, i++)
     {
     {
-      MSymbol bidi = (MSymbol) mchar_get_prop (g->c, Mbidi_category);
-
-      if (bidi == MbidiR || bidi == MbidiAL
-         || bidi == MbidiRLE || bidi == MbidiRLO)
+      if (! bidi_sensitive
+#ifndef HAVE_FRIBIDI
+         || 1
+#endif /* not HAVE_FRIBIDI */
+         )
        {
        {
-         bidi_sensitive = 1;
-         levels[size] = 1;
+         MSymbol bidi = (MSymbol) mchar_get_prop (g->g.c, Mbidi_category);
+
+         if (bidi == MbidiR || bidi == MbidiAL
+             || bidi == MbidiRLE || bidi == MbidiRLO)
+           {
+             bidi_sensitive = 1;
+#ifndef HAVE_FRIBIDI
+             levels[i] = 1;
+#endif /* not HAVE_FRIBIDI */
+           }
+#ifndef HAVE_FRIBIDI
+         else if (bidi == MbidiNSM && i > 0 && levels[i - 1])
+           levels[i] = 1;          
+#endif /* not HAVE_FRIBIDI */
        }
        }
-      else
-       levels[size] = 0;
-      idx[size] = GLYPH_INDEX (g);
-      logical[size++] = g++->c;
-      while (g->type != GLYPH_ANCHOR && g->combining_code)
-       g++;
+      logical[i] = g->g.c;
     }
 
   if (! bidi_sensitive)
     }
 
   if (! bidi_sensitive)
-    return;
+    return 0;
 
 
-  glyphs = alloca (sizeof (MGlyph) * gstring->used);
-  memcpy (glyphs, gstring->glyphs, (sizeof (MGlyph) * gstring->used));
 #ifdef HAVE_FRIBIDI
 #ifdef HAVE_FRIBIDI
-  visual = alloca (sizeof (FriBidiChar) * size);
-  indices = alloca (sizeof (FriBidiStrIndex) * size);
+  levels = alloca (sizeof (FriBidiLevel) * (len + 1));
+  indices = alloca (sizeof (FriBidiStrIndex) * (len + 1));
 
 
-  fribidi_log2vis (logical, size, &base, visual, NULL, indices, levels);
-#else  /* not HAVE_FRIBIDI */
-  indices = alloca (sizeof (int) * size);
-  for (i = 0; i < size; i++)
-    {
-      if (levels[i])
-       {
-         int j, k;
+  fribidi_log2vis (logical, len, &base, NULL, NULL, indices, levels);
+#endif /* not HAVE_FRIBIDI */
 
 
-         for (j = i + 1; j < size && levels[j]; j++);
-         for (k = j--; i < k; i++, j--)
-           indices[i] = j;
-         i--;
-       }
-      else
-       indices[i] = i;
+  MGLYPH (0)->bidi_level = 0;
+  max_level = 0;
+  for (g = MGLYPH (1), i = 0; i < len; g++, i++)
+    {
+      g->bidi_level = levels[i];
+      if (max_level < g->bidi_level)
+       max_level = g->bidi_level;
     }
     }
-#endif /* not HAVE_FRIBIDI */
+  MGLYPH (i)->bidi_level = 0;
+  return max_level;
+}
 
 
-  /* IDX are indices to gstring->glyphs[].  The glyphs for LOGICAL[N]
-     starts from gstring->glyphs[IDX[N]].
+static void
+visual_order (MGlyphString *gstring)
+{
+  MGlyph *glyphs = alloca (sizeof (MGlyph) * gstring->used);
+  int i, j, gidx;
 
 
-     INDICES are indices to LOGICAL[].  The glyph for VISUAL[N] is
-     originally at LOGICAL[INDICES[N]].  */
+  memcpy (glyphs, gstring->glyphs, sizeof (MGlyph) * gstring->used);
 
 
-  for (i = 0, gidx = 1; i < size; i++)
+  for (i = gidx = 0; i < gstring->used - 1; gidx++)
     {
     {
-      int j = indices[i];
-      int k = idx[j];
+      int level = glyphs[i].bidi_level;
+      
+      gstring->glyphs[gidx] = glyphs[i];
+      glyphs[i].rface = NULL;
 
 
-      glyphs[k].bidi_level = levels[j];
-#ifdef HAVE_FRIBIDI
-      if (visual[i] != logical[j])
+      if (level % 2)
        {
        {
-         /* Mirrored.  */
-         glyphs[k].c = visual[i];
-         if (glyphs[k].rface->rfont)
-           glyphs[k].code = mfont__encode_char (glyphs[k].rface->rfont,
-                                                glyphs[k].c);
+         int prev_level = glyphs[i - 1].bidi_level;
+
+         if (prev_level == level)
+           i--;
+         else if (prev_level > level)
+           {
+             for (; glyphs[i - 1].bidi_level > level; i--);
+             if (glyphs[i].bidi_level % 2)
+               for (level = glyphs[i].bidi_level;
+                    glyphs[i + 1].bidi_level == level; i++);
+           }
+         else
+           for (i++; ! glyphs[i].rface; i++);
        }
        }
-#endif /* not HAVE_FRIBIDI */
-      *(MGLYPH (gidx)) = glyphs[k];
-      for (gidx++, k++;
-          k < gstring->used - 1 && glyphs[k].combining_code;
-          gidx++, k++)
+      else
        {
        {
-         glyphs[k].bidi_level = levels[j];
-         *(MGLYPH (gidx)) = glyphs[k];
+         int next_level = glyphs[i + 1].bidi_level;
+
+         if (next_level == level)
+           i++;
+         else if (next_level > level)
+           {
+             for (; glyphs[i + 1].bidi_level > level; i++);
+             if ((glyphs[i].bidi_level % 2) == 0)
+               for (level = glyphs[i].bidi_level;
+                    glyphs[i - 1].bidi_level == level; i--);
+           }
+         else
+           {
+             int save = i + 1;
+
+             for (i--; glyphs[i].bidi_level >= level; i--);
+             if (! glyphs[i].rface)
+               for (i = save; ! glyphs[i].rface; i++);
+           }
+       }
+    }
+  for (i = 1; i < gstring->used - 1; i++)
+    {
+      MGlyph *g = gstring->glyphs + i;
+      int level = g->bidi_level;
+
+      for (j = i; g->g.from == gstring->glyphs[j + 1].g.from; j++);
+      if ((level % 2) && j > i)
+       {
+         memcpy (glyphs + i, gstring->glyphs + i,
+                 sizeof (MGlyph) * (j - i + 1));
+         for (; i <= j; i++)
+           g[j - i] = glyphs[i];
+         i--;
        }
     }
 }
 
        }
     }
 }
 
-static void
-reorder_combining_chars (MGlyphString *gstring, int from, int to)
+static MSymbol
+font_id (MFLTFont *font)
 {
 {
-  MGlyph *g, *gbeg = MGLYPH (from + 1), *gend = MGLYPH (to), temp;
-  int reordered = 1;
-  
-  while (reordered)
+  return ((MFLTFontForRealized *) font)->rfont->id;
+}
+
+static int
+run_flt (MGlyphString *gstring, int from, int to, MRealizedFace *rface)
+{
+  MRealizedFont *rfont = rface->rfont;
+  MSymbol layouter = rface->layouter;
+  MFLTGlyphString flt_gstr;
+  MFLTFontForRealized font;
+  MFLT *flt;
+  int from_pos = MGLYPH (from)->g.from;
+  int len = to - from;
+  int catcode;
+  int i;
+
+  flt = mflt_get (layouter);
+  flt_gstr.glyph_size = sizeof (MGlyph);
+  flt_gstr.glyphs = (MFLTGlyph *) (gstring->glyphs);
+  flt_gstr.used = gstring->used;
+  flt_gstr.allocated = gstring->size;
+  flt_gstr.r2l = 0;
+  font.font.family = mfont_get_prop (rfont->font, Mfamily);
+  font.font.x_ppem = rfont->x_ppem;
+  font.font.y_ppem = rfont->y_ppem;
+  font.font.get_glyph_id = mfont__get_glyph_id;
+  font.font.get_metrics = mfont__get_metrics;
+  font.font.check_otf = rfont->driver->check_otf;
+  font.font.drive_otf = rfont->driver->drive_otf;
+  font.font.internal = NULL;
+  font.rfont = rfont;
+  mflt_font_id = font_id;
+  mflt_iterate_otf_feature = rfont->driver->iterate_otf_feature;
+  mflt_try_otf = rfont->driver->try_otf;
+  for (i = 0; i < 3; i++)
     {
     {
-      reordered = 0;
-      for (g = gbeg; g != gend; g++)
-       if (COMBINING_CODE_CLASS (g->combining_code) > 0
-           && (COMBINING_CODE_CLASS (g[-1].combining_code)
-               > COMBINING_CODE_CLASS (g->combining_code)))
-         {
-           reordered = 1;
-           temp = *g;
-           *g = g[-1];
-           g[-1] = temp;
-         }
+      to = mflt_run (&flt_gstr, from, to, &font.font, flt);
+      if (to != -2)
+       break;
+      APPEND_GLYPH (gstring, *MGLYPH (0));
+      APPEND_GLYPH (gstring, *MGLYPH (0));
+      gstring->used -= 2;
     }
     }
-}
+  if (from + len != to)
+    gstring->used += to - (from + len);
+  for (i = from, catcode = -1; i < to; i++)
+    {
+      MGlyph *g = MGLYPH (i);
+
+      g->g.from += from_pos - from;
+      g->g.to += from_pos - from + 1;
+      g->g.xadv >>= 6;
+      g->g.yadv >>= 6;
+      g->g.ascent >>= 6;
+      g->g.descent >>= 6;
+      g->g.lbearing >>= 6;
+      g->g.rbearing >>= 6;
+      g->g.xoff >>= 6;
+      g->g.yoff >>= 6;
+      g->rface = rface;
+      if (catcode < 0 || g->g.from != g[-1].g.from)
+       {
+         MSymbol category = mchar_get_prop (g->g.c, Mcategory);
 
 
+         catcode = (category == McatCf
+                    ? GLYPH_CATEGORY_FORMATTER
+                    : category != Mnil && MSYMBOL_NAME (category)[0] == 'M'
+                    ? GLYPH_CATEGORY_MODIFIER
+                    : GLYPH_CATEGORY_NORMAL);
+       }
+      g->category = catcode;
+    }
+  return to;
+}
 
 /** Scan M-text MT from FROM to TO, and compose glyphs in GSTRING for
     displaying them on FRAME.
 
 
 /** Scan M-text MT from FROM to TO, and compose glyphs in GSTRING for
     displaying them on FRAME.
 
-    This function fills members <type>, <rface>, <c>, <pos>, <to>,
-    <code> of glyphs.  The other members are filled by
-    layout_glyph_string.  */
+    This function fills these members:
+      pos, to, c, code, rface, bidi_level, categories, type, combining_code
+    The other members are filled by layout_glyph_string.  */
 
 static void
 compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
                      MGlyphString *gstring)
 {
   MRealizedFace *default_rface = frame->rface;
 
 static void
 compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
                      MGlyphString *gstring)
 {
   MRealizedFace *default_rface = frame->rface;
-  int stop, face_change, language_change, charset_change;
-  MGlyph g_tmp, *g;
+  int stop, face_change, language_change, charset_change, font_change;
+  MGlyph g_tmp, *g, *last_g;
   int pos;
   MSymbol language = Mnil, script = Mnil, charset = Mnil;
   int pos;
   MSymbol language = Mnil, script = Mnil, charset = Mnil;
+  MSymbol non_latin_script = Mnil;
   MRealizedFace *rface = default_rface;
   MRealizedFace *rface = default_rface;
+  MRealizedFont *rfont;
   int size = gstring->control.fixed_width;
   int size = gstring->control.fixed_width;
+  int max_bidi_level = 0;
   int i;
   int i;
-  int last;
 
   MLIST_RESET (gstring);
   gstring->from = from;
 
 
   MLIST_RESET (gstring);
   gstring->from = from;
 
-  /* At first generate glyphs while using the member <enabled> as a
-     flag for rface re-checking.  */
+  /* At first generate glyphs with <pos>, <to>, <c>, <type>,
+     <category> and <rface> members.*/
   INIT_GLYPH (g_tmp);
 
   /** Put anchor glyphs at the head and tail.  */
   g_tmp.type = GLYPH_ANCHOR;
   INIT_GLYPH (g_tmp);
 
   /** Put anchor glyphs at the head and tail.  */
   g_tmp.type = GLYPH_ANCHOR;
-  g_tmp.pos = g_tmp.to = from;
-  g_tmp.c = 0;
+  g_tmp.g.from = g_tmp.g.to = from;
   APPEND_GLYPH (gstring, g_tmp);
   APPEND_GLYPH (gstring, g_tmp);
-
-  stop = face_change = charset_change = language_change = pos = from;
-  last = 0;
+  stop = face_change = font_change = pos = from;
   while (1)
     {
       int c;
   while (1)
     {
       int c;
-      MSymbol this_script;
+      MSymbol category;
+
+      if (pos == stop)
+       {
+         if (pos == to)
+           break;
+         if (pos < mtext_nchars (mt))
+           {
+             MFont *font = rface->font;
+             MFace *faces[64];
+             int num;
+
+             if (pos == font_change)
+               {
+                 font = mtext_get_prop (mt, pos, Mfont);
+                 mtext_prop_range (mt, Mfont, pos, NULL, &font_change, 0);
+                 if (font_change == mtext_nchars (mt))
+                   font_change++;
+               }
+             if (pos == face_change)
+               {
+                 num = mtext_get_prop_values (mt, pos, Mface,
+                                              (void **) faces, 64);
+                 mtext_prop_range (mt, Mface, pos, NULL, &face_change, 1);
+                 if (face_change == mtext_nchars (mt))
+                   face_change++;
+               }
+             else
+               {
+                 faces[0] = &rface->face;
+                 num = 1;
+               }
+             rface = mface__realize (frame, faces, num, size, font);
+           }
+         else
+           rface = default_rface;
+         stop = to;
+         if (stop > font_change)
+           stop = font_change;         
+         if (stop > face_change)
+           stop = face_change;         
+       }
 
       if (pos < mtext_nchars (mt))
        c = mtext_ref_char (mt, pos);
       else
        c = '\n';
 
       if (pos < mtext_nchars (mt))
        c = mtext_ref_char (mt, pos);
       else
        c = '\n';
-      if (c < 0x100)
+      g_tmp.type
+       = (c == ' ' || c == '\n' || c == '\t') ? GLYPH_SPACE : GLYPH_CHAR;
+      g_tmp.g.c = c;
+      g_tmp.g.from = pos++;
+      g_tmp.g.to = pos;
+      g_tmp.rface = rface;
+      category = mchar_get_prop (c, Mcategory);
+      if (category == McatCf)
+       g_tmp.category = GLYPH_CATEGORY_FORMATTER;
+      else if (category != Mnil && MSYMBOL_NAME (category)[0] == 'M')
+       g_tmp.category = GLYPH_CATEGORY_MODIFIER;
+      else
+       g_tmp.category = GLYPH_CATEGORY_NORMAL;
+      
+      if ((c <= ' ' || c == 127) && g_tmp.type == GLYPH_CHAR)
        {
        {
-         /* Short cut for the obvious case.  */
-         g_tmp.category = Mnil;
-         if (c == ' ' || c == '\n' || c == '\t')
-           g_tmp.type = GLYPH_SPACE, this_script = Mnil;
-         else
-           g_tmp.type = GLYPH_CHAR, this_script = Mlatin;
+         MGlyph ctrl[2];
+
+         ctrl[0] = ctrl[1] = g_tmp;
+         ctrl[0].g.c = '^';
+         ctrl[1].g.c = c < ' ' ? c + 0x40 : '?';
+         APPEND_GLYPH (gstring, ctrl[0]);
+         APPEND_GLYPH (gstring, ctrl[1]);
        }
       else
        }
       else
+       APPEND_GLYPH (gstring, g_tmp);
+      if (c == '\n' && gstring->control.two_dimensional)
+       break;
+    }
+  /* Append an anchor glyph.  */
+  INIT_GLYPH (g_tmp);
+  g_tmp.type = GLYPH_ANCHOR;
+  g_tmp.g.from = g_tmp.g.to = pos;
+  APPEND_GLYPH (gstring, g_tmp);
+  gstring->to = pos;
+
+  if (gstring->control.enable_bidi)
+    max_bidi_level = analyse_bidi_level (gstring);
+
+  /* The next loop is to change each <rface> member for non-ASCII
+     characters if necessary.  */
+  stop = charset_change = language_change = from;
+  rfont = default_rface->rfont;
+  for (last_g = g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++)
+    {
+      int c = g->g.c;
+      MSymbol this_script;
+
+      if (c < 0x100)
+       /* Short cut for the obvious case.  */
+       this_script = Mlatin;
+      else
        {
        {
-         g_tmp.category = mchar_get_prop (c, Mcategory);
-         g_tmp.type = GLYPH_CHAR;
          this_script = (MSymbol) mchar_get_prop (c, Mscript);
          this_script = (MSymbol) mchar_get_prop (c, Mscript);
-         if (this_script == Minherited || this_script == Mnil)
-           this_script = script;
-         if (this_script == Mnil)
-           /* Search forward for a character that explicitly
-              specifies a script.  */
-           for (i = pos + 1; i < to; i++)
-             {
-               int c1 = mtext_ref_char (mt, i); 
-               MSymbol sym = ((c1 > 0x20 && c1 < 0x100) ? Mlatin
-                              : mchar_get_prop (c1, Mscript));
-               
-               if (sym != Minherited && sym != Mnil)
+         if (this_script == Minherited || this_script == Mcommon)
+           {
+             if (g > MGLYPH (1))
+               {
+                 MSymbol category = mchar_get_prop (g[-1].g.c, Mcategory);
+
+                 if (category != Mnil && MSYMBOL_NAME (category)[0] != 'Z')
+                   this_script = script;
+               }
+           }
+         if (this_script == Mcommon && non_latin_script)
+           this_script = non_latin_script;
+         if (this_script == Mcommon)
+           {
+             /* Search forward for a character that explicitly
+                specifies a non-latin script.  */
+             MSymbol sym;
+             MGlyph *g1;
+
+             for (g1 = g + 1; g1->type != GLYPH_ANCHOR; g1++)
+               if (g1->g.c >= 0x100
+                   && (sym = mchar_get_prop (g1->g.c, Mscript)) != Mcommon
+                   && sym != Minherited)
                  {
                    this_script = sym;
                    break;
                  }
                  {
                    this_script = sym;
                    break;
                  }
-             }
+           }
+         if (this_script == Minherited || this_script == Mcommon)
+           this_script = (MSymbol) mchar_get_prop (c, Mblock);
        }
 
        }
 
-      if (pos == stop || script != this_script
-         || MGLYPH (last)->type != g_tmp.type)
+      pos = g->g.from;
+      if (pos == stop || script != this_script || g->rface->rfont != rfont)
        {
        {
-         g = MGLYPH (last);
-         if (g->type != GLYPH_ANCHOR)
-           while (g < gstring->glyphs + gstring->used)
-             g = mface__for_chars (script, language, charset,
-                                   g, gstring->glyphs + gstring->used, size);
-         if (pos == to)
-           break;
-         last = gstring->used;
+         while (last_g < g)
+           last_g = mface__for_chars (script, language, charset,
+                                      last_g, g, size);
          script = this_script;
          script = this_script;
+         if (script != Mnil && script != Mlatin)
+           non_latin_script = script;
+         rfont = g->rface->ascii_rface->rfont;
          if (pos == stop)
            {
              if (pos < mtext_nchars (mt) && pos == language_change)
          if (pos == stop)
            {
              if (pos < mtext_nchars (mt) && pos == language_change)
@@ -324,63 +512,20 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
                  mtext_prop_range (mt, Mcharset, pos, NULL,
                                    &charset_change, 0);
                }
                  mtext_prop_range (mt, Mcharset, pos, NULL,
                                    &charset_change, 0);
                }
-             if (pos < mtext_nchars (mt) && pos == face_change)
-               {
-                 MFace *faces[64];
-                 int num = mtext_get_prop_values (mt, pos, Mface,
-                                                  (void **) faces, 64);
-
-                 mtext_prop_range (mt, Mface, pos, NULL, &face_change, 1);
-                 rface = (num > 0
-                          ? mface__realize (frame, faces, num,
-                                            language, charset, size)
-                          : default_rface);
-               }
              stop = to;
              if (stop > language_change)
                stop = language_change;
              if (stop > charset_change)
                stop = charset_change;
              stop = to;
              if (stop > language_change)
                stop = language_change;
              if (stop > charset_change)
                stop = charset_change;
-             if (face_change < stop)
-               stop = face_change;             
            }
        }
            }
        }
-
-      g_tmp.c = c;
-      g_tmp.pos = pos++;
-      g_tmp.to = pos;
-      g_tmp.rface = rface;
-      
-      if ((c <= 32 || c == 127) && g_tmp.type == GLYPH_CHAR)
-       {
-         MGlyph ctrl[2];
-
-         ctrl[0] = ctrl[1] = g_tmp;
-         ctrl[0].c = '^';
-         ctrl[1].c = c < ' ' ? c + 0x40 : '?';
-         mface__for_chars (Mlatin, language, charset, ctrl, ctrl + 2, size);
-         APPEND_GLYPH (gstring, ctrl[0]);
-         APPEND_GLYPH (gstring, ctrl[1]);
-       }
-      else
-       APPEND_GLYPH (gstring, g_tmp);
-      if (c == '\n'
-         && gstring->control.two_dimensional)
-       break;
     }
     }
+  while (last_g < g)
+    last_g = mface__for_chars (script, language, charset, last_g, g, size);
 
 
-  /* Append an anchor glyph.  */
-  g_tmp.type = GLYPH_ANCHOR;
-  g_tmp.c = 0;
-  g_tmp.code = MCHAR_INVALID_CODE;
-  g_tmp.pos = g_tmp.to = pos;
-  g_tmp.rface = NULL;
-  APPEND_GLYPH (gstring, g_tmp);
-
-  gstring->to = pos;
-
-  /* Next, run FLT if necessary.  */
-  for (i = 1, g = MGLYPH (i); g->type != GLYPH_ANCHOR;)
+  /* The next loop is to run FLT or perform the default combining if
+     necessary.  */
+  for (i = 1, g = MGLYPH (1); g->type != GLYPH_ANCHOR;)
     {
       MGlyph *this = g;
 
     {
       MGlyph *this = g;
 
@@ -388,53 +533,49 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
        {
          int start = i++;
 
        {
          int start = i++;
 
-         if (this->rface->rfont->layouter != Mnil)
+         if (this->rface->layouter != Mnil)
            {
            {
-             MGlyph *prev;
-             unsigned code;
+             MGlyph *prev = MGLYPH (start - 1);
 
 
-             for (prev = MGLYPH (start - 1);
-                  (prev->type == GLYPH_CHAR
-                   && prev->category == McatCf
-                   && (code = mfont__encode_char (this->rface->rfont, prev->c)
-                       != MCHAR_INVALID_CODE));
-                  start--, prev--)
-               prev->code = code;
+             while (prev->type == GLYPH_CHAR
+                    && prev->category == GLYPH_CATEGORY_FORMATTER
+                    && (mfont__encode_char (NULL, (MFont *) this->rface->rfont,
+                                            NULL, prev->g.c)
+                        != MCHAR_INVALID_CODE))
+               {
+                 prev->rface->rfont = this->rface->rfont;
+                 start--, prev--;
+               }
 
              for (g++;
                   (g->type == GLYPH_CHAR
 
              for (g++;
                   (g->type == GLYPH_CHAR
+                   && g->rface->layouter == this->rface->layouter
                    && (g->rface->rfont == this->rface->rfont
                    && (g->rface->rfont == this->rface->rfont
-                       || (g->category == McatCf
-                           && ((code = mfont__encode_char (this->rface->rfont,
-                                                           g->c))
+                       || (g->category == GLYPH_CATEGORY_FORMATTER
+                           && (mfont__encode_char (NULL,
+                                                   (MFont *) this->rface->rfont,
+                                                   NULL, g->g.c)
                                != MCHAR_INVALID_CODE))));
                   i++, g++)
                                != MCHAR_INVALID_CODE))));
                   i++, g++)
-               if (g->rface->rfont != this->rface->rfont)
-                 {
-                   g->rface->rfont = this->rface->rfont;
-                   g->code = code;
-                 }
-             i = mfont__flt_run (gstring, start, i, this->rface);
+               g->rface->rfont = this->rface->rfont;
+             i = run_flt (gstring, start, i, this->rface);
            }
          else
            {
            }
          else
            {
-             while (this->type == GLYPH_CHAR
-                    && this->c >= 0x100
-                    && this->category
-                    && MSYMBOL_NAME (this->category)[0] == 'M'
-                    && this->rface->rfont
-                    && this->rface->rfont->layouter == Mnil)
+             g++;
+             while (g->type == GLYPH_CHAR
+                    && g->g.c >= 0x100
+                    && g->category == GLYPH_CATEGORY_MODIFIER
+                    && g->rface->rfont
+                    && g->rface->layouter == Mnil)
+               i++, g++;
+             if (start + 1 < i)
                {
                {
-                 int class = (int) mchar_get_prop (this->c,
-                                                   Mcombining_class);
-                 this->combining_code
-                   = MAKE_COMBINING_CODE_BY_CLASS (class);
-                 i++, this++;
+                 this->rface->layouter = Mcombining;
+                 run_flt (gstring, start, i, this->rface);
                }
                }
-             if (start + 1 < i)
-               reorder_combining_chars (gstring, start, i);
-             if (this->type == GLYPH_ANCHOR)
-               break;
+             else
+               mfont__get_metric (gstring, start, i);
            }
          g = MGLYPH (i);
        }
            }
          g = MGLYPH (i);
        }
@@ -443,223 +584,39 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
     }
 
   /* At last, reorder glyphs visually if necessary.  */
     }
 
   /* At last, reorder glyphs visually if necessary.  */
-  if (gstring->control.enable_bidi)
+  if (max_bidi_level > 0)
     visual_order (gstring);
 }
 
     visual_order (gstring);
 }
 
-
-static int
-combining_code_from_class (int class)
-{
-  int code;
-
-  if (class < 200)
-    code = MAKE_COMBINING_CODE (3, 1, 3, 1, 128, 128);
-  else if (class == 200)       /* below left attached */
-    code = MAKE_COMBINING_CODE (2, 0, 0, 1, 128, 128);
-  else if (class == 202)       /* below attached*/
-    code = MAKE_COMBINING_CODE (2, 1, 0, 1, 128, 128);
-  else if (class == 204)       /* below right attached */
-    code = MAKE_COMBINING_CODE (2, 2, 0, 1, 128, 128);
-  else if (class == 208)       /* left attached */
-    code = MAKE_COMBINING_CODE (3, 0, 3, 2, 128, 128);
-  else if (class == 210)       /* right attached */
-    code = MAKE_COMBINING_CODE (3, 2, 3, 0, 128, 128);
-  else if (class == 212)       /* above left attached */
-    code = MAKE_COMBINING_CODE (0, 0, 2, 1, 128, 128);
-  else if (class == 214)       /* above attached */
-    code = MAKE_COMBINING_CODE (0, 1, 2, 1, 128, 128);
-  else if (class == 216)       /* above right attached */
-    code = MAKE_COMBINING_CODE (0, 2, 2, 1, 128, 128);
-  else if (class == 218)       /* below left */
-    code = MAKE_COMBINING_CODE (2, 0, 0, 1, 122, 128);
-  else if (class == 220)       /* below */
-    code = MAKE_COMBINING_CODE (2, 1, 0, 1, 122, 128);
-  else if (class == 222)       /* below right */
-    code = MAKE_COMBINING_CODE (2, 2, 0, 1, 122, 128);
-  else if (class == 224)       /* left */
-    code = MAKE_COMBINING_CODE (3, 0, 3, 2, 128, 122);
-  else if (class == 226)       /* right */
-    code = MAKE_COMBINING_CODE (3, 2, 3, 0, 128, 133);
-  else if (class == 228)       /* above left */
-    code = MAKE_COMBINING_CODE (0, 0, 2, 1, 133, 128);
-  else if (class == 230)       /* above */
-    code = MAKE_COMBINING_CODE (0, 1, 2, 1, 133, 128);
-  else if (class == 232)       /* above right */
-    code = MAKE_COMBINING_CODE (0, 2, 2, 1, 133, 128);
-  else if (class == 233)       /* double below */
-    code = MAKE_COMBINING_CODE (2, 2, 0, 2, 122, 128);
-  else if (class == 234)       /* double above */
-    code = MAKE_COMBINING_CODE (0, 2, 2, 2, 133, 128);
-  else if (class == 240)       /* iota subscript */
-    code = MAKE_COMBINING_CODE (2, 1, 0, 1, 122, 128);
-  else                         /* unknown */
-    code = MAKE_COMBINING_CODE (3, 1, 3, 1, 128, 128);
-  return code;
-}
-
+typedef struct {
+  int width, lbearing, rbearing;
+} MSubTextExtents;
 
 static void
 
 static void
-layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to)
+layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to,
+              MSubTextExtents *extents)
 {
   int g_physical_ascent, g_physical_descent;
 {
   int g_physical_ascent, g_physical_descent;
-  int g_width, g_lbearing, g_rbearing;
   MGlyph *g = MGLYPH (from);
   MGlyph *last_g = MGLYPH (to);
 
   g_physical_ascent = gstring->physical_ascent;
   g_physical_descent = gstring->physical_descent;
   MGlyph *g = MGLYPH (from);
   MGlyph *last_g = MGLYPH (to);
 
   g_physical_ascent = gstring->physical_ascent;
   g_physical_descent = gstring->physical_descent;
-  g_width = g_lbearing = g_rbearing = 0;
-
-  mfont__get_metric (gstring, from, to);
+  extents->width = extents->lbearing = extents->rbearing = 0;
 
 
-#ifdef HAVE_OTF
-  while (g < last_g)
+  for (g = MGLYPH (from); g < last_g; g++)
     {
     {
-      MGlyph *base = g++;
-
-      if (base->otf_cmd)
-       {
-         while (g < last_g && base->otf_cmd == g->otf_cmd) g++;
-         mfont__ft_drive_gpos (gstring, GLYPH_INDEX (base), GLYPH_INDEX (g));
-       }
-    }
-  g = MGLYPH (from);
-#endif
-
-  while (g < last_g)
-    {
-      MGlyph *base = g++;
-      MRealizedFont *rfont = base->rface->rfont;
-      int size = rfont->font.property[MFONT_SIZE];
-      int width, lbearing, rbearing;
-
-      if (g == last_g || ! g->combining_code)
-       {
-         /* No combining.  */
-         if (base->left_padding && base->lbearing < 0)
-           {
-             base->xoff = - base->lbearing;
-             base->width += base->xoff;
-             base->rbearing += base->xoff;
-             base->lbearing = 0;
-           }
-         if (base->right_padding && base->rbearing > base->width)
-           {
-             base->width = base->rbearing;
-           }
-         lbearing = (base->lbearing < 0 ? base->lbearing : 0);
-         rbearing = base->rbearing;
-       }
-      else
-       {
-         /* With combining glyphs.  */
-         int left = -base->width;
-         int right = 0;
-         int top = - base->ascent;
-         int bottom = base->descent;
-         int height = bottom - top;
-         int begin = base->pos;
-         int end = base->to;
-         int i;
-
-         width = base->width;
-         lbearing = (base->lbearing < 0 ? base->lbearing : 0);
-         rbearing = base->rbearing;
-
-         while (g != last_g && g->combining_code)
-           {
-             int combining_code, base_x, base_y, add_x, add_y, off_x, off_y;
-
-             combining_code = g->combining_code;
-             if (COMBINING_BY_CLASS_P (combining_code))
-               g->combining_code = combining_code
-                 = combining_code_from_class (COMBINING_CODE_CLASS
-                                              (combining_code));
-
-             rfont = g->rface->rfont;
-             size = rfont->font.property[MFONT_SIZE];
-             off_x = (size * (COMBINING_CODE_OFF_X (combining_code) - 128)
-                      / 1000);
-             off_y = (size * (COMBINING_CODE_OFF_Y (combining_code) - 128)
-                      / 1000);
-             base_x = COMBINING_CODE_BASE_X (combining_code);
-             base_y = COMBINING_CODE_BASE_Y (combining_code);
-             add_x = COMBINING_CODE_ADD_X (combining_code);
-             add_y = COMBINING_CODE_ADD_Y (combining_code);
-
-             if (begin > g->pos)
-               begin = g->pos;
-             else if (end < g->to)
-               end = g->to;
-               
-             g->xoff = left + (width * base_x - g->width * add_x) / 2 + off_x;
-             if (g->xoff < left)
-               left = g->xoff;
-             if (g->xoff + g->width > right)
-               right = g->xoff + g->width;
-             width = right - left;
-             if (g->xoff + g->lbearing < left + lbearing)
-               lbearing = g->xoff + g->lbearing - left;
-             if (g->xoff + g->rbearing > left + rbearing)
-               rbearing = g->xoff + g->rbearing - left;
-
-             if (base_y < 3)
-               g->yoff = top + height * base_y / 2;
-             else
-               g->yoff = 0;
-             if (add_y < 3)
-               g->yoff -= (g->ascent + g->descent) * add_y / 2 - g->ascent;
-             g->yoff -= off_y;
-             if (g->yoff - g->ascent < top)
-               top = g->yoff - g->ascent;
-             if (g->yoff + g->descent > bottom)
-               bottom = g->yoff + g->descent;
-             height = bottom - top;
-
-             g->width = 0;
-             g++;
-           }
-
-         base->ascent = - top;
-         base->descent = bottom;
-         base->lbearing = lbearing;
-         base->rbearing = rbearing;
-         if (left < - base->width)
-           {
-             base->xoff = - base->width - left;
-             base->width += base->xoff;
-             base->rbearing += base->xoff;
-             base->lbearing += base->xoff;
-           }
-         if (right > 0)
-           {
-             base->width += right;
-             base->rbearing += right;
-             base->right_padding = 1;
-             for (i = 1; base + i != g; i++)
-               base[i].xoff -= right;
-           }
-
-         for (i = 0; base + i != g; i++)
-           {
-             base[i].pos = begin;
-             base[i].to = end;
-           }
-       }
-
-      g_physical_ascent = MAX (g_physical_ascent, base->ascent);
-      g_physical_descent = MAX (g_physical_descent, base->descent);
-      g_lbearing = MIN (g_lbearing, g_width + lbearing);
-      g_rbearing = MAX (g_rbearing, g_width + rbearing);
-      g_width += base->width;
+      g_physical_ascent = MAX (g_physical_ascent, g->g.ascent);
+      g_physical_descent = MAX (g_physical_descent, g->g.descent);
+      extents->lbearing = MIN (extents->lbearing,
+                              extents->width + g->g.lbearing);
+      extents->rbearing = MAX (extents->rbearing,
+                              extents->width + g->g.rbearing);
+      extents->width += g->g.xadv;
     }
 
   gstring->physical_ascent = g_physical_ascent;
   gstring->physical_descent = g_physical_descent;
     }
 
   gstring->physical_ascent = g_physical_ascent;
   gstring->physical_descent = g_physical_descent;
-  gstring->sub_width = g_width;
-  gstring->sub_lbearing = g_lbearing;
-  gstring->sub_rbearing = g_rbearing;
 }
 
 
 }
 
 
@@ -703,16 +660,16 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
              MGlyph box_glyph = g[-1];
 
              box_glyph.type = GLYPH_BOX;
              MGlyph box_glyph = g[-1];
 
              box_glyph.type = GLYPH_BOX;
-             box_glyph.width
+             box_glyph.g.xadv
                = (control->fixed_width
                   ? frame->space_width
                   : box->inner_hmargin + box->width + box->outer_hmargin);
                = (control->fixed_width
                   ? frame->space_width
                   : box->inner_hmargin + box->width + box->outer_hmargin);
-             box_glyph.lbearing = 0;
-             box_glyph.rbearing = box_glyph.width;
-             box_glyph.xoff = 0;
+             box_glyph.g.lbearing = 0;
+             box_glyph.g.rbearing = box_glyph.g.xadv;
+             box_glyph.g.xoff = 0;
              box_glyph.right_padding = 1;
              box_glyph.right_padding = 1;
-             gstring->width += box_glyph.width;
-             gstring->rbearing += box_glyph.width;
+             gstring->width += box_glyph.g.xadv;
+             gstring->rbearing += box_glyph.g.xadv;
              INSERT_GLYPH (gstring, gidx, box_glyph);
              gidx++;
              g = MGLYPH (gidx);
              INSERT_GLYPH (gstring, gidx, box_glyph);
              gidx++;
              g = MGLYPH (gidx);
@@ -729,23 +686,23 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
              if (box_line_height < box_height)
                box_line_height = box_height;
              box_glyph.type = GLYPH_BOX;
              if (box_line_height < box_height)
                box_line_height = box_height;
              box_glyph.type = GLYPH_BOX;
-             box_glyph.width
+             box_glyph.g.xadv
                = (control->fixed_width
                   ? frame->space_width
                   : box->inner_hmargin + box->width + box->outer_hmargin);
                = (control->fixed_width
                   ? frame->space_width
                   : box->inner_hmargin + box->width + box->outer_hmargin);
-             box_glyph.lbearing = 0;
-             box_glyph.rbearing = box_glyph.width;
-             box_glyph.xoff = 0;
+             box_glyph.g.lbearing = 0;
+             box_glyph.g.rbearing = box_glyph.g.xadv;
+             box_glyph.g.xoff = 0;
              box_glyph.left_padding = 1;
              box_glyph.left_padding = 1;
-             gstring->width += box_glyph.width;
-             gstring->rbearing += box_glyph.width;
+             gstring->width += box_glyph.g.xadv;
+             gstring->rbearing += box_glyph.g.xadv;
              INSERT_GLYPH (gstring, gidx, box_glyph);
              gidx++;
              g = MGLYPH (gidx);
            }
        }
 
              INSERT_GLYPH (gstring, gidx, box_glyph);
              gidx++;
              g = MGLYPH (gidx);
            }
        }
 
-      if (g->category == McatCf && ignore_formatting_char)
+      if (g->category == GLYPH_CATEGORY_FORMATTER && ignore_formatting_char)
        g->type = GLYPH_SPACE;
 
       if (g->type == GLYPH_CHAR)
        g->type = GLYPH_SPACE;
 
       if (g->type == GLYPH_CHAR)
@@ -758,33 +715,39 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
          for (g++; g->type == GLYPH_CHAR; g++)
            if (! rfont != ! g->rface->rfont
                || box != g->rface->box
          for (g++; g->type == GLYPH_CHAR; g++)
            if (! rfont != ! g->rface->rfont
                || box != g->rface->box
-               || ((fromg->code == MCHAR_INVALID_CODE)
-                   != (g->code == MCHAR_INVALID_CODE))
-               || (g->category == McatCf && ignore_formatting_char))
+               || ((fromg->g.code == MCHAR_INVALID_CODE)
+                   != (g->g.code == MCHAR_INVALID_CODE))
+               || (g->category == GLYPH_CATEGORY_FORMATTER
+                   && ignore_formatting_char))
              break;
              break;
-         if (rfont && fromg->code != MCHAR_INVALID_CODE)
+         if (rfont && fromg->g.code != MCHAR_INVALID_CODE)
            {
              int extra_width;
              int to = GLYPH_INDEX (g);
            {
              int extra_width;
              int to = GLYPH_INDEX (g);
+             MSubTextExtents extents;
 
 
-             layout_glyphs (frame, gstring, from, to);
-             extra_width = - gstring->sub_lbearing;
+             layout_glyphs (frame, gstring, from, to, &extents);
+             extra_width = - extents.lbearing;
              if (extra_width > 0
              if (extra_width > 0
-                 && (GLYPH_INDEX (g) > 1
-                     || control->align_head))
+                 && ! control->disable_overlapping_adjustment
+                 && (! control->orientation_reversed
+                     ? ((to > 1 || control->align_head)
+                        && g->type != GLYPH_ANCHOR)
+                     : (((g->type && GLYPH_ANCHOR) || control->align_head)
+                        && to > 1)))
                {
                  g = MGLYPH (from);
                  pad = *g;
                  pad.type = GLYPH_PAD;
                {
                  g = MGLYPH (from);
                  pad = *g;
                  pad.type = GLYPH_PAD;
-                 pad.xoff = 0;
-                 pad.lbearing = 0;
-                 pad.width = pad.rbearing = extra_width;
+                 pad.g.xoff = 0;
+                 pad.g.lbearing = 0;
+                 pad.g.xadv = pad.g.rbearing = extra_width;
                  pad.left_padding = 1;
                  INSERT_GLYPH (gstring, from, pad);
                  to++;
                  pad.left_padding = 1;
                  INSERT_GLYPH (gstring, from, pad);
                  to++;
-                 gstring->sub_lbearing = 0;
-                 gstring->sub_width += extra_width;
-                 gstring->sub_rbearing += extra_width;
+                 extents.lbearing = 0;
+                 extents.width += extra_width;
+                 extents.rbearing += extra_width;
 
                  g = MGLYPH (from - 1);
                  if (g->type == GLYPH_SPACE)
 
                  g = MGLYPH (from - 1);
                  if (g->type == GLYPH_SPACE)
@@ -797,65 +760,66 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
                         face, or a default value of the current
                         frame, which is, however, not yet
                         implemented.  */
                         face, or a default value of the current
                         frame, which is, however, not yet
                         implemented.  */
-                     if (extra_width + 2 < g->width)
+                     if (extra_width + 2 < g->g.xadv)
                        {
                        {
-                         g->width -= extra_width;
+                         g->g.xadv -= extra_width;
                        }
                      else
                        {
                        }
                      else
                        {
-                         extra_width -= g->width - 2;
-                         g->width = 2;
+                         extra_width = g->g.xadv - 2;
+                         g->g.xadv = 2;
                        }
                      gstring->width -= extra_width;
                      gstring->rbearing -= extra_width;
                    }
                }
 
                        }
                      gstring->width -= extra_width;
                      gstring->rbearing -= extra_width;
                    }
                }
 
-             extra_width = gstring->sub_rbearing - gstring->sub_width;
-             if (extra_width > 0)
+             g = MGLYPH (to);
+             extra_width = extents.rbearing - extents.width;
+             if (extra_width > 0
+                 && ! control->disable_overlapping_adjustment
+                 && (GLYPH_INDEX (g) < gstring->used - 1
+                     || (control->orientation_reversed && control->align_head)))
                {
                {
-                 g = MGLYPH (to);
                  if (g->type == GLYPH_SPACE && box == g->rface->box)
                    {
                  if (g->type == GLYPH_SPACE && box == g->rface->box)
                    {
-                     g--;
-                     pad = *g;
+                     pad = g[-1];
                      pad.type = GLYPH_PAD;
                      pad.type = GLYPH_PAD;
-                     pad.xoff = 0;
-                     pad.lbearing = 0;
-                     pad.width = pad.rbearing = extra_width;
-                     pad.rbearing = 1;
+                     pad.g.xoff = 0;
+                     pad.g.lbearing = 0;
+                     pad.g.xadv = pad.g.rbearing = extra_width;
                      INSERT_GLYPH (gstring, to, pad);
                      to++;
                      INSERT_GLYPH (gstring, to, pad);
                      to++;
+                     g = MGLYPH (to);
                    }
                  else
                    }
                  else
-                   g[-1].width += extra_width;
-                 gstring->sub_width += extra_width;
+                   g[-1].g.xadv += extra_width;
+                 extents.width += extra_width;
                }
 
                }
 
-             if (gstring->lbearing > gstring->width + gstring->sub_lbearing)
-               gstring->lbearing = gstring->width + gstring->sub_lbearing;
-             if (gstring->rbearing < gstring->width + gstring->sub_rbearing)
-               gstring->rbearing = gstring->width + gstring->sub_rbearing;
-             gstring->width += gstring->sub_width;
+             if (gstring->lbearing > gstring->width + extents.lbearing)
+               gstring->lbearing = gstring->width + extents.lbearing;
+             if (gstring->rbearing < gstring->width + extents.rbearing)
+               gstring->rbearing = gstring->width + extents.rbearing;
+             gstring->width += extents.width;
              if (gstring->ascent < rface->ascent)
                gstring->ascent = rface->ascent;
              if (gstring->descent < rface->descent)
                gstring->descent = rface->descent;
              if (gstring->ascent < rface->ascent)
                gstring->ascent = rface->ascent;
              if (gstring->descent < rface->descent)
                gstring->descent = rface->descent;
-             g = MGLYPH (to);
            }
          else
            {
              for (; fromg < g; fromg++)
                {
            }
          else
            {
              for (; fromg < g; fromg++)
                {
-                 if ((fromg->c >= 0x200B && fromg->c <= 0x200F)
-                     || (fromg->c >= 0x202A && fromg->c <= 0x202E))
-                   fromg->width = fromg->rbearing = 1;
+                 if ((fromg->g.c >= 0x200B && fromg->g.c <= 0x200F)
+                     || (fromg->g.c >= 0x202A && fromg->g.c <= 0x202E))
+                   fromg->g.xadv = fromg->g.rbearing = 1;
                  else
                  else
-                   fromg->width = fromg->rbearing = rface->space_width;
-                 fromg->xoff = fromg->lbearing = 0;
-                 fromg->ascent = fromg->descent = 0;
-                 gstring->width += fromg->width;
-                 gstring->rbearing += fromg->width;
+                   fromg->g.xadv = fromg->g.rbearing = rface->space_width;
+                 fromg->g.xoff = fromg->g.lbearing = 0;
+                 fromg->g.ascent = fromg->g.descent = 0;
+                 gstring->width += fromg->g.xadv;
+                 gstring->rbearing += fromg->g.xadv;
                }
              if (gstring->ascent < frame->rface->ascent)
                gstring->ascent = frame->rface->ascent;
                }
              if (gstring->ascent < frame->rface->ascent)
                gstring->ascent = frame->rface->ascent;
@@ -865,40 +829,40 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
        }
       else if (g->type == GLYPH_SPACE)
        {
        }
       else if (g->type == GLYPH_SPACE)
        {
-         if (g->c == ' ')
-           g->width = g->rface->space_width;
-         else if (g->c == '\n')
+         if (g->g.c == ' ')
+           g->g.xadv = g->rface->space_width;
+         else if (g->g.c == '\n')
            {
            {
-             g->width = control->cursor_width;
-             if (g->width)
+             g->g.xadv = control->cursor_width;
+             if (g->g.xadv)
                {
                  if (control->cursor_bidi)
                {
                  if (control->cursor_bidi)
-                   g->width = 3;
-                 else if (g->width < 0)
-                   g->width = g->rface->space_width;
+                   g->g.xadv = 3;
+                 else if (g->g.xadv < 0)
+                   g->g.xadv = g->rface->space_width;
                }
            }
                }
            }
-         else if (g->c == '\t')
+         else if (g->g.c == '\t')
            {
            {
-             g->width = tab_width - ((gstring->indent + gstring->width)
-                                     % tab_width);
+             g->g.xadv = tab_width - ((gstring->indent + gstring->width)
+                                      % tab_width);
              tab_found = 1;
            }
          else
              tab_found = 1;
            }
          else
-           g->width = 1;
+           g->g.xadv = 1;
          if (g[-1].type == GLYPH_PAD)
            {
              /* This space glyph absorbs (maybe partially) the
                 previous padding glyph.  */
          if (g[-1].type == GLYPH_PAD)
            {
              /* This space glyph absorbs (maybe partially) the
                 previous padding glyph.  */
-             g->width -= g[-1].width;
-             if (g->width < 1)
+             g->g.xadv -= g[-1].g.xadv;
+             if (g->g.xadv < 1)
                /* But, keep at least some space width.  For the
                   moment, we use the arbitrary width 2-pixel.  */
                /* But, keep at least some space width.  For the
                   moment, we use the arbitrary width 2-pixel.  */
-               g->width = 2;
+               g->g.xadv = 2;
            }
            }
-         g->rbearing = g->width;
-         gstring->width += g->width;
-         gstring->rbearing += g->width;
+         g->g.rbearing = g->g.xadv;
+         gstring->width += g->g.xadv;
+         gstring->rbearing += g->g.xadv;
          if (g->rface->rfont)
            {
              if (gstring->ascent < g->rface->ascent)
          if (g->rface->rfont)
            {
              if (gstring->ascent < g->rface->ascent)
@@ -910,8 +874,8 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
        }
       else
        {
        }
       else
        {
-         gstring->width += g->width;
-         gstring->rbearing += g->width;
+         gstring->width += g->g.xadv;
+         gstring->rbearing += g->g.xadv;
          g++;
        }
     }
          g++;
        }
     }
@@ -923,16 +887,16 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
       MGlyph box_glyph = g[-1];
 
       box_glyph.type = GLYPH_BOX;
       MGlyph box_glyph = g[-1];
 
       box_glyph.type = GLYPH_BOX;
-      box_glyph.width
+      box_glyph.g.xadv
        = (control->fixed_width
           ? frame->space_width
           : box->inner_hmargin + box->width + box->outer_hmargin);
        = (control->fixed_width
           ? frame->space_width
           : box->inner_hmargin + box->width + box->outer_hmargin);
-      box_glyph.lbearing = 0;
-      box_glyph.rbearing = box_glyph.width;
-      box_glyph.xoff = 0;
+      box_glyph.g.lbearing = 0;
+      box_glyph.g.rbearing = box_glyph.g.xadv;
+      box_glyph.g.xoff = 0;
       box_glyph.right_padding = 1;
       box_glyph.right_padding = 1;
-      gstring->width += box_glyph.width;
-      gstring->rbearing += box_glyph.width;
+      gstring->width += box_glyph.g.xadv;
+      gstring->rbearing += box_glyph.g.xadv;
       INSERT_GLYPH (gstring, gidx, box_glyph);
     }
 
       INSERT_GLYPH (gstring, gidx, box_glyph);
     }
 
@@ -975,23 +939,23 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
 
       for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--)
        {
 
       for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--)
        {
-         if (g->type == GLYPH_CHAR && g->c == '\t')
+         if (g->type == GLYPH_CHAR && g->g.c == '\t')
            {
              int this_width = tab_width - (width % tab_width);
 
              if (g[1].type == GLYPH_PAD)
            {
              int this_width = tab_width - (width % tab_width);
 
              if (g[1].type == GLYPH_PAD)
-               this_width -= g[1].width;
+               this_width -= g[1].g.xadv;
              if (g[-1].type == GLYPH_PAD)
              if (g[-1].type == GLYPH_PAD)
-               this_width -= g[-1].width;              
+               this_width -= g[-1].g.xadv;             
              if (this_width < 2)
                this_width = 2;
              if (this_width < 2)
                this_width = 2;
-             gstring->width += this_width - g->width;
-             gstring->rbearing += this_width - g->width;
-             g->width = this_width;
+             gstring->width += this_width - g->g.xadv;
+             gstring->rbearing += this_width - g->g.xadv;
+             g->g.xadv = this_width;
              width += this_width;
            }
          else
              width += this_width;
            }
          else
-           width += g->width;
+           width += g->g.xadv;
        }
     }
 }
        }
     }
 }
@@ -1014,16 +978,18 @@ draw_background (MFrame *frame, MDrawWindow win, int x, int y,
       if (gstring->from <= control->cursor_pos
          && gstring->to > control->cursor_pos)
        cursor_pos = control->cursor_pos;
       if (gstring->from <= control->cursor_pos
          && gstring->to > control->cursor_pos)
        cursor_pos = control->cursor_pos;
-      if (cursor_bidi
+      if (cursor_pos >= 0
+         && cursor_bidi
          && gstring->from <= control->cursor_pos - 1
          && gstring->to > control->cursor_pos - 1)
        prev_pos = control->cursor_pos - 1;
     }
 
   *from_idx = *to_idx = 0;
          && gstring->from <= control->cursor_pos - 1
          && gstring->to > control->cursor_pos - 1)
        prev_pos = control->cursor_pos - 1;
     }
 
   *from_idx = *to_idx = 0;
+  *to_x = x;
   while (g->type != GLYPH_ANCHOR)
     {
   while (g->type != GLYPH_ANCHOR)
     {
-      if (g->pos >= from && g->pos < to)
+      if (g->g.from >= from && g->g.from < to)
        {
          MGlyph *fromg = g, *cursor = NULL;
          MRealizedFace *rface = g->rface;
        {
          MGlyph *fromg = g, *cursor = NULL;
          MRealizedFace *rface = g->rface;
@@ -1033,18 +999,18 @@ draw_background (MFrame *frame, MDrawWindow win, int x, int y,
 
          if (! *from_idx)
            *from_idx = GLYPH_INDEX (g);
 
          if (! *from_idx)
            *from_idx = GLYPH_INDEX (g);
-         while (g->pos >= from && g->pos < to
+         while (g->g.from >= from && g->g.from < to
                 && g->rface == rface)
            {
              g->enabled = 1;
              if (g->type != GLYPH_BOX
                 && g->rface == rface)
            {
              g->enabled = 1;
              if (g->type != GLYPH_BOX
-                 && g->pos <= cursor_pos && g->to > cursor_pos)
+                 && g->g.from <= cursor_pos && g->g.to > cursor_pos)
                {
                  if (! cursor)
                    cursor = g, cursor_x = x + width;
                {
                  if (! cursor)
                    cursor = g, cursor_x = x + width;
-                 cursor_width += g->width;
+                 cursor_width += g->g.xadv;
                }
                }
-             width += g++->width;
+             width += g++->g.xadv;
            }
          if (width > 0
              && (control->as_image
            }
          if (width > 0
              && (control->as_image
@@ -1053,9 +1019,9 @@ draw_background (MFrame *frame, MDrawWindow win, int x, int y,
              int this_x = x, this_width = width;
 
              if (fromg->type == GLYPH_BOX)
              int this_x = x, this_width = width;
 
              if (fromg->type == GLYPH_BOX)
-               this_x += fromg->width, this_width -= fromg->width;
+               this_x += fromg->g.xadv, this_width -= fromg->g.xadv;
              if (g[-1].type == GLYPH_BOX)
              if (g[-1].type == GLYPH_BOX)
-               this_width -= g[-1].width;
+               this_width -= g[-1].g.xadv;
              (frame->driver->fill_space)
                (frame, win, rface, 0,
                 this_x, y - gstring->text_ascent, this_width,
              (frame->driver->fill_space)
                (frame, win, rface, 0,
                 this_x, y - gstring->text_ascent, this_width,
@@ -1076,11 +1042,9 @@ draw_background (MFrame *frame, MDrawWindow win, int x, int y,
                                ? control->cursor_width : cursor_width);
                }
              else
                                ? control->cursor_width : cursor_width);
                }
              else
-               {
-                 if (cursor->bidi_level % 2)
-                   rect.x += cursor_width - 1;
-                 rect.width = 1;
-               }
+               rect.width = 1;
+             if (cursor->bidi_level % 2)
+               rect.x += cursor_width - rect.width;
              (*frame->driver->fill_space)
                (frame, win, rface, 1, rect.x, rect.y, rect.width, rect.height,
                 control->clip_region);
              (*frame->driver->fill_space)
                (frame, win, rface, 1, rect.x, rect.y, rect.width, rect.height,
                 control->clip_region);
@@ -1111,13 +1075,13 @@ draw_background (MFrame *frame, MDrawWindow win, int x, int y,
              while (fromg < g)
                {
                  if (fromg->type != GLYPH_BOX
              while (fromg < g)
                {
                  if (fromg->type != GLYPH_BOX
-                     && fromg->pos <= prev_pos && fromg->to > prev_pos)
+                     && fromg->g.from <= prev_pos && fromg->g.to > prev_pos)
                    {
                      if (! cursor)
                        cursor = fromg, cursor_x = x + temp_width;
                    {
                      if (! cursor)
                        cursor = fromg, cursor_x = x + temp_width;
-                     cursor_width += fromg->width;
+                     cursor_width += fromg->g.xadv;
                    }
                    }
-                 temp_width += fromg++->width;
+                 temp_width += fromg++->g.xadv;
                }
              if (cursor)
                {
                }
              if (cursor)
                {
@@ -1172,10 +1136,10 @@ render_glyphs (MFrame *frame, MDrawWindow win, int x, int y, int width,
       (*frame->driver->region_to_rect) (region, &rect);
       if (rect.x > x)
        {
       (*frame->driver->region_to_rect) (region, &rect);
       if (rect.x > x)
        {
-         while (g != gend && x + g->rbearing <= rect.x)
+         while (g != gend && x + g->g.rbearing <= rect.x)
            {
            {
-             x += g->width;
-             width -= g++->width;
+             x += g->g.xadv;
+             width -= g++->g.xadv;
              while (! g->enabled && g != gend)
                g++;
            }
              while (! g->enabled && g != gend)
                g++;
            }
@@ -1184,14 +1148,15 @@ render_glyphs (MFrame *frame, MDrawWindow win, int x, int y, int width,
       if (rect.x < x + width)
        {
          while (g != gend
       if (rect.x < x + width)
        {
          while (g != gend
-                && (x + width - gend[-1].width + gend[-1].lbearing >= rect.x))
+                && (x + width - gend[-1].g.xadv + gend[-1].g.lbearing >= rect.x))
            {
            {
-             width -= (--gend)->width;
+             width -= (--gend)->g.xadv;
              while (! gend->enabled && g != gend)
                gend--;
            }
          if (g != gend)
              while (! gend->enabled && g != gend)
                gend--;
            }
          if (g != gend)
-           while (gend[-1].to == gend->to) gend++;
+           while (gend->type != GLYPH_ANCHOR && gend[-1].g.to == gend->g.to)
+             gend++;
        }
     }
 
        }
     }
 
@@ -1200,20 +1165,21 @@ render_glyphs (MFrame *frame, MDrawWindow win, int x, int y, int width,
       if (g->enabled)
        {
          MRealizedFace *rface = g->rface;
       if (g->enabled)
        {
          MRealizedFace *rface = g->rface;
-         int width = g->width;
+         int width = g->g.xadv;
          MGlyph *from_g = g++;
 
          /* Handle the glyphs of the same type/face at once.  */
          while (g != gend
                 && g->type == from_g->type
                 && g->rface == rface
          MGlyph *from_g = g++;
 
          /* Handle the glyphs of the same type/face at once.  */
          while (g != gend
                 && g->type == from_g->type
                 && g->rface == rface
-                && (g->code < 0) == (from_g->code < 0)
+                && ((g->g.code == MCHAR_INVALID_CODE)
+                    == (from_g->g.code == MCHAR_INVALID_CODE))
                 && g->enabled)
                 && g->enabled)
-           width += g++->width;
+           width += g++->g.xadv;
 
          if (from_g->type == GLYPH_CHAR)
            {
 
          if (from_g->type == GLYPH_CHAR)
            {
-             if (rface->rfont && from_g->code != MCHAR_INVALID_CODE)
+             if (rface->rfont && from_g->g.code != MCHAR_INVALID_CODE)
                (rface->rfont->driver->render) (win, x, y, gstring, from_g, g,
                                                reverse, region);
              else
                (rface->rfont->driver->render) (win, x, y, gstring, from_g, g,
                                                reverse, region);
              else
@@ -1257,11 +1223,11 @@ find_overlapping_glyphs (MGlyphString *gstring, int *left, int *right,
 
   for (g = MGLYPH (*left) - 1, x = 0; g->type != GLYPH_ANCHOR; g--)
     {
 
   for (g = MGLYPH (*left) - 1, x = 0; g->type != GLYPH_ANCHOR; g--)
     {
-      x -= g->width;
-      if (x + g->rbearing > 0)
+      x -= g->g.xadv;
+      if (x + g->g.rbearing > 0)
        {
        {
-         while (g[-1].pos == g->pos && g[-1].type != GLYPH_ANCHOR)
-           x -= (--g)->width;
+         while (g[-1].g.from == g->g.from && g[-1].type != GLYPH_ANCHOR)
+           x -= (--g)->g.xadv;
          left_idx = GLYPH_INDEX (g);
          left_x = x;
        }
          left_idx = GLYPH_INDEX (g);
          left_x = x;
        }
@@ -1269,11 +1235,11 @@ find_overlapping_glyphs (MGlyphString *gstring, int *left, int *right,
 
   for (g = MGLYPH (*right), x = 0; g->type != GLYPH_ANCHOR; g++)
     {
 
   for (g = MGLYPH (*right), x = 0; g->type != GLYPH_ANCHOR; g++)
     {
-      x += g->width;
-      if (x - g->width + g->lbearing < 0)
+      x += g->g.xadv;
+      if (x - g->g.xadv + g->g.lbearing < 0)
        {
        {
-         while (g->pos == g[1].pos && g[1].type != GLYPH_ANCHOR)
-           x += (++g)->width;
+         while (g->g.from == g[1].g.from && g[1].type != GLYPH_ANCHOR)
+           x += (++g)->g.xadv;
          right_idx = GLYPH_INDEX (g) + 1;
          right_x = x;
        }
          right_idx = GLYPH_INDEX (g) + 1;
          right_x = x;
        }
@@ -1301,26 +1267,33 @@ find_overlapping_glyphs (MGlyphString *gstring, int *left, int *right,
 
 
 static int
 
 
 static int
-gstring_width (MGlyphString *gstring, int from, int to, int *rbearing)
+gstring_width (MGlyphString *gstring, int from, int to,
+              int *lbearing, int *rbearing)
 {
   MGlyph *g;
   int width;
 
   if (from <= gstring->from && to >= gstring->to)
     {
 {
   MGlyph *g;
   int width;
 
   if (from <= gstring->from && to >= gstring->to)
     {
+      if (lbearing)
+       *lbearing = gstring->lbearing;
       if (rbearing)
        *rbearing = gstring->rbearing;
       return gstring->width;
     }
 
       if (rbearing)
        *rbearing = gstring->rbearing;
       return gstring->width;
     }
 
+  if (lbearing)
+    *lbearing = 0;
   if (rbearing)
     *rbearing = 0;
   for (g = MGLYPH (1), width = 0; g->type != GLYPH_ANCHOR; g++)
   if (rbearing)
     *rbearing = 0;
   for (g = MGLYPH (1), width = 0; g->type != GLYPH_ANCHOR; g++)
-    if (g->pos >= from && g->pos < to)
+    if (g->g.from >= from && g->g.from < to)
       {
       {
-       if (rbearing && width + g->rbearing > *rbearing)
-         *rbearing = width + g->rbearing;
-       width += g->width;
+       if (lbearing && width + g->g.lbearing < *lbearing)
+         *lbearing = width + g->g.lbearing;
+       if (rbearing && width + g->g.rbearing > *rbearing)
+         *rbearing = width + g->g.rbearing;
+       width += g->g.xadv;
       }
   return width;
 }
       }
   return width;
 }
@@ -1336,8 +1309,10 @@ render_glyph_string (MFrame *frame, MDrawWindow win, int x, int y,
   int from_idx, to_idx;
   int to_x;
 
   int from_idx, to_idx;
   int to_x;
 
+  if (from == to)
+    return;
   if (control->orientation_reversed)
   if (control->orientation_reversed)
-    x -= gstring->indent + gstring_width (gstring, from, to, NULL);
+    x -= gstring->indent + gstring_width (gstring, from, to, NULL, NULL);
   else
     x += gstring->indent;
 
   else
     x += gstring->indent;
 
@@ -1405,7 +1380,33 @@ alloc_gstring (MFrame *frame, MText *mt, int pos, MDrawControl *control,
 
   if (pos == mt->nchars)
     {
 
   if (pos == mt->nchars)
     {
+      MGlyph *g;
+
       gstring = &scratch_gstring;
       gstring = &scratch_gstring;
+      if (gstring->size == 0)
+       {
+         MGlyph g_tmp;
+
+         INIT_GLYPH (g_tmp);
+         g_tmp.type = GLYPH_ANCHOR;
+         APPEND_GLYPH (gstring, g_tmp);
+         APPEND_GLYPH (gstring, g_tmp);
+         APPEND_GLYPH (gstring, g_tmp);
+         gstring->glyphs[1].type = GLYPH_SPACE;
+         gstring->glyphs[1].g.c = '\n';
+         gstring->glyphs[1].g.code = '\n';
+       }
+      gstring->from = pos;
+      g = MGLYPH (0);
+      g->rface = frame->rface;
+      g->g.from = g->g.to = pos;
+      g++;
+      g->rface = frame->rface;
+      g->g.from = pos++, g->g.to = pos;
+      g++;
+      g->rface = frame->rface;
+      g->g.from = g->g.to = pos;
+      gstring->to = pos;
     }
   else
     {
     }
   else
     {
@@ -1417,7 +1418,6 @@ alloc_gstring (MFrame *frame, MText *mt, int pos, MDrawControl *control,
   gstring->frame = frame;
   gstring->tick = frame->tick;
   gstring->top = gstring;
   gstring->frame = frame;
   gstring->tick = frame->tick;
   gstring->top = gstring;
-  gstring->mt = mt;
   gstring->control = *control;
   gstring->indent = gstring->width_limit = 0;
   if (control->format)
   gstring->control = *control;
   gstring->indent = gstring->width_limit = 0;
   if (control->format)
@@ -1428,6 +1428,9 @@ alloc_gstring (MFrame *frame, MText *mt, int pos, MDrawControl *control,
   return gstring;
 }
 
   return gstring;
 }
 
+static MGlyph *find_glyph_in_gstring (MGlyphString *gstring, int pos,
+                                     int forwardp);
+
 /* Truncate the line width of GSTRING to GSTRING->width_limit.  */
 
 static void
 /* Truncate the line width of GSTRING to GSTRING->width_limit.  */
 
 static void
@@ -1440,13 +1443,13 @@ truncate_gstring (MFrame *frame, MText *mt, MGlyphString *gstring)
   int pos;
 
   /* Setup the array POS_WIDTH so that POS_WIDTH[I - GSTRING->from] is
   int pos;
 
   /* Setup the array POS_WIDTH so that POS_WIDTH[I - GSTRING->from] is
-     a width of glyphs for the character at I of GSTRING->mt.  If I is
-     not a beginning of a grapheme cluster, the corresponding element
-     is 0.  */
+     a width of glyphs for the character at I of MT.  If I is not a
+     beginning of a grapheme cluster, the corresponding element is
+     0.  */
   MTABLE_ALLOCA (pos_width, gstring->to - gstring->from, MERROR_DRAW);
   memset (pos_width, 0, sizeof (int) * (gstring->to - gstring->from));
   for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++)
   MTABLE_ALLOCA (pos_width, gstring->to - gstring->from, MERROR_DRAW);
   memset (pos_width, 0, sizeof (int) * (gstring->to - gstring->from));
   for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++)
-    pos_width[g->pos - gstring->from] += g->width;
+    pos_width[g->g.from - gstring->from] += g->g.xadv;
   for (i = 0, width = 0; i < gstring->to - gstring->from; i++)
     {
       if (pos_width[i] > 0)
   for (i = 0, width = 0; i < gstring->to - gstring->from; i++)
     {
       if (pos_width[i] > 0)
@@ -1460,13 +1463,27 @@ truncate_gstring (MFrame *frame, MText *mt, MGlyphString *gstring)
   pos = gstring->from + i;
   if (gstring->control.line_break)
     {
   pos = gstring->from + i;
   if (gstring->control.line_break)
     {
-      pos = (*gstring->control.line_break) (gstring->mt, gstring->from + i,
-                                           gstring->from, gstring->to, 0, 0);
-      if (pos <= gstring->from || pos >= gstring->to)
-       return;
+      pos = (*gstring->control.line_break) (mt, gstring->from + i,
+                                           gstring->from, gstring->from + i,
+                                           0, 0);
+      if (pos <= gstring->from)
+       {
+         g = find_glyph_in_gstring (gstring, gstring->from, 1);
+         pos = g->g.to;
+       }
+      else if (pos >= gstring->to)
+       pos = gstring->to;
+    }
+  else if (i == 0)
+    {
+      g = find_glyph_in_gstring (gstring, gstring->from, 1);
+      pos = g->g.to;
+    }
+  if (pos < gstring->to)
+    {
+      compose_glyph_string (frame, mt, gstring->from, pos, gstring);
+      layout_glyph_string (frame, gstring);
     }
     }
-  compose_glyph_string (frame, mt, gstring->from, pos, gstring);
-  layout_glyph_string (frame, gstring);
 }
 
 
 }
 
 
@@ -1497,7 +1514,10 @@ get_gstring (MFrame *frame, MText *mt, int pos, int to, MDrawControl *control)
              || gstring->tick != frame->tick
              || memcmp (control, &gstring->control,
                         (char *) (&control->with_cursor)
              || gstring->tick != frame->tick
              || memcmp (control, &gstring->control,
                         (char *) (&control->with_cursor)
-                        - (char *) (control)))
+                        - (char *) (control))
+             || control->cursor_pos != gstring->control.cursor_pos
+             || control->cursor_width != gstring->control.cursor_width
+             || control->cursor_bidi != gstring->control.cursor_bidi)
            {
              mtext_detach_property (prop);
              gstring = NULL;
            {
              mtext_detach_property (prop);
              gstring = NULL;
@@ -1527,8 +1547,8 @@ get_gstring (MFrame *frame, MText *mt, int pos, int to, MDrawControl *control)
            gst->to += offset;
            for (i = 0; i < gst->used; i++)
              {
            gst->to += offset;
            for (i = 0; i < gst->used; i++)
              {
-               gst->glyphs[i].pos += offset;
-               gst->glyphs[i].to += offset;
+               gst->glyphs[i].g.from += offset;
+               gst->glyphs[i].g.to += offset;
              }
          }
       M17N_OBJECT_REF (gstring);
              }
          }
       M17N_OBJECT_REF (gstring);
@@ -1538,26 +1558,23 @@ get_gstring (MFrame *frame, MText *mt, int pos, int to, MDrawControl *control)
       int beg, end;
       int line = 0, y = 0;
 
       int beg, end;
       int line = 0, y = 0;
 
-      if (control->two_dimensional)
+      if (pos < mtext_nchars (mt))
        {
          beg = mtext_character (mt, pos, 0, '\n');
          if (beg < 0)
            beg = 0;
          else
            beg++;
        {
          beg = mtext_character (mt, pos, 0, '\n');
          if (beg < 0)
            beg = 0;
          else
            beg++;
-         end = mtext_nchars (mt) + (control->cursor_width != 0);
        }
       else
        }
       else
-       {
-         beg = pos;
-         end = to;
-       }
+       beg = pos;
+      end = mtext_nchars (mt) + (control->cursor_width != 0);
       gstring = alloc_gstring (frame, mt, beg, control, line, y);
       gstring = alloc_gstring (frame, mt, beg, control, line, y);
-      compose_glyph_string (frame, mt, beg, end, gstring);
+      if (beg < mtext_nchars (mt))
+       compose_glyph_string (frame, mt, beg, end, gstring);
       layout_glyph_string (frame, gstring);
       end = gstring->to;
       layout_glyph_string (frame, gstring);
       end = gstring->to;
-      if (control->two_dimensional
-         && gstring->width_limit
+      if (gstring->width_limit
          && gstring->width > gstring->width_limit)
        {
          MGlyphString *gst = gstring;
          && gstring->width > gstring->width_limit)
        {
          MGlyphString *gst = gstring;
@@ -1652,13 +1669,13 @@ find_glyph_in_gstring (MGlyphString *gstring, int pos, int forwardp)
   if (forwardp)
     {
       for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++)
   if (forwardp)
     {
       for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++)
-       if (g->pos <= pos && g->to > pos)
+       if (g->g.from <= pos && g->g.to > pos)
          break;
     }
   else
     {
       for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--)
          break;
     }
   else
     {
       for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--)
-       if (g->pos <= pos && g->to > pos)
+       if (g->g.from <= pos && g->g.to > pos)
          break;
     }
   return g;
          break;
     }
   return g;
@@ -1668,62 +1685,43 @@ find_glyph_in_gstring (MGlyphString *gstring, int pos, int forwardp)
 /* for debugging... */
 char work[16];
 
 /* for debugging... */
 char work[16];
 
-char *
-dump_combining_code (int code)
-{
-  char *vallign = "tcbB";
-  char *hallign = "lcr";
-  char *p;
-  int off_x, off_y;
-
-  if (! code)
-    return "none";
-  if (COMBINING_BY_CLASS_P (code))
-    code = combining_code_from_class (COMBINING_CODE_CLASS (code));
-  work[0] = vallign[COMBINING_CODE_BASE_Y (code)];
-  work[1] = hallign[COMBINING_CODE_BASE_X (code)];
-  off_y = COMBINING_CODE_OFF_Y (code) - 128;
-  off_x = COMBINING_CODE_OFF_X (code) - 128;
-  if (off_y > 0)
-    sprintf (work + 2, "+%d", off_y);
-  else if (off_y < 0)
-    sprintf (work + 2, "%d", off_y);
-  else if (off_x == 0)
-    sprintf (work + 2, ".");
-  p = work + strlen (work);
-  if (off_x > 0)
-    sprintf (p, ">%d", off_x);
-  else if (off_x < 0)
-    sprintf (p, "<%d", -off_x);
-  p += strlen (p);
-  p[0] = vallign[COMBINING_CODE_ADD_Y (code)];
-  p[1] = hallign[COMBINING_CODE_ADD_X (code)];
-  p[2] = '\0';
-  return work;
-}
-
 void
 void
-dump_gstring (MGlyphString *gstring, int indent)
+dump_gstring (MGlyphString *gstring, int indent, int type)
 {
   char *prefix = (char *) alloca (indent + 1);
 {
   char *prefix = (char *) alloca (indent + 1);
-  MGlyph *g, *last_g = gstring->glyphs + gstring->used;
+  MGlyph *g, *first_g, *last_g;
 
   memset (prefix, 32, indent);
   prefix[indent] = 0;
 
   fprintf (stderr, "(glyph-string");
 
 
   memset (prefix, 32, indent);
   prefix[indent] = 0;
 
   fprintf (stderr, "(glyph-string");
 
-  for (g = MGLYPH (0); g < last_g; g++)
-    fprintf (stderr,
-            "\n%s  (%02d %s pos:%d-%d c:%04X code:%04X face:%x cmb:%s w:%02d bidi:%d)",
-            prefix,
-            g - gstring->glyphs,
-            (g->type == GLYPH_SPACE ? "SPC": g->type == GLYPH_PAD ? "PAD"
-             : g->type == GLYPH_ANCHOR ? "ANC"
-             : g->type == GLYPH_BOX ? "BOX" : "CHR"),
-            g->pos, g->to, g->c, g->code, (unsigned) g->rface,
-            dump_combining_code (g->combining_code),
-            g->width, g->bidi_level);
+  if (type == 0)
+    {
+      first_g = MGLYPH (0);
+      last_g = first_g + gstring->used;
+    }
+  else
+    {
+      first_g = (MGlyph *) ((MFLTGlyphString *) gstring)->glyphs;
+      last_g = first_g + ((MFLTGlyphString *) gstring)->used;
+    }
+
+  for (g = first_g; g < last_g; g++)
+    {
+      fprintf (stderr,
+              "\n%s  (%02d %s pos:%d-%d c:%04X code:%04X face:%x w:%02d bidi:%d",
+              prefix,
+              g - first_g,
+              (g->type == GLYPH_SPACE ? "SPC": g->type == GLYPH_PAD ? "PAD"
+               : g->type == GLYPH_ANCHOR ? "ANC"
+               : g->type == GLYPH_BOX ? "BOX" : "CHR"),
+              g->g.from, g->g.to, g->g.c, g->g.code, (unsigned) g->rface,
+              g->g.xadv, g->bidi_level);
+      if (g->g.xoff || g->g.yoff)
+       fprintf (stderr, " off:%d,%d", g->g.xoff, g->g.yoff);
+      fprintf (stderr, ")");
+    }
   fprintf (stderr, ")");
 }
 \f
   fprintf (stderr, ")");
 }
 \f
@@ -1738,8 +1736,7 @@ mdraw__init ()
   memset (&scratch_gstring, 0, sizeof (scratch_gstring));
   MLIST_INIT1 (&scratch_gstring, glyphs, 3);
 
   memset (&scratch_gstring, 0, sizeof (scratch_gstring));
   MLIST_INIT1 (&scratch_gstring, glyphs, 3);
 
-  Mlatin = msymbol ("latin");
-  Minherited = msymbol ("inherited");
+  Mcommon = msymbol ("common");
 
   McatCc = msymbol ("Cc");
   McatCf = msymbol ("Cf");
 
   McatCc = msymbol ("Cc");
   McatCf = msymbol ("Cf");
@@ -1750,9 +1747,22 @@ mdraw__init ()
   MbidiRLO = msymbol ("RLO");
   MbidiBN = msymbol ("BN");
   MbidiS = msymbol ("S");
   MbidiRLO = msymbol ("RLO");
   MbidiBN = msymbol ("BN");
   MbidiS = msymbol ("S");
+  MbidiNSM = msymbol ("NSM");
 #ifdef HAVE_FRIBIDI
 #ifdef HAVE_FRIBIDI
+#if FRIBIDI_INTERFACE_VERSION < 3
   fribidi_set_mirroring (TRUE);
   fribidi_set_mirroring (TRUE);
+#else
+  fribidi_set_mirroring (1);
 #endif
 #endif
+#endif
+
+  M_break_at_space = msymbol ("bs");
+  M_break_at_word = msymbol ("bw");
+  M_break_at_any = msymbol ("ba");
+  M_kinsoku_bol = msymbol ("kb");
+  M_kinsoku_eol = msymbol ("ke");
+
+  mflt_enable_new_feature = 1;
 
   return 0;
 }
 
   return 0;
 }
@@ -1761,6 +1771,8 @@ void
 mdraw__fini ()
 {
   MLIST_FREE1 (&scratch_gstring, glyphs);
 mdraw__fini ()
 {
   MLIST_FREE1 (&scratch_gstring, glyphs);
+  M17N_OBJECT_UNREF (linebreak_table);
+  linebreak_table = NULL;
 }
 
 /*** @} */
 }
 
 /*** @} */
@@ -1816,7 +1828,7 @@ mdraw__fini ()
         of the script and language.  If no entry is found, proceed to
         the next step.  
 
         of the script and language.  If no entry is found, proceed to
         the next step.  
 
-        If an entry is found, use one of the fonts in the entry that
+         If an entry is found, use one of the fonts in the entry that
         has a glyph for the character and that matches best with the
         face properties.  If no such font exists, proceed to the next
         step.
         has a glyph for the character and that matches best with the
         face properties.  If no such font exists, proceed to the next
         step.
@@ -1846,67 +1858,57 @@ mdraw__fini ()
     @brief ¥¦¥£¥ó¥É¥¦¤Ë M-text ¤òÉÁ²è¤¹¤ë.
 
     ´Ø¿ô mdraw_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤ÎºÂɸ 
     @brief ¥¦¥£¥ó¥É¥¦¤Ë M-text ¤òÉÁ²è¤¹¤ë.
 
     ´Ø¿ô mdraw_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤ÎºÂɸ 
-    ($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥­¥¹¥È¤ò
-    ÉÁ²è¤¹¤ë¡£
+    ($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥­¥¹¥È¤òÉÁ²è¤¹¤ë¡£
 
     ¥Æ¥­¥¹¥È¤Î¸«±É¤¨¡Ê¥Õ¥©¥ó¥È¡¢¥¹¥¿¥¤¥ë¡¢¿§¤Ê¤É¡Ë¤Ï¡¢¥­¡¼¤¬ @c Mface 
 
     ¥Æ¥­¥¹¥È¤Î¸«±É¤¨¡Ê¥Õ¥©¥ó¥È¡¢¥¹¥¿¥¤¥ë¡¢¿§¤Ê¤É¡Ë¤Ï¡¢¥­¡¼¤¬ @c Mface 
-    ¤Ç¤¢¤ë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ÎÃͤˤè¤Ã¤Æ·è¤Þ¤ë¡£M-text ¤Î°ìÉô¤¢¤ë¤¤¤Ï
-    Á´Éô¤Ë¤½¤Î¤è¤¦¤Ê¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬ÉÕ¤¤¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢$FRAME 
-    ¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤¬ÍѤ¤¤é¤ì¤ë¡£
+    ¤Ç¤¢¤ë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ÎÃͤˤè¤Ã¤Æ·è¤Þ¤ë¡£M-text 
+    ¤Î°ìÉô¤¢¤ë¤¤¤ÏÁ´Éô¤Ë¤½¤Î¤è¤¦¤Ê¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬ÉÕ¤¤¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢$FRAME 
+    ¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤òÂå¤ï¤ê¤ËÍѤ¤¤ë¡£
 
 
-    M-text ¤Î³Æʸ»ú¤òɽ¼¨¤¹¤ë¥Õ¥©¥ó¥È¤Ï¡¢¥Õ¥§¡¼¥¹¤Î fontset ¥×¥í¥Ñ¥Æ¥£
-    ¤ÎÃͤ«¤é°Ê²¼¤Î¥¢¥ë¥´¥ê¥º¥à¤ÇÁª¤Ð¤ì¤ë¡£
+    M-text ¤Î³Æʸ»ú¤òɽ¼¨¤¹¤ë¥Õ¥©¥ó¥È¤Ï¡¢¥Õ¥§¡¼¥¹¤Î fontset 
+    ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤΤ¦¤Á¤«¤é¡¢°Ê²¼¤Î¥¢¥ë¥´¥ê¥º¥à¤ÇÁª¤Ð¤ì¤ë¡£
 
     <ol>
 
 
     <ol>
 
-    <li> ¤½¤Îʸ»ú¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ @c Mcharset ¤Ç¤¢¤ë
-         ¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£¤³¤ÎÃͤÏʸ»ú¥»¥Ã¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« #Mnil 
-         ¤Î¤É¤Á¤é¤«¤Ç¤¢¤ë¡£#Mnil ¤Ê¤é¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£¤½¤¦¤Ç¤Ê
-         ¤±¤ì¤Ð¡¢¤½¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤«¤é¤½¤Îʸ»ú¥»¥Ã
-         ¥ÈÍѤΤâ¤Î¤òõ¤¹¡£¥Õ¥©¥ó¥È¤¬¤ß¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë
-         ¿Ê¤à¡£
+    <li> ¤½¤Îʸ»ú¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ @c Mcharset
+         ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£¤³¤ÎÃͤÏʸ»ú¥»¥Ã¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« #Mnil 
+         ¤Î¤É¤Á¤é¤«¤Ç¤¢¤ë¡£#Mnil ¤Ê¤é¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
+        ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢fontset 
+        ¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤Ë¤½¤Îʸ»ú¥»¥Ã¥ÈÍѤΥե©¥ó¥È¤¬¤¢¤ë¤«¤É¤¦¤«¤òÄ´¤Ù¤ë¡£
+        Ìµ¤±¤ì¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
          
          
-         ¤½¤Îʸ»ú¥»¥Ã¥ÈÍѤΥե©¥ó¥È¤¬¤ß¤Ä¤«¤ì¤Ð¡¢¤½¤ì¤é¤Î¤¦¤Á¸½ºß¤Îʸ
-        »úÍѤΥ°¥ê¥Õ¤ò»ý¤Á¡¢¥Õ¥§¡¼¥¹¤Î³Æ¥×¥í¥Ñ¥Æ¥£¤ËºÇ¤â¤è¤¯¹çÃפ·¤Æ
-        ¤¤¤ë¤â¤Î¤ò»È¤¦¡£¤½¤Î¤è¤¦¤Ê¥Õ¥©¥ó¥È¤¬Ìµ¤±¤ì¤Ð¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê
-        ¤à¡£
+         ¤½¤Îʸ»ú¥»¥Ã¥ÈÍѤΥե©¥ó¥È¤¬¤ß¤Ä¤«¤ì¤Ð¡¢¤½¤ì¤é¤Î¤¦¤Á¸½ºß¤Îʸ»úÍѤΥ°¥ê¥Õ¤ò»ý¤Á¡¢¥Õ¥§¡¼¥¹¤Î³Æ¥×¥í¥Ñ¥Æ¥£¤ËºÇ¤â¤è¤¯¹çÃפ¹¤ë¤â¤Î¤ò»È¤¦¡£
+        ¤½¤Î¤è¤¦¤Ê¥Õ¥©¥ó¥È¤¬Ìµ¤±¤ì¤Ð¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
 
 
-    <li> ¤½¤Îʸ»ú¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£ "script" ¡Ê¥¹¥¯¥ê¥×¥È¡Ë¤òÄ´¤Ù¤ë¡£·Ñ
-         ¾µ¤µ¤ì¤Æ¤¤¤ë¤Ê¤é¤Ð¤½¤ì°ÊÁ°¤Îʸ»ú¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£ "script" ¤ò
-         Ä´¤Ù¤ë¡£Á°¤Îʸ»ú¤¬¤Ê¤«¤Ã¤¿¤ê¡¢¤½¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ã¤Æ¤¤¤Ê
-         ¤«¤Ã¤¿¾ì¹ç¤Ë¤Ï¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
+    <li> ¤½¤Îʸ»ú¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£ "script" ¡Ê¥¹¥¯¥ê¥×¥È¡Ë¤òÄ´¤Ù¤ë¡£
+         ¤½¤Î¥×¥í¥Ñ¥Æ¥£¤¬·Ñ¾µ¤µ¤ì¤Æ¤¤¤ë¤Ê¤é¤Ð¤½¤ì°ÊÁ°¤Îʸ»ú¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£ "script" 
+        ¤òÄ´¤Ù¤ë¡£Á°¤Îʸ»ú¤¬¤Ê¤«¤Ã¤¿¤ê¡¢¤½¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ã¤Æ¤¤¤Ê¤«¤Ã¤¿¾ì¹ç¤Ë¤Ï¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
 
 
-         ¤½¤Îʸ»ú¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ @c Mlanguage ¤Ç¤¢
-         ¤ë¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£¤³¤ÎÃͤϸÀ¸ì¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« @c Mnil ¤Î
-         ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
+         ¤½¤Îʸ»ú¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ @c Mlanguage ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£
+        ¤³¤ÎÃͤϸÀ¸ì¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« @c Mnil ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
 
 
-        ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤½¤Î¸À¸ì¤È¥¹¥¯¥ê¥×¥È¤ÎÁȤ߹ç¤ï¤»ÍѤΥե©¥ó¥È
-        ¥»¥Ã¥È¤ò¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤«¤éõ¤¹¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¼¡¤Î¥¹¥Æ¥Ã
-        ¥×¤Ë¿Ê¤à¡£
+        ¤½¤Î¸À¸ì¤È¥¹¥¯¥ê¥×¥È¤ÎÁȤ߹ç¤ï¤»¤¬ fontset
+        ¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤Ë¤¢¤ë¤«¤É¤¦¤«¤òÄ´¤Ù¤ë¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
 
 
-        ¤½¤Î¤è¤¦¤Êʸ»ú¥»¥Ã¥ÈÍѤΥե©¥ó¥È¤¬¤ß¤Ä¤«¤ì¤Ð¡¢¤½¤ì¤é¤Î¤¦¤Á¸½
-        ºß¤Îʸ»úÍѤΥ°¥ê¥Õ¤ò»ý¤Á¡¢¥Õ¥§¡¼¥¹¤Î³Æ¥×¥í¥Ñ¥Æ¥£¤ËºÇ¤â¤è¤¯¹ç
-        Ãפ·¤Æ¤¤¤ë¤â¤Î¤ò»È¤¦¡£¤½¤Î¤è¤¦¤Ê¥Õ¥©¥ó¥È¤¬Ìµ¤±¤ì¤Ð¼¡¤Î¥¹¥Æ¥Ã
-        ¥×¤Ë¿Ê¤à¡£
+        ¸«¤Ä¤«¤Ã¤¿¤Ð¤¢¤¤¤Ë¤Ï¡¢¤½¤ì¤é¤Î¥Õ¥©¥ó¥È¤Î¤¦¤Á¸½ºß¤Îʸ»úÍѤΥ°¥ê¥Õ¤ò»ý¤Á¡¢¥Õ¥§¡¼¥¹¤Î³Æ¥×¥í¥Ñ¥Æ¥£¤ËºÇ¤â¤è¤¯¹çÃפ·¤Æ¤¤¤ë¤â¤Î¤ò»È¤¦¡£
+        ¤½¤Î¤è¤¦¤Ê¥Õ¥©¥ó¥È¤¬Ìµ¤±¤ì¤Ð¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£
 
 
-    <li> ¤½¤Îʸ»ú¤Î¥°¥ê¥Õ¤ò»ý¤Ä¥Õ¥©¥ó¥È¤ò¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Îfall-back¥Æ¡¼
-         ¥Ö¥ë¤«¤éõ¤¹¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤ì¤Ð¤½¤ì¤ò»È¤¦¡£
+    <li> ¤½¤Îʸ»ú¤Î¥°¥ê¥Õ¤ò»ý¤Ä¥Õ¥©¥ó¥È¤ò¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î fall-back 
+         ¥Æ¡¼¥Ö¥ë¤«¤éõ¤¹¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤ì¤Ð¤½¤ì¤ò»È¤¦¡£
 
     </ol>
 
 
     </ol>
 
-    °Ê¾å¤Î¥¢¥ë¥´¥ê¥º¥à¤Ç¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¤½¤Îʸ»ú
-    ¤È¤·¤Æ¶õ¤Î»Í³Ñ·Á¤òɽ¼¨¤¹¤ë¡£
+    °Ê¾å¤Î¥¢¥ë¥´¥ê¥º¥à¤Ç¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¤½¤Îʸ»ú¤È¤·¤Æ¶õ¤Î»Í³Ñ·Á¤òɽ¼¨¤¹¤ë¡£
 
 
-    ¤³¤Î´Ø¿ô¤¬ÉÁ²è¤¹¤ë¤Î¤Ï¥°¥ê¥Õ¤ÎÁ°·Ê¤À¤±¤Ç¤¢¤ë¡£ÇØ·Ê¿§¤ò»ØÄꤹ¤ë¤Ë¤Ï¡¢
-    ´Ø¿ô mdraw_image_text () ¤«´Ø¿ô mdraw_text_with_control () ¤ò»È¤¦
-    ¤³¤È¡£
+    ¤³¤Î´Ø¿ô¤¬ÉÁ²è¤¹¤ë¤Î¤Ï¥°¥ê¥Õ¤ÎÁ°·Ê¤À¤±¤Ç¤¢¤ë¡£ÇØ·Ê¿§¤ò»ØÄꤹ¤ë¤Ë¤Ï¡¢´Ø¿ô
+    mdraw_image_text () ¤«´Ø¿ô mdraw_text_with_control () ¤ò»È¤¦¤³¤È¡£
 
     ¤³¤Î´Ø¿ô¤Ï¡¢X ¥¦¥£¥ó¥É¥¦¤Ë¤ª¤±¤ë´Ø¿ô <tt>XDrawString ()</tt>,
     <tt>XmbDrawString ()</tt>, <tt>XwcDrawString ()</tt> ¤ËÁêÅö¤¹¤ë¡£
 
     @return
 
     ¤³¤Î´Ø¿ô¤Ï¡¢X ¥¦¥£¥ó¥É¥¦¤Ë¤ª¤±¤ë´Ø¿ô <tt>XDrawString ()</tt>,
     <tt>XmbDrawString ()</tt>, <tt>XwcDrawString ()</tt> ¤ËÁêÅö¤¹¤ë¡£
 
     @return
-    ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_text () ¤Ï 0 ÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì
-    ¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
+    ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_text () ¤Ï 0 ÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï
+    -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
 
     @latexonly \IPAlabel{mdraw_text} @endlatexonly  */
 
 
     @latexonly \IPAlabel{mdraw_text} @endlatexonly  */
 
@@ -1955,21 +1957,20 @@ mdraw_text (MFrame *frame, MDrawWindow win, int x, int y,
 /***ja
     @brief ¥Ç¥£¥¹¥×¥ì¥¤¤ËM-text ¤ò²èÁü¤È¤·¤ÆÉÁ¤¯.
   
 /***ja
     @brief ¥Ç¥£¥¹¥×¥ì¥¤¤ËM-text ¤ò²èÁü¤È¤·¤ÆÉÁ¤¯.
   
-    ´Ø¿ô mdraw_image_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤Î
-    ºÂɸ ($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥­¥¹¥È¤ò²è
-    Áü¤È¤·¤ÆÉÁ¤¯¡£
+    ´Ø¿ô mdraw_image_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN 
+    ¤ÎºÂɸ ($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO 
+    ¤Þ¤Ç¤Î¥Æ¥­¥¹¥È¤ò²èÁü¤È¤·¤ÆÉÁ¤¯¡£
 
 
-    ¥Æ¥­¥¹¥È¤ÎÉÁ²èÊýË¡¤Ï mdraw_text () ¤È¤Û¤ÜƱ¤¸¤Ç¤¢¤ë¤¬¡¢¤³¤Î´Ø¿ô¤Ç
-    ¤Ï¥Õ¥§¡¼¥¹¤Ç»ØÄꤵ¤ì¤¿¿§¤ÇÇطʤâÉÁ¤¯ÅÀ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¡£
+    ¥Æ¥­¥¹¥È¤ÎÉÁ²èÊýË¡¤Ï mdraw_text ()
+    ¤È¤Û¤ÜƱ¤¸¤Ç¤¢¤ë¤¬¡¢¤³¤Î´Ø¿ô¤Ç¤Ï¥Õ¥§¡¼¥¹¤Ç»ØÄꤵ¤ì¤¿¿§¤ÇÇطʤâÉÁ¤¯ÅÀ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¡£
 
     ¤³¤Î´Ø¿ô¤Ï¡¢X ¥¦¥£¥ó¥É¥¦¤Ë¤ª¤±¤ë <tt>XDrawImageString ()</tt>,
 
     ¤³¤Î´Ø¿ô¤Ï¡¢X ¥¦¥£¥ó¥É¥¦¤Ë¤ª¤±¤ë <tt>XDrawImageString ()</tt>,
-    <tt>XmbDrawImageString ()</tt>, <tt>XwcDrawImageString ()</tt> ¤Ë
-    ÁêÅö¤¹¤ë¡£
+    <tt>XmbDrawImageString ()</tt>, <tt>XwcDrawImageString ()</tt> 
+    ¤ËÁêÅö¤¹¤ë¡£
 
     @return
 
     @return
-    ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_image_text () ¤Ï 0 ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð
-    ¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #m_errro ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ
-    ¤ë¡£
+    ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_image_text () ¤Ï 0 
+    ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
 
     @latexonly \IPAlabel{mdraw_image_text} @endlatexonly   */
 
 
     @latexonly \IPAlabel{mdraw_image_text} @endlatexonly   */
 
@@ -2005,26 +2006,25 @@ mdraw_image_text (MFrame *frame, MDrawWindow win, int x, int y,
     this function also follows what specified in the drawing control
     object $CONTROL.
 
     this function also follows what specified in the drawing control
     object $CONTROL.
 
-    For instance, if <two_dimensional> of $CONTROL is nonzero, this
+    For instance, if \<two_dimensional\> of $CONTROL is nonzero, this
     function draw an M-text 2-dimensionally, i.e., newlines in M-text
     breaks lines and the following characters are drawn in the next
     line.  See the documentation of the structure @ MDrawControl for
     more detail.  */
 
 /***ja
     function draw an M-text 2-dimensionally, i.e., newlines in M-text
     breaks lines and the following characters are drawn in the next
     line.  See the documentation of the structure @ MDrawControl for
     more detail.  */
 
 /***ja
-    @brief ¥Ç¥£¥¹¥×¥ì¥¤¤ËM-text ¤òÉÁ¤¯¡Ê¾ÜºÙ¤ÊÀ©¸æ¤Ä¤­¡Ë.
+    @brief ¥Ç¥£¥¹¥×¥ì¥¤¤ËM-text ¤ò¾ÜºÙ¤ÊÀ©¸æ¤Ä¤­¤ÇÉÁ¤¯.
 
     ´Ø¿ô mdraw_text_with_control () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ 
     $WIN ¤ÎºÂɸ ($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥­¥¹
     ¥È¤òÉÁ¤¯¡£
 
 
     ´Ø¿ô mdraw_text_with_control () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ 
     $WIN ¤ÎºÂɸ ($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥­¥¹
     ¥È¤òÉÁ¤¯¡£
 
-    ¥Æ¥­¥¹¥È¤ÎÉÁ²èÊýË¡¤Ï mdraw_text () ¤È¤Û¤ÜƱ¤¸¤Ç¤¢¤ë¤¬¡¢¤³¤Î´Ø¿ô¤Ï
-    ÉÁ²èÀ©¸æÍѤΥª¥Ö¥¸¥§¥¯¥È $CONTROL ¤Ç¤Î»Ø¼¨¤Ë¤â½¾¤¦ÅÀ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¡£
+    ¥Æ¥­¥¹¥È¤ÎÉÁ²èÊýË¡¤Ï mdraw_text () ¤È¤Û¤ÜƱ¤¸¤Ç¤¢¤ë¤¬¡¢¤³¤Î´Ø¿ô¤ÏÉÁ²èÀ©¸æÍѤΥª¥Ö¥¸¥§¥¯¥È
+    $CONTROL ¤Î»Ø¼¨¤Ë¤â½¾¤¦ÅÀ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¡£
 
 
-    ¤¿¤È¤¨¤Ð $CONTROL ¤Î <two_dimensional> ¤¬¥¼¥í¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô
-    ¤ÏM-text ¤ò2¼¡¸µÅª¤ËÉÁ¤¯¡£¤¹¤Ê¤ï¤Á M-text Ãæ¤Î²þ¹Ô¤Ç¹Ô¤ò²þ¤á¡¢Â³¤¯
-    Ê¸»ú¤Ï¼¡¤Î¹Ô¤ËÉÁ¤¯¡£¾ÜºÙ¤Ï¹½Â¤ÂΠ@ MDrawControl ¤ÎÀâÌÀ¤ò»²¾È¤¹¤ë¤³
-    ¤È¡£*/
+    ¤¿¤È¤¨¤Ð $CONTROL ¤Î \<two_dimensional\> ¤¬¥¼¥í¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 
+    M-text ¤ò2¼¡¸µÅª¤ËÉÁ¤¯¡£¤¹¤Ê¤ï¤Á M-text Ãæ¤Î²þ¹Ô¤Ç¹Ô¤ò²þ¤á¡¢Â³¤¯Ê¸»ú¤Ï¼¡¤Î¹Ô¤ËÉÁ¤¯¡£¾ÜºÙ¤Ï¹½Â¤ÂÎ
+    @ MDrawControl ¤ÎÀâÌÀ¤ò»²¾È¤¹¤ë¤³¤È¡£*/
 
 int
 mdraw_text_with_control (MFrame *frame, MDrawWindow win, int x, int y,
 
 int
 mdraw_text_with_control (MFrame *frame, MDrawWindow win, int x, int y,
@@ -2051,13 +2051,13 @@ mdraw_text_with_control (MFrame *frame, MDrawWindow win, int x, int y,
     surrounding box, the box is included in the bounding box.
 
     If $OVERALL_LOGICAL_RETURN is not @c NULL, this function also
     surrounding box, the box is included in the bounding box.
 
     If $OVERALL_LOGICAL_RETURN is not @c NULL, this function also
-    computes the bounding box that provides mininum spacing to other
+    computes the bounding box that provides minimum spacing to other
     graphical features (such as surrounding box) for the M-text, and
     stores the results in the members of the structure pointed to by
     $OVERALL_LOGICAL_RETURN.
 
     If $OVERALL_LINE_RETURN is not @c NULL, this function also
     graphical features (such as surrounding box) for the M-text, and
     stores the results in the members of the structure pointed to by
     $OVERALL_LOGICAL_RETURN.
 
     If $OVERALL_LINE_RETURN is not @c NULL, this function also
-    computes the bounding box that provides mininum spacing to the
+    computes the bounding box that provides minimum spacing to the
     other M-text drawn, and stores the results in the members of the
     structure pointed to by $OVERALL_LINE_RETURN.  This is a union of
     $OVERALL_INK_RETURN and $OVERALL_LOGICAL_RETURN if the members
     other M-text drawn, and stores the results in the members of the
     structure pointed to by $OVERALL_LINE_RETURN.  This is a union of
     $OVERALL_INK_RETURN and $OVERALL_LOGICAL_RETURN if the members
@@ -2075,31 +2075,31 @@ mdraw_text_with_control (MFrame *frame, MDrawWindow win, int x, int y,
 /***ja 
     @brief ¥Æ¥­¥¹¥È¤ÎÉý¡Ê¥Ô¥¯¥»¥ëñ°Ì¡Ë¤ò·×»»¤¹¤ë.
 
 /***ja 
     @brief ¥Æ¥­¥¹¥È¤ÎÉý¡Ê¥Ô¥¯¥»¥ëñ°Ì¡Ë¤ò·×»»¤¹¤ë.
 
-    ´Ø¿ô mdraw_text_extents () ¤Ï¡¢´Ø¿ô mdraw_text_with_control () ¤¬
-    ÉÁ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤¤Æ M-text $MT ¤Î $FROM ¤«¤é $TO 
+    ´Ø¿ô mdraw_text_extents () ¤Ï¡¢´Ø¿ô mdraw_text_with_control () 
+    ¤¬ÉÁ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤¤Æ M-text $MT ¤Î $FROM ¤«¤é $TO 
     ¤Þ¤Ç¤ò¥Õ¥ì¡¼¥à $FRAME ¤Ëɽ¼¨¤¹¤ëºÝ¤ËɬÍפȤʤëÉý¤òÊÖ¤¹¡£
 
     ¤Þ¤Ç¤ò¥Õ¥ì¡¼¥à $FRAME ¤Ëɽ¼¨¤¹¤ëºÝ¤ËɬÍפȤʤëÉý¤òÊÖ¤¹¡£
 
-    $OVERALL_INK_RETURN ¤¬ @c NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï M-text ¤Îʸ
-    »ú¤Î¥¤¥ó¥¯¤Î¥Ð¥¦¥ó¥Ç¥£¥ó¥°¥Ü¥Ã¥¯¥¹¤â·×»»¤·¡¢$OVERALL_INK_RETURN ¤¬
-    »Ø¤¹¹½Â¤ÂΤΥá¥ó¥Ð¤Ë¤½¤Î·ë²Ì¤òÀßÄꤹ¤ë¡£M-text ¤Ë°Ï¤ßÏÈ(surrounding box)
+    $OVERALL_INK_RETURN ¤¬ @c NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï M-text 
+    ¤Îʸ»ú¤Î¥¤¥ó¥¯¤Î¥Ð¥¦¥ó¥Ç¥£¥ó¥°¥Ü¥Ã¥¯¥¹¤â·×»»¤·¡¢$OVERALL_INK_RETURN 
+    ¤¬»Ø¤¹¹½Â¤ÂΤΥá¥ó¥Ð¤Ë¤½¤Î·ë²Ì¤òÀßÄꤹ¤ë¡£M-text ¤Ë°Ï¤ßÏÈ (surrounding box)
     ¤ò»ØÄꤹ¤ë¥Õ¥§¡¼¥¹¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤â¥Ð¥¦¥ó¥Ç¥£¥ó¥°¥Ü¥Ã¥¯¥¹¤Ë´Þ¤à¡£
 
     $OVERALL_LOGICAL_RETURN ¤¬ @c NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï M-text 
     ¤ò»ØÄꤹ¤ë¥Õ¥§¡¼¥¹¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤â¥Ð¥¦¥ó¥Ç¥£¥ó¥°¥Ü¥Ã¥¯¥¹¤Ë´Þ¤à¡£
 
     $OVERALL_LOGICAL_RETURN ¤¬ @c NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï M-text 
-    ¤È¾¤Î graphical feature ¡Ê°Ï¤ßÏȤʤɡˤȤδ֤κǾ®¤Î¥¹¥Ú¡¼¥¹¤ò¼¨
-    ¤¹¥Ð¥¦¥ó¥Ç¥£¥ó¥°¥Ü¥Ã¥¯¥¹¤â·×»»¤·¡¢$OVERALL_LOGICAL_RETURN ¤¬»Ø¤¹¹½
-    Â¤ÂΤΥá¥ó¥Ð¤Ë¤½¤Î·ë²Ì¤òÀßÄꤹ¤ë¡£
+    ¤È¾¤Î graphical feature ¡Ê°Ï¤ßÏȤʤɡË
+    ¤È¤Î´Ö¤ÎºÇ¾®¤Î¥¹¥Ú¡¼¥¹¤ò¼¨¤¹¥Ð¥¦¥ó¥Ç¥£¥ó¥°¥Ü¥Ã¥¯¥¹¤â·×»»¤·¡¢$OVERALL_LOGICAL_RETURN
+    ¤¬»Ø¤¹¹½Â¤ÂΤΥá¥ó¥Ð¤Ë¤½¤Î·ë²Ì¤òÀßÄꤹ¤ë¡£
 
     $OVERALL_LINE_RETURN ¤¬ @c NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¾¤Î M-text 
     ¤È¤Î´Ö¤ÎºÇ¾®¤Î¥¹¥Ú¡¼¥¹¤ò¼¨¤¹¥Ð¥¦¥ó¥Ç¥£¥ó¥°¥Ü¥Ã¥¯¥¹¤â·×»»¤·¡¢
 
     $OVERALL_LINE_RETURN ¤¬ @c NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¾¤Î M-text 
     ¤È¤Î´Ö¤ÎºÇ¾®¤Î¥¹¥Ú¡¼¥¹¤ò¼¨¤¹¥Ð¥¦¥ó¥Ç¥£¥ó¥°¥Ü¥Ã¥¯¥¹¤â·×»»¤·¡¢
-    $OVERALL_LINE_RETURN ¤¬»Ø¤¹¹½Â¤ÂΤΥá¥ó¥Ð¤Ë¤½¤Î·ë²Ì¤òÀßÄꤹ¤ë¡£¥ª
-    ¥Ö¥¸¥§¥¯¥È $CONTROL ¤Î¥á¥ó¥Ð min_line_ascent, min_line_descent,
+    $OVERALL_LINE_RETURN ¤¬»Ø¤¹¹½Â¤ÂΤΥá¥ó¥Ð¤Ë¤½¤Î·ë²Ì¤òÀßÄꤹ¤ë¡£¥ª¥Ö¥¸¥§¥¯¥È
+    $CONTROL ¤Î¥á¥ó¥Ð min_line_ascent, min_line_descent,
     max_line_ascent, max_line_descent ¤¬¤¹¤Ù¤Æ0¤Î»þ¤Ë¤Ï¡¢¤³¤ÎÃͤϠ
     $OVERALL_INK_RETURN ¤È$OVERALL_LOGICAL_RETURN ¤ÎϤȤʤ롣
 
     max_line_ascent, max_line_descent ¤¬¤¹¤Ù¤Æ0¤Î»þ¤Ë¤Ï¡¢¤³¤ÎÃͤϠ
     $OVERALL_INK_RETURN ¤È$OVERALL_LOGICAL_RETURN ¤ÎϤȤʤ롣
 
-    @return ¤³¤Î´Ø¿ô¤Ïɽ¼¨¤ËɬÍפʥƥ­¥¹¥È¤ÎÉý¤ò¥Ô¥¯¥»¥ëñ°Ì¤ÇÊÖ¤¹¡£
-    $CONTROL->two_dimensional ¤¬0¤Ç¤Ê¤¯¡¢¥Æ¥­¥¹¥È¤¬Ê£¿ô¤Î¹Ô¤ËÅϤäÆÉÁ
-    ¤«¤ì¤ë¾ì¹ç¤Ë¤Ï¡¢ºÇÂç¤ÎÉý¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬À¸¤¸¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°
-    ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
+    @return 
+    ¤³¤Î´Ø¿ô¤Ïɽ¼¨¤ËɬÍפʥƥ­¥¹¥È¤ÎÉý¤ò¥Ô¥¯¥»¥ëñ°Ì¤ÇÊÖ¤¹¡£$CONTROL->two_dimensional
+    ¤¬0¤Ç¤Ê¤¯¡¢¥Æ¥­¥¹¥È¤¬Ê£¿ô¤Î¹Ô¤ËÅϤäÆÉÁ¤«¤ì¤ë¾ì¹ç¤Ë¤Ï¡¢ºÇÂç¤ÎÉý¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬À¸¤¸¤¿¾ì¹ç¤Ï
+    -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
 
     @latexonly \IPAlabel{mdraw_text_extents} @endlatexonly  */
 
 
     @latexonly \IPAlabel{mdraw_text_extents} @endlatexonly  */
 
@@ -2116,7 +2116,7 @@ mdraw_text_extents (MFrame *frame,
 {
   MGlyphString *gstring;
   int y = 0;
 {
   MGlyphString *gstring;
   int y = 0;
-  int width, rbearing;
+  int width, lbearing, rbearing;
 
   ASSURE_CONTROL (control);
   M_CHECK_POS_X (mt, from, -1);
 
   ASSURE_CONTROL (control);
   M_CHECK_POS_X (mt, from, -1);
@@ -2128,52 +2128,49 @@ mdraw_text_extents (MFrame *frame,
   gstring = get_gstring (frame, mt, from, to, control);
   if (! gstring)
     MERROR (MERROR_DRAW, -1);
   gstring = get_gstring (frame, mt, from, to, control);
   if (! gstring)
     MERROR (MERROR_DRAW, -1);
-  width = gstring_width (gstring, from, to, &rbearing);
+  width = gstring_width (gstring, from, to, &lbearing, &rbearing);
   if (overall_ink_return)
   if (overall_ink_return)
-    {
-      overall_ink_return->y = - gstring->physical_ascent;
-      overall_ink_return->x = gstring->lbearing;
-    }
+    overall_ink_return->y = - gstring->physical_ascent;
   if (overall_logical_return)
   if (overall_logical_return)
-    {
-      overall_logical_return->y = - gstring->ascent;
-      overall_logical_return->x = 0;
-    }
+    overall_logical_return->y = - gstring->ascent;
   if (overall_line_return)
   if (overall_line_return)
-    {
-      overall_line_return->y = - gstring->line_ascent;
-      overall_line_return->x = gstring->lbearing;
-    }
+    overall_line_return->y = - gstring->line_ascent;
 
   for (from = gstring->to; from < to; from = gstring->to)
     {
 
   for (from = gstring->to; from < to; from = gstring->to)
     {
-      int this_width, this_rbearing;
+      int this_width, this_lbearing, this_rbearing;
 
       y += gstring->line_descent;
       M17N_OBJECT_UNREF (gstring->top);
       gstring = get_gstring (frame, mt, from, to, control);
 
       y += gstring->line_descent;
       M17N_OBJECT_UNREF (gstring->top);
       gstring = get_gstring (frame, mt, from, to, control);
-      this_width = gstring_width (gstring, from, to, &this_rbearing);
+      this_width = gstring_width (gstring, from, to,
+                                 &this_lbearing, &this_rbearing);
       y += gstring->line_ascent;
       if (width < this_width)
        width = this_width;
       if (rbearing < this_rbearing)
        rbearing = this_rbearing;
       y += gstring->line_ascent;
       if (width < this_width)
        width = this_width;
       if (rbearing < this_rbearing)
        rbearing = this_rbearing;
+      if (lbearing > this_lbearing)
+       lbearing = this_lbearing;
     }
   if (overall_ink_return)
     {
     }
   if (overall_ink_return)
     {
-      overall_ink_return->width = rbearing;
+      overall_ink_return->x = lbearing;
+      overall_ink_return->width = rbearing - lbearing;
       overall_ink_return->height
        = y + gstring->physical_descent - overall_ink_return->y;
     }
   if (overall_logical_return)
     {
       overall_ink_return->height
        = y + gstring->physical_descent - overall_ink_return->y;
     }
   if (overall_logical_return)
     {
+      overall_logical_return->x = 0;
       overall_logical_return->width = width;
       overall_logical_return->height
        = y + gstring->descent - overall_logical_return->y;
     }
   if (overall_line_return)
     {
       overall_logical_return->width = width;
       overall_logical_return->height
        = y + gstring->descent - overall_logical_return->y;
     }
   if (overall_line_return)
     {
-      overall_line_return->width = MAX (width, rbearing);
+      overall_line_return->x = lbearing;
+      overall_line_return->width = MAX (width, rbearing - lbearing);
       overall_line_return->height
        = y + gstring->line_descent - overall_line_return->y;
     }
       overall_line_return->height
        = y + gstring->line_descent - overall_line_return->y;
     }
@@ -2215,15 +2212,14 @@ mdraw_text_extents (MFrame *frame,
 /***ja
     @brief  M-text ¤Î³Æʸ»ú¤Îɽ¼¨ÈϰϤò·×»»¤¹¤ë.
 
 /***ja
     @brief  M-text ¤Î³Æʸ»ú¤Îɽ¼¨ÈϰϤò·×»»¤¹¤ë.
 
-    ´Ø¿ô mdraw_text_per_char_extents () ¤Ï¡¢´Ø¿ô 
-    mdraw_text_with_control () ¤¬ÉÁ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤
-    ¤Æ M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤ò¥Õ¥ì¡¼¥à $FRAME ¤Ëɽ¼¨¤¹¤ëºÝ
-    ¤Î³Æʸ»ú¤Î¥µ¥¤¥º¤ò·×»»¤¹¤ë¡£
+    ´Ø¿ô mdraw_text_per_char_extents () ¤Ï¡¢´Ø¿ô mdraw_text_with_control ()
+    ¤¬ÉÁ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤¤Æ M-text $MT ¤Î $FROM ¤«¤é $TO 
+    ¤Þ¤Ç¤ò¥Õ¥ì¡¼¥à $FRAME ¤Ëɽ¼¨¤¹¤ëºÝ¤Î³Æʸ»ú¤Î¥µ¥¤¥º¤ò·×»»¤¹¤ë¡£
 
 
-    $ARRAY_SIZE ¤Ë¤è¤Ã¤Æ $INK_ARRAY_RETURN ¤È$LOGICAL_ARRAY_RETURN ¤Î
-    ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¡£$INK_ARRAY_RETURN ¤È$LOGICAL_ARRAY_RETURN ¤Î³ÆÍ×
-    ÁǤϡ¢¤½¤ì¤¾¤ìʸ»ú¤ÎÉÁ²è¥¤¥ó¥¯¤ÈÏÀÍý¥µ¥¤¥º¡ÊM-text¤Îɽ¼¨¸¶ÅÀ¤«¤é¤Î
-    ÁêÂаÌÃ͡ˤˤè¤Ã¤Æ½ç¤ËËä¤á¤é¤ì¤ë¡£ÀßÄꤵ¤ì¤¿ $INK_ARRAY_RETURN ¤È 
+    $ARRAY_SIZE ¤Ë¤è¤Ã¤Æ $INK_ARRAY_RETURN ¤È$LOGICAL_ARRAY_RETURN 
+    ¤Î¥µ¥¤¥º¤ò»ØÄꤹ¤ë¡£$INK_ARRAY_RETURN ¤È$LOGICAL_ARRAY_RETURN 
+    ¤Î³ÆÍ×ÁǤϡ¢¤½¤ì¤¾¤ìʸ»ú¤ÎÉÁ²è¥¤¥ó¥¯¤ÈÏÀÍý¥µ¥¤¥º¡ÊM-text 
+    ¤Îɽ¼¨¸¶ÅÀ¤«¤é¤ÎÁêÂаÌÃ͡ˤˤè¤Ã¤Æ½ç¤ËËä¤á¤é¤ì¤ë¡£ÀßÄꤵ¤ì¤¿ $INK_ARRAY_RETURN ¤È 
     $LOGICAL_ARRAY_RETURN ¤ÎÍ×ÁǤοô¤Ï¡¢$NUM_CHARS_RETURN ¤ËÌᤵ¤ì¤ë¡£
    
     $ARRAY_SIZE ¤¬¤¹¤Ù¤Æ¤ÎÀ£Ë¡¤òÌ᤻¤Ê¤¤¤Û¤É¾®¤µ¤¤¾ì¹ç¤Ë¤Ï¡¢´Ø¿ô¤Ï -1 
     $LOGICAL_ARRAY_RETURN ¤ÎÍ×ÁǤοô¤Ï¡¢$NUM_CHARS_RETURN ¤ËÌᤵ¤ì¤ë¡£
    
     $ARRAY_SIZE ¤¬¤¹¤Ù¤Æ¤ÎÀ£Ë¡¤òÌ᤻¤Ê¤¤¤Û¤É¾®¤µ¤¤¾ì¹ç¤Ë¤Ï¡¢´Ø¿ô¤Ï -1 
@@ -2232,11 +2228,9 @@ mdraw_text_extents (MFrame *frame,
 
     ¥Ý¥¤¥ó¥¿ $OVERALL_INK_RETURN ¤È $OVERALL_LOGICAL_RETURN ¤¬@c NULL 
     ¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¥Æ¥­¥¹¥ÈÁ´ÂΤΥµ¥¤¥º¤â·×»»¤·¡¢·ë²Ì¤ò
 
     ¥Ý¥¤¥ó¥¿ $OVERALL_INK_RETURN ¤È $OVERALL_LOGICAL_RETURN ¤¬@c NULL 
     ¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¥Æ¥­¥¹¥ÈÁ´ÂΤΥµ¥¤¥º¤â·×»»¤·¡¢·ë²Ì¤ò
-    $OVERALL_INK_RETURN ¤È $OVERALL_LOGICAL_RETURN ¤Ç»Ø¤µ¤ì¤ë¹½Â¤¤Î¥á
-    ¥ó¥Ð¤ËÊݸ¤¹¤ë¡£
+    $OVERALL_INK_RETURN ¤È $OVERALL_LOGICAL_RETURN ¤Ç»Ø¤µ¤ì¤ë¹½Â¤¤Î¥á¥ó¥Ð¤ËÊݸ¤¹¤ë¡£
 
 
-    $CONTROL->two_dimensional ¤¬0¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤ÏºÇ½é¤Î¹Ô¤Îʸ»ú
-    ¤Î¥µ¥¤¥º¤À¤±¤ò·×»»¤¹¤ë¡£ */
+    $CONTROL->two_dimensional ¤¬0¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤ÏºÇ½é¤Î¹Ô¤Îʸ»ú¤Î¥µ¥¤¥º¤À¤±¤ò·×»»¤¹¤ë¡£ */
 
 int
 mdraw_text_per_char_extents (MFrame *frame,
 
 int
 mdraw_text_per_char_extents (MFrame *frame,
@@ -2270,48 +2264,65 @@ mdraw_text_per_char_extents (MFrame *frame,
       return 0;
     }
 
       return 0;
     }
 
-  for (g = MGLYPH (1), x = 0; g->type != GLYPH_ANCHOR;)
-    if (g->pos >= from && g->pos < to)
+  for (g = MGLYPH (1), x = 0; g->type != GLYPH_ANCHOR; g++)
+    if (g->g.from >= from && g->g.from < to)
       {
       {
-       int start = g->pos;
-       int end = g->to;
-       int width = g->width;
-       int lbearing = g->lbearing;
-       int rbearing = g->rbearing;
-       int ascent = g->ascent;
-       int descent = g->descent;
-       int logical_ascent = g->rface->rfont->ascent;
-       int logical_descent = g->rface->rfont->descent;
-
-       for (g++; g->type != GLYPH_ANCHOR && g->pos == start; g++)
+       int start = g->g.from;
+       int end = g->g.to;
+       int width = g->g.xadv;
+       int lbearing = g->g.lbearing;
+       int rbearing = g->g.rbearing;
+       int ascent = g->g.ascent;
+       int descent = g->g.descent;
+       int logical_ascent;
+       int logical_descent;
+
+       if (g->rface->rfont)
+         {
+           logical_ascent = g->rface->rfont->ascent;
+           logical_descent = g->rface->rfont->descent;
+         }
+       else
          {
          {
-           if (lbearing < width + g->lbearing)
-             lbearing = width + g->lbearing;
-           if (rbearing < width + g->rbearing)
-             rbearing = width + g->rbearing;
-           width += g->width;
-           if (ascent < g->ascent)
-             ascent = g->ascent;
-           if (descent < g->descent)
-             descent = g->descent;
+           logical_ascent = g->rface->ascent;
+           logical_descent = g->rface->descent;
+         }
+       for (g++; g->type != GLYPH_ANCHOR && g->g.from == start; g++)
+         {
+           if (lbearing < width + g->g.lbearing)
+             lbearing = width + g->g.lbearing;
+           if (rbearing < width + g->g.rbearing)
+             rbearing = width + g->g.rbearing;
+           width += g->g.xadv;
+           if (ascent < g->g.ascent)
+             ascent = g->g.ascent;
+           if (descent < g->g.descent)
+             descent = g->g.descent;
          }
 
        if (end > to)
          end = to;
        while (start < end)
          {
          }
 
        if (end > to)
          end = to;
        while (start < end)
          {
-           ink_array_return[start - from].x = x + lbearing;
-           ink_array_return[start - from].y = - ascent;
-           ink_array_return[start - from].width = rbearing - lbearing;
-           ink_array_return[start - from].height = ascent + descent;
-           logical_array_return[start - from].x = x;
-           logical_array_return[start - from].y = - logical_descent;
-           logical_array_return[start - from].height
-             = logical_ascent + logical_descent;
-           logical_array_return[start - from].width = width;
+           if (ink_array_return)
+             {
+               ink_array_return[start - from].x = x + lbearing;
+               ink_array_return[start - from].y = - ascent;
+               ink_array_return[start - from].width = rbearing - lbearing;
+               ink_array_return[start - from].height = ascent + descent;
+             }
+           if (logical_array_return)
+             {
+               logical_array_return[start - from].x = x;
+               logical_array_return[start - from].y = - logical_descent;
+               logical_array_return[start - from].height
+                 = logical_ascent + logical_descent;
+               logical_array_return[start - from].width = width;
+             }
            start++;
          }
        x += width;
            start++;
          }
        x += width;
+       g--;
       }
 
   if (overall_ink_return)
       }
 
   if (overall_ink_return)
@@ -2353,12 +2364,12 @@ mdraw_text_per_char_extents (MFrame *frame,
     mdraw_coordinates_position () returns the character position of
     that character.\n\n
     If $Y is less than the minimum Y-coordinate of the drawn area, it
     mdraw_coordinates_position () returns the character position of
     that character.\n\n
     If $Y is less than the minimum Y-coordinate of the drawn area, it
-    returns $FROM.\n\n\n
+    returns $FROM.\n\n
     If $Y is greater than the maximum Y-coordinate of the drawn area,
     If $Y is greater than the maximum Y-coordinate of the drawn area,
-    it returns $TO.\n\n\n
+    it returns $TO.\n\n
     If $Y fits in with the drawn area but $X is less than the minimum
     X-coordinate, it returns the character position of the first
     If $Y fits in with the drawn area but $X is less than the minimum
     X-coordinate, it returns the character position of the first
-    character drawn on the line $Y.\n\n\n
+    character drawn on the line $Y.\n\n
     If $Y fits in with the drawn area but $X is greater than the
     maximum X-coordinate, it returns the character position of the
     last character drawn on the line $Y.  */
     If $Y fits in with the drawn area but $X is greater than the
     maximum X-coordinate, it returns the character position of the
     last character drawn on the line $Y.  */
@@ -2367,25 +2378,21 @@ mdraw_text_per_char_extents (MFrame *frame,
     @brief »ØÄꤷ¤¿ºÂɸ¤ËºÇ¤â¶á¤¤Ê¸»ú¤Îʸ»ú°ÌÃÖ¤òÆÀ¤ë.
 
     ´Ø¿ô mdraw_coordinates_position () ¤Ï¡¢´Ø¿ô 
     @brief »ØÄꤷ¤¿ºÂɸ¤ËºÇ¤â¶á¤¤Ê¸»ú¤Îʸ»ú°ÌÃÖ¤òÆÀ¤ë.
 
     ´Ø¿ô mdraw_coordinates_position () ¤Ï¡¢´Ø¿ô 
-    mdraw_text_with_control () ¤¬ÉÁ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤
-    ¤ÆM-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤òºÂɸ (0, 0) ¤òµ¯ÅÀ¤È¤·¤ÆÉÁ²è
-    ¤·¤¿¾ì¹ç¤Ë¡¢ºÂɸ ($X, $Y) ¤ËÉÁ²è¤µ¤ì¤ëʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£¤³¤³¤Ç
-    Ê¸»ú°ÌÃ֤Ȥϡ¢Åö³º M-text Ãæ¤Ë¤ª¤¤¤Æ¤½¤Îʸ»ú¤¬ºÇ½é¤«¤é²¿ÈÖÌܤ«¤ò¼¨
-    ¤¹À°¿ô¤Ç¤¢¤ë¡£¤¿¤À¤·ºÇ½é¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤Ï0¤È¤¹¤ë¡£
+    mdraw_text_with_control () ¤¬ÉÁ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤¤Æ¡¢
+    M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤òºÂɸ (0, 0) 
+    ¤òµ¯ÅÀ¤È¤·¤ÆÉÁ²è¤¹¤ëºÝ¤Ë¡¢ºÂɸ ($X, $Y) 
+    ¤ËÉÁ²è¤µ¤ì¤ëʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£¤³¤³¤Çʸ»ú°ÌÃ֤Ȥϡ¢Åö³º
+    M-text Ãæ¤Ë¤ª¤¤¤Æ¤½¤Îʸ»ú¤¬ºÇ½é¤«¤é²¿ÈÖÌܤ«¤ò¼¨¤¹À°¿ô¤Ç¤¢¤ë¡£¤¿¤À¤·ºÇ½é¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤Ï0¤È¤¹¤ë¡£
 
     $FRAME ¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Õ¥§¡¼¥¹¤Î¾ðÊó¤òÆÀ¤ë¤¿¤á¤À¤±¤ËÍѤ¤¤é¤ì¤ë¡£
 
     @return
     ºÂɸ ($X, $Y) ¤¬¤¢¤ëʸ»ú¤Î¥°¥ê¥Õ¤Çʤ¤ï¤ì¤ë¾ì¹ç¡¢ ´Ø¿ô 
 
     $FRAME ¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Õ¥§¡¼¥¹¤Î¾ðÊó¤òÆÀ¤ë¤¿¤á¤À¤±¤ËÍѤ¤¤é¤ì¤ë¡£
 
     @return
     ºÂɸ ($X, $Y) ¤¬¤¢¤ëʸ»ú¤Î¥°¥ê¥Õ¤Çʤ¤ï¤ì¤ë¾ì¹ç¡¢ ´Ø¿ô 
-    mdraw_coordinates_position () ¤Ï¤½¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£
-
-    ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤ÎºÇ¾®YºÂɸ¤è¤ê¤â¾®¤µ¤¤¤Ê¤é¤Ð $FROM ¤òÊÖ¤¹¡£
-
-    ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤ÎºÇÂçYºÂɸ¤è¤ê¤âÂ礭¤¤¤Ê¤é¤Ð $TO ¤òÊÖ¤¹¡£
-
+    mdraw_coordinates_position () ¤Ï¤½¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£\n\n
+    ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤ÎºÇ¾®YºÂɸ¤è¤ê¤â¾®¤µ¤¤¤Ê¤é¤Ð $FROM ¤òÊÖ¤¹¡£\n\n
+    ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤ÎºÇÂçYºÂɸ¤è¤ê¤âÂ礭¤¤¤Ê¤é¤Ð $TO ¤òÊÖ¤¹¡£\n\n
     ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤Ë¾è¤Ã¤Æ¤¤¤Æ¤«¤Ä $X ¤¬ÉÁ²èÎΰè¤ÎºÇ¾®XºÂɸ¤è¤ê¤â
     ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤Ë¾è¤Ã¤Æ¤¤¤Æ¤«¤Ä $X ¤¬ÉÁ²èÎΰè¤ÎºÇ¾®XºÂɸ¤è¤ê¤â
-    ¾®¤µ¤¤¾ì¹ç¤Ï¡¢Ä¾Àþ y = $Y ¾å¤ËÉÁ²è¤µ¤ì¤ëºÇ½é¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£
-
+    ¾®¤µ¤¤¾ì¹ç¤Ï¡¢Ä¾Àþ y = $Y ¾å¤ËÉÁ²è¤µ¤ì¤ëºÇ½é¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£\n\n
     ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤Ë¾è¤Ã¤Æ¤¤¤Æ¤«¤Ä $X ¤¬ÉÁ²èÎΰè¤ÎºÇÂçXºÂɸ¤è¤ê¤â
     Â礭¤¤¾ì¹ç¤Ï¡¢Ä¾Àþ y = $Y ¾å¤ËÉÁ²è¤µ¤ì¤ëºÇ¸å¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£ */
 
     ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤Ë¾è¤Ã¤Æ¤¤¤Æ¤«¤Ä $X ¤¬ÉÁ²èÎΰè¤ÎºÇÂçXºÂɸ¤è¤ê¤â
     Â礭¤¤¾ì¹ç¤Ï¡¢Ä¾Àþ y = $Y ¾å¤ËÉÁ²è¤µ¤ì¤ëºÇ¸å¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£ */
 
@@ -2422,10 +2429,10 @@ mdraw_coordinates_position (MFrame *frame, MText *mt, int from, int to,
   if (! control->orientation_reversed)
     {
       width = gstring->indent;
   if (! control->orientation_reversed)
     {
       width = gstring->indent;
-      for (g = MGLYPH (1); g[1].type != GLYPH_ANCHOR; g++)
-       if (g->pos >= from && g->pos < to)
+      for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++)
+       if (g->g.from >= from && g->g.from < to)
          {
          {
-           width += g->width;
+           width += g->g.xadv;
            if (width > x_offset)
              break;
          }
            if (width > x_offset)
              break;
          }
@@ -2434,14 +2441,18 @@ mdraw_coordinates_position (MFrame *frame, MText *mt, int from, int to,
     {
       width = - gstring->indent;
       for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--)
     {
       width = - gstring->indent;
       for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--)
-       if (g->pos >= from && g->pos < to)
+       if (g->g.from >= from && g->g.from < to)
          {
          {
-           width -= g->width;
+           width -= g->g.xadv;
            if (width < x_offset)
              break;
          }
     }
            if (width < x_offset)
              break;
          }
     }
-  from = g->pos;
+  if (g->type == GLYPH_ANCHOR
+      && control->two_dimensional
+      && g[-1].g.c == '\n')
+    g--;
+  from = g->g.from;
   M17N_OBJECT_UNREF (gstring->top);
 
   return from;
   M17N_OBJECT_UNREF (gstring->top);
 
   return from;
@@ -2462,10 +2473,10 @@ mdraw_coordinates_position (MFrame *frame, MText *mt, int from, int to,
 /***ja
     @brief ¥°¥ê¥Õ¤Ë´Ø¤¹¤ë¾ðÊó¤ò·×»»¤¹¤ë.
 
 /***ja
     @brief ¥°¥ê¥Õ¤Ë´Ø¤¹¤ë¾ðÊó¤ò·×»»¤¹¤ë.
 
-    ´Ø¿ô mdraw_glyph_info () ¤Ï¡¢´Ø¿ô mdraw_text_with_control () ¤¬ÉÁ
-    ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤¤ÆM-text $MT ¤Î $FROM ¤«¤é $TO 
-    ¤Þ¤Ç¤ò¥Õ¥ì¡¼¥à $FRAME ¤ËÉÁ²è¤·¤¿¾ì¹ç¡¢M-text ¤Îʸ»ú°ÌÃÖ $POS ¤Îʸ
-    »ú¤òʤ¤¦¥°¥ê¥Õ¤Ë´Ø¤¹¤ë¾ðÊó¤ò·×»»¤¹¤ë¡£
+    ´Ø¿ô mdraw_glyph_info () ¤Ï¡¢´Ø¿ô mdraw_text_with_control () 
+    ¤¬ÉÁ ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤¤ÆM-text $MT ¤Î $FROM ¤«¤é $TO 
+    ¤Þ¤Ç¤ò¥Õ¥ì¡¼¥à $FRAME ¤ËÉÁ²è¤·¤¿¾ì¹ç¡¢M-text ¤Îʸ»ú°ÌÃÖ $POS 
+    ¤Îʸ»ú¤òʤ¤¦¥°¥ê¥Õ¤Ë´Ø¤¹¤ë¾ðÊó¤ò·×»»¤¹¤ë¡£
 
     ¾ðÊó¤Ï$INFO ¤Î¥á¥ó¥Ð¤ËÊÝ»ý¤µ¤ì¤ë¡£  */
 
 
     ¾ðÊó¤Ï$INFO ¤Î¥á¥ó¥Ð¤ËÊÝ»ý¤µ¤ì¤ë¡£  */
 
@@ -2504,26 +2515,25 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
   if (! control->orientation_reversed)
     {
       info->x = gstring->indent;
   if (! control->orientation_reversed)
     {
       info->x = gstring->indent;
-      for (g = MGLYPH (1); g->pos > pos || g->to <= pos; g++)
-       info->x += g->width;
+      for (g = MGLYPH (1); g->g.from > pos || g->g.to <= pos; g++)
+       info->x += g->g.xadv;
     }
   else
     {
       info->x = - gstring->indent;
     }
   else
     {
       info->x = - gstring->indent;
-      for (g = MGLYPH (gstring->used - 2); g->pos > pos || g->to <= pos; g--)
-       info->x -= g->width;
-      while (g[-1].to == g->to)
+      for (g = MGLYPH (gstring->used - 2); g->g.from > pos || g->g.to <= pos; g--)
+       info->x -= g->g.xadv;
+      while (g[-1].g.to == g->g.to)
        g--;
     }
        g--;
     }
-  info->from = g->pos;
-  info->to = g->to;
-  info->glyph_code = g->code;
-  info->this.x = g->lbearing;
-  info->this.y = - gstring->line_ascent;
-  info->this.height = gstring->height;
-  info->this.width = - g->lbearing + g->width;
+  info->from = g->g.from;
+  info->to = g->g.to;
+  info->metrics.x = g->g.lbearing;
+  info->metrics.y = - gstring->line_ascent;
+  info->metrics.height = gstring->height;
+  info->metrics.width = - g->g.lbearing + g->g.xadv;
   if (g->rface->rfont)
   if (g->rface->rfont)
-    info->font = &g->rface->rfont->font;
+    info->font = (MFont *) g->rface->rfont;
   else
     info->font = NULL;
   /* info->logical_width is calculated later.  */
   else
     info->font = NULL;
   /* info->logical_width is calculated later.  */
@@ -2533,23 +2543,24 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
       /* The logically previous glyph is on this line.  */
       MGlyph *g_tmp = find_glyph_in_gstring (gstring, info->from - 1, 1);
 
       /* The logically previous glyph is on this line.  */
       MGlyph *g_tmp = find_glyph_in_gstring (gstring, info->from - 1, 1);
 
-      info->prev_from = g_tmp->pos;
+      info->prev_from = g_tmp->g.from;
     }
     }
-  else if (info->line_from > 0)
+  else if (info->line_from > 0
+          && gstring->from > 0)
     {
       /* The logically previous glyph is on the previous line.  */
       MGlyphString *gst = get_gstring (frame, mt, gstring->from - 1,
                                       gstring->from, control);
       MGlyph *g_tmp = find_glyph_in_gstring (gst, info->from - 1, 1);
 
     {
       /* The logically previous glyph is on the previous line.  */
       MGlyphString *gst = get_gstring (frame, mt, gstring->from - 1,
                                       gstring->from, control);
       MGlyph *g_tmp = find_glyph_in_gstring (gst, info->from - 1, 1);
 
-      info->prev_from = g_tmp->pos;
+      info->prev_from = g_tmp->g.from;
       M17N_OBJECT_UNREF (gst->top);
     }
   else
     info->prev_from = -1;
 
   if (GLYPH_INDEX (g) > 1)
       M17N_OBJECT_UNREF (gst->top);
     }
   else
     info->prev_from = -1;
 
   if (GLYPH_INDEX (g) > 1)
-    info->left_from = g[-1].pos, info->left_to = g[-1].to;
+    info->left_from = g[-1].g.from, info->left_to = g[-1].g.to;
   else if (! control->orientation_reversed)
     {
       if (info->line_from > 0)
   else if (! control->orientation_reversed)
     {
       if (info->line_from > 0)
@@ -2560,7 +2571,7 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
 
          gst = get_gstring (frame, mt, p, gstring->from, control);
          g_tmp = gst->glyphs + (gst->used - 2);
 
          gst = get_gstring (frame, mt, p, gstring->from, control);
          g_tmp = gst->glyphs + (gst->used - 2);
-         info->left_from = g_tmp->pos, info->left_to = g_tmp->to;
+         info->left_from = g_tmp->g.from, info->left_to = g_tmp->g.to;
          M17N_OBJECT_UNREF (gst->top);
        }
       else
          M17N_OBJECT_UNREF (gst->top);
        }
       else
@@ -2576,7 +2587,7 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
 
          gst = get_gstring (frame, mt, p, p + 1, control);
          g_tmp = gst->glyphs + (gst->used - 2);
 
          gst = get_gstring (frame, mt, p, p + 1, control);
          g_tmp = gst->glyphs + (gst->used - 2);
-         info->left_from = g_tmp->pos, info->left_to = g_tmp->to;
+         info->left_from = g_tmp->g.from, info->left_to = g_tmp->g.to;
          M17N_OBJECT_UNREF (gst->top);
        }
       else
          M17N_OBJECT_UNREF (gst->top);
        }
       else
@@ -2588,7 +2599,7 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
       /* The logically next glyph is on this line.   */
       MGlyph *g_tmp = find_glyph_in_gstring (gstring, info->to, 0);
 
       /* The logically next glyph is on this line.   */
       MGlyph *g_tmp = find_glyph_in_gstring (gstring, info->to, 0);
 
-      info->next_to = g_tmp->to;
+      info->next_to = g_tmp->g.to;
     }
   else if (info->to + (control->cursor_width == 0) <= mtext_nchars (mt))
     {
     }
   else if (info->to + (control->cursor_width == 0) <= mtext_nchars (mt))
     {
@@ -2597,19 +2608,19 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
       MGlyphString *gst = get_gstring (frame, mt, p, p + 1, control);
       MGlyph *g_tmp = find_glyph_in_gstring (gst, p, 0);
 
       MGlyphString *gst = get_gstring (frame, mt, p, p + 1, control);
       MGlyph *g_tmp = find_glyph_in_gstring (gst, p, 0);
 
-      info->next_to = g_tmp->to;
+      info->next_to = g_tmp->g.to;
       M17N_OBJECT_UNREF (gst->top);
     }
   else
     info->next_to = -1;
 
       M17N_OBJECT_UNREF (gst->top);
     }
   else
     info->next_to = -1;
 
-  for (info->logical_width = (g++)->width;
-       g->pos == pos && g->type != GLYPH_ANCHOR;
-       info->this.width += g->width, info->logical_width += (g++)->width);
-  info->this.width += g[-1].rbearing - g[-1].width;
+  for (info->logical_width = (g++)->g.xadv;
+       g->g.from == pos && g->type != GLYPH_ANCHOR;
+       info->metrics.width += g->g.xadv, info->logical_width += (g++)->g.xadv);
+  info->metrics.width += g[-1].g.rbearing - g[-1].g.xadv;
 
   if (g->type != GLYPH_ANCHOR)
 
   if (g->type != GLYPH_ANCHOR)
-    info->right_from = g->pos, info->right_to = g->to;
+    info->right_from = g->g.from, info->right_to = g->g.to;
   else if (! control->orientation_reversed)
     {
       if (gstring->to + (control->cursor_width == 0) <= mtext_nchars (mt))
   else if (! control->orientation_reversed)
     {
       if (gstring->to + (control->cursor_width == 0) <= mtext_nchars (mt))
@@ -2618,7 +2629,7 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
          M17N_OBJECT_UNREF (gstring->top);
          gstring = get_gstring (frame, mt, pos, pos + 1, control);
          g = MGLYPH (1);
          M17N_OBJECT_UNREF (gstring->top);
          gstring = get_gstring (frame, mt, pos, pos + 1, control);
          g = MGLYPH (1);
-         info->right_from = g->pos, info->right_to = g->to;
+         info->right_from = g->g.from, info->right_to = g->g.to;
        }
       else
        info->right_from = info->right_to = -1;
        }
       else
        info->right_from = info->right_to = -1;
@@ -2631,7 +2642,7 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
          M17N_OBJECT_UNREF (gstring->top);
          gstring = get_gstring (frame, mt, pos, pos + 1, control);
          g = MGLYPH (1);
          M17N_OBJECT_UNREF (gstring->top);
          gstring = get_gstring (frame, mt, pos, pos + 1, control);
          g = MGLYPH (1);
-         info->right_from = g->pos, info->right_to = g->to;
+         info->right_from = g->g.from, info->right_to = g->g.to;
        }
       else
        info->right_from = info->right_to = -1;
        }
       else
        info->right_from = info->right_to = -1;
@@ -2643,15 +2654,53 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
 
 /*=*/
 
 
 /*=*/
 
+/***en
+    @brief Compute information about glyph sequence.
+
+    The mdraw_glyph_list () function computes information about glyphs
+    corresponding to the text between $FROM and $TO of M-text $MT when
+    it is drawn on a window of frame $FRAME using the
+    mdraw_text_with_control () function with the drawing control
+    object $CONTROL.  $GLYPHS is an array of objects to store the
+    information, and $ARRAY_SIZE is the array size.
+
+    If $ARRAY_SIZE is large enough to cover all glyphs, it stores the
+    number of actually filled elements in the place pointed by
+    $NUM_GLYPHS_RETURN, and returns 0.
+
+    Otherwise, it stores the required array size in the place pointed
+    by $NUM_GLYPHS_RETURN, and returns -1.  */
+
+/***ja
+    @brief ¥°¥ê¥ÕÎó¤Ë´Ø¤¹¤ë¾ðÊó¤ò·×»»¤¹¤ë.
+
+    ´Ø¿ô mdraw_glyph_list () ¤Ï¡¢´Ø¿ô mdraw_text_with_control () 
+    ¤¬ÉÁ²èÀ©¸æ¥ª¥Ö¥¸¥§¥¯¥È $CONTROL ¤òÍѤ¤¤ÆM-text $MT ¤Î $FROM ¤«¤é $TO
+    ¤Þ¤Ç¤ò¥Õ¥ì¡¼¥à $FRAME ¤ËÉÁ²è¤·¤¿¾ì¹ç¤Î¡¢³Æ¥°¥ê¥Õ¤Î¾ðÊó¤ò $GLYPHS 
+    ¤¬»Ø¤¹ÇÛÎó¤Ë³ÊǼ¤¹¤ë¡£ $ARRAY_SIZE ¤Ï¤½¤ÎÇÛÎó¤Î¥µ¥¤¥º¤Ç¤¢¤ë¡£
+
+    ¤â¤· $ARRAY_SIZE ¤¬¤¹¤Ù¤Æ¤Î¥°¥ê¥Õ¤Ë¤Ä¤¤¤Æ¤Î¾ðÊó¤ò³ÊǼ¤¹¤ë¤Î¤Ë½½Ê¬¤Ç¤¢¤ì¤Ð¡¢
+    $NUM_GLYPHS_RETURN ¤¬»Ø¤¹¾ì½ê¤Ë¼ÂºÝ¤ËËä¤á¤¿Í×ÁǤοô¤òÀßÄꤷ 0 ¤òÊÖ¤¹¡£
+
+    
+    ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢$NUM_GLYPHS_RETURN ¤¬»Ø¤¹¾ì½ê¤ËɬÍפÊÇÛÎó¤Î¥µ¥¤¥º¤òÀßÄꤷ¡¢
+    -1 ¤òÊÖ¤¹¡£
+    */
+
+/***
+    @seealso
+    MDrawGlyph
+*/
+
 int
 mdraw_glyph_list (MFrame *frame, MText *mt, int from, int to,
 int
 mdraw_glyph_list (MFrame *frame, MText *mt, int from, int to,
-                 MDrawControl *control, MDrawGlyphInfo *info,
+                 MDrawControl *control, MDrawGlyph *glyphs,
                  int array_size, int *num_glyphs_return)
 {
   MGlyphString *gstring;
   MGlyph *g;
   int n;
                  int array_size, int *num_glyphs_return)
 {
   MGlyphString *gstring;
   MGlyph *g;
   int n;
-  int pad_width;
+  int pad_width = 0;
 
   ASSURE_CONTROL (control);
   *num_glyphs_return = 0;
 
   ASSURE_CONTROL (control);
   *num_glyphs_return = 0;
@@ -2662,40 +2711,53 @@ mdraw_glyph_list (MFrame *frame, MText *mt, int from, int to,
   for (g = MGLYPH (1), n = 0; g->type != GLYPH_ANCHOR; g++)
     {
       if (g->type == GLYPH_BOX
   for (g = MGLYPH (1), n = 0; g->type != GLYPH_ANCHOR; g++)
     {
       if (g->type == GLYPH_BOX
-         || g->pos < from || g->pos >= to)
+         || g->g.from < from || g->g.from >= to)
        continue;
       if (g->type == GLYPH_PAD)
        {
          if (g->left_padding)
        continue;
       if (g->type == GLYPH_PAD)
        {
          if (g->left_padding)
-           pad_width = g->width;
+           pad_width = g->g.xadv;
          else if (n > 0)
            {
              pad_width = 0;
          else if (n > 0)
            {
              pad_width = 0;
-             info[-1]->x += g->width;
-             info[-1]->this.x += g->width;
-             info[-1]->this.width += g->width;
-             info[-1]->logical_width += g->width;
+             glyphs[-1].x_advance += g->g.xadv;
            }
          continue;
        }
       if (n < array_size)
        {
            }
          continue;
        }
       if (n < array_size)
        {
-         info->from = g->pos;
-         info->to = g->to;
-         info->glyph_code = g->code;
-         info->x = g->xoff + pad_width;
-         info->y = g->yoff;
-         info->this.x = g->lbearing + pad_width;
-         info->this.y = - g->ascent;
-         info->this.height = g->ascent + g->descent;
-         info->this.width = g->rbearing - g->lbearing + pad_width;
-         info->logical_width = g->width;
+         glyphs->from = g->g.from;
+         glyphs->to = g->g.to;
+         glyphs->glyph_code = g->g.code;
+         glyphs->x_off = g->g.xoff + pad_width;
+         glyphs->y_off = g->g.yoff;
+         glyphs->lbearing = g->g.lbearing;
+         glyphs->rbearing = g->g.rbearing;
+         glyphs->ascent = g->g.ascent;
+         glyphs->descent = g->g.descent;
+         glyphs->x_advance = g->g.xadv + pad_width;
+         glyphs->y_advance = 0;
          if (g->rface->rfont)
          if (g->rface->rfont)
-           info->font = &g->rface->rfont->font;
+           {
+             glyphs->font = (MFont *) g->rface->rfont;
+#ifdef HAVE_FREETYPE
+             glyphs->font_type
+               = (glyphs->font->source == MFONT_SOURCE_X ? Mx
+                  : g->rface->rfont->driver == &mfont__ft_driver ? Mfreetype
+                  : Mxft);
+#else  /* not HAVE_FREETYPE */
+             glyphs->font_type = Mx;
+#endif /* not HAVE_FREETYPE */
+             glyphs->fontp = g->rface->rfont->fontp;
+           }
          else
          else
-           info->font = NULL;
+           {
+             glyphs->font = NULL;
+             glyphs->font_type = Mnil;
+             glyphs->fontp = NULL;
+           }
          pad_width = 0;
          pad_width = 0;
-         info++;
+         glyphs++;
        }
       n++;
     }
        }
       n++;
     }
@@ -2711,17 +2773,16 @@ mdraw_glyph_list (MFrame *frame, MText *mt, int from, int to,
     @brief Draw one or more textitems.
 
     The mdraw_text_items () function draws one or more M-texts on
     @brief Draw one or more textitems.
 
     The mdraw_text_items () function draws one or more M-texts on
-    window $WIN of $FRAME at coordinate ($X, $Y).  $ITEMS is an array
+    window $WIN of frame $FRAME at coordinate ($X, $Y).  $ITEMS is an array
     of the textitems to be drawn and $NITEMS is the number of
     of the textitems to be drawn and $NITEMS is the number of
-    textimtems in the array.  */
+    textitems in the array.  */
 
 /***ja
     @brief textitem ¤òɽ¼¨¤¹¤ë.
 
 
 /***ja
     @brief textitem ¤òɽ¼¨¤¹¤ë.
 
-    ´Ø¿ô mdraw_text_items () ¤Ï¡¢°ì¸Ä°Ê¾å¤Î¥Æ¥­¥¹¥È¥¢¥¤¥Æ¥à¤ò¡¢¥Õ¥ì¡¼
-    ¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤ÎºÂɸ ($X, $Y) ¤Ëɽ¼¨¤¹¤ë¡£$ITEMS ¤Ï
-    É½¼¨¤¹¤Ù¤­¥Æ¥­¥¹¥È¥¢¥¤¥Æ¥à¤ÎÇÛÎó¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ê¡¢$NITEMS ¤Ï¤½¤Î
-    ¸Ä¿ô¤Ç¤¢¤ë¡£
+    ´Ø¿ô mdraw_text_items () ¤Ï¡¢°ì¸Ä°Ê¾å¤Î¥Æ¥­¥¹¥È¥¢¥¤¥Æ¥à¤ò¡¢¥Õ¥ì¡¼¥à
+    $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤ÎºÂɸ ($X, $Y) ¤Ëɽ¼¨¤¹¤ë¡£$ITEMS 
+    ¤Ïɽ¼¨¤¹¤Ù¤­¥Æ¥­¥¹¥È¥¢¥¤¥Æ¥à¤ÎÇÛÎó¤Ç¤¢¤ê¡¢$NITEMS ¤Ï¤½¤Î¸Ä¿ô¤Ç¤¢¤ë¡£
 
     @latexonly \IPAlabel{mdraw_text_items} @endlatexonly  */
 
 
     @latexonly \IPAlabel{mdraw_text_items} @endlatexonly  */
 
@@ -2752,69 +2813,63 @@ mdraw_text_items (MFrame *frame, MDrawWindow win, int x, int y,
 }
 
 /*=*/
 }
 
 /*=*/
-/***en 
-      @brief   calculate a line breaking position.
-
-      The function mdraw_default_line_break () calculates a line
-      breaking position based on the line number $LINE and the
-      coordinate $Y, when a line is too long to fit within the width
-      limit.  $POS is the position of the character next to the last
-      one that fits within the limit.  $FROM is the position of the
-      first character of the line, and TO is the position of the last
-      character displayed on the line if there were not width limit.
-      LINE and Y are reset to 0 when a line is broken by a newline
-      character, and incremented each time when a long line is broken
-      because of the width limit.  
+/***en
+    @brief Option of line breaking for drawing text.
 
 
-      @return 
-      This function returns a character position to break the
-      line.
+    The variable #mdraw_line_break_option specifies line breaking
+    options by logical-or of the members of #MTextLineBreakOption.  It
+    controls the line breaking algorithm of the function
+    mdraw_default_line_break ().  */
+    
+int mdraw_line_break_option;
 
 
+/*=*/
+/***en 
+    @brief Calculate a line breaking position.
+
+    The function mdraw_default_line_break () calculates a line
+    breaking position based on the line number $LINE and the
+    coordinate $Y, when a line is too long to fit within the width
+    limit.  $POS is the position of the character next to the last one
+    that fits within the limit.  $FROM is the position of the first
+    character of the line, and $TO is the position of the last
+    character displayed on the line if there were not width limit.
+    $LINE and $Y are reset to 0 when a line is broken by a newline
+    character, and incremented each time when a long line is broken
+    because of the width limit.
+
+    @return 
+    This function returns a character position to break the
+    line.
 */
 */
+
 /***ja 
       @brief ²þ¹Ô°ÌÃÖ¤ò·×»»¤¹¤ë.
 
 /***ja 
       @brief ²þ¹Ô°ÌÃÖ¤ò·×»»¤¹¤ë.
 
-      ´Ø¿ô mdraw_default_line_break () ¤Ï¡¢¹Ô¤¬ºÇÂçÉýÃæ¤Ë¼ý¤Þ¤é¤Ê¤¤¾ì
-      ¹ç¤Ë¹Ô¤ò²þ¤á¤ë°ÌÃÖ¤ò¡¢¹ÔÈÖ¹æ LINE ¤ÈºÂɸ Y ¤Ë´ð¤Å¤¤¤Æ·×»»¤¹¤ë¡£
-      $POS ¤ÏºÇÂçÉý¤Ë¼ý¤Þ¤ëºÇ¸å¤Îʸ»ú¤Î¼¡¤Îʸ»ú¤Î°ÌÃ֤Ǥ¢¤ë¡£$FROM ¤Ï
-      ¹Ô¤ÎºÇ½é¤Îʸ»ú¤Î°ÌÃÖ¡¢$TO ¤ÏºÇÂçÉý¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¤½¤Î¹Ô¤Ë
-      É½¼¨¤µ¤ì¤ëºÇ¸å¤Îʸ»ú¤Î°ÌÃ֤Ǥ¢¤ë¡£ LINE ¤È Y ¤Ï²þ¹Ôʸ»ú¤Ë¤è¤Ã¤Æ
-      ¹Ô¤¬²þ¤Þ¤Ã¤¿ºÝ¤Ë¤Ï 0 ¤Ë¥ê¥»¥Ã¥È¤µ¤ì¡¢ºÇÂçÉý¤Ë¤è¤Ã¤Æ¹Ô¤¬²þ¤Þ¤Ã¤¿
-      ¾ì¹ç¤Ë¤Ï 1 ¤Å¤ÄÁý¤ä¤µ¤ì¤ë¡£
+      ´Ø¿ô mdraw_default_line_break () ¤Ï¡¢¹Ô¤¬ºÇÂçÉýÃæ¤Ë¼ý¤Þ¤é¤Ê¤¤¾ì¹ç¤Î²þ¹Ô°ÌÃÖ¤ò¡¢¹ÔÈÖ¹æ
+      $LINE ¤ÈºÂɸ $Y ¤Ë´ð¤Å¤¤¤Æ·×»»¤¹¤ë¡£
+      $POS ¤ÏºÇÂçÉý¤Ë¼ý¤Þ¤ëºÇ¸å¤Îʸ»ú¤Î¼¡¤Îʸ»ú¤Î°ÌÃ֤Ǥ¢¤ë¡£
+      $FROM ¤Ï¤½¤Î¹Ô¤ÎºÇ½é¤Îʸ»ú¤Î°ÌÃÖ¡¢$TO 
+      ¤ÏºÇÂçÉý¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¤½¤Î¹Ô¤Ëɽ¼¨¤µ¤ì¤ëºÇ¸å¤Îʸ»ú¤Î°ÌÃ֤Ǥ¢¤ë¡£
+      $LINE ¤È $Y ¤Ï²þ¹Ôʸ»ú¤Ë¤è¤Ã¤Æ¹Ô¤¬²þ¤Þ¤Ã¤¿ºÝ¤Ë¤Ï 0
+      ¤Ë¥ê¥»¥Ã¥È¤µ¤ì¡¢ºÇÂçÉý¤Ë¤è¤Ã¤Æ¹Ô¤¬²þ¤Þ¤Ã¤¿¾ì¹ç¤Ë¤Ï 1 ¤Å¤ÄÁý¤ä¤µ¤ì¤ë¡£
 
       @return 
 
       @return 
-      ¤³¤Î´Ø¿ô¤Ï¹Ô¤ò²þ¤á¤ëʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£
+      ¤³¤Î´Ø¿ô¤Ï²þ¹Ô¤¹¤ëʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£
 */
 
 int
 mdraw_default_line_break (MText *mt, int pos,
                          int from, int to, int line, int y)
 {
 */
 
 int
 mdraw_default_line_break (MText *mt, int pos,
                          int from, int to, int line, int y)
 {
-  int c = mtext_ref_char (mt, pos);
-  int orig_pos = pos;
-
-  if (c == ' ' || c == '\t')
-    {
-      pos++;
-      while (pos < to
-            && ((c = mtext_ref_char (mt, pos)) == ' ' || c == '\t'))
-       pos++;
-    }
-  else
-    {
-      while (pos > from)
-       {
-         if (c == ' ' || c == '\t')
-           break;
-         pos--;
-         c = mtext_ref_char (mt, pos);
-       }
-      if (pos == from)
-       pos = orig_pos;
-      else
-       pos++;
-    }
-  return pos;
+  int p, after;
+
+  p = mtext_line_break (mt, pos, mdraw_line_break_option, &after);
+  if (p < from)
+    p = from;
+  else if (p >= to)
+    p = to;
+  return p;
 }
 
 /*=*/
 }
 
 /*=*/
@@ -2839,17 +2894,17 @@ mdraw_default_line_break (MText *mt, int pos,
 /***ja
     @brief M-text ¤Îʸ»úËè¤Îɽ¼¨ÈϰϾðÊó¤òÆÀ¤ë.
 
 /***ja
     @brief M-text ¤Îʸ»úËè¤Îɽ¼¨ÈϰϾðÊó¤òÆÀ¤ë.
 
-    ´Ø¿ô mdraw_per_char_extents () ¤Ï¡¢M-text $MT Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈÏ°Ï
-    ¤ò·×»»¤¹¤ë¡£¤³¤Î·×»»¤ËÍѤ¤¤ë¥Õ¥©¥ó¥È¤Ï¡¢$MT ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ç
-    »ØÄꤵ¤ì¤¿¥Õ¥§¡¼¥¹¤Èa¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤Ë¤è¤Ã¤Æ
-    ·è¤Þ¤ë¡£$ARRAY_RETURN ¤Î³ÆÍ×ÁǤϡ¢Åö³º M-text Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈÏ°Ï
-    ¾ðÊó¤Ë¤è¤Ã¤Æ½ç¤ËËä¤á¤é¤ì¤ë¡£¤³¤Îɽ¼¨ÈϰϾðÊó¤Ï¡¢M-text ¤Îɽ¼¨¸¶ÅÀ¤«
-    ¤é¤ÎÁêÂаÌÃ֤Ǥ¢¤ë¡£$ARRAY_RETURN ¤ÎÍ×ÁÇ¿ô¤Ï¡¢M-text ¤Î°Ê¾å¤Ç¤Ê¤±¤ì
-    ¤Ð¤Ê¤é¤Ê¤¤¡£
+    ´Ø¿ô mdraw_per_char_extents () ¤Ï¡¢M-text $MT 
+    Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈϰϤò·×»»¤¹¤ë¡£¤³¤Î·×»»¤ËÍѤ¤¤ë¥Õ¥©¥ó¥È¤Ï¡¢
+    $MT ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ç»ØÄꤵ¤ì¤¿¥Õ¥§¡¼¥¹¤È¡¢¥Õ¥ì¡¼¥à $FRAME
+    ¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤Ë¤è¤Ã¤Æ·è¤Þ¤ë¡£$ARRAY_RETURN ¤Î³ÆÍ×ÁǤϡ¢$MT
+    Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈϰϾðÊó¤Ë¤è¤Ã¤Æ½ç¤ËËä¤á¤é¤ì¤ë¡£É½¼¨ÈϰϾðÊó¤È¤Ï¡¢
+    É½¼¨¸¶ÅÀ¤«¤é¤ÎÁêÂаÌÃ֤ȳÆʸ»ú¤ÎÀê¤á¤ëĹÊý·Á¤Ç¤¢¤ë¡£$ARRAY_RETURN 
+    ¤ÎÍ×ÁÇ¿ô¤Ï¡¢M-text Ãæ¤Îʸ»ú¿ô°Ê¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
 
 
-    ¥Ý¥¤¥ó¥¿ $OVERALL_RETURN ¤¬ @c NULL ¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢¥Æ¥­¥¹¥ÈÁ´ÂΤÎɽ
-    ¼¨ÈϰϾðÊó¤â·×»»¤·¡¢¤½¤Î·ë²Ì¤ò $OVERALL_RETURN ¤Î»Ø¤¹¹½Â¤ÂΤ˳ÊǼ
-    ¤¹¤ë¡£
+    ¥Ý¥¤¥ó¥¿ $OVERALL_RETURN ¤¬ @c NULL 
+    ¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢¥Æ¥­¥¹¥ÈÁ´ÂΤÎɽ¼¨ÈϰϾðÊó¤â·×»»¤·¡¢¤½¤Î·ë²Ì¤ò 
+    $OVERALL_RETURN ¤Î»Ø¤¹¹½Â¤ÂΤ˳ÊǼ¤¹¤ë¡£
 
     @latexonly \IPAlabel{mdraw_per_char_extents} @endlatexonly  */
 
 
     @latexonly \IPAlabel{mdraw_per_char_extents} @endlatexonly  */
 
@@ -2869,7 +2924,7 @@ mdraw_per_char_extents (MFrame *frame, MText *mt,
 
     The mdraw_clear_cache () function clear cached information
     on M-text $MT that was attached by any of the drawing functions.
 
     The mdraw_clear_cache () function clear cached information
     on M-text $MT that was attached by any of the drawing functions.
-    When the behaviour of `format' or `line_break'
+    When the behavior of `format' or `line_break'
     member functions of MDrawControl is changed, the cache must be cleared.
 
     @seealso
     member functions of MDrawControl is changed, the cache must be cleared.
 
     @seealso
@@ -2877,10 +2932,11 @@ mdraw_per_char_extents (MFrame *frame, MText *mt,
 /***ja 
     @brief ¥­¥ã¥Ã¥·¥å¾ðÊó¤ò¾Ã¤¹.
 
 /***ja 
     @brief ¥­¥ã¥Ã¥·¥å¾ðÊó¤ò¾Ã¤¹.
 
-    ´Ø¿ô mdraw_clear_cache () ¤ÏÉÁ²è´Ø¿ô¤Ë¤è¤Ã¤Æ M-text $MT ¤ËÉÕ²Ã
-    ¤µ¤ì¤¿¥­¥ã¥Ã¥·¥å¾ðÊó¤ò¤¹¤Ù¤Æ¾Ãµî¤¹¤ë¡£MDrawControl ¤Î `format' ¤¢
-    ¤ë¤¤¤Ï `line_break' ¥á¥ó¥Ð´Ø¿ô¤Î¿¶Éñ¤¤¤¬ÊѤï¤Ã¤¿¾ì¹ç¤Ë¤Ï¥­¥ã¥Ã¥·¥å
-    ¤ò¾Ãµî¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
+    ´Ø¿ô mdraw_clear_cache () ¤ÏÉÁ²è´Ø¿ô¤Ë¤è¤Ã¤Æ M-text $MT 
+    ¤ËÉղ䵤줿¥­¥ã¥Ã¥·¥å¾ðÊó¤ò¤¹¤Ù¤Æ¾Ãµî¤¹¤ë¡£MDrawControl ¤Î `format' 
+    ¤¢¤ë¤¤¤Ï `line_break' 
+    ¥á¥ó¥Ð´Ø¿ô¤Î¿¶Éñ¤¤¤¬ÊѤï¤Ã¤¿¾ì¹ç¤Ë¤Ï¥­¥ã¥Ã¥·¥å¤ò¾Ãµî¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
+
     @seealso
     MDrawControl */
 
     @seealso
     MDrawControl */