*** empty log message ***
[m17n/m17n-lib.git] / src / draw.c
index 4da7478..1fab5d6 100644 (file)
@@ -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 ¤ÎÉÁ²è¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï¿ÍͤÊÊýË¡¤ÇÀ©¸æ¤Ç¤­¤ë¤Î¤Ç¡¢¶¯ÎϤÊÆ󼡸µ¥ì¥¤¥¢¥¦¥Èµ¡Ç½¤¬¼Â¸½¤Ç¤­¤ë¡£
     */
 
 /*=*/
     */
 
 /*=*/
@@ -65,6 +64,7 @@
 #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 "face.h"
 #include "textprop.h"
 #include "internal-gui.h"
 #include "face.h"
 static MSymbol M_glyph_string;
 
 /* Special scripts */
 static MSymbol M_glyph_string;
 
 /* Special scripts */
-static MSymbol Mlatin, Minherited;
+static MSymbol Minherited, 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.  */
 
@@ -99,62 +103,63 @@ visual_order (MGlyphString *gstring)
 {
   int len = gstring->used - 2;
   MGlyph *glyphs;
 {
   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);
+  MGlyph *g;
   int i;
 #ifdef HAVE_FRIBIDI
   int i;
 #ifdef HAVE_FRIBIDI
-  FriBidiCharType base = (gstring->control.orientation_reversed
-                         ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR);
+  FriBidiCharType base = bidi_sensitive ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR;
   FriBidiChar *logical = alloca (sizeof (FriBidiChar) * len);
   FriBidiChar *visual;
   FriBidiStrIndex *indices;
   FriBidiChar *logical = alloca (sizeof (FriBidiChar) * len);
   FriBidiChar *visual;
   FriBidiStrIndex *indices;
-  FriBidiLevel *levels = alloca (sizeof (FriBidiLevel) * len);
+  FriBidiLevel *levels;
 #else  /* not HAVE_FRIBIDI */
   int *logical = alloca (sizeof (int) * len);
   int *indices;
   char *levels = alloca (len);
 #endif /* not HAVE_FRIBIDI */
 
 #else  /* not HAVE_FRIBIDI */
   int *logical = alloca (sizeof (int) * len);
   int *indices;
   char *levels = alloca (len);
 #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->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 */
+           }
        }
        }
-      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->c;
     }
 
   if (! bidi_sensitive)
     return;
 
     }
 
   if (! bidi_sensitive)
     return;
 
-  glyphs = alloca (sizeof (MGlyph) * gstring->used);
-  memcpy (glyphs, gstring->glyphs, (sizeof (MGlyph) * gstring->used));
+  glyphs = alloca (sizeof (MGlyph) * len);
+  memcpy (glyphs, gstring->glyphs + 1, sizeof (MGlyph) * len);
 #ifdef HAVE_FRIBIDI
 #ifdef HAVE_FRIBIDI
-  visual = alloca (sizeof (FriBidiChar) * size);
-  indices = alloca (sizeof (FriBidiStrIndex) * size);
+  visual = alloca (sizeof (FriBidiChar) * (len + 1));
+  indices = alloca (sizeof (FriBidiStrIndex) * (len + 1));
+  levels = alloca (sizeof (FriBidiLevel) * (len + 1));
 
 
-  fribidi_log2vis (logical, size, &base, visual, NULL, indices, levels);
+  fribidi_log2vis (logical, len, &base, visual, indices, NULL, levels);
 #else  /* not HAVE_FRIBIDI */
 #else  /* not HAVE_FRIBIDI */
