*** empty log message ***
[m17n/m17n-lib.git] / src / fontset.c
index d3f3c7c..2f2ca55 100644 (file)
@@ -1,5 +1,5 @@
 /* fontset.c -- fontset module.
-   Copyright (C) 2003, 2004
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
@@ -17,7 +17,7 @@
 
    You should have received a copy of the GNU Lesser General Public
    License along with the m17n library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    02111-1307, USA.  */
 
 /***en
 
     @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ïʸ»ú¤«¤é¥Õ¥©¥ó¥È¤Ø¤ÎÂбþÉÕ¤±¤ò¹Ô¤¦¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë.
 
-    @e ¥Õ¥©¥ó¥È¥»¥Ã¥È ¤Ï @c MFontset ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£M-text ¤ò
-    É½¼¨¤¹¤ëºÝ¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï M-text Ãæ¤Î¸Ä¡¹¤Îʸ»ú¤ËÂФ·¤Æ¤É¤Î¥Õ¥©
-    ¥ó¥È¤òÍѤ¤¤ë¤«¤Îµ¬Â§¤ò¡¢°Ê²¼¤Î¾ðÊó¤Ë½¾¤Ã¤ÆÍ¿¤¨¤ë¡£
+    @e ¥Õ¥©¥ó¥È¥»¥Ã¥È ¤Ï @c MFontset ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£M-text 
+    ¤Îɽ¼¨¤ÎºÝ¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï°Ê²¼¤Î¾ðÊó¤òÍѤ¤¤Æ M-text 
+    Ãæ¤Î¸Ä¡¹¤Îʸ»ú¤Ë¤É¤Î¥Õ¥©¥ó¥È¤òÍѤ¤¤ë¤«·è¤á¤ëµ¬Â§¤òÍ¿¤¨¤ë¡£
 
     @li Ê¸»ú¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£ "¥¹¥¯¥ê¥×¥È"
     @li Ê¸»ú¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£ "¸À¸ì"
     @li Ê¸»ú¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£ "ʸ»ú¥»¥Ã¥È"
 
-    ¤³¤ì¤é¤Î¾ðÊ󤬤ɤΤ褦¤ËÍѤ¤¤é¤ì¤ë¤«¤Ï mdraw_text () ¤ÎÀâÌÀ¤ò»²¾È
-    ¤Î¤³¤È¡£
+    ¤³¤ì¤é¤Î¾ðÊ󤬤ɤΤ褦¤ËÍѤ¤¤é¤ì¤ë¤«¤Ï mdraw_text () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
 
     */
 
 #include "font.h"
 #include "fontset.h"
 
+static int mdebug_flag = MDEBUG_FONTSET;
+
+static M17NObjectArray fontset_table;
+
 struct MFontset
 {
   M17NObject control;
@@ -98,9 +101,6 @@ struct MFontset
 
   /* FONT-GROUP */
   MPlist *fallback;
-
-  /* Plist of Mt vs font specs. */
-  MPlist *font_spec_list;
 };
 
 static MFontset *default_fontset;
@@ -115,8 +115,11 @@ struct MRealizedFontset
   /* Initialized to <fontset>->tick.  */
   unsigned tick;
 
-  /* Font spec extracted from a face.  */
-  MFont spec;
+  /* Font spec that must be satisfied, or NULL.  */
+  MFont *spec;
+
+  /* Font spec requested by a face.  */
+  MFont request;
 
   /* The frame on which the realized fontset is realized.  */
   MFrame *frame;
@@ -130,13 +133,13 @@ struct MRealizedFontset
 
 
 static MPlist *
