(libm17n_core_la_LIBADD): Add THAI_WORDSEG_LD_FLAGS,
[m17n/m17n-lib.git] / src / fontset.c
index 6f922ec..ea836af 100644 (file)
     M-text, a fontset provides rules to select a font for each
     character in the M-text according to the following information.
 
-    - The script character property of a character.
-    - The language text property of a character.
-    - The charset text property of a character.
+    @li The script character property of a character.
+    @li The language text property of a character.
+    @li The charset text property of a character.
 
     The documentation of mdraw_text () describes how that information is
     used.  */
 
-/***ja
-    @addtogroup m17nFontset
-    @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï°ìÄê¤Î¥¹¥¿¥¤¥ë¤ò¶¦Í­¤¹¤ë¥Õ¥©¥ó¥È¤Î½¸¹ç¤Ç¤¢¤ë
+/***ja @addtogroup m17nFontset 
+
+    @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ïʸ»ú¤«¤é¥Õ¥©¥ó¥È¤Ø¤ÎÂбþÉÕ¤±¤ò¹Ô¤¦¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë.
+
+    @e ¥Õ¥©¥ó¥È¥»¥Ã¥È ¤Ï @c MFontset ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£M-text 
+    ¤Îɽ¼¨¤ÎºÝ¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï°Ê²¼¤Î¾ðÊó¤òÍѤ¤¤Æ M-text 
+    Ãæ¤Î¸Ä¡¹¤Îʸ»ú¤Ë¤É¤Î¥Õ¥©¥ó¥È¤òÍѤ¤¤ë¤«·è¤á¤ëµ¬Â§¤òÍ¿¤¨¤ë¡£
+
+    @li Ê¸»ú¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£ "¥¹¥¯¥ê¥×¥È"
+    @li Ê¸»ú¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£ "¸À¸ì"
+    @li Ê¸»ú¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£ "ʸ»ú¥»¥Ã¥È"
 
-    @e ¥Õ¥©¥ó¥È¥»¥Ã¥È ¤Ï @c MFontset ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ê¡¢Â¿¸À¸ìʸ
-    ½ñ¤Îɽ¼¨¤ÎºÝ¡¢¸«¤«¤±¤Î»÷¤¿¥Õ¥©¥ó¥È¤ò½¸¤á¤Æ°ì´Ó¤·¤Æ¼è¤ê°·¤¦¤¿¤á¤Ë»È
-    ¤ï¤ì¤ë¡£¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï¤Þ¤¿¡¢¸À¸ì¡¢Ê¸»ú¥»¥Ã¥È¡¢Ê¸»ú¤¬Í¿¤¨¤é¤ì¤¿¤È
-    ¤­¤ËŬÀڤʥե©¥ó¥È¤òÁªÂò¤¹¤ë¤¿¤á¤Î¾ðÊó¤âÊÝ»ý¤·¤Æ¤¤¤ë¡£  */
+    ¤³¤ì¤é¤Î¾ðÊ󤬤ɤΤ褦¤ËÍѤ¤¤é¤ì¤ë¤«¤Ï mdraw_text () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
+
+    */
 
 /*=*/
 
@@ -55,6 +62,7 @@
 #include <string.h>
 #include <ctype.h>
 
+#include "config.h"
 #include "m17n-gui.h"
 #include "m17n-misc.h"
 #include "internal.h"
