Include <stdio.h>.
[m17n/m17n-lib.git] / src / draw.c
index e0921f8..c4d3c4a 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;
 /* Special categories */
 static MSymbol McatCc, McatCf;
 
 /* Special categories */
 static MSymbol McatCc, McatCf;
 
-static MSymbol Mdepth;
+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.  */
@@ -101,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--;
@@ -166,36 +169,35 @@ 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 (g->rface->rfont, 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;
     }
 }
 
     }
 }
 
@@ -225,9 +227,9 @@ 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,
 
 static void
 compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
@@ -235,137 +237,173 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
 {
   MRealizedFace *default_rface = frame->rface;
   int stop, face_change, language_change, charset_change;
 {
   MRealizedFace *default_rface = frame->rface;
   int stop, face_change, language_change, charset_change;
-  MGlyph g_tmp, *g;
+  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;
-  int non_ascii_found;
+  MRealizedFont *rfont;
   int size = gstring->control.fixed_width;
   int size = gstring->control.fixed_width;
-  int i, limit;
-  int last;
+  int i;
 
   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;
-  non_ascii_found = 0;
+  stop = face_change = pos = from;
   while (1)
     {
       int c;
   while (1)
     {
       int c;
-      MSymbol this_script;
-
-      if (pos < mtext_nchars (mt))
-       c = mtext_ref_char (mt, pos);
-      else
-       c = '\n';
-      g_tmp.category = Mnil;
-      if (c < 0x100)
-       {
-         if (c == ' ' || c == '\n' || c == '\t')
-           g_tmp.type = GLYPH_SPACE, this_script = Mnil;
-         else
-           g_tmp.type = GLYPH_CHAR, 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);
-         if (this_script == Minherited)
-           this_script = script;
-       }
+      MSymbol category;
 
 
-      if (pos == stop || script != this_script
-         || MGLYPH (last)->type != g_tmp.type)
+      if (pos == stop)
        {
        {
-         g = MGLYPH (last);
-         if (non_ascii_found && g->type == GLYPH_CHAR)
-           while (g < gstring->glyphs + gstring->used)
-             g = mface__for_chars (script, language, charset,
-                                   g, gstring->glyphs + gstring->used, size);
-         last = gstring->used;
-         non_ascii_found = 0;
-         script = this_script;
          if (pos == to)
            break;
          if (pos == to)
            break;
-         if (pos < mtext_nchars (mt) && pos == language_change)
+         if (pos == face_change)
            {
            {
-             language = (MSymbol) mtext_get_prop (mt, pos, Mlanguage);
-             mtext_prop_range (mt, Mlanguage, pos, NULL, &language_change, 0);
-           }
-         if (pos < mtext_nchars (mt) && pos == charset_change)
-           {
-             charset = (MSymbol) mtext_get_prop (mt, pos, Mcharset);
-             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);
+             if (pos < mtext_nchars (mt))
+               {
+                 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);
+                 if (face_change == mtext_nchars (mt))
+                   face_change++;
+                 rface = (num > 0 ? mface__realize (frame, faces, num, size)
+                          : default_rface);
+               }
+             else
+               rface = default_rface;
            }
          stop = to;
            }
          stop = to;
-         if (stop > language_change)
-           stop = language_change;
-         if (stop > charset_change)
-           stop = charset_change;
-         if (face_change < stop)
+         if (stop > face_change)
            stop = face_change;         
        }
 
            stop = face_change;         
        }
 
-      g_tmp.c = g_tmp.code = c;
+      if (pos < mtext_nchars (mt))
+       c = mtext_ref_char (mt, pos);
+      else
+       c = '\n';
+      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;
       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 >= 0x100)
-       non_ascii_found = 1;
-      else if (g_tmp.type == GLYPH_CHAR && (c <= 32 || c == 127))
+      if ((c <= ' ' || c == 127) && g_tmp.type == GLYPH_CHAR)
        {
        {
-         g_tmp.code = '^';
-         APPEND_GLYPH (gstring, g_tmp);
-         if (c < ' ')
-           g_tmp.code = g_tmp.c + 0x40;
-         else
-           g_tmp.code = '?';
+         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]);
        }
        }