-  indices = alloca (sizeof (int) * size);
-  for (i = 0; i < size; i++)
+  indices = alloca (sizeof (int) * len);
+  for (i = 0; i < len; i++)
     {
       if (levels[i])
        {
          int j, k;
 
     {
       if (levels[i])
        {
          int j, k;
 
-         for (j = i + 1; j < size && levels[j]; j++);
+         for (j = i + 1; j < len && levels[j]; j++);
          for (k = j--; i < k; i++, j--)
            indices[i] = j;
          i--;
          for (k = j--; i < k; i++, j--)
            indices[i] = j;
          i--;
@@ -164,36 +169,36 @@ visual_order (MGlyphString *gstring)
     }
 #endif /* not HAVE_FRIBIDI */
 
     }
 #endif /* not HAVE_FRIBIDI */
 
-  /* IDX are indices to gstring->glyphs[].  The glyphs for LOGICAL[N]
-     starts from gstring->glyphs[IDX[N]].
-
-     INDICES are indices to LOGICAL[].  The glyph for VISUAL[N] is
-     originally at LOGICAL[INDICES[N]].  */
-
-  for (i = 0, gidx = 1; i < size; i++)
+  for (i = 0; i < len;)
     {
     {
+      /* Index into gstring->glyphs plus 1 for GLYPHS[i].  */
       int j = indices[i];
       int j = indices[i];
-      int k = idx[j];
+      /* Length of grapheme-cluster */
+      int seglen;
 
 
-      glyphs[k].bidi_level = levels[j];
+      g = glyphs + i;
 #ifdef HAVE_FRIBIDI
 #ifdef HAVE_FRIBIDI
-      if (visual[i] != logical[j])
+      if (visual[j] != logical[i])
        {
          /* Mirrored.  */
        {
          /* Mirrored.  */
-         glyphs[k].c = visual[i];
-         if (glyphs[k].rface->rfont)
-           glyphs[k].code = mfont__encode_char (glyphs[k].rface->rfont,
-                                                glyphs[k].c);
+         g->c = visual[j];
+         if (g->rface->rfont)
+           g->code = mfont__encode_char (NULL, (MFont *) g->rface->rfont,
+                                         NULL, g->c);
        }
        }
-#endif /* not HAVE_FRIBIDI */
-      *(MGLYPH (gidx)) = glyphs[k];
-      for (gidx++, k++;
-          k < gstring->used - 1 && glyphs[k].combining_code;
-          gidx++, k++)
+#endif /* HAVE_FRIBIDI */
+      g->bidi_level = levels[i];
+      for (seglen = 1, g++;
+          i + seglen < len && (glyphs[i].pos == glyphs[i + seglen].pos
+                               || glyphs[i + seglen].combining_code);
+          seglen++, g++)
        {
        {
-         glyphs[k].bidi_level = levels[j];
-         *(MGLYPH (gidx)) = glyphs[k];
+         g->bidi_level = levels[i];
+         if (indices[i + seglen] < j)
+           j = indices[i + seglen];
        }
        }
+      memcpy (MGLYPH (j + 1), glyphs + i, sizeof (MGlyph) * seglen);
+      i += seglen;
     }
 }
 
     }
 }
 