@@ -308,9 +316,12 @@ realize_font_group (MFrame *frame, MFont *request, MPlist *font_group,
   MPLIST_DO (pl, plist)
     {
       MSymbol layouter = MPLIST_KEY (pl);
-      MRealizedFont *rfont = mfont__select (frame, MPLIST_VAL (pl), request,
-                                           size,
-                                           layouter == Mt ? Mnil : layouter);
+      MFont this_request = *request;
+      MRealizedFont *rfont;
+
+      mfont__resize (MPLIST_VAL (pl), &this_request);
+      rfont = mfont__select (frame, MPLIST_VAL (pl), &this_request,
+                            size, layouter == Mt ? Mnil : layouter);
 
       if (rfont)
        {
@@ -322,6 +333,96 @@ realize_font_group (MFrame *frame, MFont *request, MPlist *font_group,
     }
 }
 
+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 ();
+  MPLIST_DO (plist, fontset->per_script)
+    {
+      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);
+       }
+    }
+
+  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);
+    }
+
+  realized->fallback = mplist ();
+  mplist_add (realized->fallback, Mplist, fontset->fallback);
+
+}
+
+static void
+free_realized_fontset_elements (MRealizedFontset *realized)
+{
+  MPlist *plist, *pl, *p;
+  MRealizedFont *rfont;
+
+  if (realized->per_script)
+    {
+      MPLIST_DO (plist, realized->per_script)
+       {
+         MPLIST_DO (pl, MPLIST_PLIST (plist))
+           {
+             MPLIST_DO (p, MPLIST_PLIST (pl))
+               if ((rfont = MPLIST_VAL (p)) && ! rfont->frame)
+                 free (rfont);
+             p = MPLIST_PLIST (pl);
+             M17N_OBJECT_UNREF (p);
+           }
+         pl = MPLIST_PLIST (plist);
+         M17N_OBJECT_UNREF (pl);
+       }
+      M17N_OBJECT_UNREF (realized->per_script);
+    }
+  if (realized->per_charset)
+    {
+      MPLIST_DO (plist, realized->per_charset)
+       {
+         MPLIST_DO (pl, MPLIST_PLIST (plist))
+           if ((rfont = MPLIST_VAL (pl)) && ! rfont->frame)
+             free (rfont);
+         pl = MPLIST_PLIST (plist);
+         M17N_OBJECT_UNREF (pl);
+       }
+      M17N_OBJECT_UNREF (realized->per_charset);
+    }
+  if (realized->fallback)
+    {
+      MPLIST_DO (plist, realized->fallback)
+       if ((rfont = MPLIST_VAL (plist)) && ! rfont->frame)
+         free (rfont);
+      M17N_OBJECT_UNREF (realized->fallback);
+    }
+}
+
+static void
+update_fontset_elements (MRealizedFontset *realized)
+{
+  free_realized_fontset_elements (realized);
+  realize_fontset_elements (realized->frame, realized, realized->fontset,
+                           &realized->spec);
+}
+
+
 \f
 
 /* Internal API */
@@ -364,8 +465,7 @@ mfont__realize_fontset (MFrame *frame, MFontset *fontset, MFace *face)
 {
   MRealizedFontset *realized;
   MFont request;
-  MPlist *per_script, *per_lang, *per_charset, *font_group;
-  MPlist *plist, *pl, *p;
+  MPlist *plist;
 
   if (fontset->mdb)
     load_fontset_contents (fontset);
@@ -376,43 +476,16 @@ mfont__realize_fontset (MFrame *frame, MFontset *fontset, MFace *face)
       mdebug_hook ();
       request.property[MFONT_SIZE] = 120;
     }
-  MPLIST_DO (p, frame->realized_fontset_list)
+  MPLIST_DO (plist, frame->realized_fontset_list)
     {
-      realized = (MRealizedFontset *) MPLIST_VAL (p);
-      if (fontset->name == MPLIST_KEY (p)
+      realized = (MRealizedFontset *) MPLIST_VAL (plist);
+      if (fontset->name == MPLIST_KEY (plist)
          && ! memcmp (&request, &realized->spec, sizeof (request)))
        return realized;
     }
 
   MSTRUCT_MALLOC (realized, MERROR_FONTSET);
-  realized->fontset = fontset;
-  realized->tick = fontset->tick;
-  realized->spec = request;
-  realized->frame = frame;
-  realized->per_script = per_script = mplist ();
-  MPLIST_DO (plist, fontset->per_script)
-    {
-      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);
-       }
-    }
-
-  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);
-    }
-
-  realized->fallback = mplist ();
-  mplist_add (realized->fallback, Mplist, fontset->fallback);
-
+  realize_fontset_elements (frame, realized, fontset, &request);
   mplist_add (frame->realized_fontset_list, fontset->name, realized);
   return realized;
 }