-      APPEND_GLYPH (gstring, g_tmp);
-      if (c == '\n'
-         && gstring->control.two_dimensional)
+      else
+       APPEND_GLYPH (gstring, g_tmp);
+      if (c == '\n' && gstring->control.two_dimensional)
        break;
     }
        break;
     }
-
-  limit = pos - from;
-
   /* Append an anchor glyph.  */
   /* Append an anchor glyph.  */
+  INIT_GLYPH (g_tmp);
   g_tmp.type = GLYPH_ANCHOR;
   g_tmp.type = GLYPH_ANCHOR;
-  g_tmp.c = 0;
-  g_tmp.code = MCHAR_INVALID_CODE;
   g_tmp.pos = g_tmp.to = pos;
   g_tmp.pos = g_tmp.to = pos;
-  g_tmp.rface = NULL;
   APPEND_GLYPH (gstring, g_tmp);
   APPEND_GLYPH (gstring, g_tmp);
-
   gstring->to = pos;
 
   gstring->to = pos;
 
-  /* Next, run FLT if necessary.  */
-  for (i = 1, g = MGLYPH (i); g->type != GLYPH_ANCHOR;)
+  /* 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
+       {
+         this_script = (MSymbol) mchar_get_prop (c, Mscript);
+         if (this_script == Minherited || this_script == Mnil)
+           this_script = script;
+         if (this_script == Mnil)
+           this_script = non_latin_script;
+         if (this_script == Mnil)
+           {
+             /* 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)) != Mnil
+                   && sym != Minherited)
+                 {
+                   this_script = sym;
+                   break;
+                 }
+           }
+       }
+
+      pos = g->pos;
+      if (pos == stop || script != this_script || g->rface->rfont != rfont)
+       {
+         while (last_g < g)
+           last_g = mface__for_chars (script, language, charset,
+                                      last_g, g, size);
+         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)
+               {
+                 language = (MSymbol) mtext_get_prop (mt, pos, Mlanguage);
+                 mtext_prop_range (mt, Mlanguage, pos, NULL,
+                                   &language_change, 0);
+               }
+             if (pos < mtext_nchars (mt) && pos == charset_change)
+               {
+                 charset = (MSymbol) mtext_get_prop (mt, pos, Mcharset);
+                 mtext_prop_range (mt, Mcharset, pos, NULL,
+                                   &charset_change, 0);
+               }
+             stop = to;
+             if (stop > language_change)
+               stop = language_change;
+             if (stop > charset_change)
+               stop = charset_change;
+           }
+       }
+    }
+  while (last_g < g)
+    last_g = mface__for_chars (script, language, charset, last_g, g, size);
+
+  /* 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;
 
@@ -380,7 +418,7 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
 
              for (prev = MGLYPH (start - 1);
                   (prev->type == GLYPH_CHAR
 
              for (prev = MGLYPH (start - 1);
                   (prev->type == GLYPH_CHAR
-                   && prev->category == McatCf
+                   && prev->category == GLYPH_CATEGORY_FORMATTER
                    && (code = mfont__encode_char (this->rface->rfont, prev->c)
                        != MCHAR_INVALID_CODE));
                   start--, prev--)
                    && (code = mfont__encode_char (this->rface->rfont, prev->c)
                        != MCHAR_INVALID_CODE));
                   start--, prev--)
@@ -389,21 +427,23 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
              for (g++;
                   (g->type == GLYPH_CHAR
                    && (g->rface->rfont == this->rface->rfont
              for (g++;
                   (g->type == GLYPH_CHAR
                    && (g->rface->rfont == this->rface->rfont
-                       || (g->category == McatCf
+                       || (g->category == GLYPH_CATEGORY_FORMATTER
                            && ((code = mfont__encode_char (this->rface->rfont,
                                                            g->c))
                                != MCHAR_INVALID_CODE))));
                   i++, g++)
                if (g->rface->rfont != this->rface->rfont)
                            && ((code = mfont__encode_char (this->rface->rfont,
                                                            g->c))
                                != MCHAR_INVALID_CODE))));
                   i++, g++)
                if (g->rface->rfont != this->rface->rfont)
-                 g->code = code;
+                 {
+                   g->rface->rfont = this->rface->rfont;
+                   g->code = code;
+                 }
              i = mfont__flt_run (gstring, start, i, this->rface);
            }
          else
            {
              while (this->type == GLYPH_CHAR
                     && this->c >= 0x100
              i = mfont__flt_run (gstring, start, i, this->rface);
            }
          else
            {
              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)
                {
@@ -415,6 +455,8 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
                }
              if (start + 1 < i)
                reorder_combining_chars (gstring, start, i);
                }
              if (start + 1 < i)
                reorder_combining_chars (gstring, start, i);
+             if (this->type == GLYPH_ANCHOR)
+               break;
            }
          g = MGLYPH (i);
        }
            }
          g = MGLYPH (i);
        }
@@ -479,20 +521,37 @@ 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);
+  for (i = from; i < to;)
+    {
+      if ( MGLYPH (i)->otf_encoded)
+       i++;
+      else
+       {
+         int j = i++;
+
+         while (i < to && ! MGLYPH (i)->otf_encoded) i++;
+         mfont__get_metric (gstring, j, i);
+       }
+    }
 
 
+  g = MGLYPH (from);
   while (g < last_g)
     {
       MGlyph *base = g++;
   while (g < last_g)
     {
       MGlyph *base = g++;
@@ -503,6 +562,21 @@ layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to)
       if (g == last_g || ! g->combining_code)
        {
          /* No combining.  */
       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;