@@ -223,93 +228,170 @@ reorder_combining_chars (MGlyphString *gstring, int from, int 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 i;
   int size = gstring->control.fixed_width;
   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;
   g_tmp.pos = g_tmp.to = from;
   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;
   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.c = c;
+      g_tmp.pos = pos++;
+      g_tmp.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].c = '^';
+         ctrl[1].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.pos = g_tmp.to = pos;
+  APPEND_GLYPH (gstring, g_tmp);
+  gstring->to = pos;
+
+  /* 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->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)
+         if (this_script == Minherited || this_script == Mcommon)
            this_script = script;
            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 == Mcommon)
+           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->c >= 0x100
+                   && (sym = mchar_get_prop (g1->c, Mscript)) != Mcommon
+                   && sym != Minherited)
                  {
                    this_script = sym;
                    break;
                  }
                  {
                    this_script = sym;
                    break;
                  }
-             }
+           }
        }
 
        }
 
-      if (pos == stop || script != this_script
-         || MGLYPH (last)->type != g_tmp.type)
+      pos = g->pos;
+      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 +406,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,24 +427,29 @@ 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;
 
              for (prev = MGLYPH (start - 1);
                   (prev->type == GLYPH_CHAR
            {
              MGlyph *prev;
              unsigned code;
 
              for (prev = MGLYPH (start - 1);
                   (prev->type == GLYPH_CHAR
-                   && prev->category == McatCf
-                   && (code = mfont__encode_char (this->rface->rfont, prev->c)
+                   && prev->category == GLYPH_CATEGORY_FORMATTER
+                   && (code = mfont__encode_char (NULL,
+                                                  (MFont *) this->rface->rfont,
+                                                  NULL, prev->c)
                        != MCHAR_INVALID_CODE));
                   start--, prev--)
                prev->code = code;
 
              for (g++;
                   (g->type == GLYPH_CHAR
                        != MCHAR_INVALID_CODE));
                   start--, prev--)
                prev->code = code;
 
              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->category == GLYPH_CATEGORY_FORMATTER
+                           && ((code = mfont__encode_char (NULL,
+                                                           (MFont *) this->rface->rfont,
+                                                           NULL,
                                                            g->c))
                                != MCHAR_INVALID_CODE))));
                   i++, g++)
                                                            g->c))
                                != MCHAR_INVALID_CODE))));
                   i++, g++)
@@ -420,8 +464,7 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
            {
              while (this->type == GLYPH_CHAR
                     && this->c >= 0x100
            {
              while (this->type == GLYPH_CHAR
                     && this->c >= 0x100
-                    && this->category
-                    && MSYMBOL_NAME (this->category)[0] == 'M'
+                    && this->category == GLYPH_CATEGORY_MODIFIER
                     && this->rface->rfont
                     && this->rface->rfont->layouter == Mnil)
                {
                     && this->rface->rfont
                     && this->rface->rfont->layouter == Mnil)
                {
@@ -499,44 +542,62 @@ combining_code_from_class (int class)
 }
 
 
 }
 
 
+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);
   MGlyph *g = MGLYPH (from);
   MGlyph *last_g = MGLYPH (to);
+  int i;
 
   g_physical_ascent = gstring->physical_ascent;
   g_physical_descent = gstring->physical_descent;
 
   g_physical_ascent = gstring->physical_ascent;
   g_physical_descent = gstring->physical_descent;
-  g_width = g_lbearing = g_rbearing = 0;
+  extents->width = extents->lbearing = extents->rbearing = 0;
 
 
-  mfont__get_metric (gstring, from, to);
-
-#ifdef HAVE_OTF
-  while (g < last_g)
+  for (i = from; i < to;)
     {
     {
-      MGlyph *base = g++;
-
-      if (base->otf_cmd)
+      if ( MGLYPH (i)->otf_encoded)
+       i++;
+      else
        {
        {
-         while (g < last_g && base->otf_cmd == g->otf_cmd) g++;
-         mfont__ft_drive_gpos (gstring, GLYPH_INDEX (base), GLYPH_INDEX (g));
+         int j = i++;
+
+         while (i < to && ! MGLYPH (i)->otf_encoded) i++;
+         mfont__get_metric (gstring, j, i);
        }
     }
        }
     }
-  g = MGLYPH (from);
-#endif
 
 
+  g = MGLYPH (from);
   while (g < last_g)
     {
       MGlyph *base = g++;
       MRealizedFont *rfont = base->rface->rfont;
   while (g < last_g)
     {
       MGlyph *base = g++;
       MRealizedFont *rfont = base->rface->rfont;
-      int size = rfont->font.property[MFONT_SIZE];
+      int size = rfont->spec.size;
       int width, lbearing, rbearing;
 
       if (g == last_g || ! g->combining_code)
        {
          /* No combining.  */
       int width, lbearing, rbearing;
 
       if (g == last_g || ! g->combining_code)
        {
          /* No combining.  */
+         if (base->width == 0 && ! base->left_padding && ! base->right_padding
+             && GLYPH_INDEX (base) > from)
+           {
+             MGlyph *prev = base - 1; 
+
+             if (base->pos < prev->pos)
+               prev->pos = base->pos;
+             else
+               base->pos = prev->pos;
+             if (base->to > prev->to)
+               prev->to = base->to;
+             else
+               base->to = prev->to;
+           }
+
          if (base->left_padding && base->lbearing < 0)
            {
              base->xoff = - base->lbearing;
          if (base->left_padding && base->lbearing < 0)
            {
              base->xoff = - base->lbearing;
@@ -548,8 +609,9 @@ layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to)
            {
              base->width = base->rbearing;
            }
            {
              base->width = base->rbearing;
            }
-         lbearing = (base->lbearing < 0 ? base->lbearing : 0);
-         rbearing = base->rbearing;
+         lbearing = (base->xoff + base->lbearing < 0
+                     ? base->xoff + base->lbearing : 0);
+         rbearing = base->xoff + base->rbearing;
        }
       else
        {
        }
       else
        {
@@ -569,48 +631,53 @@ layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to)
 
          while (g != last_g && g->combining_code)
            {
 
          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);
+             int combining_code = g->combining_code;
 
              if (begin > g->pos)
                begin = g->pos;
              else if (end < g->to)
                end = g->to;
                
 
              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 (! COMBINING_PRECOMPUTED_P (combining_code))
+               {
+                 int base_x, base_y, add_x, add_y, off_x, off_y;
+
+                 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->spec.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);
+
+                 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 (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->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 (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)
              if (g->yoff - g->ascent < top)
                top = g->yoff - g->ascent;
              if (g->yoff + g->descent > bottom)
@@ -650,16 +717,13 @@ layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to)
 
       g_physical_ascent = MAX (g_physical_ascent, base->ascent);
       g_physical_descent = MAX (g_physical_descent, base->descent);
 
       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;
+      extents->lbearing = MIN (extents->lbearing, extents->width + lbearing);
+      extents->rbearing = MAX (extents->rbearing, extents->width + rbearing);
+      extents->width += base->width;
     }
 
   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;
 }
 
 
 }
 
 