@@ -421,155 +494,163 @@ mfont__realize_fontset (MFrame *frame, MFontset *fontset, MFace *face)
 void
 mfont__free_realized_fontset (MRealizedFontset *realized)
 {
-  MPlist *plist, *pl, *p;
+  free_realized_fontset_elements (realized);
+  free (realized);
+}
+
+
+static MRealizedFont *
+try_font_group (MRealizedFontset *realized,
+               MPlist *font_group, MGlyph *g, int *num, int size)
+{
+  MFrame *frame = realized->frame;
   MRealizedFont *rfont;
+  MPlist *plist;
+  int i;
 
-  if (realized->per_script)
+  if (MPLIST_PLIST_P (font_group))
+    realize_font_group (frame, &realized->spec, font_group, size);
+
+  MPLIST_DO (plist, font_group)
     {
-      MPLIST_DO (plist, realized->per_script)
+      rfont = (MRealizedFont *) MPLIST_VAL (plist);
+      if (rfont->status < 0)
+       continue;
+      /* Check if this font can display all glyphs.  */
+      for (i = 0; i < *num; i++)
        {
-         MPLIST_DO (pl, MPLIST_PLIST (plist))
-           {
-             MPLIST_DO (p, MPLIST_PLIST (pl))
-               if ((rfont = MPLIST_VAL (p)) && ! rfont->frame)
-                 free (rfont);
-             p = MPLIST_PLIST (pl);
-             M17N_OBJECT_UNREF (p);
-           }
-         pl = MPLIST_PLIST (plist);
-         M17N_OBJECT_UNREF (pl);
+         g[i].code = mfont__encode_char (rfont,
+                                         g[i].type == GLYPH_CHAR ? g[i].c
+                                         : ' ');
+         if (g[i].code == MCHAR_INVALID_CODE)
+           break;
        }
-      M17N_OBJECT_UNREF (realized->per_script);
-    }
-  if (realized->per_charset)
-    {
-      MPLIST_DO (plist, realized->per_charset)
+      if (i == *num)
        {
-         MPLIST_DO (pl, MPLIST_PLIST (plist))
-           if ((rfont = MPLIST_VAL (pl)) && ! rfont->frame)
-             free (rfont);
-         pl = MPLIST_PLIST (plist);
-         M17N_OBJECT_UNREF (pl);
+         if (rfont->status > 0
+             || mfont__open (rfont) == 0)
+           /* We found a font that can display all glyphs.  */
+           return rfont;
        }
-      M17N_OBJECT_UNREF (realized->per_charset);
     }
-  if (realized->fallback)
+
+  /* We couldn't find a font that can display all glyphs.  Find one
+     that can display at least the first glyph.  */
+  MPLIST_DO (plist, font_group)
     {
-      MPLIST_DO (plist, realized->fallback)
-       if ((rfont = MPLIST_VAL (plist)) && ! rfont->frame)
-         free (rfont);
-      M17N_OBJECT_UNREF (realized->fallback);
+      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)
+           {
+             /* Ok, let's use this font.  Check how many more
+                characters it supports.  */
+             int i;
+
+             for (i = 1; i < *num; i++)
+               {
+                 g[i].code = mfont__encode_char (rfont,
+                                                 g[i].type == GLYPH_CHAR
+                                                 ? g[i].c : ' ');
+                 if (g[i].code == MCHAR_INVALID_CODE)
+                   break;
+               }
+             *num = i;
+             return rfont;
+           }
+       }
     }
 
-  free (realized);
+  return NULL;
 }
 