-load_font_group (MPlist *plist, MPlist *elt, MPlist *spec_list)
+load_font_group (MPlist *plist, MPlist *elt)
 {
   MPLIST_DO (elt, elt)
     {
-      /* ELT ::= ( FONT-SPEC-LIST [ LAYOUTER ] ) ...  */
-      MPlist *elt2, *p;
-      MFont font, *spec = NULL;
+      /* ELT ::= ( FONT-SPEC [ LAYOUTER ] ) ...  */
+      MPlist *elt2;
+      MFont *font;
       MSymbol layouter_name;
 
       if (! MPLIST_PLIST_P (elt))
@@ -144,28 +147,15 @@ load_font_group (MPlist *plist, MPlist *elt, MPlist *spec_list)
       elt2 = MPLIST_PLIST (elt);
       if (! MPLIST_PLIST_P (elt2))
        MWARNING (MERROR_FONTSET);
-      mfont__set_spec_from_plist (&font, MPLIST_PLIST (elt2));
-      MPLIST_DO (p, spec_list)
-        {
-         if (! memcmp (MPLIST_VAL (p), &font, sizeof (MFont)))
-           {
-             spec = MPLIST_VAL (p);
-             break;
-           }
-        }
-      if (! spec)
-       {
-         MSTRUCT_MALLOC (spec, MERROR_FONTSET);
-         *spec = font;
-         mplist_add (spec_list, Mt, spec);
-       }
+      MSTRUCT_CALLOC (font, MERROR_FONTSET);
+      mfont__set_spec_from_plist (font, MPLIST_PLIST (elt2));
       elt2 = MPLIST_NEXT (elt2);
       layouter_name = Mt;
       if (MPLIST_SYMBOL_P (elt2))
        layouter_name = MPLIST_SYMBOL (elt2);
       if (layouter_name == Mnil)
        layouter_name = Mt;
-      plist = mplist_add (plist, layouter_name, spec);
+      plist = mplist_add (plist, layouter_name, font);
       continue;
     warning:
       /* ANSI-C requires some statement after a label.  */
@@ -179,59 +169,53 @@ load_font_group (MPlist *plist, MPlist *elt, MPlist *spec_list)
 static void
 load_fontset_contents (MFontset *fontset)
 {
-  MPlist *per_script, *per_charset, *fallback, *spec_list, *font_group;
-  MSymbol script, lang;
+  MPlist *per_script, *per_charset, *font_group;
   MPlist *fontset_def, *plist;
 
   fontset->per_script = per_script = mplist ();
   fontset->per_charset = per_charset = mplist ();
-  fontset->fallback = fallback = mplist ();
-  fontset->font_spec_list = spec_list = mplist ();
+  fontset->fallback = mplist ();
   if (! (fontset_def = (MPlist *) mdatabase_load (fontset->mdb)))
     return;
 
   MPLIST_DO (plist, fontset_def)
     {
-      /* PLIST ::= ( SCRIPT ( LANGUAGE FONT-SPEC-ELT ... ) ... )
-                  | (CHARSET FONT-SPEC-ELT ...)
-                  | FONT-SPEC-ELT  */
+      /* PLIST ::=   ( SCRIPT ( LANGUAGE ( FONT-SPEC [LAYOUTER]) ... ) ... )
+                  | ( CHARSET ( FONT-SPEC [LAYOUTER] ) ...)
+                  | ( nil ( FONT-SPEC [LAYOUTER] ) ...)
+        FONT-SPEC :: = ( ... ) */
       MPlist *elt;
+      MSymbol sym;
 
       if (! MPLIST_PLIST_P (plist))
        MWARNING (MERROR_FONTSET);
       elt = MPLIST_PLIST (plist);
       if (! MPLIST_SYMBOL_P (elt))
        MWARNING (MERROR_FONTSET);
-      script = MPLIST_SYMBOL (elt);
+      sym = MPLIST_SYMBOL (elt);
       elt = MPLIST_NEXT (elt);
       if (! MPLIST_PLIST_P (elt))
        MWARNING (MERROR_FONTSET);
-      if (script == Mnil)
-       fallback = load_font_group (fallback, elt, spec_list);
+      if (sym == Mnil)
+       load_font_group (fontset->fallback, elt);
       else if (MPLIST_PLIST_P (MPLIST_PLIST (elt)))
        {
-         font_group = mplist_find_by_key (fontset->per_charset, script);
-         if (! font_group)
-           {
-             font_group = mplist ();
-             per_charset = mplist_add (per_charset, script, font_group);
-           }
-         load_font_group (font_group, elt, spec_list);
+         /* SYM is a charset.  */
+         font_group = mplist ();
+         per_charset = mplist_add (per_charset, sym, font_group);
+         load_font_group (font_group, elt);
        }
       else
        {
-         MPlist *per_lang = mplist_find_by_key (fontset->per_script, script);
-
-         if (! per_lang)
-           {
-             per_lang = mplist ();
-             per_script = mplist_add (per_script, script, per_lang);
-           }
+         /* SYM is a script */
+         MPlist *per_lang = mplist ();
 
+         per_script = mplist_add (per_script, sym, per_lang);
          MPLIST_DO (elt, elt)
            {
              /* ELT ::= ( LANGUAGE FONT-DEF ...) ... */
              MPlist *elt2;
+             MSymbol lang;
 
              if (! MPLIST_PLIST_P (elt))
                MWARNING (MERROR_FONTSET);
@@ -241,14 +225,10 @@ load_fontset_contents (MFontset *fontset)
              lang = MPLIST_SYMBOL (elt2);
              if (lang == Mnil)
                lang = Mt;
-             font_group = mplist_find_by_key (per_lang, lang);
-             if (! font_group)
-               {
-                 font_group = mplist ();
-                 mplist_add (per_lang, lang, font_group);
-               }
+             font_group = mplist ();
+             mplist_add (per_lang, lang, font_group);
              elt2 = MPLIST_NEXT (elt2);
-             load_font_group (font_group, elt2, spec_list);
+             load_font_group (font_group, elt2);
            }
        }
       continue;
@@ -274,6 +254,8 @@ free_fontset (void *object)
        {
          MPLIST_DO (pl, MPLIST_PLIST (plist))
            {
+             MPLIST_DO (p, MPLIST_PLIST (pl))
+               free (MPLIST_VAL (p));
              p = MPLIST_PLIST (pl);
              M17N_OBJECT_UNREF (p);
            }
@@ -284,98 +266,129 @@ free_fontset (void *object)
     }
   if (fontset->per_charset)
     {
-      MPLIST_DO (plist, fontset->per_charset)
+      MPLIST_DO (pl, fontset->per_charset)
        {
-         pl = MPLIST_PLIST (plist);
-         M17N_OBJECT_UNREF (pl);
+         MPLIST_DO (p, MPLIST_PLIST (pl))
+           free (MPLIST_VAL (p));
+         p = MPLIST_PLIST (p);
+         M17N_OBJECT_UNREF (p);
        }
       M17N_OBJECT_UNREF (fontset->per_charset);
     }
   if (fontset->fallback)
-    M17N_OBJECT_UNREF (fontset->fallback);
+    {
+      MPLIST_DO (p, fontset->fallback)
+       free (MPLIST_VAL (p));
+      M17N_OBJECT_UNREF (fontset->fallback);
+    }
+
   plist = mplist_find_by_key (fontset_list, fontset->name);
   if (! plist)
     mdebug_hook ();
   mplist_pop (plist);
-  if (fontset->font_spec_list)
+  if (MPLIST_TAIL_P (fontset_list))
     {
-      if (((M17NObject *) (fontset->font_spec_list))->ref_count == 1)
-       MPLIST_DO (plist, fontset->font_spec_list)
-         free (MPLIST_VAL (plist));
-      M17N_OBJECT_UNREF (fontset->font_spec_list);
+      M17N_OBJECT_UNREF (fontset_list);
+      fontset_list = NULL;
     }
+  M17N_OBJECT_UNREGISTER (fontset_table, fontset);
   free (object);
 }
 
 static void
-realize_font_group (MFrame *frame, MFont *request, MPlist *font_group,
-                   int size)
+realize_fontset_elements (MFrame *frame, MRealizedFontset *realized)
 {
-  MPlist *plist = MPLIST_VAL (font_group), *pl, *p;
-
-  mplist_set (font_group, Mnil, NULL);
-  MPLIST_DO (pl, plist)
-    {
-      MSymbol layouter = MPLIST_KEY (pl);
-      MFont this_request = *request;
-      MRealizedFont *rfont;
+  MFontset *fontset = realized->fontset;
+  MPlist *per_script, *per_charset, *font_group;
+  MPlist *plist, *p;
 
-      mfont__resize (MPLIST_VAL (pl), &this_request);
-      rfont = mfont__select (frame, MPLIST_VAL (pl), &this_request,
-                            size, layouter == Mt ? Mnil : layouter);
-
-      if (rfont)
-       {
-         MPLIST_DO (p, font_group)
-           if (((MRealizedFont *) (MPLIST_VAL (p)))->score > rfont->score)
-             break;
-         mplist_push (p, Mt, rfont);
-       }
-    }
-}
-
-static void
-realize_fontset_elements (MFrame *frame, MRealizedFontset *realized,
-                         MFontset *fontset, MFont *request)
-{
-  MPlist *per_script, *per_lang, *per_charset, *font_group;
-  MPlist *plist, *pl;
-
-  realized->fontset = fontset;
-  realized->tick = fontset->tick;
-  realized->spec = *request;
-  realized->frame = frame;
   realized->per_script = per_script = mplist ();
+  /* The actual elements of per_script are realized on demand.  */
+#if 0
   MPLIST_DO (plist, fontset->per_script)
     {
+      MPlist *pl;
+
       per_lang = mplist ();
       per_script = mplist_add (per_script, MPLIST_KEY (plist), per_lang);
       MPLIST_DO (pl, MPLIST_PLIST (plist))
        {
          font_group = mplist ();
-         mplist_add (font_group, Mplist, MPLIST_VAL (pl));
          per_lang = mplist_add (per_lang, MPLIST_KEY (pl), font_group);
+         MPLIST_DO (p, MPLIST_PLIST (pl))
+           font_group = mplist_add (font_group,
+                                    MPLIST_KEY (p), MPLIST_VAL (p));
        }
     }
+#endif
 
   realized->per_charset = per_charset = mplist ();
   MPLIST_DO (plist, fontset->per_charset)
     {
       font_group = mplist ();
-      mplist_add (font_group, Mplist, MPLIST_VAL (plist));
       per_charset = mplist_add (per_charset, MPLIST_KEY (plist), font_group);
+      MPLIST_DO (p, MPLIST_PLIST (plist))
+       font_group = mplist_add (font_group, MPLIST_KEY (p), MPLIST_VAL (p));
     }
+  realized->fallback = font_group = mplist ();
+  MPLIST_DO (p, fontset->fallback)
+    font_group = mplist_add (font_group, MPLIST_KEY (p), MPLIST_VAL (p));
+}
+
+
+/* Return a plist of fonts for SCRIPT in FONTSET.  The returned list
+   is acutally a plist of languages vs font groups (which is a plist).
+   If SCRIPT is nil, return a plist of fallback fonts.  If FONTSET
+   doesn't record any fonts for SCRIPT, generate a proper font spec
+   lists for X backend and FreeType backend.  */
+
+MPlist *
+get_per_script (MFontset *fontset, MSymbol script)
+{
+  MPlist *plist;
+
+  if (script == Mnil)
+    return fontset->fallback;
+  plist = mplist_get (fontset->per_script, script);
+  if (! plist)
+    {
+      int len = MSYMBOL_NAMELEN (script);
+      char *cap = alloca (8 + len + 1);
+      MSymbol capability;
+      MFont *font;
+      MPlist *pl, *p;
 
-  realized->fallback = mplist ();
-  mplist_add (realized->fallback, Mplist, fontset->fallback);
+      sprintf (cap, ":script=%s", MSYMBOL_NAME (script));
+      capability = msymbol (cap);
 
+      pl = mplist ();
+      MPLIST_DO (p, fontset->fallback)
+       {
+         font = mfont_copy (MPLIST_VAL (p));
+         mfont_put_prop (font, Mregistry, Municode_bmp);
+         font->source = MFONT_SOURCE_FT;
+         font->capability = capability;
+         mplist_add (pl, Mt, font);
+
+         font = mfont_copy (MPLIST_VAL (p));
+         mfont_put_prop (font, Mregistry, Miso10646_1);
+         font->source = MFONT_SOURCE_X;
+         font->capability = capability;
+         mplist_add (pl, Mt, font);
+       }
+      plist = mplist ();
+      mplist_add (plist, Mt, pl);
+      mplist_add (fontset->per_script, script, plist);
+    }
+  return plist;
 }
 
 static void
 free_realized_fontset_elements (MRealizedFontset *realized)
 {
   MPlist *plist, *pl, *p;
-  MRealizedFont *rfont;
+  MFont *font;
+  MFontList *font_list;
 
   if (realized->per_script)
     {
@@ -384,8 +397,18 @@ free_realized_fontset_elements (MRealizedFontset *realized)
          MPLIST_DO (pl, MPLIST_PLIST (plist))
            {
              MPLIST_DO (p, MPLIST_PLIST (pl))
-               if ((rfont = MPLIST_VAL (p)) && ! rfont->frame)
-                 free (rfont);
+               {
+                 font = MPLIST_VAL (p);
+                 if (font->type == MFONT_TYPE_OBJECT)
+                   {
+                     font_list = (MFontList *) font;
+                     free (font_list->fonts);
+                     free (font_list);
+                   }
+                 /* This is to avoid freeing rfont again by the later
+                    M17N_OBJECT_UNREF (p) */
+                 MPLIST_KEY (p) = Mt;
+               }
              p = MPLIST_PLIST (pl);
              M17N_OBJECT_UNREF (p);
            }
@@ -399,8 +422,16 @@ free_realized_fontset_elements (MRealizedFontset *realized)
       MPLIST_DO (plist, realized->per_charset)
        {
          MPLIST_DO (pl, MPLIST_PLIST (plist))
-           if ((rfont = MPLIST_VAL (pl)) && ! rfont->frame)
-             free (rfont);
+           {
+             font = MPLIST_VAL (pl);
+             if (font->type == MFONT_TYPE_OBJECT)
+               {
+                 font_list = (MFontList *) font;
+                 free (font_list->fonts);
+                 free (font_list);
+               }
+             MPLIST_KEY (pl) = Mt;
+           }
          pl = MPLIST_PLIST (plist);
          M17N_OBJECT_UNREF (pl);
        }
@@ -409,8 +440,16 @@ free_realized_fontset_elements (MRealizedFontset *realized)
   if (realized->fallback)
     {
       MPLIST_DO (plist, realized->fallback)
-       if ((rfont = MPLIST_VAL (plist)) && ! rfont->frame)
-         free (rfont);
+       {
+         font = MPLIST_VAL (plist);
+         if (font->type == MFONT_TYPE_OBJECT)
+           {
+             font_list = (MFontList *) font;
+             free (font_list->fonts);
+             free (font_list);
+           }
+         MPLIST_KEY (plist) = Mt;
+       }
       M17N_OBJECT_UNREF (realized->fallback);
     }
 }
@@ -419,8 +458,7 @@ static void
 update_fontset_elements (MRealizedFontset *realized)
 {
   free_realized_fontset_elements (realized);
-  realize_fontset_elements (realized->frame, realized, realized->fontset,
-                           &realized->spec);
+  realize_fontset_elements (realized->frame, realized);
 }
 
 
@@ -431,6 +469,8 @@ update_fontset_elements (MRealizedFontset *realized)
 int
 mfont__fontset_init ()
 {
+  M17N_OBJECT_ADD_ARRAY (fontset_table, "Fontset");
+
   Mfontset = msymbol ("fontset");
   Mfontset->managing_key = 1;
   fontset_list = mplist ();
@@ -454,15 +494,14 @@ mfont__fontset_init ()
 void
 mfont__fontset_fini ()
 {
-  while (! MPLIST_TAIL_P (fontset_list))
-    free_fontset ((MFontset *) MPLIST_VAL (fontset_list));
-  M17N_OBJECT_UNREF (fontset_list);
-  fontset_list = NULL;
+  M17N_OBJECT_UNREF (default_fontset);
+  default_fontset = NULL;
 }
 
 
 MRealizedFontset *
-mfont__realize_fontset (MFrame *frame, MFontset *fontset, MFace *face)
+mfont__realize_fontset (MFrame *frame, MFontset *fontset,
+                       MFace *face, MFont *spec)
 {
   MRealizedFontset *realized;
   MFont request;
@@ -471,22 +510,36 @@ mfont__realize_fontset (MFrame *frame, MFontset *fontset, MFace *face)
   if (fontset->mdb)
     load_fontset_contents (fontset);
 
+  MFONT_INIT (&request);
   mfont__set_spec_from_face (&request, face);
-  if (request.property[MFONT_SIZE] <= 0)
+  if (request.size <= 0)
     {
       mdebug_hook ();
-      request.property[MFONT_SIZE] = 120;
+      request.size = 120;
     }
   MPLIST_DO (plist, frame->realized_fontset_list)
     {
       realized = (MRealizedFontset *) MPLIST_VAL (plist);
       if (fontset->name == MPLIST_KEY (plist)
-         && ! memcmp (&request, &realized->spec, sizeof (request)))
+         && ! memcmp (&request, &realized->request, sizeof (MFont))
+         && (realized->spec
+             ? (spec && ! memcmp (spec, &realized->spec, sizeof (MFont)))
+             : ! spec))
        return realized;
     }
 
-  MSTRUCT_MALLOC (realized, MERROR_FONTSET);
-  realize_fontset_elements (frame, realized, fontset, &request);
+  MSTRUCT_CALLOC (realized, MERROR_FONTSET);
+  realized->fontset = fontset;
+  M17N_OBJECT_REF (fontset);
+  realized->tick = fontset->tick;
+  if (spec)
+    {
+      MSTRUCT_CALLOC (realized->spec, MERROR_FONTSET);
+      *realized->spec = *spec;
+    }
+  realized->request = request;
+  realized->frame = frame;
+  realize_fontset_elements (frame, realized);
   mplist_add (frame->realized_fontset_list, fontset->name, realized);
   return realized;
 }
@@ -496,134 +549,429 @@ void
 mfont__free_realized_fontset (MRealizedFontset *realized)
 {
   free_realized_fontset_elements (realized);
+  M17N_OBJECT_UNREF (realized->fontset);
+  if (realized->spec)
+    free (realized->spec);
   free (realized);
 }
 
 
+static MRealizedFont *
+try_font_list (MFrame *frame, MFontList *font_list, MFont *request,
+              MSymbol layouter, MGlyph *g, int *num, int all, int exact)
+{
+  int i, j;
+  MFont *font;
+  MRealizedFont *rfont;
+
+  for (i = 0; i < font_list->nfonts; i++)
+    {
+      if (font_list->fonts[i].font->type == MFONT_TYPE_SPEC)
+       MFATAL (MERROR_FONT);
+      if (exact)
+       {
+         if (font_list->fonts[i].score > 0)
+           break;
+       }
+      else
+       {
+         if (font_list->fonts[i].score == 0)
+           continue;
+       }
+      font = font_list->fonts[i].font;
+      if (font->type == MFONT_TYPE_FAILURE)
+       continue;
+      /* Check if this font can display all glyphs.  */
+      for (j = 0; j < *num; j++)
+       {
+         int c = g[j].type == GLYPH_CHAR ? g[j].g.c : ' ';
+         MFLT *flt;
+         MCharTable *coverage;
+
+         if (layouter != Mt
+             ? ((flt = mflt_get (layouter))
+                ? (coverage = mflt_coverage (flt),
+                   ! mchartable_lookup (coverage, c))
+                : 0)
+             : ! mfont__has_char (frame, font, &font_list->object, c))
+           break;
+       }
+      if (j == 0 && *num > 0)
+       continue;
+      if (j == *num || !all)
+       {
+         MCharTable *coverage = NULL;
+
+         /* We found a font that can display the requested range of
+            glyphs.  */
+         if (font->type == MFONT_TYPE_REALIZED)
+           rfont = (MRealizedFont *) font;
+         else
+           {
+             rfont = mfont__open (frame, font, &font_list->object);
+             if (! rfont)
+               continue;
+             font_list->fonts[i].font = (MFont *) rfont;
+           }
+         rfont->layouter = layouter == Mt ? Mnil : layouter;
+         if (rfont->layouter)
+           {
+             MFLT *flt = mflt_get (rfont->layouter);
+
+             if (flt)
+               coverage = mflt_coverage (flt);
+           }
+         *num = j;
+         for (j = 0; j < *num; j++)
+           {
+             int c = g[j].type == GLYPH_CHAR ? g[j].g.c : ' ';
+
+             g[j].g.code = (coverage
+                            ? (unsigned ) mchartable_lookup (coverage, c)
+                            : mfont__encode_char (frame, (MFont *) rfont,
+                                                  &font_list->object, c));
+           }
+         return rfont;
+       }
+    }
+  return NULL;
+}
+
+
+static MRealizedFont *
+try_font_group (MRealizedFontset *realized, MFont *request,
+               MPlist *font_group, MGlyph *g, int *num, int size)
+{
+  MFrame *frame = realized->frame;
+  MFont *font;
+  MFontList *font_list;
+  MRealizedFont *rfont;
+  MPlist *plist;
+  MSymbol layouter;
+  int best_score = -1, worst_score;
+
+  for (plist = font_group; ! MPLIST_TAIL_P (plist); )
+    {
+      int this_score;
+
+      layouter = MPLIST_KEY (plist);
+      font = MPLIST_VAL (plist);
+      if (font->type == MFONT_TYPE_SPEC)
+       {
+         /* We have not yet made this entry a MFontList.  */
+         if (realized->spec)
+           {
+             MFont this = *font;
+             
+             if (mfont__merge (&this, realized->spec, 1) < 0)
+               {
+                 mplist_pop (plist);
+                 continue;
+               }
+             font_list = mfont__list (frame, &this, &this, size);
+           }
+         else
+           font_list = mfont__list (frame, font, request, size);
+         if (! font_list)
+           {
+             /* As there's no font matching this spec, remove this
+                element from the font group.  */
+             mplist_pop (plist);
+             continue;
+           }
+         MPLIST_VAL (plist) = font_list;
+       }
+      else
+       font_list = (MFontList *) font;
+
+      this_score = font_list->fonts[0].score;
+      if ((this_score == 0)
+         && (rfont = try_font_list (frame, font_list, request,
+                                    layouter, g, num, 1, 1)))
+       return rfont;
+      if (best_score < 0)
+       {
+         best_score = worst_score = this_score;
+         plist = MPLIST_NEXT (plist);
+       }
+      else if (this_score >= worst_score)
+       {
+         worst_score = this_score;
+         plist = MPLIST_NEXT (plist);
+       }
+      else
+       {
+         MPlist *pl;
+
+         MPLIST_DO (pl, font_group)
+           if (this_score < ((MFontList *) MPLIST_VAL (pl))->fonts[0].score)
+             break;
+         mplist_pop (plist);
+         mplist_push (pl, layouter, font_list);
+       }
+    }
+
+  /* We couldn't find an exact matching font that can display all
+     glyphs.  Find one that can at least display all glyphs.  */
+  MPLIST_DO (plist, font_group)
+    {
+      rfont = try_font_list (frame, MPLIST_VAL (plist), request,
+                            MPLIST_KEY (plist), g, num, 1, 0);
+      if (rfont)
+       return rfont;
+    }
+
+  /* We couldn't find a font that can display all glyphs.  Find an
+     exact matching font that can at least display the first
+     glyph.  */
+  MPLIST_DO (plist, font_group)
+    {
+      rfont = try_font_list (frame, MPLIST_VAL (plist), request,
+                            MPLIST_KEY (plist), g, num, 0, 1);
+      if (rfont)
+       return rfont;
+    }
+
+  /* Find any font that can at least display the first glyph.  */
+  MPLIST_DO (plist, font_group)
+    {
+      rfont = try_font_list (frame, MPLIST_VAL (plist), request,
+                            MPLIST_KEY (plist), g, num, 0, 0);
+      if (rfont)
+       return rfont;
+    }
+
+  return NULL;
+}
+
 MRealizedFont *
 mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num,
                       MSymbol script, MSymbol language, MSymbol charset,
-                      int size)
+                      int size, int ignore_fallback)
 {
-  MFrame *frame = realized->frame;
   MCharset *preferred_charset = (charset == Mnil ? NULL : MCHARSET (charset));
   MPlist *per_charset, *per_script, *per_lang;
-  MPlist *font_groups[256], *plist;
-  int n_font_group = 0;
-  MRealizedFont *rfont;
-  int i;
+  MPlist *plist;
+  MRealizedFont *rfont = NULL;
+
+  if (MDEBUG_FLAG ())
+    {
+      int i;
+
+      MDEBUG_PRINT1 (" [FONTSET] fontset looking up for %s:",
+                    script ? script->name : "none");
+      for (i = 0; i < *num; i++)
+       MDEBUG_PRINT1 (" U+%04X", g[i].g.c);
+      MDEBUG_PRINT ("\n");
+    }
 
   if (realized->tick != realized->fontset->tick)
     update_fontset_elements (realized);
 
   if (preferred_charset
-      && (per_charset = mplist_get (realized->per_charset, charset)) != NULL)
-    font_groups[n_font_group++] = per_charset;
-  if (script != Mnil
-      && ((per_script = mplist_find_by_key (realized->per_script, script))
-         != NULL))
+      && (per_charset = mplist_get (realized->per_charset, charset)) != NULL
+      && (rfont = try_font_group (realized, &realized->request, per_charset,
+                                 g, num, size)))
+    goto done;
+
+  if (script != Mnil)
     {
+      MFont request = realized->request;
+
+      if (script != Mlatin)
+       /* This is not appropriate for non-Latin scripts.  */
+       request.property[MFONT_REGISTRY] = 0;
+
+      per_script = mplist_get (realized->per_script, script);
+      if (! per_script)
+       {
+         per_script = mplist_copy (get_per_script (realized->fontset, script));
+         /* PER_SCRIPT ::= (LANGUAGE:(LAYOUTER:FONT-SPEC ...) ...) */
+         MPLIST_DO (plist, per_script)
+           MPLIST_VAL (plist) = mplist_copy (MPLIST_VAL (plist));
+         mplist_add (realized->per_script, script, per_script);
+       }
+
       /* We prefer font groups in this order:
-         (1) group matching LANGUAGE
-         (2) group for generic LANGUAGE
-         (3) group non-matching LANGUAGE  */
+         (1) group matching with LANGUAGE if LANGUAGE is not Mnil
+         (2) group for generic language
+         (3) group not matching with LANGUAGE  */
       if (language == Mnil)
        language = Mt;
-      per_lang = mplist_find_by_key (MPLIST_PLIST (per_script), language);
-      if (per_lang)
+      if ((per_lang = mplist_get (per_script, language))
+         && (rfont = try_font_group (realized, &request, per_lang,
+                                     g, num, size)))
+       goto done;
+
+      if (per_lang && *num > 1)
+       *num = 1;
+      if (language == Mt)
        {
-         font_groups[n_font_group++] = MPLIST_PLIST (per_lang);
-         if (language == Mt)
-           {
-             MPLIST_DO (per_lang, MPLIST_PLIST (per_script))
-               if (MPLIST_KEY (per_lang) != language)
-                 font_groups[n_font_group++] = MPLIST_PLIST (per_lang);
-           }
+         /* Try the above (3) */
+         MPLIST_DO (plist, per_script)
+           if (MPLIST_KEY (plist) != language
+               && (rfont = try_font_group (realized, &request,
+                                           MPLIST_PLIST (plist),
+                                           g, num, size)))
+             goto done;
        }
-      if (language != Mt)
+      else
        {
-         plist = mplist_get (MPLIST_PLIST (per_script), Mt);
-         if (plist)
-           font_groups[n_font_group++] = plist;
+         /* At first try the above (2) */
+         if ((per_lang = mplist_get (per_script, Mt))
+             && (rfont = try_font_group (realized, &request, per_lang,
+                                         g, num, size)))
+           goto done;
+
+         if (per_lang && *num > 1)
+           *num = 1;
+         /* Then try the above (3) */
+         MPLIST_DO (plist, per_script)
+           if (MPLIST_KEY (plist) != language
+               && MPLIST_KEY (plist) != Mt
+               && (rfont = try_font_group (realized, &request,
+                                           MPLIST_PLIST (plist),
+                                           g, num, size)))
+             goto done;
        }
-      MPLIST_DO (per_lang, MPLIST_PLIST (per_script))
-       if (MPLIST_KEY (per_lang) != language
-           && MPLIST_KEY (per_lang) != Mt)
-         font_groups[n_font_group++] = MPLIST_PLIST (per_lang);
+      if (ignore_fallback)
+       goto done;
     }
-  font_groups[n_font_group++] = realized->fallback;
 
-  if (n_font_group == 1)
+  if (language != Mnil)
+    /* Find a font group for this language from all scripts.  */
+    MPLIST_DO (plist, realized->per_script)
+      {
+       MFont request = realized->request;
+
+       if (MPLIST_KEY (plist) != Mlatin)
+         request.property[MFONT_FOUNDRY]
+           = request.property[MFONT_FAMILY]
+           = request.property[MFONT_FAMILY] = 0;
+       if ((per_lang = mplist_get (MPLIST_PLIST (plist), language))
+           && (rfont = try_font_group (realized, &request, per_lang,
+                                       g, num, size)))
+         goto done;
+      }
+
+  /* Try fallback fonts.  */
+  rfont = try_font_group (realized, &realized->request,
+                         realized->fallback, g, num, size);
+ done:
+  if (MDEBUG_FLAG ())
     {
-      /* As we only have a fallback font group, try all the other
-        fonts too.  */
-      MPLIST_DO (per_script, realized->per_script)
-       MPLIST_DO (per_lang, MPLIST_PLIST (per_script))
-         font_groups[n_font_group++] = MPLIST_PLIST (per_lang);
-      MPLIST_DO (per_charset, realized->per_charset)
-       font_groups[n_font_group++] = MPLIST_PLIST (per_charset);
+      if (rfont)
+       {
+         MSymbol family = mfont_get_prop (rfont->font, Mfamily);
+         MDEBUG_PRINT1 (" [FONTSET] found %s\n", family->name);
+       }
+      else
+       MDEBUG_PRINT (" [FONTSET] not found\n");
     }
 
-  for (i = 0; i < n_font_group; i++)
-    {
-      int j;
-      
-      if (MPLIST_PLIST_P (font_groups[i]))
-       realize_font_group (frame, &realized->spec, font_groups[i], size);
+  return rfont;
+}
 
-      MPLIST_DO (plist, font_groups[i])
-        {
-         rfont = (MRealizedFont *) MPLIST_VAL (plist);
-         if (rfont->status < 0)
-           continue;
-         /* Check if this font can display all glyphs.  */
-         for (j = 0; j < *num; j++)
-           {
-             g[j].code = mfont__encode_char (rfont,
-                                             g[j].type == GLYPH_CHAR ? g[j].c
-                                             : ' ');
-             if (g[j].code == MCHAR_INVALID_CODE)
-               break;
-           }
-         if (j == *num)
-           {
-             if (rfont->status > 0
-                 || mfont__open (rfont) == 0)
-               /* We found a font that can display all glyphs.  */
-               break;
-           }
+MRealizedFont *
+get_font_from_group (MFrame *frame, MPlist *plist, MFont *font)
+{
+  MRealizedFont *rfont;
+
+  MPLIST_DO (plist, plist)
+    {
+      MFont spec = *(MFont *) MPLIST_VAL (plist);
+      if (mfont__merge (&spec, font, 1) < 0)
+       continue;
+      if (font->type == MFONT_TYPE_SPEC)
+       rfont = (MRealizedFont *) mfont_find (frame, &spec, NULL, 0);
+      else if (font->type == MFONT_TYPE_OBJECT)
+       rfont = mfont__open (frame, font, &spec);
+      else
+       rfont = (MRealizedFont *) font;
+      if (rfont
+         && (spec.capability == Mnil
+             || mfont__check_capability (rfont, spec.capability) == 0))
+       {
+         rfont->layouter
+           = MPLIST_KEY (plist) == Mt ? Mnil : MPLIST_KEY (plist);
+         return rfont;
        }
-      if (! MPLIST_TAIL_P (plist))
-       break;
     }
+  return NULL;
+}
 
-  if (i < n_font_group) 
-    return rfont;
+MRealizedFont *
+mfontset__get_font (MFrame *frame, MFontset *fontset,
+                   MSymbol script, MSymbol language, MFont *font,
+                   int *best)
+{
+  MPlist *per_script, *per_lang;
+  MRealizedFont *rfont;
+
+  if (best)
+    *best = 0;
 
-  /* We couldn't find a font that can display all glyphs.  Find one
-     that can display at least the first glyph.  */
-  for (i = 0; i < n_font_group; i++)
+  if (language == Mnil)
+    language = Mt;
+
+  if (script != Mnil)
     {
-      MPLIST_DO (plist, font_groups[i])
+      per_script = get_per_script (fontset, script);
+      if ((per_lang = mplist_get (per_script, language))
+         && (rfont = get_font_from_group (frame, per_lang, font)))
        {
-         rfont = (MRealizedFont *) MPLIST_VAL (plist);
-         if (rfont->status < 0)
-           continue;
-         g->code = mfont__encode_char (rfont,
-                                       g->type == GLYPH_CHAR ? g->c : ' ');
-         if (g->code != MCHAR_INVALID_CODE)
-           {
-             if (rfont->status > 0
-                 || mfont__open (rfont) == 0)
-               break;
-           }
+         if (best)
+           *best = 1;
+         return rfont;
+       }
+      if (best)
+       *best = per_lang ? 0 : 1;
+      if (language == Mt)
+       {
+         MPLIST_DO (per_script, per_script)
+           if (MPLIST_KEY (per_script) != language
+               && (rfont = get_font_from_group (frame,
+                                                MPLIST_PLIST (per_script),
+                                                font)))
+             return rfont;
+       }
+      else
+       {
+         if ((per_lang = mplist_get (per_script, Mt))
+             && (rfont = get_font_from_group (frame, per_lang, font)))
+           return rfont;
+         if (best)
+           *best = 0;
+         MPLIST_DO (per_script, per_script)
+           if (MPLIST_KEY (per_script) != language
+               && MPLIST_KEY (per_script) != Mt
+               && (rfont = get_font_from_group (frame,
+                                                MPLIST_PLIST (per_script),
+                                                font)))
+             return rfont;
        }
-      if (! MPLIST_TAIL_P (plist))
-       break;
     }
-  return (i < n_font_group ? rfont : NULL);
+
+  if (language != Mt)
+    MPLIST_DO (per_script, fontset->per_script)
+      {
+       if ((per_lang = mplist_get (MPLIST_PLIST (per_script), language))
+           && (rfont = get_font_from_group (frame, per_lang, font)))
+         {
+           if (best)
+             *best = 1;
+           return rfont;
+         }
+      }
+
+  if (best)
+    *best = 0;
+  if ((rfont = get_font_from_group (frame, fontset->fallback, font)))
+    return rfont;
+  return NULL;
 }
 
+
 /*** @} */
 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
 
@@ -657,18 +1005,16 @@ mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num,
 /***ja 
     @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÊÖ¤¹.
 
-    ´Ø¿ô mfontset () ¤Ï̾Á° $NAME ¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î
-    ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ $NAME ¤¬ @c NULL ¤Ê¤é¤Ð¡¢¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¥»¥Ã¥È
-    ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
+    ´Ø¿ô mfontset () ¤Ï̾Á° $NAME ¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ 
+    $NAME ¤¬ @c NULL ¤Ê¤é¤Ð¡¢¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
 
-    $NAME ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¤¬¤Ê¤±¤ì¤Ð¡¢¿·¤·¤¤¤â¤Î¤¬ºî¤é¤ì
-    ¤ë¡£¤½¤ÎºÝ¡¢m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë \<@c fontset, $NAME\> ¤È¤¤¤¦¥Ç¡¼¥¿
-    ¤¬¤¢¤ì¤Ð¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï¤½¤Î¥Ç¡¼¥¿¤Ë±è¤Ã¤Æ½é´ü²½¤µ¤ì¤ë¡£¤Ê¤±¤ì¤Ð¡¢
-    ¶õ¤Î¤Þ¤Þ¤Ë¤µ¤ì¤ë¡£
+    $NAME ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¤¬¤Ê¤±¤ì¤Ð¡¢¿·¤·¤¤¤â¤Î¤¬ºî¤é¤ì¤ë¡£¤½¤ÎºÝ¡¢
+    m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë \<@c fontset, $NAME\> 
+    ¤È¤¤¤¦¥Ç¡¼¥¿¤¬¤¢¤ì¤Ð¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï¤½¤Î¥Ç¡¼¥¿¤Ë±è¤Ã¤Æ½é´ü²½¤µ¤ì¤ë¡£
+    ¤Ê¤±¤ì¤Ð¡¢¶õ¤Î¤Þ¤Þ¤Ë¤µ¤ì¤ë¡£
 
-    ¥Þ¥¯¥í M17N_INIT () ¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤òºî¤ë¡£¥¢¥×¥ê¥±¡¼
-    ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï mframe () ¤ò½é¤á¤Æ¸Æ¤Ö¤Þ¤Ç¤Ï¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È
-    ¥»¥Ã¥È¤òÊѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£
+    ¥Þ¥¯¥í M17N_INIT () ¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤òºî¤ë¡£¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï
+    mframe () ¤ò½é¤á¤Æ¸Æ¤Ö¤Þ¤Ç¤Î´Ö¤Ï¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÊѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£
 
     @return
     ¤³¤Î´Ø¿ô¤Ï¸«¤Ä¤«¤Ã¤¿¡¢¤¢¤ë¤¤¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
@@ -681,14 +1027,20 @@ mfontset (char *name)
   MFontset *fontset;
 
   if (! name)
-    fontset = default_fontset;
+    {
+      fontset = default_fontset;
+      M17N_OBJECT_REF (fontset);
+    }
   else
     {
       sym = msymbol (name);
       fontset = mplist_get (fontset_list, sym);
-      if (! fontset)
+      if (fontset)
+       M17N_OBJECT_REF (fontset);
+      else
        {
          M17N_OBJECT (fontset, free_fontset, MERROR_FONTSET);
+         M17N_OBJECT_REGISTER (fontset_table, fontset);
          fontset->name = sym;
          fontset->mdb = mdatabase_find (Mfontset, sym, Mnil, Mnil);
          if (! fontset->mdb)
@@ -700,7 +1052,6 @@ mfontset (char *name)
          mplist_put (fontset_list, sym, fontset);
        }
     }
-  M17N_OBJECT_REF (fontset);
   return fontset;
 }
 
@@ -732,9 +1083,9 @@ mfontset_name (MFontset *fontset)
 /***ja
     @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
 
-    ´Ø¿ô mfontset_copy () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤Î¥³¥Ô¡¼¤òºî¤Ã¤Æ¡¢
-    Ì¾Á° $NAME ¤òÍ¿¤¨¡¢¤½¤Î¥³¥Ô¡¼¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$NAME ¤Ï´û¸¤Î
-    ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î̾Á°¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤½¤Î¾ì¹ç¤Ë¤Ï¥³¥Ô¡¼¤òºî¤é¤º
+    ´Ø¿ô mfontset_copy () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤Î¥³¥Ô¡¼¤òºî¤Ã¤Æ¡¢Ì¾Á°
+    $NAME ¤òÍ¿¤¨¡¢¤½¤Î¥³¥Ô¡¼¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$NAME 
+    ¤Ï´û¸¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î̾Á°¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤½¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¥³¥Ô¡¼¤òºî¤é¤º¤Ë
     NULL ¤òÊÖ¤¹¡£  */
 
 MFontset *
@@ -742,40 +1093,62 @@ mfontset_copy (MFontset *fontset, char *name)
 {
   MSymbol sym = msymbol (name);
   MFontset *copy = mplist_get (fontset_list, sym);
-  MPlist *plist, *pl;
+  MPlist *plist, *pl, *p;
 
   if (copy)
     return NULL;
   M17N_OBJECT (copy, free_fontset, MERROR_FONTSET);
+  M17N_OBJECT_REGISTER (fontset_table, copy);
   copy->name = sym;
 
+  if (fontset->mdb)
+    load_fontset_contents (fontset);
+
   if (fontset->per_script)
     {
       copy->per_script = mplist ();
       MPLIST_DO (plist, fontset->per_script)
         {
-         MPlist *new = mplist ();
+         MPlist *per_lang = mplist ();
 
+         mplist_add (copy->per_script, MPLIST_KEY (plist), per_lang);
          MPLIST_DO (pl, MPLIST_PLIST (plist))
-           mplist_add (new, MPLIST_KEY (pl), mplist_copy (MPLIST_PLIST (pl)));
-         mplist_add (copy->per_script, MPLIST_KEY (plist), new);
+           {
+             MPlist *font_group = mplist ();
+
+             per_lang = mplist_add (per_lang, MPLIST_KEY (pl), font_group);
+             MPLIST_DO (p, MPLIST_PLIST (pl))
+               font_group = mplist_add (font_group, MPLIST_KEY (p),
+                                        mfont_copy (MPLIST_VAL (p)));
+           }
        }
     }
   if (fontset->per_charset)
     {
-      copy->per_charset = mplist ();
-      MPLIST_DO (plist, fontset->per_charset)
-       mplist_add (copy->per_charset, MPLIST_KEY (plist),
-                   mplist_copy (MPLIST_PLIST (plist)));
+      MPlist *per_charset = mplist ();
+
+      copy->per_charset = per_charset;
+      MPLIST_DO (pl, fontset->per_charset)
+       {
+         MPlist *font_group = mplist ();
+
+         per_charset = mplist_add (per_charset, MPLIST_KEY (pl), font_group);
+         MPLIST_DO (p, MPLIST_PLIST (pl))
+           font_group = mplist_add (font_group, MPLIST_KEY (p),
+                                    mfont_copy (MPLIST_VAL (p)));
+       }
     }
   if (fontset->fallback)
-    copy->fallback = mplist_copy (fontset->fallback);
+    {
+      MPlist *font_group = mplist ();
 
-  copy->font_spec_list = fontset->font_spec_list;
-  M17N_OBJECT_REF (copy->font_spec_list);
+      copy->fallback = font_group;
+      MPLIST_DO (p, fontset->fallback)
+       font_group = mplist_add (font_group, MPLIST_KEY (p),
+                                mfont_copy (MPLIST_VAL (p)));
+    }                           
 
   mplist_put (fontset_list, sym, copy);
-  M17N_OBJECT_REF (copy);
   return copy;
 }
 
@@ -816,10 +1189,10 @@ mfontset_copy (MFontset *fontset, char *name)
     only available font for the associated item; all the other fonts
     are removed from the group.
 
-    If $LAYOUTER_NAME is not @c Mnil, it must be a symbol
-    representing a @ref flt.  In that case, if $FONT is selected for
-    drawing an M-text, that font layout table is used to generate a
-    glyph code sequence from a character sequence.
+    If $LAYOUTER_NAME is not @c Mnil, it must be a symbol representing
+    a @ref mdbFLT (font layout table).  In that case, if $FONT is
+    selected for drawing an M-text, that font layout table is used to
+    generate a glyph code sequence from a character sequence.
 
     @return
     If the operation was successful, mfontset_modify_entry () returns 0.
@@ -829,43 +1202,38 @@ mfontset_copy (MFontset *fontset, char *name)
 /***ja
     @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ÎÆâÍƤòÊѹ¹¤¹¤ë.
 
-    ´Ø¿ô mfontset_modify_entry () ¤Ï¡¢$LANGUAGE ¤È $SCRIPT ¤ÎÁȤ߹ç¤ï
-    ¤»¤Þ¤¿¤Ï $CHARSET ¤ËÂФ·¤Æ $FONT ¤Î¥³¥Ô¡¼¤ò»È¤¦¤è¤¦¤Ë¡¢¥Õ¥©¥ó¥È¥»¥Ã
-    ¥È $FONTSET ¤òÀßÄꤹ¤ë¡£
+    ´Ø¿ô mfontset_modify_entry () ¤Ï¡¢$LANGUAGE ¤È $SCRIPT ¤ÎÁȤ߹ç¤ï¤»¡¢¤Þ¤¿¤Ï
+    $CHARSET ¤ËÂФ·¤Æ $FONT ¤Î¥³¥Ô¡¼¤ò»È¤¦¤è¤¦¤Ë¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤òÀßÄꤹ¤ë¡£
 
-    ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î³Æ¥Õ¥©¥ó¥È¤Ï¡¢ÆÃÄê¤Î¥¹¥¯¥ê¥×¥È¤È¸À¸ì¤Î¥Ú¥¢¡¢ÆÃÄê¤Î
-    Ê¸»ú¥»¥Ã¥È¡¢¥·¥ó¥Ü¥ë @c Mnil ¤Î¤¤¤º¤ì¤«¤È´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤ë¡£Æ±¤¸
-    ¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×¤ò¹½À®¤¹¤ë¡£
+    ¥Õ¥©¥ó¥È¥»¥Ã¥ÈÃæ¤Î³Æ¥Õ¥©¥ó¥È¤Ï¡¢ÆÃÄê¤Î¥¹¥¯¥ê¥×¥È¤È¸À¸ì¤Î¥Ú¥¢¡¢ÆÃÄê¤Îʸ»ú¥»¥Ã¥È¡¢¥·¥ó¥Ü¥ë
+    @c Mnil ¤Î¤¤¤º¤ì¤«¤È´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤ë¡£Æ±¤¸¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×¤ò¹½À®¤¹¤ë¡£
 
     $SCRIPT ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥¹¥¯¥ê¥×¥È¤òÆÃÄꤹ¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
     ¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï¡¢$LANGUAGE ¤Ï¸À¸ì¤òÆÃÄꤹ¤ë¥·¥ó¥Ü¥ë¤« @c
     Mnil ¤Ç¤¢¤ê¡¢$FONT ¤Ïthe $SCRIPT / $LANGUAGE ¥Ú¥¢¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£
 
-    $CHARSET ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢Ê¸»ú¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¤¹¥·¥ó¥Ü¥ë
-    ¤Ç¤¢¤ë¡£¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï $FONT ¤Ï¤½¤Îʸ»ú¥»¥Ã¥È¤È´ØÏ¢ÉÕ¤±¤é¤ì
-    ¤ë¡£
+    $CHARSET ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢Ê¸»ú¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+    ¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï $FONT ¤Ï¤½¤Îʸ»ú¥»¥Ã¥È¤È´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£
 
-    $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ç¤Ê¤¤¾ì¹ç¤Ë¤Ï $FONT ¤Î¥³¥Ô¡¼
-    ¤¬£²¤Äºî¤é¤ì¡¢¤½¤ì¤¾¤ì $SCRIPT / $LANGUAGE ¥Ú¥¢¤Èʸ»ú¥»¥Ã¥È¤Ë´ØÏ¢
-    ÉÕ¤±¤é¤ì¤ë¡£
+    $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ç¤Ê¤¤¾ì¹ç¤Ë¤Ï $FONT 
+    ¤Î¥³¥Ô¡¼¤¬£²¤Äºî¤é¤ì¡¢¤½¤ì¤¾¤ì $SCRIPT / $LANGUAGE 
+    ¥Ú¥¢¤Èʸ»ú¥»¥Ã¥È¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£
 
-    $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ê¤é¤Ð¡¢ $FONT ¤Ï @c Mnil ¤È
-    ´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£¤³¤Î¼ï¤Î¥Õ¥©¥ó¥È¤Ï @e fallback @e font ¤È¸Æ¤Ð¤ì¤ë¡£
+    $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ê¤é¤Ð¡¢ $FONT ¤Ï @c Mnil 
+    ¤È´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£¤³¤Î¼ï¤Î¥Õ¥©¥ó¥È¤Ï @e fallback @e font ¤È¸Æ¤Ð¤ì¤ë¡£
 
-    °ú¿ô $HOW ¤Ï $FONT ¤ÎÍ¥ÀèÅÙ¤ò»ØÄꤹ¤ë¡£$HOW ¤¬Àµ¤Ê¤é¤Ð¡¢$FONT ¤ÏƱ
-    ¤¸¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥°¥ë¡¼¥×Ãæ¤ÇºÇ¹â¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW ¤¬Éé¤Ê
-    ¤é¤Ð¡¢ºÇÄã¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW ¤¬ 0 ¤Ê¤é¤Ð¡¢$FONT ¤Ï´ØÏ¢ÉÕ¤±¤é¤ì¤¿
-    ¤â¤Î¤ËÂФ¹¤ëÍ£°ì¤ÎÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤È¤Ê¤ê¡¢Â¾¤Î¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×
-    ¤«¤é¼è¤ê½ü¤«¤ì¤ë¡£
+    °ú¿ô $HOW ¤Ï $FONT ¤ÎÍ¥ÀèÅÙ¤ò»ØÄꤹ¤ë¡£$HOW ¤¬Àµ¤Ê¤é¤Ð¡¢$FONT 
+    ¤ÏƱ¤¸¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥°¥ë¡¼¥×Ãæ¤ÇºÇ¹â¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW 
+    ¤¬Éé¤Ê¤é¤Ð¡¢ºÇÄã¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW ¤¬ 0 ¤Ê¤é¤Ð¡¢$FONT 
+    ¤Ï´ØÏ¢ÉÕ¤±¤é¤ì¤¿¤â¤Î¤ËÂФ¹¤ëÍ£°ì¤ÎÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤È¤Ê¤ê¡¢Â¾¤Î¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×¤«¤é¼è¤ê½ü¤«¤ì¤ë¡£
 
-    $LAYOUTER_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢@ref flt ¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
-    ¥·¥ó¥Ü¥ë¤Ç¤¢¤ì¤Ð¡¢$FONT ¤òÍѤ¤¤ÆM-text ¤òɽ¼¨¤¹¤ëºÝ¤Ë¤Ï¡¢¤½¤Î FONT
-    LAYOUT TABLE ¤ò»È¤Ã¤Æʸ»úÎ󤫤饰¥ê¥Õ¥³¡¼¥ÉÎó¤òÀ¸À®¤¹¤ë¡£
+    $LAYOUTER_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢@ref mdbFLT 
+    ¡Ê¥Õ¥©¥ó¥È¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¡Ë¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£¥·¥ó¥Ü¥ë¤Ç¤¢¤ì¤Ð¡¢$FONT ¤òÍѤ¤¤Æ
+    M-text ¤òɽ¼¨¤¹¤ëºÝ¤Ë¤Ï¡¢¤½¤Î¥Õ¥©¥ó¥È¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¤ò»È¤Ã¤Æʸ»úÎ󤫤饰¥ê¥Õ¥³¡¼¥ÉÎó¤òÀ¸À®¤¹¤ë¡£
 
     @return 
     ½èÍý¤¬À®¸ù¤·¤¿¤È¤­¡¢mfontset_modify_entry () ¤Ï 0 ¤òÊÖ¤¹¡£
-    ¼ºÇÔ¤·¤¿¤È¤­¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤ò
-    ÀßÄꤹ¤ë¡£  */
+    ¼ºÇÔ¤·¤¿¤È¤­¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
 
 /***
     @errors
@@ -877,31 +1245,13 @@ mfontset_modify_entry (MFontset *fontset,
                       MFont *spec, MSymbol layouter_name,
                       int how)
 {
-  MPlist *per_lang, *plist[3], *pl;
+  MPlist *per_lang, *plist[3];
   MFont *font = NULL;
   int i;
 
   if (fontset->mdb)
     load_fontset_contents (fontset);
 
-  if (! fontset->font_spec_list)
-    fontset->font_spec_list = mplist ();
-  else
-    MPLIST_DO (pl, fontset->font_spec_list)
-      {
-       if (! memcmp (MPLIST_VAL (pl), spec, sizeof (MFont)))
-         {
-           font = MPLIST_VAL (pl);
-           break;
-         }
-      }
-  if (! font)
-    {
-      font = mfont ();
-      *font = *spec;
-      mplist_add (fontset->font_spec_list, Mt, font);
-    }
-
   i = 0;
   if (script != Mnil)
     {
@@ -931,12 +1281,18 @@ mfontset_modify_entry (MFontset *fontset,
     layouter_name = Mt;
   for (i--; i >= 0; i--)
     {
-      if (how == -1)
+      font = mfont_copy (spec);
+      font->type = MFONT_TYPE_SPEC;
+      if (how == 1)
        mplist_push (plist[i], layouter_name, font);
-      else if (how == 1)
+      else if (how == -1)
        mplist_add (plist[i], layouter_name, font);
       else
        {
+         MPlist *pl;
+
+         MPLIST_DO (pl, plist[i])
+           free (MPLIST_VAL (pl));
          mplist_set (plist[i], Mnil, NULL);
          mplist_add (plist[i], layouter_name, font);
        }
@@ -958,37 +1314,78 @@ mfontset_modify_entry (MFontset *fontset,
     If $SCRIPT is @c Mt, keys of the returned plist are script name
     symbols for which some fonts are specified and values are NULL.
 
-    If $SCIRPT is a script symbol, the returned plist is decided by
-    $LANGUAGE.
+    If $SCRIPT is a script name symbol, the returned plist is decided
+    by $LANGUAGE.
+    
+    @li If $LANGUAGE is @c Mt, keys of the plist are language name
+    symbols for which some fonts are specified and values are NULL.  A
+    key may be @c Mt which means some fallback fonts are specified for
+    the script.
 
-    If $LANGUAGE is @c Mt, keys of the plist are language name symbols
-    for which some fonts are specified and values are NULL.  A key may
-    be @c Mt which means some fallback fonts are specified for the
-    script.
+    @li If $LANGUAGE is a language name symbol, the plist is a @c
+    FONT-GROUP for the specified script and language.  @c FONT-GROUP
+    is a plist whose keys are FLT (FontLayoutTable) name symbols (@c
+    Mt if no FLT is associated with the font) and values are pointers
+    to #MFont.
 
-    If $LANGUAGE is a language name symbol, the plist is a @c
-    FONT-GROUP for the specified script and langauge.
-
-    If $LANGAUGE is @c Mt, the plist is fallback @c FONT-GROUP for the
-    script.
+    @li If $LANGUAGE is @c Mnil, the plist is fallback @c FONT-GROUP
+    for the script. 
 
     If $SCRIPT is @c Mnil, the returned plist is decided as below.
 
-    If $CHARSET is @c Mt, keys of the returned plist are charset name
+    @li If $CHARSET is @c Mt, keys of the returned plist are charset name
     symbols for which some fonts are specified and values are NULL.
 
-    If $CHARSET is a charset symbol, the plist is a @c FONT-GROUP for
+    @li If $CHARSET is a charset name symbol, the plist is a @c FONT-GROUP for
     the charset.
 
-    If $CHARSET is @c Mnil, the plist is a fallback @c FONT-GROUP.
-
-    @c FONT-GROUP is a plist whose keys are FLT name symbols (@c Mt if
-    no FLT is associated with the font) and values are pointers to
-    #MFont.
+    @li If $CHARSET is @c Mnil, the plist is a fallback @c FONT-GROUP.
 
     @return
     It returns a plist describing the contents of a fontset.  The
     plist should be freed by m17n_object_unref ().  */
+/***ja
+    @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ò¸¡º÷¤¹¤ë.
+
+    ´Ø¿ô mfontset_lookup () ¤Ï $FONTSET ¤ò¸¡º÷¤·¡¢$FONTSET 
+    ¤ÎÆâÍƤΤ¦¤Á»ØÄꤷ¤¿¥¹¥¯¥ê¥×¥È¡¢¸À¸ì¡¢Ê¸»ú¥»¥Ã¥È¤ËÂбþ¤¹¤ëÉôʬ¤òɽ¤¹
+    plist ¤òÊÖ¤¹¡£
+
+    $SCRIPT ¤¬ @c Mt ¤Ê¤é¤Ð¡¢ÊÖ¤¹ plist 
+    ¤Î¥­¡¼¤Ï¥Õ¥©¥ó¥È¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¥¹¥¯¥ê¥×¥È̾¤Î¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ÃͤÏ
+    NULL ¤Ç¤¢¤ë¡£
+
+    $SCRIPT ¤¬¥¹¥¯¥ê¥×¥È̾¤Î¥·¥ó¥Ü¥ë¤Ç¤¢¤ì¤Ð¡¢ÊÖ¤¹ 
+    plist ¤Ï $LANGUAGE¤Ë¤è¤Ã¤ÆÄê¤Þ¤ë¡£
+    
+    @li $LANGUAGE ¤¬ @c Mt ¤Ê¤é¤Ð¡¢plist 
+    ¤Î¥­¡¼¤Ï¥Õ¥©¥ó¥È¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¸À¸ì̾¤Î¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ÃͤÏ
+    NULL ¤Ç¤¢¤ë¡£¥­¡¼¤Ï @c Mt
+    ¤Ç¤¢¤ë¤³¤È¤â¤¢¤ê¡¢¤½¤Î¾ì¹ç¤½¤Î¥¹¥¯¥ê¥×¥È¤Ë¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¥Õ¥©¥ó¥È¤¬¤¢¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
+
+    @li $LANGUAGE ¤¬¸À¸ì̾¤Î¥·¥ó¥Ü¥ë¤Ê¤é¤Ð¡¢plist ¤Ï»ØÄê¤Î¥¹¥¯¥ê¥×¥È¤È¸À¸ì¤ËÂФ¹¤ë
+    @c FONT-GROUP ¤Ç¤¢¤ë¡£@c FONT-GROUP ¤È¤Ï¡¢¥­¡¼¤¬ FLT
+    (FontLayoutTable) Ì¾¤Î¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤ¬ #MFont 
+    ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Ê plist ¤Ç¤¢¤ë¡£¤¿¤À¤·¥Õ¥©¥ó¥È¤Ë FLT 
+    ¤¬ÂбþÉÕ¤±¤é¤ì¤Æ¤¤¤Ê¤¤»þ¤Ë¤Ï¡¢¥­¡¼¤Ï @c Mt ¤Ë¤Ê¤ë¡£
+
+    @li $LANGUAGE ¤¬ @c Mnil ¤Ê¤é¤Ð¡¢plist ¤Ï¤½¤Î¥¹¥¯¥ê¥×¥ÈÍѤΥե©¡¼¥ë¥Ð¥Ã¥¯
+    @c FONT-GROUP ¤Ç¤¢¤ë¡£
+
+    $SCRIPT ¤¬ @c Mnil ¤Ê¤é¤Ð¡¢ÊÖ¤¹ plist ¤Ï°Ê²¼¤Î¤è¤¦¤ËÄê¤Þ¤ë¡£
+
+    @li $CHARSET ¤¬ @c Mt ¤Ê¤é¤Ð¡¢plist 
+    ¤Î¥­¡¼¤Ï¥Õ¥©¥ó¥È¤¬»ØÄꤵ¤ì¤Æ¤¤¤ëʸ»ú¥»¥Ã¥È̾¤Î¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ÃͤÏ
+    NULL ¤Ç¤¢¤ë¡£
+
+    @li $CHARSET ¤¬Ê¸»ú¥»¥Ã¥È̾¤Î¥·¥ó¥Ü¥ë¤Ê¤é¤Ð¡¢plist ¤Ï¤½¤Îʸ»ú¥»¥Ã¥ÈÍѤΠ
+    @c FONT-GROUP ¤Ç¤¢¤ë¡£
+
+    @li $CHARSET ¤¬ @c Mnil ¤Ê¤é¤Ð¡¢plist ¤Ï¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯ @c FONT-GROUP ¤Ç¤¢¤ë¡£
+
+    @return
+    ¤³¤Î´Ø¿ô¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È¤ÎÆâÍƤòɽ¤¹ plist ¤òÊÖ¤¹¡£
+    plist ¤Ï m17n_object_unref () ¤Ç²òÊü¤µ¤ì¤ë¤Ù¤­¤Ç¤¢¤ë¡£  */
 
 MPlist *
 mfontset_lookup (MFontset *fontset,
@@ -1009,10 +1406,8 @@ mfontset_lookup (MFontset *fontset,
     }
   if (script != Mnil)
     {
-      if (! fontset->per_script)
-       return plist;
-      pl = mplist_get (fontset->per_script, script);
-      if (! pl)
+      pl = get_per_script (fontset, script);
+      if (MPLIST_TAIL_P (pl))
        return plist;
       if (language == Mt)
        {
@@ -1064,9 +1459,8 @@ mfontset_lookup (MFontset *fontset,
 /***ja
     @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ò¥À¥ó¥×¤¹¤ë.
 
-    ´Ø¿ô mdebug_dump_face () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤ò stderr ¤Ë¿Í
-    ´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ
-    ¤ë¡£
+    ´Ø¿ô mdebug_dump_face () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤ò stderr 
+    ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
 
     @return
     ¤³¤Î´Ø¿ô¤Ï $FONTSET ¤òÊÖ¤¹¡£  */
@@ -1090,7 +1484,8 @@ mdebug_dump_fontset (MFontset *fontset, int indent)
            fprintf (stderr, "\n    %s(%s", prefix, MPLIST_KEY (pl)->name);
            MPLIST_DO (p, MPLIST_PLIST (pl))
              {
-               fprintf (stderr, "\n      %s(%s ", prefix,
+               fprintf (stderr, "\n      %s(0x%X %s ", prefix,
+                        (unsigned) MPLIST_VAL (p),
                         MPLIST_KEY (p)->name);
                mdebug_dump_font (MPLIST_VAL (p));
                fprintf (stderr, ")");