@@ -745,7 +809,7 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
            }
        }
 
            }
        }
 
-      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)
@@ -760,18 +824,24 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
                || box != g->rface->box
                || ((fromg->code == MCHAR_INVALID_CODE)
                    != (g->code == MCHAR_INVALID_CODE))
                || box != g->rface->box
                || ((fromg->code == MCHAR_INVALID_CODE)
                    != (g->code == MCHAR_INVALID_CODE))
-               || (g->category == McatCf && ignore_formatting_char))
+               || (g->category == GLYPH_CATEGORY_FORMATTER
+                   && ignore_formatting_char))
              break;
          if (rfont && fromg->code != MCHAR_INVALID_CODE)
            {
              int extra_width;
              int to = GLYPH_INDEX (g);
              break;
          if (rfont && fromg->code != MCHAR_INVALID_CODE)
            {
              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;
                {
                  g = MGLYPH (from);
                  pad = *g;
@@ -779,11 +849,12 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
                  pad.xoff = 0;
                  pad.lbearing = 0;
                  pad.width = pad.rbearing = extra_width;
                  pad.xoff = 0;
                  pad.lbearing = 0;
                  pad.width = pad.rbearing = extra_width;
+                 pad.left_padding = 1;
                  INSERT_GLYPH (gstring, from, pad);
                  to++;
                  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)
@@ -802,7 +873,7 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
                        }
                      else
                        {
                        }
                      else
                        {
-                         extra_width -= g->width - 2;
+                         extra_width = g->width - 2;
                          g->width = 2;
                        }
                      gstring->width -= extra_width;
                          g->width = 2;
                        }
                      gstring->width -= extra_width;
@@ -810,36 +881,38 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
                    }
                }
 
                    }
                }
 
-             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.xoff = 0;
                      pad.lbearing = 0;
                      pad.width = pad.rbearing = extra_width;
                      INSERT_GLYPH (gstring, to, pad);
                      to++;
                      pad.type = GLYPH_PAD;
                      pad.xoff = 0;
                      pad.lbearing = 0;
                      pad.width = pad.rbearing = extra_width;
                      INSERT_GLYPH (gstring, to, pad);
                      to++;
+                     g = MGLYPH (to);
                    }
                  else
                    g[-1].width += extra_width;
                    }
                  else
                    g[-1].width += extra_width;
-                 gstring->sub_width += 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
            {
            }
          else
            {
@@ -1012,7 +1085,8 @@ 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;
          && gstring->from <= control->cursor_pos - 1
          && gstring->to > control->cursor_pos - 1)
        prev_pos = control->cursor_pos - 1;
@@ -1074,11 +1148,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);
@@ -1205,7 +1277,8 @@ render_glyphs (MFrame *frame, MDrawWindow win, int x, int y, int width,
          while (g != gend
                 && g->type == from_g->type
                 && g->rface == rface
          while (g != gend
                 && g->type == from_g->type
                 && g->rface == rface
-                && (g->code < 0) == (from_g->code < 0)
+                && ((g->code == MCHAR_INVALID_CODE)
+                    == (from_g->code == MCHAR_INVALID_CODE))
                 && g->enabled)
            width += g++->width;
 
                 && g->enabled)
            width += g++->width;
 
@@ -1403,7 +1476,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].c = '\n';
+         gstring->glyphs[1].code = '\n';
+       }
+      gstring->from = pos;
+      g = MGLYPH (0);
+      g->rface = frame->rface;
+      g->pos = g->to = pos;
+      g++;
+      g->rface = frame->rface;
+      g->pos = pos++, g->to = pos;
+      g++;
+      g->rface = frame->rface;
+      g->pos = g->to = pos;
+      gstring->to = pos;
     }
   else
     {
     }
   else
     {
@@ -1415,7 +1514,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)
@@ -1438,9 +1536,9 @@ 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++)
@@ -1458,11 +1556,15 @@ 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)
+       pos = gstring->from + 1;
+      else if (pos >= gstring->to)
+       pos = gstring->to;
     }
     }