-
 MRealizedFont *
 mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num,
                       MSymbol script, MSymbol language, MSymbol charset,
                       int size)
 {
-  MFrame *frame = realized->frame;
   MCharset *preferred_charset = (charset == Mnil ? NULL : MCHARSET (charset));
-  MPlist *per_charset, *per_script, *per_lang, *font_group;
-  MPlist *font_groups[256], *plist;
-  int n_font_group = 0;
-  MRealizedFont *first = NULL, *rfont;
-  int first_len;
-  int i;
+  MPlist *per_charset, *per_script, *per_lang;
+  MPlist *plist;
+  MRealizedFont *rfont = NULL;
+
+  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;
+      && (per_charset = mplist_get (realized->per_charset, charset)) != NULL
+      && (rfont = try_font_group (realized, per_charset, g, num, size)))
+    return rfont;
+
   if (script != Mnil
-      && ((per_script = mplist_find_by_key (realized->per_script, script))
-         != NULL))
+      && (per_script = mplist_get (realized->per_script, script)))
     {
-      /* The first loop is for matching language (if any), and the second
-        loop is for non-matching languages.  */
+      /* We prefer font groups in this order:
+         (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;
-      for (i = 0; i < 2; i++)
-       {
-         MPLIST_DO (per_lang, MPLIST_PLIST (per_script))
-           if ((MPLIST_KEY (per_lang) == language) != i)
-             font_groups[n_font_group++] = MPLIST_PLIST (per_lang);
-       }
-    }
-  font_groups[n_font_group++] = realized->fallback;
+      if ((per_lang = mplist_get (per_script, language))
+         && (rfont = try_font_group (realized, per_lang, g, num, size)))
+       return rfont;
 
-  if (n_font_group == 1)
-    {
-      /* 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);
-    }
-
-  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);
-
-      MPLIST_DO (plist, font_groups[i])
-        {
-         rfont = (MRealizedFont *) MPLIST_VAL (plist);
-         g->code = mfont__encode_char (rfont, g->c);
-         if (g->code != MCHAR_INVALID_CODE)
-           break;
-       }
-      if (MPLIST_TAIL_P (plist))
-       continue;
-      for (j = 1; j < *num; j++)
+      if (language == Mt)
        {
-         g[j].code = mfont__encode_char (rfont, g[j].c);
-         if (g[j].code == MCHAR_INVALID_CODE)
-           break;
+         /* Try the above (3) */
+         MPLIST_DO (plist, per_script)
+           if (MPLIST_KEY (plist) != language
+               && (rfont = try_font_group (realized, MPLIST_PLIST (plist),
+                                           g, num, size)))
+             return rfont;
        }
-      if (! first)
-       first = rfont, first_len = j;
-      if (j == *num)
-       /* We found a font that can display all requested
-          characters.  */
-       break;
-
-      MPLIST_DO (plist, MPLIST_NEXT (plist))
+      else
        {
-         rfont = (MRealizedFont *) MPLIST_VAL (plist);
-         for (j = 0; j < *num; j++)
-           {
-             g[j].code = mfont__encode_char (rfont, g[j].c);
-             if (g[j].code == MCHAR_INVALID_CODE)
-               break;
-           }
-         if (j == *num)
-           break;
+         /* At first try the above (2) */
+         if ((per_lang = mplist_get (per_script, Mt))
+             && (rfont = try_font_group (realized, per_lang, g, num, size)))
+           return rfont;
+
+         /* Then try the above (3) */
+         MPLIST_DO (plist, per_script)
+           if (MPLIST_KEY (plist) != language
+               && MPLIST_KEY (plist) != Mt
+               && (rfont = try_font_group (realized, MPLIST_PLIST (plist),
+                                           g, num, size)))
+             return rfont;
        }
-      if (! MPLIST_TAIL_P (plist))
-       break;
     }
 
-  if (i == n_font_group) 
-    {
-      if (! first)
-       return NULL;
-      rfont = first, *num = first_len;
-      for (i = 0; i < *num; i++)
-       g[i].code = mfont__encode_char (rfont, g[i].c);
-    }
-  if (! rfont->status
-      && mfont__open (rfont) < 0)
+  if (language != Mnil)
+    /* Find a font group for this language from all scripts.  */
+    MPLIST_DO (plist, realized->per_script)
+      if ((per_lang = mplist_get (MPLIST_PLIST (plist), language))
+         && (rfont = try_font_group (realized, per_lang, g, num, size)))
+       return rfont;
+
+  /* Try fallback fonts.  */
+  if ((rfont = try_font_group (realized, realized->fallback, g, num, size)))
+    return rfont;
+
+  /* At last try all fonts.  */
+  MPLIST_DO (per_script, realized->per_script)
     {
-      MPLIST_VAL (font_group) = NULL;
-      return NULL;
+      MPLIST_DO (per_lang, MPLIST_PLIST (per_script))
+       if ((rfont = try_font_group (realized, MPLIST_PLIST (per_lang),
+                                    g, num, size)))
+         return rfont;
     }
-  return rfont;
+  MPLIST_DO (per_charset, realized->per_charset)
+    if ((rfont = try_font_group (realized, MPLIST_PLIST (per_charset),
+                                g, num, size)))
+      return rfont;
+
+  return NULL;
 }
 
 /*** @} */
@@ -596,12 +677,29 @@ mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num,
     vacant.
 
     The macro M17N_INIT () creates the default fontset.  An