@@ -514,8 +588,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
        {
@@ -535,48 +610,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->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);
+
+                 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)
@@ -616,16 +696,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;
 }
 
 
 }
 
 
@@ -711,7 +788,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)
@@ -726,18 +803,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;
@@ -745,11 +828,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)
@@ -768,7 +852,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;
@@ -776,36 +860,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
            {
@@ -978,7 +1064,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;
@@ -1012,7 +1099,6 @@ draw_background (MFrame *frame, MDrawWindow win, int x, int y,
            }
          if (width > 0
              && (control->as_image
            }
          if (width > 0
              && (control->as_image
-                 || rface->face.property[MFACE_BACKGROUND] != Mnil
                  || rface->face.property[MFACE_VIDEOMODE] == Mreverse))
            {
              int this_x = x, this_width = width;
                  || rface->face.property[MFACE_VIDEOMODE] == Mreverse))
            {
              int this_x = x, this_width = width;
@@ -1021,10 +1107,11 @@ draw_background (MFrame *frame, MDrawWindow win, int x, int y,
                this_x += fromg->width, this_width -= fromg->width;
              if (g[-1].type == GLYPH_BOX)
                this_width -= g[-1].width;
                this_x += fromg->width, this_width -= fromg->width;
              if (g[-1].type == GLYPH_BOX)
                this_width -= g[-1].width;
-             mwin__fill_space (frame, win, rface, 0,
-                               this_x, y - gstring->text_ascent, this_width,
-                               gstring->text_ascent + gstring->text_descent,
-                               control->clip_region);
+             (frame->driver->fill_space)
+               (frame, win, rface, 0,
+                this_x, y - gstring->text_ascent, this_width,
+                gstring->text_ascent + gstring->text_descent,
+                control->clip_region);
            }
          if (cursor)
            {
            }
          if (cursor)
            {
@@ -1040,30 +1127,27 @@ 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;
-               }
-             mwin__fill_space (frame, win, rface, 1,
-                               rect.x, rect.y, rect.width, rect.height,
-                               control->clip_region);
+               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);
              if (! region)
              if (! region)
-               region = mwin__region_from_rect (&rect);
+               region = (*frame->driver->region_from_rect) (&rect);
              else
              else
-               mwin__region_add_rect (region, &rect);
-             mwin__verify_region (frame, region);
+               (*frame->driver->region_add_rect) (region, &rect);
              if (cursor_bidi)
                {
                  if (cursor->bidi_level % 2)
                    rect.x -= 3;
                  rect.height = 2;
                  rect.width = cursor_width < 4 ? cursor_width : 4;
              if (cursor_bidi)
                {
                  if (cursor->bidi_level % 2)
                    rect.x -= 3;
                  rect.height = 2;
                  rect.width = cursor_width < 4 ? cursor_width : 4;
-                 mwin__fill_space (frame, win, rface, 1,
-                                   rect.x, rect.y, rect.width, rect.height,
-                                   control->clip_region);
-                 mwin__region_add_rect (region, &rect);
-                 mwin__verify_region (frame, region);
+                 (*frame->driver->fill_space)
+                   (frame, win, rface, 1,
+                    rect.x, rect.y, rect.width, rect.height,
+                    control->clip_region);
+                 (*frame->driver->region_add_rect) (region, &rect);
                }
            }
 
                }
            }
 