+  else if (i == 0)
+    pos++;
   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);
 }
@@ -1495,7 +1597,9 @@ 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_width != gstring->control.cursor_width
+             || control->cursor_bidi != gstring->control.cursor_bidi)
            {
              mtext_detach_property (prop);
              gstring = NULL;
            {
              mtext_detach_property (prop);
              gstring = NULL;
@@ -1536,26 +1640,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;
@@ -1662,6 +1763,100 @@ find_glyph_in_gstring (MGlyphString *gstring, int pos, int forwardp)
   return g;
 }
 
   return g;
 }
 
+#define GET_LB_TYPE(MT, POS, LB_TYPE)                                  \
+  do {                                                                 \
+    int c = mtext_ref_char ((MT), (POS));                              \
+    (LB_TYPE) = ((c == ' ' || c == '\t' || c == '\n') ? M_kinsoku_bol  \
+                : mchartable_lookup (linebreak_table, c));             \
+  } while (0)
+
+static int
+find_break_backward (MText *mt, int pos, int limit)
+{
+  MSymbol lb_type;
+
+  if (pos <= limit)
+    return limit;
+
+  GET_LB_TYPE (mt, pos, lb_type);
+  if (lb_type == M_kinsoku_bol)
+    return find_break_backward (mt, pos - 1, limit);
+  if (lb_type == Mnil)
+    {
+      while (pos > limit)
+       {
+         GET_LB_TYPE (mt, pos - 1, lb_type);
+         if (lb_type != Mnil)
+           break;
+         pos--;
+       }
+    }
+  else if (lb_type == M_break_at_word)
+    {
+      int beg = limit, end = mtext_nchars (mt);
+      int in_word = mtext__word_segment (mt, pos, &beg, &end);
+
+      if (in_word)
+       pos = beg;
+      else if (beg > limit)
+       {
+         end = beg;
+         beg = limit;
+         mtext__word_segment (mt, beg - 1, &beg, &end);
+         pos = beg;
+       }
+    }
+  while (pos > limit)
+    {
+      GET_LB_TYPE (mt, pos - 1, lb_type);
+      if (lb_type != M_kinsoku_eol)
+       return pos;
+      pos--;
+    }
+  return limit;
+}
+
+static int
+find_break_forward (MText *mt, int pos, int limit)
+{
+  MSymbol lb_type;
+
+  GET_LB_TYPE (mt, pos, lb_type);
+  if (lb_type == Mnil)
+    {
+      while (pos < limit)
+       {
+         pos++;
+         GET_LB_TYPE (mt, pos, lb_type);
+       }
+    }
+  else if (lb_type == M_break_at_word)
+    {
+      int beg = 0, end = mtext_nchars (mt);
+      int in_word = mtext__word_segment (mt, pos, &beg, &end);
+
+      if (! in_word)
+       pos = end;
+      else if (end < limit)
+       {
+         beg = end;
+         pos = end = mtext_nchars (mt);
+         mtext__word_segment (mt, pos, &beg, &end);
+         pos = end;
+       }
+    }
+  else if (lb_type == M_kinsoku_bol)
+    pos++;
+  while (pos < limit)
+    {
+      GET_LB_TYPE (mt, pos, lb_type);
+      if (lb_type != M_kinsoku_bol)
+       return pos;
+      pos++;
+    }
+  return limit;
+}
+
 \f
 /* for debugging... */
 char work[16];
 \f
 /* for debugging... */
 char work[16];
@@ -1736,8 +1931,8 @@ 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");
   Minherited = msymbol ("inherited");
+  Mcommon = msymbol ("common");
 
   McatCc = msymbol ("Cc");
   McatCf = msymbol ("Cf");
 
   McatCc = msymbol ("Cc");
   McatCf = msymbol ("Cf");
@@ -1752,6 +1947,12 @@ mdraw__init ()
   fribidi_set_mirroring (TRUE);
 #endif
 
   fribidi_set_mirroring (TRUE);
 #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");