-    application program can modify it before the first call of mframe
-    ().
+    application program can modify it before the first call of 
+    mframe ().
 
     @return
     This function returns a pointer to the found or newly created
     fontset.  */
+/***ja 
+    @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÊÖ¤¹.
+
+    ´Ø¿ô mfontset () ¤Ï̾Á° $NAME ¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ 
+    $NAME ¤¬ @c NULL ¤Ê¤é¤Ð¡¢¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
+
+    $NAME ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¤¬¤Ê¤±¤ì¤Ð¡¢¿·¤·¤¤¤â¤Î¤¬ºî¤é¤ì¤ë¡£¤½¤ÎºÝ¡¢
+    m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë \<@c fontset, $NAME\> 
+    ¤È¤¤¤¦¥Ç¡¼¥¿¤¬¤¢¤ì¤Ð¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï¤½¤Î¥Ç¡¼¥¿¤Ë±è¤Ã¤Æ½é´ü²½¤µ¤ì¤ë¡£
+    ¤Ê¤±¤ì¤Ð¡¢¶õ¤Î¤Þ¤Þ¤Ë¤µ¤ì¤ë¡£
+
+    ¥Þ¥¯¥í M17N_INIT () ¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤òºî¤ë¡£¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï
+    mframe () ¤ò½é¤á¤Æ¸Æ¤Ö¤Þ¤Ç¤Î´Ö¤Ï¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÊѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£
+
+    @return
+    ¤³¤Î´Ø¿ô¤Ï¸«¤Ä¤«¤Ã¤¿¡¢¤¢¤ë¤¤¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
+     */
 
 MFontset *
 mfontset (char *name)
@@ -610,21 +708,26 @@ mfontset (char *name)
   MFontset *fontset;
 
   if (! name)
-    return default_fontset;
-  sym = msymbol (name);
-  fontset = mplist_get (fontset_list, sym);
-  if (fontset)
-    return fontset;
-  M17N_OBJECT (fontset, free_fontset, MERROR_FONTSET);
-  fontset->name = sym;
-  fontset->mdb = mdatabase_find (Mfontset, sym, Mnil, Mnil);
-  if (! fontset->mdb)
+    fontset = default_fontset;
+  else
     {
-      fontset->per_script = mplist ();
-      fontset->per_charset = mplist ();
-      fontset->fallback = mplist ();
+      sym = msymbol (name);
+      fontset = mplist_get (fontset_list, sym);
+      if (! fontset)
+       {
+         M17N_OBJECT (fontset, free_fontset, MERROR_FONTSET);
+         fontset->name = sym;
+         fontset->mdb = mdatabase_find (Mfontset, sym, Mnil, Mnil);
+         if (! fontset->mdb)
+           {
+             fontset->per_script = mplist ();
+             fontset->per_charset = mplist ();
+             fontset->fallback = mplist ();
+             fontset->font_spec_list = mplist ();
+           }
+         mplist_put (fontset_list, sym, fontset);
+       }
     }
-  mplist_put (fontset_list, sym, fontset);
   M17N_OBJECT_REF (fontset);
   return fontset;
 }