@@ -1094,24 +1178,23 @@ draw_background (MFrame *frame, MDrawWindow win, int x, int y,
                  rect.y = y - gstring->text_ascent;
                  rect.height = gstring->text_ascent + gstring->text_descent;
                  rect.width = 1;
                  rect.y = y - gstring->text_ascent;
                  rect.height = gstring->text_ascent + gstring->text_descent;
                  rect.width = 1;
-                 mwin__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);
                  if (! region)
                  if (! region)
-                   region = mwin__region_from_rect (&rect);
+                   region = (*frame->driver->region_from_rect) (&rect);
                  else
                  else
-                   mwin__region_add_rect (region, &rect);
-                 mwin__verify_region (frame, region);
+                   (*frame->driver->region_add_rect) (region, &rect);
                  rect.y += rect.height - 2;
                  rect.height = 2;
                  rect.width = cursor_width < 4 ? cursor_width : 4;
                  if (! (cursor->bidi_level % 2))
                    rect.x -= rect.width - 1;
                  rect.y += rect.height - 2;
                  rect.height = 2;
                  rect.width = cursor_width < 4 ? cursor_width : 4;
                  if (! (cursor->bidi_level % 2))
                    rect.x -= rect.width - 1;
-                 mwin__fill_space (frame, win, rface, 1,
+                 (*frame->driver->fill_space) (frame, win, rface, 1,
                                    rect.x, rect.y, rect.width, rect.height,
                                    control->clip_region);
                                    rect.x, rect.y, rect.width, rect.height,
                                    control->clip_region);
-                 mwin__region_add_rect (region, &rect);
-                 mwin__verify_region (frame, region);
+                 (*frame->driver->region_add_rect) (region, &rect);
                }
            }
          x += width;
                }
            }
          x += width;