+
   return 0;
 }
 
   return 0;
 }
 
@@ -1759,6 +1960,8 @@ void
 mdraw__fini ()
 {
   MLIST_FREE1 (&scratch_gstring, glyphs);
 mdraw__fini ()
 {
   MLIST_FREE1 (&scratch_gstring, glyphs);
+  M17N_OBJECT_UNREF (linebreak_table);
+  linebreak_table = NULL;
 }
 
 /*** @} */
 }
 
 /*** @} */
@@ -1814,7 +2017,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.
@@ -1844,67 +2047,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  */
 
@@ -1953,21 +2146,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 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #m_errro ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
 
     @latexonly \IPAlabel{mdraw_image_text} @endlatexonly   */
 
 
     @latexonly \IPAlabel{mdraw_image_text} @endlatexonly   */
 
@@ -2010,19 +2202,18 @@ mdraw_image_text (MFrame *frame, MDrawWindow win, int x, int y,
     more detail.  */
 
 /***ja
     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,
@@ -2049,13 +2240,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
@@ -2073,31 +2264,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  */
 
@@ -2213,15 +2404,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 
@@ -2230,11 +2420,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,
@@ -2268,7 +2456,7 @@ mdraw_text_per_char_extents (MFrame *frame,
       return 0;
     }
 
       return 0;
     }
 
-  for (g = MGLYPH (1), x = 0; g->type != GLYPH_ANCHOR;)
+  for (g = MGLYPH (1), x = 0; g->type != GLYPH_ANCHOR; g++)
     if (g->pos >= from && g->pos < to)
       {
        int start = g->pos;
     if (g->pos >= from && g->pos < to)
       {
        int start = g->pos;
@@ -2278,9 +2466,19 @@ mdraw_text_per_char_extents (MFrame *frame,
        int rbearing = g->rbearing;
        int ascent = g->ascent;
        int descent = g->descent;
        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;
+       int logical_ascent;
+       int logical_descent;
 
 
+       if (g->rface->rfont)
+         {
+           logical_ascent = g->rface->rfont->ascent;
+           logical_descent = g->rface->rfont->descent;
+         }
+       else
+         {
+           logical_ascent = g->rface->ascent;
+           logical_descent = g->rface->descent;
+         }
        for (g++; g->type != GLYPH_ANCHOR && g->pos == start; g++)
          {
            if (lbearing < width + g->lbearing)
        for (g++; g->type != GLYPH_ANCHOR && g->pos == start; g++)
          {
            if (lbearing < width + g->lbearing)
@@ -2298,18 +2496,25 @@ mdraw_text_per_char_extents (MFrame *frame,
          end = to;
        while (start < end)
          {
          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)
@@ -2351,12 +2556,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.  */
@@ -2365,25 +2570,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 ¾å¤ËÉÁ²è¤µ¤ì¤ëºÇ¸å¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£ */
 
@@ -2420,7 +2621,7 @@ 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++)
+      for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++)
        if (g->pos >= from && g->pos < to)
          {
            width += g->width;
        if (g->pos >= from && g->pos < to)
          {
            width += g->width;
@@ -2439,6 +2640,10 @@ mdraw_coordinates_position (MFrame *frame, MText *mt, int from, int to,
              break;
          }
     }
              break;
          }
     }
+  if (g->type == GLYPH_ANCHOR
+      && control->two_dimensional
+      && g[-1].c == '\n')
+    g--;
   from = g->pos;
   M17N_OBJECT_UNREF (gstring->top);
 
   from = g->pos;
   M17N_OBJECT_UNREF (gstring->top);
 
@@ -2460,10 +2665,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 ¤Î¥á¥ó¥Ð¤ËÊÝ»ý¤µ¤ì¤ë¡£  */
 
@@ -2515,13 +2720,12 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
     }
   info->from = g->pos;
   info->to = g->to;
     }
   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->metrics.x = g->lbearing;
+  info->metrics.y = - gstring->line_ascent;
+  info->metrics.height = gstring->height;
+  info->metrics.width = - g->lbearing + g->width;
   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.  */
@@ -2603,8 +2807,8 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
 
   for (info->logical_width = (g++)->width;
        g->pos == pos && g->type != GLYPH_ANCHOR;
 
   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;
+       info->metrics.width += g->width, info->logical_width += (g++)->width);
+  info->metrics.width += g[-1].rbearing - g[-1].width;
 
   if (g->type != GLYPH_ANCHOR)
     info->right_from = g->pos, info->right_to = g->to;
 
   if (g->type != GLYPH_ANCHOR)
     info->right_from = g->pos, info->right_to = g->to;
@@ -2641,14 +2845,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 = 0;
 
   ASSURE_CONTROL (control);
   *num_glyphs_return = 0;
 
   ASSURE_CONTROL (control);
   *num_glyphs_return = 0;
@@ -2661,26 +2904,47 @@ mdraw_glyph_list (MFrame *frame, MText *mt, int from, int to,
       if (g->type == GLYPH_BOX
          || g->pos < from || g->pos >= to)
        continue;
       if (g->type == GLYPH_BOX
          || g->pos < from || g->pos >= to)
        continue;
+      if (g->type == GLYPH_PAD)
+       {
+         if (g->left_padding)
+           pad_width = g->width;
+         else if (n > 0)
+           {
+             pad_width = 0;
+             glyphs[-1].x_advance += g->width;
+           }
+         continue;
+       }
       if (n < array_size)
        {
       if (n < array_size)
        {
-         info->from = g->pos;
-         info->to = g->to;
-         if (g->type == GLYPH_CHAR)
-           info->glyph_code = g->code;
-         else
-           info->glyph_code = mfont__encode_char (g->rface->rfont, ' ');
-         info->x = g->xoff;
-         info->y = g->yoff;
-         info->this.x = g->lbearing;
-         info->this.y = - g->ascent;
-         info->this.height = g->ascent + g->descent;
-         info->this.width = g->rbearing - g->lbearing;
-         info->logical_width = g->width;
+         glyphs->from = g->pos;
+         glyphs->to = g->to;
+         glyphs->glyph_code = g->code;
+         glyphs->x_off = g->xoff + pad_width;
+         glyphs->y_off = g->yoff;
+         glyphs->lbearing = g->lbearing;
+         glyphs->rbearing = g->rbearing;
+         glyphs->ascent = g->ascent;
+         glyphs->descent = g->descent;
+         glyphs->x_advance = g->width + 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;
+             glyphs->font_type
+               = (g->rface->rfont->font->type == MFONT_SOURCE_X ? Mx
+                  : g->rface->rfont->driver == &mfont__ft_driver ? Mfreetype
+                  : Mxft);
+             glyphs->fontp = g->rface->rfont->fontp;
+           }
          else
          else
-           info->font = NULL;
-         info++;
+           {
+             glyphs->font = NULL;
+             glyphs->font_type = Mnil;
+             glyphs->fontp = NULL;
+           }
+         pad_width = 0;
+         glyphs++;
        }
       n++;
     }
        }
       n++;
     }