@@ -632,9 +735,13 @@ mfontset (char *name)
 /*=*/
 
 /***en
-    @brief Return the name of a fontset
+    @brief Return the name of a fontset.
+
+    The mfontset_name () function returns the name of fontset $FONTSET.  */
+/***ja
+    @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î̾Á°¤òÊÖ¤¹.
 
-    The mfontset_name () function returns the name of $FONTSET.  */
+    ´Ø¿ô mfontset_name () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤Î̾Á°¤òÊÖ¤¹¡£  */
 MSymbol
 mfontset_name (MFontset *fontset)
 {
@@ -644,12 +751,19 @@ mfontset_name (MFontset *fontset)
 /*=*/
 
 /***en
-    @brief Make a copy a fontset
+    @brief Make a copy of a fontset.
 
-    The mfontset_copy () function makes a copy of $FONTSET, gives it a
+    The mfontset_copy () function makes a copy of fontset $FONTSET, gives it a
     name $NAME, and returns a pointer to the created copy.  $NAME must
-    not be a name of existing fontset.  Otherwise, this function
+    not be a name of existing fontset.  In such case, this function
     returns NULL without making a copy.  */
+/***ja
+    @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
+
+    ´Ø¿ô mfontset_copy () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤Î¥³¥Ô¡¼¤òºî¤Ã¤Æ¡¢Ì¾Á°
+    $NAME ¤òÍ¿¤¨¡¢¤½¤Î¥³¥Ô¡¼¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$NAME 
+    ¤Ï´û¸¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î̾Á°¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤½¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¥³¥Ô¡¼¤òºî¤é¤º¤Ë
+    NULL ¤òÊÖ¤¹¡£  */
 
 MFontset *
 mfontset_copy (MFontset *fontset, char *name)
@@ -663,6 +777,9 @@ mfontset_copy (MFontset *fontset, char *name)
   M17N_OBJECT (copy, free_fontset, MERROR_FONTSET);
   copy->name = sym;
 
+  if (fontset->mdb)
+    load_fontset_contents (fontset);
+
   if (fontset->per_script)
     {
       copy->per_script = mplist ();
@@ -698,8 +815,9 @@ mfontset_copy (MFontset *fontset, char *name)
 /***en
     @brief Modify the contents of a fontset.
 
-    The mfontset_modify_entry () function associates, in $FONTSET, a
-    copy of $FONT with the $SCRIPT / $LANGUAGE pair or with $CHARSET.
+    The mfontset_modify_entry () function associates, in fontset
+    $FONTSET, a copy of $FONT with the $SCRIPT / $LANGUAGE pair or
+    with $CHARSET.
 
     Each font in a fontset is associated with a particular
     script/language pair, with a particular charset, or with the
@@ -716,12 +834,11 @@ mfontset_copy (MFontset *fontset, char *name)
     charset.
 
     If both $SCRIPT and $CHARSET are not @c Mnil, two copies of $FONT
-    are created.  Then one is associated with the script/language pair
-    and the other with the charset.
+    are created.  Then one is associated with the $SCRIPT / $LANGUAGE
+    pair and the other with that charset.
 
-    If both $SCRIPT and $CHARSET are @c Mnil, $FONT is associated
-    with @c Mnil.  This kind of fonts are called <i>fallback
-    fonts</i>.
+    If both $SCRIPT and $CHARSET are @c Mnil, $FONT is associated with
+    @c Mnil.  This kind of fonts are called @e fallback @e fonts.
 
     The argument $HOW specifies the priority of $FONT.  If $HOW is
     positive, $FONT has the highest priority in the group of fonts
@@ -730,33 +847,51 @@ 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 flt (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.
     Otherwise it returns -1 and assigns an error code to the external
-    variable @c merror_code.  */
+    variable #merror_code.  */
 
 /***ja
-    @brief ¸À¸ì¤È¥¹¥¯¥ê¥×¥È¤ÎÁȤ߹ç¤ï¤»¤Ë¥Õ¥©¥ó¥È¤ò´ØÏ¢ÉÕ¤±¤ë
+    @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ÎÆâÍƤòÊѹ¹¤¹¤ë.
 
-    ´Ø¿ô mfontset_set_language_script () ¤Ï¡¢$LANGUAGE ¤È $SCRIPT ¤ÎÁÈ
-    ¤ß¹ç¤ï¤»¤ËÂФ·¤Æ¥Õ¥©¥ó¥È $FONT ¤ò»È¤¦¤è¤¦¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET 
-    ¤òÀßÄꤹ¤ë¡£$LANGUAGE ¤È $SCRIPT ¤Ï¡¢¤½¤ì¤¾¤ì¸À¸ì¤È¥¹¥¯¥ê¥×¥È¤ò»Ø
-    Äꤹ¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+    ´Ø¿ô mfontset_modify_entry () ¤Ï¡¢$LANGUAGE ¤È $SCRIPT ¤ÎÁȤ߹ç¤ï¤»¡¢¤Þ¤¿¤Ï
+    $CHARSET ¤ËÂФ·¤Æ $FONT ¤Î¥³¥Ô¡¼¤ò»È¤¦¤è¤¦¤Ë¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤òÀßÄꤹ¤ë¡£
 
-    ¸À¸ì¤È¥¹¥¯¥ê¥×¥È¤ÎÁȤ߹ç¤ï¤»°ì¤Ä¤ËÂФ·¤ÆÊ£¿ô¤Î¥Õ¥©¥ó¥È¤òÀßÄꤹ¤ë¤³
-    ¤È¤â¤Ç¤­¤ë¡£$PREPEND_P ¤¬ 0 °Ê³°¤Ê¤é¤Ð¡¢$FONT ¤Ï¤½¤ÎÁȤ߹ç¤ï¤»¤ËÂÐ
-    ¤·¤ÆºÇÍ¥Àè¤ÇÍѤ¤¤é¤ì¤ë¤â¤Î¤È¤Ê¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢Í¥ÀèÅÙºÇÄã¤Î¥Õ¥©
-    ¥ó¥È¤È¤·¤ÆÅÐÏ¿¤µ¤ì¤ë¡£
+    ¥Õ¥©¥ó¥È¥»¥Ã¥ÈÃæ¤Î³Æ¥Õ¥©¥ó¥È¤Ï¡¢ÆÃÄê¤Î¥¹¥¯¥ê¥×¥È¤È¸À¸ì¤Î¥Ú¥¢¡¢ÆÃÄê¤Îʸ»ú¥»¥Ã¥È¡¢¥·¥ó¥Ü¥ë
+    @c Mnil ¤Î¤¤¤º¤ì¤«¤È´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤ë¡£Æ±¤¸¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×¤ò¹½À®¤¹¤ë¡£
 
-    @return
-    ½èÍý¤¬À®¸ù¤·¤¿¤È¤­¡¢mfontset_set_language_script () ¤Ï 0 ¤òÊÖ¤¹¡£
-    ¼ºÇÔ¤·¤¿¤È¤­¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤ò
-    ÀßÄꤹ¤ë¡£  */
+    $SCRIPT ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥¹¥¯¥ê¥×¥È¤òÆÃÄꤹ¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+    ¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï¡¢$LANGUAGE ¤Ï¸À¸ì¤òÆÃÄꤹ¤ë¥·¥ó¥Ü¥ë¤« @c
+    Mnil ¤Ç¤¢¤ê¡¢$FONT ¤Ïthe $SCRIPT / $LANGUAGE ¥Ú¥¢¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£
+
+    $CHARSET ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢Ê¸»ú¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+    ¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï $FONT ¤Ï¤½¤Îʸ»ú¥»¥Ã¥È¤È´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£
+
+    $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ç¤Ê¤¤¾ì¹ç¤Ë¤Ï $FONT 
+    ¤Î¥³¥Ô¡¼¤¬£²¤Äºî¤é¤ì¡¢¤½¤ì¤¾¤ì $SCRIPT / $LANGUAGE 
+    ¥Ú¥¢¤Èʸ»ú¥»¥Ã¥È¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£
+
+    $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ê¤é¤Ð¡¢ $FONT ¤Ï @c Mnil 
+    ¤È´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£¤³¤Î¼ï¤Î¥Õ¥©¥ó¥È¤Ï @e fallback @e font ¤È¸Æ¤Ð¤ì¤ë¡£
+
+    °ú¿ô $HOW ¤Ï $FONT ¤ÎÍ¥ÀèÅÙ¤ò»ØÄꤹ¤ë¡£$HOW ¤¬Àµ¤Ê¤é¤Ð¡¢$FONT 
+    ¤ÏƱ¤¸¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥°¥ë¡¼¥×Ãæ¤ÇºÇ¹â¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW 
+    ¤¬Éé¤Ê¤é¤Ð¡¢ºÇÄã¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW ¤¬ 0 ¤Ê¤é¤Ð¡¢$FONT 
+    ¤Ï´ØÏ¢ÉÕ¤±¤é¤ì¤¿¤â¤Î¤ËÂФ¹¤ëÍ£°ì¤ÎÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤È¤Ê¤ê¡¢Â¾¤Î¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×¤«¤é¼è¤ê½ü¤«¤ì¤ë¡£
+
+    $LAYOUTER_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢@ref flt 
+    ¡Ê¥Õ¥©¥ó¥È¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¡Ë¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£¥·¥ó¥Ü¥ë¤Ç¤¢¤ì¤Ð¡¢$FONT ¤òÍѤ¤¤Æ
+    M-text ¤òɽ¼¨¤¹¤ëºÝ¤Ë¤Ï¡¢¤½¤Î¥Õ¥©¥ó¥È¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¤ò»È¤Ã¤Æʸ»úÎ󤫤饰¥ê¥Õ¥³¡¼¥ÉÎó¤òÀ¸À®¤¹¤ë¡£
+
+    @return 
+    ½èÍý¤¬À®¸ù¤·¤¿¤È¤­¡¢mfontset_modify_entry () ¤Ï 0 ¤òÊÖ¤¹¡£
+    ¼ºÇÔ¤·¤¿¤È¤­¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
 
 /***
     @errors
@@ -775,14 +910,17 @@ mfontset_modify_entry (MFontset *fontset,
   if (fontset->mdb)
     load_fontset_contents (fontset);
 
-  MPLIST_DO (pl, fontset->font_spec_list)
-    {
-      if (! memcmp (MPLIST_VAL (pl), spec, sizeof (MFont)))
-       {
-         font = MPLIST_VAL (pl);
-         break;
-       }
-    }
+  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 ();
@@ -819,9 +957,9 @@ mfontset_modify_entry (MFontset *fontset,
     layouter_name = Mt;
   for (i--; i >= 0; i--)
     {
-      if (how == -1)
+      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
        {
@@ -830,9 +968,151 @@ mfontset_modify_entry (MFontset *fontset,
        }
     }
 
+  fontset->tick++;
   return 0;
 }
 
+/*=*/
+
+/***en
+    @brief Lookup a fontset.
+
+    The mfontset_lookup () function lookups $FONTSET and returns a
+    plist that describes the contents of $FONTSET corresponding to the
+    specified script, language, and charset.
+
+    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 $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.
+
+    @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.
+
+    @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.
+
+    @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.
+
+    @li If $CHARSET is a charset name symbol, the plist is a @c FONT-GROUP for
+    the charset.
+
+    @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,
+                MSymbol script, MSymbol language, MSymbol charset)
+{
+  MPlist *plist = mplist (), *pl, *p;
+
+  if (fontset->mdb)
+    load_fontset_contents (fontset);
+  if (script == Mt)
+    {
+      if (! fontset->per_script)
+       return plist;
+      p = plist;
+      MPLIST_DO (pl, fontset->per_script)
+       p = mplist_add (p, MPLIST_KEY (pl), NULL);
+      return plist;
+    }
+  if (script != Mnil)
+    {
+      if (! fontset->per_script)
+       return plist;
+      pl = mplist_get (fontset->per_script, script);
+      if (! pl)
+       return plist;
+      if (language == Mt)
+       {
+         p = plist;
+         MPLIST_DO (pl, pl)
+           p = mplist_add (p, MPLIST_KEY (pl), NULL);
+         return plist;
+       }
+      if (language == Mnil)
+       language = Mt;
+      pl = mplist_get (pl, language);
+    }
+  else if (charset != Mnil)
+    {
+      if (! fontset->per_charset)
+       return plist;
+      if (charset == Mt)
+       {
+         p = plist;
+         MPLIST_DO (pl, fontset->per_charset)
+           p = mplist_add (p, MPLIST_KEY (pl), NULL);
+         return plist;
+       }
+      pl = mplist_get (fontset->per_charset, charset);
+    }
+  else
+    pl = fontset->fallback;
+  if (! pl)
+    return plist;
+  return mplist_copy (pl);
+}
+
+
 /*** @} */
 
 /*** @addtogroup m17nDebug */
@@ -840,14 +1120,22 @@ mfontset_modify_entry (MFontset *fontset,
 /*** @{  */
 
 /***en
-    @brief Dump a fontset
+    @brief Dump a fontset.
 
-    The mdebug_dump_fontset () function prints $FONTSET in a human readable
+    The mdebug_dump_fontset () function prints fontset $FONTSET in a human readable
     way to the stderr.  $INDENT specifies how many columns to indent
     the lines but the first one.
 
     @return
     This function returns $FONTSET.  */
+/***ja
+    @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ò¥À¥ó¥×¤¹¤ë.
+
+    ´Ø¿ô mdebug_dump_face () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤ò stderr 
+    ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
+
+    @return
+    ¤³¤Î´Ø¿ô¤Ï $FONTSET ¤òÊÖ¤¹¡£  */
 
 MFontset *
 mdebug_dump_fontset (MFontset *fontset, int indent)