@@ -1135,7 +1218,7 @@ render_glyphs (MFrame *frame, MDrawWindow win, int x, int y, int width,
     {
       MDrawMetric rect;
 
     {
       MDrawMetric rect;
 
-      mwin__region_to_rect (region, &rect);
+      (*frame->driver->region_to_rect) (region, &rect);
       if (rect.x > x)
        {
          while (g != gend && x + g->rbearing <= rect.x)
       if (rect.x > x)
        {
          while (g != gend && x + g->rbearing <= rect.x)
@@ -1173,38 +1256,37 @@ 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;
 
          if (from_g->type == GLYPH_CHAR)
            {
                 && g->enabled)
            width += g++->width;
 
          if (from_g->type == GLYPH_CHAR)
            {
-             MFontDriver *driver;
-
-             if (rface->rfont && from_g->code >= 0)
-               driver = rface->rfont->driver;
+             if (rface->rfont && from_g->code != MCHAR_INVALID_CODE)
+               (rface->rfont->driver->render) (win, x, y, gstring, from_g, g,
+                                               reverse, region);
              else
              else
-               driver = mfont__driver_list[MFONT_TYPE_WIN];
-             (driver->render) (win, x, y, gstring, from_g, g,
-                               reverse, region);
+               (*frame->driver->draw_empty_boxes) (win, x, y, gstring, from_g, g,
+                                       reverse, region);
            }
          else if (from_g->type == GLYPH_BOX)
            {
              /* Draw the left or right side of a box.  If
                 from_g->lbearing is nonzero, this is the left side,
                 else this is the right side.  */
            }
          else if (from_g->type == GLYPH_BOX)
            {
              /* Draw the left or right side of a box.  If
                 from_g->lbearing is nonzero, this is the left side,
                 else this is the right side.  */
-             mwin__draw_box (frame, win, gstring, from_g, x, y, 0, region);
+             (*frame->driver->draw_box) (frame, win, gstring, from_g, x, y, 0, region);
            }
 
          if (from_g->type != GLYPH_BOX)
            {
              if (rface->hline)
            }
 
          if (from_g->type != GLYPH_BOX)
            {
              if (rface->hline)
-               mwin__draw_hline (frame, win, gstring, rface, reverse,
+               (*frame->driver->draw_hline) (frame, win, gstring, rface, reverse,
                                  x, y, width, region);
              if (rface->box
                  && ! reverse)
                /* Draw the top and bottom side of a box.  */
                                  x, y, width, region);
              if (rface->box
                  && ! reverse)
                /* Draw the top and bottom side of a box.  */
-                  mwin__draw_box (frame, win, gstring, from_g,
+               (*frame->driver->draw_box) (frame, win, gstring, from_g,
                                   x, y, width, region);
            }
          x += width;
                                   x, y, width, region);
            }
          x += width;
@@ -1321,9 +1403,9 @@ render_glyph_string (MFrame *frame, MDrawWindow win, int x, int y,
        {
          rect.y = y - gstring->line_ascent;
          rect.height = gstring->height;
        {
          rect.y = y - gstring->line_ascent;
          rect.height = gstring->height;
-         clip_region = mwin__region_from_rect (&rect);
+         clip_region = (*frame->driver->region_from_rect) (&rect);
          if (control->clip_region)
          if (control->clip_region)
-           mwin__intersect_region (clip_region, control->clip_region);
+           (*frame->driver->intersect_region) (clip_region, control->clip_region);
        }
       else
        clip_region = control->clip_region;
        }
       else
        clip_region = control->clip_region;
@@ -1336,14 +1418,14 @@ render_glyph_string (MFrame *frame, MDrawWindow win, int x, int y,
   if (cursor_region)
     {
       if (clip_region)
   if (cursor_region)
     {
       if (clip_region)
-       mwin__intersect_region (cursor_region, clip_region);
+       (*frame->driver->intersect_region) (cursor_region, clip_region);
       render_glyphs (frame, win, x, y, to_x - x, gstring, from_idx, to_idx,
                     1, cursor_region);
     }
   if (clip_region != control->clip_region)
       render_glyphs (frame, win, x, y, to_x - x, gstring, from_idx, to_idx,
                     1, cursor_region);
     }
   if (clip_region != control->clip_region)
-    mwin__free_region (clip_region);
+    (*frame->driver->free_region) (clip_region);
   if (cursor_region)
   if (cursor_region)
-    mwin__free_region (cursor_region);
+    (*frame->driver->free_region) (cursor_region);
   return;
 }
 
   return;
 }
 
@@ -1373,7 +1455,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
     {
@@ -1382,8 +1490,9 @@ alloc_gstring (MFrame *frame, MText *mt, int pos, MDrawControl *control,
       gstring_num++;
     }
 
       gstring_num++;
     }
 
+  gstring->frame = frame;
+  gstring->tick = frame->tick;
   gstring->top = gstring;
   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)
@@ -1391,9 +1500,6 @@ alloc_gstring (MFrame *frame, MText *mt, int pos, MDrawControl *control,
   else
     gstring->width_limit = control->max_line_width;
   gstring->anti_alias = control->anti_alias;
   else
     gstring->width_limit = control->max_line_width;
   gstring->anti_alias = control->anti_alias;
-  if (gstring->anti_alias
-      && (unsigned) mwin__device_get_prop (frame->device, Mdepth) < 8)
-    gstring->anti_alias = 0;
   return gstring;
 }
 
   return gstring;
 }
 
@@ -1409,9 +1515,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++)
@@ -1429,11 +1535,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);
 }