@@ -2696,17 +2960,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  */
 
@@ -2745,61 +3008,62 @@ mdraw_text_items (MFrame *frame, MDrawWindow win, int x, int y,
       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
       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
+      first character of the line, and $TO is the position of the last
       character displayed on the line if there were not width limit.
       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
+      $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.
       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;
+  int p;
 
 
-  if (c == ' ' || c == '\t')
+  if (! linebreak_table)
     {
     {
-      pos++;
-      while (pos < to
-            && ((c = mtext_ref_char (mt, pos)) == ' ' || c == '\t'))
-       pos++;
+      MDatabase *mdb = mdatabase_find (Mchar_table, Msymbol,
+                                      msymbol ("linebreak"), Mnil);
+
+      if (mdb)
+       linebreak_table = mdatabase_load (mdb);
+      if (! linebreak_table)
+       linebreak_table = mchartable (Msymbol, Mnil);
     }
     }
-  else
+
+  if (pos > from)
     {
     {
-      while (pos > from)
-       {
-         if (c == ' ' || c == '\t')
-           break;
-         pos--;
-         c = mtext_ref_char (mt, pos);
-       }
-      if (pos == from)
-       pos = orig_pos;
-      else
-       pos++;
+      p = find_break_backward (mt, pos, from);
+      if (p > from)
+       return p;
     }
     }
-  return pos;
+  if (pos < to)
+    {
+      p = find_break_forward (mt, pos, to);
+      if (p < to)
+       return p;
+    }
+  return to;
 }
 
 /*=*/
 }
 
 /*=*/
@@ -2824,17 +3088,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  */
 
@@ -2854,7 +3118,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
@@ -2862,10 +3126,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 */