@@ -1462,9 +1572,13 @@ get_gstring (MFrame *frame, MText *mt, int pos, int to, MDrawControl *control)
       if (prop)
        {
          gstring = prop->val;
       if (prop)
        {
          gstring = prop->val;
-         if (memcmp (control, &gstring->control,
-                     (char *) (&control->with_cursor)
-                     - (char *) (control)))
+         if (gstring->frame != frame
+             || gstring->tick != frame->tick
+             || memcmp (control, &gstring->control,
+                        (char *) (&control->with_cursor)
+                        - (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;
@@ -1505,26 +1619,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;
@@ -1631,6 +1742,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];
@@ -1705,12 +1910,10 @@ 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");
 
   McatCc = msymbol ("Cc");
   McatCf = msymbol ("Cf");
   Minherited = msymbol ("inherited");
 
   McatCc = msymbol ("Cc");
   McatCf = msymbol ("Cf");
-  Mdepth = msymbol ("depth");
 
   MbidiR = msymbol ("R");
   MbidiAL = msymbol ("AL");
 
   MbidiR = msymbol ("R");
   MbidiAL = msymbol ("AL");
@@ -1722,6 +1925,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;
 }
 
@@ -1729,6 +1938,8 @@ void
 mdraw__fini ()
 {
   MLIST_FREE1 (&scratch_gstring, glyphs);
 mdraw__fini ()
 {
   MLIST_FREE1 (&scratch_gstring, glyphs);
+  M17N_OBJECT_UNREF (linebreak_table);
+  linebreak_table = NULL;
 }
 
 /*** @} */
 }
 
 /*** @} */
@@ -1784,7 +1995,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.
@@ -1814,67 +2025,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  */
 
@@ -1891,6 +2092,7 @@ mdraw_text (MFrame *frame, MDrawWindow win, int x, int y,
 {
   MDrawControl control;
 
 {
   MDrawControl control;
 
+  M_CHECK_WRITABLE (frame, MERROR_DRAW, -1);
   memset (&control, 0, sizeof control);
   control.as_image = 0;
   return draw_text (frame, win, x, y, mt, from, to, &control);
   memset (&control, 0, sizeof control);
   control.as_image = 0;
   return draw_text (frame, win, x, y, mt, from, to, &control);
@@ -1922,21 +2124,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   */
 
@@ -1953,6 +2154,7 @@ mdraw_image_text (MFrame *frame, MDrawWindow win, int x, int y,
 {
   MDrawControl control;
 
 {
   MDrawControl control;
 
+  M_CHECK_WRITABLE (frame, MERROR_DRAW, -1);
   memset (&control, 0, sizeof control);
   control.as_image = 1;
   return draw_text (frame, win, x, y, mt, from, to, &control);
   memset (&control, 0, sizeof control);
   control.as_image = 1;
   return draw_text (frame, win, x, y, mt, from, to, &control);
@@ -1978,24 +2180,24 @@ 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,
                         MText *mt, int from, int to, MDrawControl *control)
 {
 
 int
 mdraw_text_with_control (MFrame *frame, MDrawWindow win, int x, int y,
                         MText *mt, int from, int to, MDrawControl *control)
 {
+  M_CHECK_WRITABLE (frame, MERROR_DRAW, -1);
   return draw_text (frame, win, x, y, mt, from, to, control);
 }
 
   return draw_text (frame, win, x, y, mt, from, to, control);
 }
 
@@ -2016,13 +2218,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
@@ -2040,31 +2242,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  */
 
@@ -2180,15 +2382,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 
@@ -2197,11 +2398,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,
@@ -2221,7 +2420,7 @@ mdraw_text_per_char_extents (MFrame *frame,
   ASSURE_CONTROL (control);
   *num_chars_return = to - from;
   if (array_size < *num_chars_return)
   ASSURE_CONTROL (control);
   *num_chars_return = to - from;
   if (array_size < *num_chars_return)
-    return 0;
+    MERROR (MERROR_DRAW, -1);
   if (overall_logical_return)
     memset (overall_logical_return, 0, sizeof (MDrawMetric));
   if (overall_ink_return)
   if (overall_logical_return)
     memset (overall_logical_return, 0, sizeof (MDrawMetric));
   if (overall_ink_return)
@@ -2235,7 +2434,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;
@@ -2245,9 +2444,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)
@@ -2265,18 +2474,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)
@@ -2295,7 +2511,7 @@ mdraw_text_per_char_extents (MFrame *frame,
     }
 
   M17N_OBJECT_UNREF (gstring->top);
     }
 
   M17N_OBJECT_UNREF (gstring->top);
-  return 1;
+  return 0;
 }
 
 /*=*/
 }
 
 /*=*/
@@ -2318,12 +2534,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.  */
@@ -2332,25 +2548,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 ¾å¤ËÉÁ²è¤µ¤ì¤ëºÇ¸å¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£ */
 
@@ -2387,7 +2599,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;
@@ -2406,6 +2618,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);
 
@@ -2427,10 +2643,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 ¤Î¥á¥ó¥Ð¤ËÊÝ»ý¤µ¤ì¤ë¡£  */
 
@@ -2482,14 +2698,15 @@ 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->this.x = g->lbearing;
-  info->this.y = - gstring->line_ascent;
-  info->this.height = gstring->height;
+  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)
     info->font = &g->rface->rfont->font;
   else
     info->font = NULL;
   if (g->rface->rfont)
     info->font = &g->rface->rfont->font;
   else
     info->font = NULL;
-  /* info->this.width is calculated later.  */
+  /* info->logical_width is calculated later.  */
 
   if (info->from > info->line_from)
     {
 
   if (info->from > info->line_from)
     {
@@ -2566,9 +2783,10 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
   else
     info->next_to = -1;
 
   else
     info->next_to = -1;
 
-  for (info->this.width = (g++)->width;
+  for (info->logical_width = (g++)->width;
        g->pos == pos && g->type != GLYPH_ANCHOR;
        g->pos == pos && g->type != GLYPH_ANCHOR;
-       info->this.width += (g++)->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;
@@ -2606,20 +2824,127 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
 /*=*/
 
 /***en
 /*=*/
 
 /***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,
+                 MDrawControl *control, MDrawGlyph *glyphs,
+                 int array_size, int *num_glyphs_return)
+{
+  MGlyphString *gstring;
+  MGlyph *g;
+  int n;
+  int pad_width = 0;
+
+  ASSURE_CONTROL (control);
+  *num_glyphs_return = 0;
+  M_CHECK_RANGE (mt, from, to, -1, 0);
+  gstring = get_gstring (frame, mt, from, to, control);
+  if (! gstring)
+    return -1;
+  for (g = MGLYPH (1), n = 0; g->type != GLYPH_ANCHOR; g++)
+    {
+      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)
+       {
+         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)
+           {
+             glyphs->font = &g->rface->rfont->font;
+             glyphs->font_type = g->rface->rfont->type;
+             glyphs->fontp = g->rface->rfont->fontp;
+           }
+         else
+           {
+             glyphs->font = NULL;
+             glyphs->font_type = Mnil;
+             glyphs->fontp = NULL;
+           }
+         pad_width = 0;
+         glyphs++;
+       }
+      n++;
+    }
+  M17N_OBJECT_UNREF (gstring->top);
+
+  *num_glyphs_return = n;
+  return (n <= array_size ? 0 : -1);
+}
+
+/*=*/
+
+/***en
     @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  */
 
@@ -2631,6 +2956,8 @@ void
 mdraw_text_items (MFrame *frame, MDrawWindow win, int x, int y,
                  MDrawTextItem *items, int nitems)
 {
 mdraw_text_items (MFrame *frame, MDrawWindow win, int x, int y,
                  MDrawTextItem *items, int nitems)
 {
+  if (! (frame->device_type & MDEVICE_SUPPORT_OUTPUT))
+    return;
   while (nitems-- > 0)
     {
       if (items->face)
   while (nitems-- > 0)
     {
       if (items->face)
@@ -2648,36 +2975,70 @@ 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.  
+
+      @return 
+      This function returns a character position to break the
+      line.
+*/
+
+/***ja 
+      @brief ²þ¹Ô°ÌÃÖ¤ò·×»»¤¹¤ë.
+
+      ´Ø¿ô mdraw_default_line_break () ¤Ï¡¢¹Ô¤¬ºÇÂçÉýÃæ¤Ë¼ý¤Þ¤é¤Ê¤¤¾ì¹ç¤Î²þ¹Ô°ÌÃÖ¤ò¡¢¹ÔÈÖ¹æ
+      $LINE ¤ÈºÂɸ $Y ¤Ë´ð¤Å¤¤¤Æ·×»»¤¹¤ë¡£
+      $POS ¤ÏºÇÂçÉý¤Ë¼ý¤Þ¤ëºÇ¸å¤Îʸ»ú¤Î¼¡¤Îʸ»ú¤Î°ÌÃ֤Ǥ¢¤ë¡£
+      $FROM ¤Ï¤½¤Î¹Ô¤ÎºÇ½é¤Îʸ»ú¤Î°ÌÃÖ¡¢$TO 
+      ¤ÏºÇÂçÉý¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¤½¤Î¹Ô¤Ëɽ¼¨¤µ¤ì¤ëºÇ¸å¤Îʸ»ú¤Î°ÌÃ֤Ǥ¢¤ë¡£
+      $LINE ¤È $Y ¤Ï²þ¹Ôʸ»ú¤Ë¤è¤Ã¤Æ¹Ô¤¬²þ¤Þ¤Ã¤¿ºÝ¤Ë¤Ï 0
+      ¤Ë¥ê¥»¥Ã¥È¤µ¤ì¡¢ºÇÂçÉý¤Ë¤è¤Ã¤Æ¹Ô¤¬²þ¤Þ¤Ã¤¿¾ì¹ç¤Ë¤Ï 1 ¤Å¤ÄÁý¤ä¤µ¤ì¤ë¡£
+
+      @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;
 }
 
 /*=*/
 }
 
 /*=*/
@@ -2697,32 +3058,57 @@ mdraw_default_line_break (MText *mt, int pos,
 
     If pointer $OVERALL_RETURN is not @c NULL, this function also
     computes the extents of the overall text and stores the results in
 
     If pointer $OVERALL_RETURN is not @c NULL, this function also
     computes the extents of the overall text and stores the results in
-    the members of the structure pointed to by $OVERALL_RETURN  */
+    the members of the structure pointed to by $OVERALL_RETURN.  */
 
 /***ja
     @brief M-text ¤Îʸ»úËè¤Îɽ¼¨ÈϰϾðÊó¤òÆÀ¤ë.
 
 
 /***ja
     @brief M-text ¤Îʸ»úËè¤Îɽ¼¨ÈϰϾðÊó¤òÆÀ¤ë.
 
-    ´Ø¿ô mdraw_per_char_extents () ¤Ï¡¢M-text $MT Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈÏ°Ï
-    ¤ò·×»»¤¹¤ë¡£¤³¤Î·×»»¤ËÍѤ¤¤ë¥Õ¥©¥ó¥È¤Ï¡¢$MT ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ç
-    »ØÄꤵ¤ì¤¿¥Õ¥§¡¼¥¹¤È¡¢¥Õ¥ì¡¼¥à $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  */
 
 void
 mdraw_per_char_extents (MFrame *frame, MText *mt,
 
     @latexonly \IPAlabel{mdraw_per_char_extents} @endlatexonly  */
 
 void
 mdraw_per_char_extents (MFrame *frame, MText *mt,
-  MDrawMetric *array_return,
-  MDrawMetric *overall_return)
+                       MDrawMetric *array_return,
+                       MDrawMetric *overall_return)
 {
 {
+  int n = mtext_nchars (mt);
+
+  mdraw_text_per_char_extents (frame, mt, 0, n, NULL, array_return, NULL,
+                              n, &n, overall_return, NULL);
 }
 
 }
 
+/***en 
+    @brief clear cached information.    
+
+    The mdraw_clear_cache () function clear cached information
+    on M-text $MT that was attached by any of the drawing functions.
+    When the behavior of `format' or `line_break'
+    member functions of MDrawControl is changed, the cache must be cleared.
+
+    @seealso
+    MDrawControl */
+/***ja 
+    @brief ¥­¥ã¥Ã¥·¥å¾ðÊó¤ò¾Ã¤¹.
+
+    ´Ø¿ô mdraw_clear_cache () ¤ÏÉÁ²è´Ø¿ô¤Ë¤è¤Ã¤Æ M-text $MT 
+    ¤ËÉղ䵤줿¥­¥ã¥Ã¥·¥å¾ðÊó¤ò¤¹¤Ù¤Æ¾Ãµî¤¹¤ë¡£MDrawControl ¤Î `format' 
+    ¤¢¤ë¤¤¤Ï `line_break' 
+    ¥á¥ó¥Ð´Ø¿ô¤Î¿¶Éñ¤¤¤¬ÊѤï¤Ã¤¿¾ì¹ç¤Ë¤Ï¥­¥ã¥Ã¥·¥å¤ò¾Ãµî¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
+
+    @seealso
+    MDrawControl */
+
 void
 mdraw_clear_cache (MText *mt)
 {
 void
 mdraw_clear_cache (MText *mt)
 {