(mfont_list): If FONT is null, use a temporary font.
[m17n/m17n-lib.git] / src / font.c
index 170a516..4cecfbd 100644 (file)
@@ -22,7 +22,7 @@
 
 /***en
     @addtogroup m17nFont
-    @brief Font object
+    @brief Font object.
 
     The m17n GUI API represents a font by an object of the type @c
     MFont.  A font can have @e font @e properties.  Like other types
     key of a font property must be one of the following symbols:
 
     @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
-    @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
+    @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mtype.
 
     When the key of a font property is @c Msize or @c Mresolution, its
-    value is an integer.  Otherwise the value is a symbol.  "The font
-    property that belongs to font F and whose key is @c Mxxx" may be
-    shortened to "the xxx property of F".
+    value is an integer.  Otherwise the value is a symbol.  
+
+    "The font property that belongs to font F and whose key is @c
+    Mxxx" may be shortened to "the xxx property of F".
 
     The value of a foundry property is a symbol representing font
     foundry information, e.g. adobe, misc, etc.
     size in the unit of 1/10 point.
 
     The value of a resolution property is an integer representing
-    assumed device resolution in the unit of dots per inch (dpi)
+    assumed device resolution in the unit of dots per inch (dpi).
+
+    The value of a type property is a symbol indicating a font driver;
+    currently Mx or Mfreetype.
 
     The m17n library uses font objects for two purposes: to receive
     font specification from an application program, and to present
 
     The m17n library, if configured to use the FreeType library,
     supports all fonts that can be handled by the FreeType library.
-    The variable #mfont_freetype_path is initialized properly accoding
+    The variable #mfont_freetype_path is initialized properly according
     to the configuration of the m17n library and the environment
     variable @c M17NDIR.  See the documentation of the variable for
     details.
 
+    If the m17n library is configured to use the fontconfig library,
+    in addition to #mfont_freetype_path, all fonts available via
+    fontconfig are supported.
+
     The family name of a FreeType font corresponds to the family
     property.  Style names of FreeType fonts correspond to the weight,
     style, and stretch properties as below.
     Narrow Bold Italic  bold    i       condensed
     Black               black   r       normal
     Black Italic        black   i       normal
-    Oblique            medium  o       normal
-    BoldOblique                bold    o       normal
+    Oblique             medium  o       normal
+    BoldOblique         bold    o       normal
 @endverbatim
 
     Style names not listed in the above table are treated as
 
 /***ja
     @addtogroup m17nFont
-    @brief ¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È
+    @brief ¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È.
 
     m17n GUI API ¤Ï¥Õ¥©¥ó¥È¤ò @c MFont ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æɽ¸½¤¹¤ë¡£
-    ¥Õ¥©¥ó¥È¤Ï @e ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ë¡£Â¾¤Î¥¿¥¤¥×¤Î
-    ¥×¥í¥Ñ¥Æ¥£Æ±ÍÍ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¥­¡¼¤ÈÃͤ«¤é¤Ê¤ë¡£¥­¡¼¤Ï°Ê²¼¤Î¥·
+    ¥Õ¥©¥ó¥È¤Ï @e ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ë¡£Â¾¤Î¥¿¥¤¥×¤Î¥×
+    ¥í¥Ñ¥Æ¥£Æ±ÍÍ¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¥­¡¼¤ÈÃͤ«¤é¤Ê¤ê¡¢¥­¡¼¤Ï°Ê²¼¤Î¥·
     ¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
 
     @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
-    @c Madstyle, @c Mregistry, @c Msize, @c Mresolution
+    @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mtype
+
+    ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution 
+    ¤Î¾ì¹ç¡¢ÃͤÏÀ°¿ôÃͤǤ¢¤ê¡¢¥­¡¼¤¬¤½¤ì°Ê³°¤Î¾ì¹ç¡¢Ãͤϥ·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
 
-    ¥­¡¼¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¡¢ÃͤÏÀ°¿ôÃͤǤ¢¤ê¡¢
-    ¥­¡¼¤¬¤½¤ì°Ê³°¤Î¾ì¹ç¡¢Ãͤϥ·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£¡Ö¥Õ¥©¥ó¥È F ¤Î¥Õ¥©¥ó¥È
-    ¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼¤¬ @c Mxxx ¤Ç¤¢¤ë¤â¤Î¡×¤Î¤³¤È¤ò´Êñ¤Ë¡ÖF ¤Î 
-    xxx ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£
+    ¡Ö¥Õ¥©¥ó¥È F ¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼¤¬ @c Mxxx 
+    ¤Ç¤¢¤ë¤â¤Î¡×¤Î¤³¤È¤ò´Êñ¤Ë¡ÖF ¤Î xxx ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£
 
-    foundry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢adobe, misc Åù¤Î¥Õ¥©¥ó¥È¤Î³«È¯¸µ¾ðÊó¤ò¼¨
-    ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+    foundry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢adobe, misc 
+    Åù¤Î¥Õ¥©¥ó¥È¤Î³«È¯¸µ¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
 
-    family ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢times, helvetica Åù¤Î¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤ò
-    ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+    family ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢times, helvetica 
+    Åù¤Î¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
 
-    weight ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, bold Åù¤ÎÂÀ¤µ¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·
-    ¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+    weight ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, bold Åù¤ÎÂÀ¤µ¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
 
-    style ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, italic Åù¤Î·¹¤­¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹
-    ¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+    style ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, italic 
+    Åù¤Î¥¹¥¿¥¤¥ë¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
 
-    stretch ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, semicondensed Åù¤Îʸ»úÉý¤Ë´Ø¤¹¤ë
-    ¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+    stretch ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, semicondensed 
+    Åù¤Îʸ»úÉý¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
 
-    adstyle ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢serif, sans-serif Åù¤ÎÃê¾ÝŪ¤Ê¥Õ¥©¥ó¥È¥Õ¥¡
-    ¥ß¥ê¡¼¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+    adstyle ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢serif, sans-serif
+    Åù¤ÎÃê¾ÝŪ¤Ê¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
 
-    registry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢iso10646, iso8895-1 ¤Î¥ì¥¸¥¹¥È¥ê¾ðÊó¤ò
-    ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+    registry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢iso10646, iso8895-1
+    Åù¤Î¥ì¥¸¥¹¥È¥ê¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
 
-    size ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤òɽ¤ï¤¹À°¿ôÃͤǤ¢
-    ¤ê¡¢Ã±°Ì¤Ï 1/10 ¥Ý¥¤¥ó¥È¤Ç¤¢¤ë¡£
+    size ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤òɽ¤ï¤¹À°¿ôÃͤǤ¢¤ê¡¢
+    Ã±°Ì¤Ï1/10 ¥Ý¥¤¥ó¥È¤Ç¤¢¤ë¡£
 
-    resolution ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢ÁÛÄꤵ¤ì¤Æ¤¤¤ë¥Ç¥Ð¥¤¥¹¤Î²òÁüÅÙ¤òɽ¤ï
-    ¤¹À°¿ôÃͤǤ¢¤ê¡¢Ã±°Ì¤Ï dots per inch (dpi) ¤Ç¤¢¤ë¡£  
+    resolution ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢ÁÛÄꤵ¤ì¤Æ¤¤¤ë¥Ç¥Ð¥¤¥¹¤Î²òÁüÅÙ¤òɽ¤ï¤¹
+    À°¿ôÃͤǤ¢¤ê¡¢Ã±°Ì¤Ïdots per inch (dpi) ¤Ç¤¢¤ë¡£
 
-    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò£²¤Ä¤ÎÌÜŪ¤ÇÍѤ¤¤Æ¤¤¤ë¡£¥¢
-    ¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¥Õ¥©¥ó¥È¤Î»ØÄê¤ò¼õ¤±¼è¤ëÌÜŪ¤È¡¢¥¢¥×¥ê
-    ¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤òÄ󼨤¹¤ëÌÜŪ¤Ç¤¢¤ë¡£¥¢¥×
-    ¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÂФ·¤ÆÄ󼨤ò¹Ô¤¦ºÝ¤Ë¤Ï¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£
-    ¤Ï¤¹¤Ù¤Æ¶ñÂÎŪ¤ÊÃͤò»ý¤Ä¡£
+    type ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤ò»Ø¼¨¤·¡¢¸½ºß Mx ¤â¤·¤¯¤Ï
+    Mfreetype ¤Ç¤¢¤ë¡£
 
-    m17n ¥é¥¤¥Ö¥é¥ê¤ÏWindow ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È¡¢FreeType¥Õ¥©¥ó¥È¡¢
+    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò£²¤Ä¤ÎÌÜŪ¤ÇÍѤ¤¤Æ¤¤¤ë¡£¥¢¥×
+    ¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¥Õ¥©¥ó¥È¤Î»ØÄê¤ò¼õ¤±¼è¤ëÌÜŪ¤È¡¢¥¢¥×¥ê¥±¡¼
+    ¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤òÄ󼨤¹¤ëÌÜŪ¤Ç¤¢¤ë¡£¥¢¥×¥ê¥±¡¼
+    ¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÂФ·¤ÆÄ󼨤ò¹Ô¤¦ºÝ¤Ë¤Ï¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù
+    ¤Æ¶ñÂÎŪ¤ÊÃͤò»ý¤Ä¡£
+
+    m17n ¥é¥¤¥Ö¥é¥ê¤Ï Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È¡¢FreeType¥Õ¥©¥ó¥È¡¢
     OpenType¥Õ¥©¥ó¥È¤Î£³¼ïÎà¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¡£
 
     <ul>
 
     <li> Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È
 
-    m17n X ¥é¥¤¥Ö¥é¥ê¤Ï¡¢X ¥µ¡¼¥Ð¤ÈX ¥Õ¥©¥ó¥È¥µ¡¼¥Ð¤¬¼è¤ê°·¤¦Á´¤Æ¤Î¥Õ¥©
-    ¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£XLFD ¤Î³Æ¥Õ¥£¡¼¥ë¥É¤È¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ÎÂбþ
-    ¤Ï°Ê²¼¤ÎÄ̤ꡣ¤³¤Îɽ¤Ë¤Ê¤¤¥Õ¥£¡¼¥ë¥É¤Ï̵»ë¤µ¤ì¤ë¡£
+    m17n X ¥é¥¤¥Ö¥é¥ê¤Ï¡¢X ¥µ¡¼¥Ð¤È X ¥Õ¥©¥ó¥È¥µ¡¼¥Ð¤¬¼è¤ê°·¤¦Á´¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£
+    XLFD ¤Î³Æ¥Õ¥£¡¼¥ë¥É¤È¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ÎÂбþ¤Ï°Ê²¼¤ÎÄ̤ꡣ¤³¤Îɽ¤Ë¤Ê¤¤¥Õ¥£¡¼¥ë¥É¤Ï̵»ë¤µ¤ì¤ë¡£
 
 @verbatim
     XLFD ¥Õ¥£¡¼¥ë¥É                             ¥×¥í¥Ñ¥Æ¥£
 
     <li> FreeType fonts
 
-    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë
-    ¤Ï¡¢FreeType ¤¬°·¤¦¤¹¤Ù¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£ÊÑ¿ô 
-    #mfont_freetype_path ¤Ïm17n ¥é¥¤¥Ö¥é¥ê¤ÎÀßÄê¤È´Ä¶­ÊÑ¿ô @c M17NDIR 
+    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢
+    FreeType ¤¬°·¤¦¤¹¤Ù¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£ÊÑ¿ô 
+    #mfont_freetype_path ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤ÎÀßÄê¤È´Ä¶­ÊÑ¿ô @c M17NDIR 
     ¤Ë±þ¤¸¤Æ½é´ü²½¤µ¤ì¤ë¡£¾ÜºÙ¤ÏÊÑ¿ô¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
 
+    ¤â¤· m17n ¥é¥¤¥Ö¥é¥ê¤¬ fontconfig ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢
+    #mfont_freetype_path ¤Ë²Ã¤¨¤Æ¡¢ fontconfig ¤Ç»ÈÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤â¤¹¤Ù¤Æ¥µ¥Ý¡¼¥È¤µ¤ì¤ë¡£
+
     FreeType ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤Ï family ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£
     FreeType ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾¤Ï¡¢²¼¤Îɽ¤Î¤è¤¦¤Ë weight, style,
     stretch ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£
     Narrow Bold Italic  bold    i       condensed
     Black               black   r       normal
     Black Italic        black   i       normal
-    Oblique            medium  o       normal
-    BoldOblique                bold    o       normal
+    Oblique             medium  o       normal
+    BoldOblique         bold    o       normal
 @endverbatim
 
     ¾å¤Îɽ¤Ë¸½¤ï¤ì¤Ê¤¤¥¹¥¿¥¤¥ë̾¤Ï "Regular" ¤È¤·¤Æ°·¤ï¤ì¤ë¡£
 
-    platform ID ¤È encoding ID ¤ÎÁȤ߹ç¤ï¤»¤Ïregistry ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ
-    ¤¹¤ë¡£¤¿¤È¤¨¤Ð¤¢¤ë¥Õ¥©¥ó¥È¤¬ (1 1) ¤È¤¤¤¦ ID ¤ÎÁȹ礻¤ò»ý¤Æ¤Ð¡¢
-    registry ¥×¥í¥Ñ¥Æ¥£¤Ï 1-1 ¤È¤Ê¤ë¡£ÉÑÈˤˤ¢¤é¤ï¤ì¤ëÁȹ礻¤Ë¤Ï°Ê²¼¤Î
-    ¤è¤¦¤ÊÄêµÁºÑ¤ß registry ¥×¥í¥Ñ¥Æ¥£ ¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤ë¡£
+    platform ID ¤È encoding ID ¤ÎÁȤ߹ç¤ï¤»¤¬ registry 
+    ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£¤¿¤È¤¨¤Ð¤¢¤ë¥Õ¥©¥ó¥È¤¬ (1 1) ¤È¤¤¤¦ ID ¤ÎÁȹ礻¤ò»ý¤Æ¤Ð¡¢
+    registry ¥×¥í¥Ñ¥Æ¥£¤Ï 1-1 ¤È¤Ê¤ë¡£ÉÑÈˤˤ¢¤é¤ï¤ì¤ëÁȹ礻¤Ë¤Ï°Ê²¼¤Î¤è¤¦¤ÊÄêµÁºÑ¤ß
+    registry ¥×¥í¥Ñ¥Æ¥£ ¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤ë¡£
 
 @verbatim
     platform ID         encoding ID     registry ¥×¥í¥Ñ¥Æ¥£
     3                   1               unicode-full
 @endverbatim
 
-    ¤·¤¿¤¬¤Ã¤Æ¡¢Æó¤Ä¤ÎÁȹ礻 (1 0) ¡¢(3 1) ¤ò»ý¤Ä¥Õ¥©¥ó¥È¤Ï¡¢¤½¤ì¤¾¤ì 
-    registry ¥×¥í¥Ñ¥Æ¥£¤¬1-0, apple-roman, 3-1, unicode-bmp ¤Ç¤¢¤ë£´¤Ä
-    ¤Î¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ËÂбþ¤¹¤ë¡£
+    ¤·¤¿¤¬¤Ã¤Æ¡¢Æó¤Ä¤ÎÁȹ礻 (1 0) ¡¢(3 1) ¤ò»ý¤Ä¥Õ¥©¥ó¥È¤Ï¡¢¤½¤ì¤¾¤ì
+    registry ¥×¥í¥Ñ¥Æ¥£¤¬ 1-0, apple-roman, 3-1, unicode-bmp
+    ¤Ç¤¢¤ë£´¤Ä¤Î¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ËÂбþ¤¹¤ë¡£
 
     <li> OpenType ¥Õ¥©¥ó¥È
 
-    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤ÈOTF ¥é¥¤¥Ö¥é¥ê¤ò»ÈÍѤ¹¤ë¤è
-    ¤¦¤ËÀßÄꤹ¤ì¤Ð¡¢¤¹¤Ù¤Æ¤Î OpenType ¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£¼ÂºÝ¤ËÍø
-    ÍѤǤ­¤ë¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤ÏFreeType ¥Õ¥©¥ó¥È¤Î¾ì¹ç¤ÈƱÍͤ˺î¤é¤ì¤ë¡£
-    OpenType ¥Õ¥©¥ó¥È¤ò FLT (Font Layout Table) ·Ðͳ¤Ç»ÈÍѤ¹¤ë¤è¤¦¥Õ¥©
-    ¥ó¥È¥»¥Ã¥È¤Ë»ØÄꤵ¤ì¤Æ¤ª¤ê¡¢FLT ¤Ë OTF ´ØÏ¢¤Î¥³¥Þ¥ó¥É (¤¿¤È¤¨¤Ð 
-    otf:deva) ¤¬¤¢¤ì¤Ð¡¢OTF ¥é¥¤¥Ö¥é¥ê¤¬¥Õ¥©¥ó¥È¤ÎOpenType ¥ì¥¤¥¢¥¦¥È
-    ¥Æ¡¼¥Ö¥ë½¾¤Ã¤Æʸ»úÎó¤ò¥°¥ê¥Õ¥³¡¼¥ÉÎó¤ËÊÑ´¹¤·¡¢FreeType ¥é¥¤¥Ö¥é¥ê
-    ¤¬³Æ¥°¥ê¥Õ¤Î¥Ó¥Ã¥È¥Þ¥Ã¥×¥¤¥á¡¼¥¸¤òÄ󶡤¹¤ë¡£
+    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤È OTF 
+    ¥é¥¤¥Ö¥é¥ê¤ò»ÈÍѤ¹¤ë¤è¤¦¤ËÀßÄꤹ¤ì¤Ð¡¢¤¹¤Ù¤Æ¤Î OpenType 
+    ¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£¼ÂºÝ¤ËÍøÍѤǤ­¤ë¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤Ï FreeType
+    ¥Õ¥©¥ó¥È¤Î¾ì¹ç¤ÈƱÍͤ˺î¤é¤ì¤ë¡£OpenType ¥Õ¥©¥ó¥È¤ò FLT (Font Layout Table)
+    ·Ðͳ¤Ç»ÈÍѤ¹¤ë¤è¤¦¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ë»ØÄꤵ¤ì¤Æ¤ª¤ê¡¢FLT ¤Ë OTF 
+    ´ØÏ¢¤Î¥³¥Þ¥ó¥É (¤¿¤È¤¨¤Ð otf:deva) ¤¬¤¢¤ì¤Ð¡¢OTF ¥é¥¤¥Ö¥é¥ê¤¬¥Õ¥©¥ó¥È¤Î OpenType
+    ¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¤Ë½¾¤Ã¤Æʸ»úÎó¤ò¥°¥ê¥Õ¥³¡¼¥ÉÎó¤ËÊÑ´¹¤·¡¢FreeType
+    ¥é¥¤¥Ö¥é¥ê¤¬³Æ¥°¥ê¥Õ¤Î¥Ó¥Ã¥È¥Þ¥Ã¥×¥¤¥á¡¼¥¸¤òÄ󶡤¹¤ë¡£
 
     </ul>
 
 #include "internal-gui.h"
 #include "font.h"
 #include "face.h"
+#include "fontset.h"
 
-MFontDriver *mfont__driver_list[MFONT_TYPE_MAX];
+MPlist *mfont__driver_list;
+
+static MSymbol M_font_capability, M_font_list, M_font_list_len;
 
 /** Indices to font properties sorted by their priority.  */
 static int font_score_priority[] =
   { MFONT_SIZE,
-    MFONT_ADSTYLE,
-    MFONT_FAMILY,
     MFONT_WEIGHT,
     MFONT_STYLE,
     MFONT_STRETCH,
+    MFONT_FAMILY,
+    MFONT_ADSTYLE,
     MFONT_FOUNDRY
   };
 
@@ -345,10 +361,10 @@ static int font_score_priority[] =
 
 /* Indexed by a font property MFONT_XXX, and the value is how many
    bits to shift the difference of property values.  */
-static int font_score_shift_bits[MFONT_PROPERTY_MAX];
+static int font_score_shift_bits[MFONT_SIZE + 1];
 
 /** Predefined symbols for each font property.  The order is important
-    because the function score_font () decides how well a font matches
+    because the function font_score () decides how well a font matches
     with a spec by checking how close the index is.  */
 
 static char *common_foundry[] =
@@ -360,32 +376,41 @@ static char *common_family[] =
     "helvetica",
     "times" };
 static char *common_weight[] =
-  { "ultralight",
+  { "thin"
+    "ultralight",
     "extralight",
     "light",
     "demilight",
     "book",
+    "regular",
     "normal",
     "medium",
-    "regular",
     "demibold",
+    "semibold",
     "bold",
     "extrabold",
     "ultrabold",
-    "black" };
+    "black",
+    "heavy" };
 static char *common_style[] =
   { "o",
     "i",
+    "slanted",
     "r",
+    "rslanted",
     "ri",
     "ro" };
 static char *common_stretch[] =
-  { "condensed",
+  { "ultracondensed",
+    "extracondensed",
+    "condensed",
     "narrow",
     "semicondensed",
     "normal",
     "semiexpanded",
-    "expanded" };
+    "expanded",
+    "extraexpanded",
+    "ultraexpanded" };
 static char *common_adstyle[] =
   { "serif",
     "",
@@ -393,6 +418,10 @@ static char *common_adstyle[] =
 static char *common_registry[] =
   { "iso8859-1" };
 
+static unsigned short font_weight_regular;
+static unsigned short font_weight_normal;
+static unsigned short font_weight_medium;
+
 /* Table containing all the data above.  */
 
 struct MFontCommonNames
@@ -432,31 +461,6 @@ MFontPropertyTable mfont__property_table[MFONT_REGISTRY + 1];
   msymbol_put((symbol), mfont__property_table[(n)].property,   \
              (void *) (numeric))
 
-static char *
-gen_font_name (char *buf, MFont *font)
-{
-  char size[16];
-  int i;
-
-  buf[0] = '\0';
-  for (i = 0; i <= MFONT_REGISTRY; i++)
-    if (FONT_PROPERTY (font, i) != Mnil)
-      {
-       char *name = msymbol_name (FONT_PROPERTY (font, i));
-
-       if (name[0])
-         {
-           if (i > 0)
-             strcat (buf, ",");
-           strcat (buf, name);
-         }
-      }
-  sprintf (size, ",%d", font->property[MFONT_SIZE] / 10);
-  strcat (buf, size);
-  return buf;
-}
-
-
 \f
 /* Font selector.  */
 
@@ -517,8 +521,9 @@ load_font_encoding_table ()
        encoding->repertory_name = MPLIST_SYMBOL (elt);
 
       if (registry == Mnil)
-       registry = Mt;
-      pl = mplist_add (pl, registry, encoding);
+       mplist_push (font_encoding_list, Mt, encoding);
+      else
+       pl = mplist_add (pl, registry, encoding);
       continue;
 
     warning:
@@ -599,56 +604,342 @@ find_encoding (MFont *font)
 
   if (! font_encoding_list)
     load_font_encoding_table ();
-  if (! MPLIST_TAIL_P (font_encoding_list))
-    while (1)
-      {
-       plist = font_encoding_list;
-       while (registry ? (plist = mplist_find_by_key (plist, registry))
-              : plist)
-         {
-           encoding = (MFontEncoding *) MPLIST_VAL (plist);
-           if (mfont__match_p (font, &encoding->spec, MFONT_ADSTYLE))
-             {
-               if (! encoding->encoding_charset)
-                 encoding->encoding_charset
-                   = MCHARSET (encoding->encoding_name);
-               if (! encoding->encoding_charset)
-                 {
-                   mplist_pop (plist);
-                   continue;
-                 }
-               if (encoding->repertory_name == encoding->encoding_name)
-                 encoding->repertory_charset = encoding->encoding_charset;
-               else if (encoding->repertory_name != Mnil)
-                 {
-                   encoding->repertory_charset
-                     = MCHARSET (encoding->repertory_name);
-                   if (! encoding->repertory_charset)
-                     {
-                       mplist_pop (plist);
-                       continue;
-                     }
-                 }
-               return encoding;
-             }
-           else
-             plist = MPLIST_NEXT (plist);
-         }
-       if (registry == Mnil || registry == Mt)
-         break;
-       registry = Mt;
-      }
+  plist = font_encoding_list;
+  while (! MPLIST_TAIL_P (plist))
+    {
+      encoding = (MFontEncoding *) MPLIST_VAL (plist);
+      if (mfont__match_p (font, &encoding->spec, MFONT_REGISTRY))
+       {
+         if (encoding->encoding_name != Mnil
+             && ! encoding->encoding_charset)
+           {
+             encoding->encoding_charset = MCHARSET (encoding->encoding_name);
+             if (! encoding->encoding_charset)
+               {
+                 mplist_pop (plist);
+                 continue;
+               }
+           }
+         if (encoding->repertory_name == encoding->encoding_name)
+           encoding->repertory_charset = encoding->encoding_charset;
+         else if (encoding->repertory_name != Mnil)
+           {
+             encoding->repertory_charset
+               = MCHARSET (encoding->repertory_name);
+             if (! encoding->repertory_charset)
+               {
+                 mplist_pop (plist);
+                 continue;
+               }
+           }
+         font->encoding = encoding;
+         return encoding;
+       }
+
+      if (registry && MPLIST_KEY (plist) != Mt)
+       {
+         plist = mplist_find_by_key (plist, registry);
+         if (! plist)
+           break;
+       }
+      else
+       plist = MPLIST_NEXT (plist);
+    }
+  font->encoding = &default_encoding;
   return &default_encoding;
 }
 
+#ifndef HAVE_OTF
+static OTF_Tag
+OTF_tag (char *name)
+{
+  unsigned char *p = (unsigned char *) name;
+
+  if (! name)
+    return (OTF_Tag) 0;
+  return (OTF_Tag) ((p[0] << 24)
+                   | (! p[1] ? 0
+                      : ((p[1] << 16)
+                         | (! p[2] ? 0
+                            : (p[2] << 8) | p[3]))));
+}
+#endif /* not HAVE_OTF */
+
+static MPlist *otf_script_list;
+
+static int
+load_otf_script_list ()
+{
+  MDatabase *mdb;
+  MPlist *plist, *pl;
+
+  otf_script_list = mplist ();
+  mdb = mdatabase_find (msymbol ("standard"), Mscript, msymbol ("otf"), Mnil);
+  if (! mdb
+      || ! (plist = mdatabase_load (mdb)))
+    MERROR (MERROR_FONT, -1);
+  MPLIST_DO (pl, plist)
+    {
+      MPlist *p;
+      MSymbol script, otf_script;
+      OTF_Tag tag;
+
+      if (! MPLIST_PLIST_P (pl))
+       continue;
+      p = MPLIST_PLIST (pl);
+      if (! MPLIST_SYMBOL_P (p))
+       continue;
+      script = MPLIST_SYMBOL (p);
+      p = MPLIST_NEXT (p);
+      if (! MPLIST_SYMBOL_P (p))
+       continue;
+      otf_script = MPLIST_SYMBOL (p);
+      tag = OTF_tag (MSYMBOL_NAME (otf_script));
+      mplist_push (otf_script_list, script, (void *) tag);
+    }
+  M17N_OBJECT_UNREF (plist);
+  return 0;
+}
+
+static MSymbol
+find_script_from_otf_tag (OTF_Tag tag)
+{
+  MPlist *plist;
+
+  if (! otf_script_list)
+    load_otf_script_list ();
+  plist = mplist_find_by_value (otf_script_list, (void *) tag);
+  return (plist ? MPLIST_KEY (plist) : Mnil);
+}
+
+
+/* XLFD parser/generator */
+
+/** Indices to each field of split font name.  */
+
+enum xlfd_field_idx
+  {
+    XLFD_FOUNDRY,
+    XLFD_FAMILY,
+    XLFD_WEIGHT,
+    XLFD_SLANT,
+    XLFD_SWIDTH,
+    XLFD_ADSTYLE,
+    XLFD_PIXEL,
+    XLFD_POINT,
+    XLFD_RESX,
+    XLFD_RESY,
+    XLFD_SPACING,
+    XLFD_AVGWIDTH,
+    XLFD_REGISTRY,             /* This contains ENCODING.  */
+    /* anchor */
+    XLFD_FIELD_MAX
+  };
+
+static int
+xlfd_parse_name (char *name, MFont *font)
+{
+  char *field[XLFD_FIELD_MAX];
+  unsigned short resy, avgwidth;
+  unsigned size;
+  MSymbol attrs[MFONT_PROPERTY_MAX];
+  char copy[513];
+  int i;
+  char *p;
+
+  if (name[0] != '-')
+    return -1;
+
+  field[0] = copy;
+  for (i = 1, p = copy, name++; *name; p++, name++)
+    {
+      if (p - copy > 512)
+       return -1;
+      if (*name == '-'
+         && i < XLFD_FIELD_MAX)
+       {
+         *p = '\0';
+         if (field[i - 1][0] == '*')
+           field[i - 1] = NULL;
+         field[i++] = p + 1;
+       }
+      else
+       *p = tolower (*name);
+    }
+  *p = '\0';
+  if (field[i - 1][0] == '*')
+    field[i - 1] = NULL;
+  while (i < XLFD_FIELD_MAX)
+    field[i++] = NULL;
+
+  resy = field[XLFD_RESY] ? atoi (field[XLFD_RESY]) : 0;
+  avgwidth = ((field[XLFD_AVGWIDTH] && isdigit (field[XLFD_AVGWIDTH][0]))
+             ? atoi (field[XLFD_AVGWIDTH]) : 1);
+  if (! avgwidth)
+    size = 0;
+  else if (! field[XLFD_PIXEL])
+    size = field[XLFD_POINT] ? atoi (field[XLFD_POINT]) * resy / 72 : 0;
+  else if (field[XLFD_PIXEL][0] == '[')
+    {
+      /* The pixel size field specifies a transformation matrix of the
+        form "[A B C D]".  The XLFD spec says that the scalar value N
+        for the pixel size is equivalent to D.  */
+      char *p0 = field[XLFD_PIXEL] + 1, *p1;
+      double d;
+
+      for (i = 0; i < 4; i++, p0 = p1)
+       d = strtod (p0, &p1);
+      size = d * 10;
+    }
+  else
+    size = atoi (field[XLFD_PIXEL]) * 10;
+
+  attrs[MFONT_FOUNDRY]
+    = field[XLFD_FOUNDRY] ? msymbol (field[XLFD_FOUNDRY]) : Mnil;
+  attrs[MFONT_FAMILY]
+    = field[XLFD_FAMILY] ? msymbol (field[XLFD_FAMILY]) : Mnil;
+  attrs[MFONT_WEIGHT]
+    = field[XLFD_WEIGHT] ? msymbol (field[XLFD_WEIGHT]) : Mnil;
+  attrs[MFONT_STYLE]
+    = field[XLFD_SLANT] ? msymbol (field[XLFD_SLANT]) : Mnil;
+  attrs[MFONT_STRETCH]
+    = field[XLFD_SWIDTH] ? msymbol (field[XLFD_SWIDTH]) : Mnil;
+  attrs[MFONT_ADSTYLE]
+    = field[XLFD_ADSTYLE] ? msymbol (field[XLFD_ADSTYLE]) : Mnil;
+  attrs[MFONT_REGISTRY]
+    = field[XLFD_REGISTRY] ? msymbol (field[XLFD_REGISTRY]) : Mnil;
+  mfont__set_spec (font, attrs, size, resy);
+  font->type = MFONT_TYPE_SPEC;
+  font->source = MFONT_SOURCE_X;
+  return 0;
+}
+
+static char *
+xlfd_unparse_name (MFont *font)
+{
+  MSymbol prop[7];
+  char name[513];
+  char *str[7];
+  int len, i;
+  unsigned short size, resy;
+
+  prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
+  prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
+  prop[2] = (MSymbol) mfont_get_prop (font, Mweight);
+  prop[3] = (MSymbol) mfont_get_prop (font, Mstyle);
+  prop[4] = (MSymbol) mfont_get_prop (font, Mstretch);
+  prop[5] = (MSymbol) mfont_get_prop (font, Madstyle);
+  prop[6] = (MSymbol) mfont_get_prop (font, Mregistry);
+  for (len = 0, i = 0; i < 7; i++)
+    {
+      if (prop[i] != Mnil)
+       {
+         str[i] = msymbol_name (prop[i]);
+         len += strlen (str[i]);
+       }
+      else
+       {
+         str[i] = "*";
+         len++;
+       }
+    }
+  if ((len
+       + 12                    /* 12 dashes */
+       + 3                     /* 3 asterisks */
+       + 30                    /* 3 integers (each 10 digits) */
+       + 1)                    /* '\0' terminal */
+      > 513)
+    return NULL;
+
+  resy = (int) mfont_get_prop (font, Mresolution);
+  size = font->size;
+  if ((size % 10) < 5)
+    size /= 10;
+  else
+    size = size / 10 + 1;
+
+  sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-*-*-%s",
+          str[0], str[1], str[2], str[3], str[4], str[5],
+          size, resy, resy,  str[6]);
+  return strdup (name);
+}
+
+/* Compare FONT with REQUEST and return how much they differs.  */
+
+static int
+font_score (MFont *font, MFont *request)
+{
+  int score = 0;
+  int i = FONT_SCORE_PRIORITY_SIZE;
+
+  while (--i >= 0)
+    {
+      enum MFontProperty prop = font_score_priority[i];
+      int val;
+
+      if (prop == MFONT_SIZE)
+       {
+         if (font->size && request->size)
+           {
+             val = font->size - request->size;
+             if (val)
+               {
+                 if (val < 0)
+                   val = - val;
+                 if (val >= 0x10000)
+                   val = 0xFFFF;
+                 score |= (val << font_score_shift_bits[MFONT_SIZE]);
+               }
+           }
+       }
+      else if (font->property[prop] && request->property[prop]
+              && font->property[prop] != request->property[prop])
+       {
+         if (prop <= MFONT_FAMILY)
+           val = 1;
+         else if (prop == MFONT_WEIGHT)
+           {
+             unsigned short v1 = font->property[prop];
+             unsigned short v2 = request->property[prop];
+
+             if (v1 == font_weight_regular || v1 == font_weight_normal)
+               v1 = font_weight_medium;
+             if (v2 == font_weight_regular || v2 == font_weight_normal)
+               v2 = font_weight_medium;
+             val = v1 > v2 ? v1 - v2 : v2 - v1;
+           }
+         else
+           {
+             val = font->property[prop] - request->property[prop];
+             if (val < 0)
+               val = - val;
+             if (val > 3)
+               val = 3;
+           }
+         score |= val << font_score_shift_bits[prop];
+       }
+    }
+  if (request->file != Mnil && request->file != font->file)
+    score |= 40000000;
+  return score;
+}
 
 \f
 /* Internal API */
 
+MSymbol Miso8859_1, Miso10646_1, Municode_bmp, Municode_full, Mapple_roman;
+
 int
 mfont__init ()
 {
   int i, shift;
+  MSymbol regular = msymbol ("regular");
+  MSymbol normal = msymbol ("normal");
+  MSymbol medium = msymbol ("medium");
+
+  M_font_capability = msymbol_as_managing_key ("  font-capability");
+  M_font_list = msymbol_as_managing_key ("  font-list");
+  M_font_list_len = msymbol ("  font-list-len");
 
   Mfoundry = msymbol ("foundry");
   mfont__property_table[MFONT_FOUNDRY].property = Mfoundry;
@@ -667,6 +958,19 @@ mfont__init ()
 
   Msize = msymbol ("size");
   Mresolution = msymbol ("resolution");
+  Mfontfile = msymbol ("fontfile");
+
+  Mfontconfig = msymbol ("fontconfig");
+
+  Mx = msymbol ("x");
+  Mfreetype = msymbol ("freetype");
+  Mxft = msymbol ("xft");
+
+  Miso8859_1 = msymbol ("iso8859-1");
+  Miso10646_1 = msymbol ("iso10646-1");
+  Municode_bmp = msymbol ("unicode-bmp");
+  Municode_full = msymbol ("unicode-full");
+  Mapple_roman = msymbol ("apple-roman");
 
   /* The first entry of each mfont__property_table must be Mnil so
      that actual properties get positive numeric numbers.  */
@@ -687,51 +991,62 @@ mfont__init ()
 
          if (sym == Mnil)
            return -1;
-         if (msymbol_put(sym, mfont__property_table[i].property,
-                         (void *) (j + 1)) < 0)
+         if (msymbol_put (sym, mfont__property_table[i].property,
+                          (void *) (j + 1)) < 0)
            return -1;
-         MLIST_APPEND1 (&mfont__property_table[i], names, sym, MERROR_FONT);
+         MLIST_APPEND1 (&mfont__property_table[i], names, sym,
+                        MERROR_FONT);
+         if (i == MFONT_WEIGHT)
+           {
+             if (sym == regular)
+               font_weight_regular = j + 1;
+             else if (sym == normal)
+               font_weight_normal = j + 1;
+             else if (sym == medium)
+               font_weight_medium = j + 1;
+           }
        }
     }
 
-  memset (mfont__driver_list, 0, sizeof mfont__driver_list);
-
   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
      of a score is a flag for a scalable font (see the documentation
-     of mfont_score).  */
+     of font_score).  */
   i = FONT_SCORE_PRIORITY_SIZE - 1;
   for (shift = 1; i >= 0; i--)
     {
       font_score_shift_bits[font_score_priority[i]] = shift;
       if (font_score_priority[i] == MFONT_SIZE)
        shift += 16;
+      else if (font_score_priority[i] <= MFONT_FAMILY)
+       shift++;
       else
        shift += 2;
     }
 
   MFONT_INIT (&default_encoding.spec);
-  default_encoding.encoding_name = Mnil;
-  default_encoding.encoding_charset = NULL;
+  default_encoding.encoding_name = Municode_full;
+  default_encoding.encoding_charset = mcharset__unicode;
   default_encoding.repertory_name = Mnil;
   default_encoding.repertory_charset = NULL;
   {
     char *path, *buf;
     int bufsize;
+    USE_SAFE_ALLOCA;
 
     mfont_freetype_path = mplist ();
     bufsize = strlen (M17NDIR) + 7;
-    buf = alloca (bufsize);
+    SAFE_ALLOCA (buf, bufsize);
     sprintf (buf, "%s/fonts", M17NDIR);
     mplist_add (mfont_freetype_path, Mstring, strdup (buf));
     path = getenv ("M17NDIR");
     if (path)
       {
-       i = strlen (path) + 7;
-       if (i > bufsize)
-         buf = alloca (i);
+       bufsize = strlen (path) + 7;
+       SAFE_ALLOCA (buf, bufsize);
        sprintf (buf, "%s/fonts", path);
        mplist_push (mfont_freetype_path, Mstring, strdup (buf));
       }
+    SAFE_FREE (buf);
   }
 
 #ifdef HAVE_FREETYPE
@@ -773,64 +1088,70 @@ mfont__fini ()
       M17N_OBJECT_UNREF (font_encoding_list);
       font_encoding_list = NULL;
     }
+  if (otf_script_list)
+    {
+      M17N_OBJECT_UNREF (otf_script_list);
+      otf_script_list = NULL;
+    }
+
   for (i = 0; i <= MFONT_REGISTRY; i++)
     MLIST_FREE1 (&mfont__property_table[i], names);
 }
 
-void
-mfont__free_realized (MRealizedFont *rfont)
-{
-  if (rfont->info)
-    M17N_OBJECT_UNREF (rfont->info);
-  free (rfont);
-}
-
 
-/* Compare FONT with REQUEST and return how much they differs.  If
-   FONT does not match with SPEC, return -1.  */
-
-int
-mfont__score (MFont *font, MFont *spec, MFont *request, int limited_size)
+MSymbol
+mfont__id (MFont *font)
 {
-  int score = 0;
-  int i = FONT_SCORE_PRIORITY_SIZE;
-
-  while (--i >= 0)
+  char *buf, *p;
+  int i;
+  int file_len = (font->file == Mnil ? 0 : MSYMBOL_NAMELEN (font->file));
+  int capability_len  = (font->capability == Mnil ? 0
+                        : MSYMBOL_NAMELEN (font->capability));
+  int total_len = MFONT_PROPERTY_MAX * 5 + 7 + file_len + capability_len;
+  MSymbol id;
+  USE_SAFE_ALLOCA;
+
+  SAFE_ALLOCA (buf, total_len);
+  p = buf;
+  if (font->property[0])
+    p += sprintf (p, "%X", font->property[0]);
+  for (i = 1; i < MFONT_PROPERTY_MAX; i++)
     {
-      enum MFontProperty prop = font_score_priority[i];
-
-      if (request->property[prop] != 0)
-       {
-         int val = 0;
-
-         if (spec->property[prop] && font->property[prop]
-             && font->property[prop] != spec->property[prop])
-           return -1;
-         if (font->property[prop])
-           val = abs (font->property[prop] - request->property[prop]);
-         if (prop == MFONT_SIZE)
-           {
-             if (font->property[MFONT_RESY] == 0)
-               /* This is a scalable font.  We prefer a bitmap font
-                  if the size matches exactly.  */
-               score |= 1;
-             else
-               score |= (val << font_score_shift_bits[MFONT_SIZE]
-                         | ((limited_size && val > 0) ? 0x400000 : 0));
-           }
-         else
-           score |= (val > 3 ? 3 : val) << font_score_shift_bits[prop];
-       }
+      if (font->property[i])
+       p += sprintf (p, "-%X", font->property[i]);
+      else
+       *p++ = '-';
     }
-  return score;
+  if (font->size)
+    p += sprintf (p, "-%X", font->size);
+  if (capability_len > 0)
+    {
+      *p++ = '-';
+      memcpy (p, MSYMBOL_NAME (font->capability), capability_len);
+      p += capability_len;
+    }
+  if (file_len > 0)
+    {
+      *p++ = '-';
+      memcpy (p, MSYMBOL_NAME (font->file), file_len);
+      p += file_len;
+    }      
+  id = msymbol__with_len (buf, p - buf);
+  SAFE_FREE (buf);
+  return id;
 }
 
-
 /** Return 1 iff FONT matches SPEC.  */
 
 int
 mfont__match_p (MFont *font, MFont *spec, int prop)
 {
+  if (spec->capability != font->capability
+      && spec->capability != Mnil && font->capability != Mnil)
+    return 0;
+  if (spec->file != font->file
+      && spec->file != Mnil && font->file != Mnil)
+    return 0;
   for (; prop >= 0; prop--)
     if (spec->property[prop] && font->property[prop]
        && font->property[prop] != spec->property[prop])
@@ -838,6 +1159,43 @@ mfont__match_p (MFont *font, MFont *spec, int prop)
   return 1;
 }
 
+/* Merge SRC into DST.  If error_on_conflict is nonzero and a font
+   property differs in SRC and DST, return -1.  */
+
+int
+mfont__merge (MFont *dst, MFont *src, int error_on_conflict)
+{
+  int i;
+
+  for (i = 0; i < MFONT_PROPERTY_MAX; i++)
+    {
+      if (! dst->property[i])
+       dst->property[i] = src->property[i];
+      else if (error_on_conflict
+              && src->property[i]
+              && dst->property[i] != src->property[i])
+       return -1;
+    }
+  if (! dst->size)
+    dst->size = src->size;
+  else if (error_on_conflict
+          && src->size
+          && dst->size != src->size)
+    return -1;
+  if (dst->capability == Mnil)
+    dst->capability = src->capability;
+  else if (error_on_conflict
+          && src->capability
+          && dst->capability != src->capability)
+    return -1;
+  if (dst->file == Mnil)
+    dst->file = src->file;
+  else if (error_on_conflict
+          && src->file
+          && dst->file != src->file)
+    return -1;
+  return 0;
+}
 
 void
 mfont__set_spec_from_face (MFont *spec, MFace *face)
@@ -846,11 +1204,13 @@ mfont__set_spec_from_face (MFont *spec, MFace *face)
 
   for (i = 0; i <= MFONT_ADSTYLE; i++)
     mfont__set_property (spec, i, face->property[i]);
-  /* The value 1 is "iso8859-1".  */
-  spec->property[MFONT_REGISTRY] = 1;
-  spec->property[MFONT_SIZE] = (int) (face->property[MFACE_SIZE]);
+  spec->property[MFONT_REGISTRY] = 0;
   spec->property[MFONT_RESY] = 0;
-  spec->property[MFONT_TYPE] = 0;
+  spec->size = (int) (face->property[MFACE_SIZE]);
+  spec->type = MFONT_TYPE_SPEC;
+  spec->source = MFONT_SOURCE_UNDECIDED;
+  spec->file = spec->capability = Mnil;
+  spec->encoding = NULL;
 }
 
 
@@ -860,6 +1220,7 @@ mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
   int i;
   MSymbol spec_list[MFONT_REGISTRY + 1];
   MSymbol registry;
+  char *reg;
 
   MFONT_INIT (spec);
   memset (spec_list, 0, sizeof spec_list);
@@ -870,144 +1231,203 @@ mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
       spec_list[i] = MPLIST_SYMBOL (plist);
     }
   registry = spec_list[i - 1];
+  if (i > 1 && registry != Mnil)
+    {
+      reg = MSYMBOL_NAME (registry);
+      if (reg[0] == ':')
+       {
+         mfont__get_capability (registry);
+         spec->capability = registry;
+         registry = spec_list[i - 2];
+         i--;
+       }
+    }
   mfont__set_property (spec, MFONT_REGISTRY, registry);
   for (i -= 2; i >= 0; i--)
     mfont__set_property (spec, i, spec_list[i]);
+  spec->type = MFONT_TYPE_SPEC;
+
   return registry;
 }
 
-MRealizedFont *
-mfont__select (MFrame *frame, MFont *spec, MFont *request, int limited_size,
-              MSymbol layouter)
-{
-  MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
-  MPlist *realized_font_list;
-  MRealizedFont *best_font[MFONT_TYPE_MAX], *best;
-  int best_index;
-  int i;
-  int mdebug_mask = MDEBUG_FONT;
 
-  if (registry == Mnil)
-    registry = Mt;
+MFont *
+mfont__select (MFrame *frame, MFont *font, int max_size)
+{
+  MFontDriver *driver;
 
-  MPLIST_DO (realized_font_list, frame->realized_font_list)
+  if (font->type == MFONT_TYPE_FAILURE)
+    return NULL;
+  if (font->type != MFONT_TYPE_SPEC)
+    return font;
+  if (font->source == MFONT_SOURCE_UNDECIDED)
     {
-      best = MPLIST_VAL (realized_font_list);
-      if (MPLIST_KEY (realized_font_list) == registry
-         && ! memcmp (&best->spec, spec, sizeof (MFont))
-         && ! memcmp (&best->request, request, sizeof (MFont)))
+      if (font->file != Mnil || font->capability != Mnil)
+       font->source = MFONT_SOURCE_FT;
+      else if (font->property[MFONT_REGISTRY])
        {
-         if (best->layouter != layouter)
-           {
-             MRealizedFont *copy;
-
-             MSTRUCT_MALLOC (copy, MERROR_FONT);
-             *copy = *best;
-             copy->layouter = layouter;
-             if (copy->info)
-               M17N_OBJECT_REF (copy->info);
-             mplist_add (frame->realized_font_list, registry, copy);
-             best = copy;
-           }
-         return best;
-       }
-    }
+         MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
+         char *reg = MSYMBOL_NAME (registry);
 
-  MDEBUG_PUSH_TIME ();
-  best = NULL;
-  best_index = -1;
-  for (i = 0; i < MFONT_TYPE_MAX; i++)
-    {
-      MFontDriver *driver = mfont__driver_list[i];
-
-      best_font[i] = (driver
-                     ? (driver->select) (frame, spec, request, limited_size)
-                     : NULL);
-      if (best_font[i]
-         && (best_index < 0
-             || best_font[best_index]->score < best_font[i]->score))
-       best_index = i;
-    }
-  for (i = 0; i < MFONT_TYPE_MAX; i++)
-    {
-      if (i == best_index)
-       best = best_font[i];
-      else if (best_font[i])
-       free (best_font[i]);
+         if (strncmp (reg, "unicode-", 8) == 0
+             || strncmp (reg, "apple-roman", 11) == 0
+             || (reg[0] >= '0' && reg[0] <= '9' && reg[1] == '-'))
+           font->source = MFONT_SOURCE_FT;
+       }
     }
-
-  if (mdebug__flag & mdebug_mask)
+  if (font->source != MFONT_SOURCE_FT)
     {
-      char buf1[256], buf2[256];
-      MFont font = *spec;
-
-      for (i = 0; i < MFONT_PROPERTY_MAX; i++)
-       if (! font.property[i])
-         font.property[i] = request->property[i];
-      gen_font_name (buf2, &font);
-
-      if (best)
-       MDEBUG_PRINT_TIME ("FONT", 
-                          (stderr, " to select <%s> from <%s>.",
-                           gen_font_name (buf1, &best->font),
-                           buf2));
-      else
-       MDEBUG_PRINT_TIME ("FONT", (stderr, " to fail to find <%s>.", buf2));
-      MDEBUG_POP_TIME ();
+      driver = mplist_get (frame->font_driver_list, Mx);
+      if (driver)
+       return (driver->select) (frame, font, max_size);
     }
-
-  if (! best)
+  driver = mplist_get (frame->font_driver_list, Mfreetype);
+  if (! driver)
     return NULL;
-  best->layouter = layouter;
-  mplist_add (frame->realized_font_list, registry, best);
-  return best;
+  return (driver->select) (frame, font, max_size);
 }
 
 
-/** Open a font specified in RFONT.  Return 0 if successfully
-    opened, otherwise return -1.  */
-
 int
-mfont__open (MRealizedFont *rfont)
+mfont__available (MFrame *frame, MFont *font)
+{
+  return -1;
+}
+
+static int
+compare_font_score (const void *e1, const void *e2)
+{
+  return (((MFontScore *) e1)->score > ((MFontScore *) e2)->score);
+}
+
+void
+mdebug_dump_font_list (MFontList *font_list)
 {
-  MPlist *realized_font_list;
-  MSymbol registry = FONT_PROPERTY (&rfont->font, MFONT_REGISTRY);
+  int i;
 
-  if (rfont->status)
-    mdebug_hook ();
+  for (i = 0; i < font_list->nfonts; i++)
+    {
+      fprintf (stderr, "%04X - ", font_list->fonts[i].score);
+      mdebug_dump_font (font_list->fonts[i].font);
+      fprintf (stderr, "\n");
+    }
+}
+
+void
+mfont__free_realized (MRealizedFont *rfont)
+{
+  MRealizedFont *next;
 
-  MPLIST_DO (realized_font_list, rfont->frame->realized_font_list)
+  for (; rfont; rfont = next)
     {
-      MRealizedFont *this_rfont = MPLIST_VAL (realized_font_list);
+      next = rfont->next;
+      M17N_OBJECT_UNREF (rfont->info);
+      free (rfont);
+      rfont = next;
+    }
+}
 
-      if (this_rfont->status != 0
-         && MPLIST_KEY (realized_font_list) == registry
-         && ! memcmp (&this_rfont->font, &rfont->font, sizeof (MFont)))
+MFontList *
+mfont__list (MFrame *frame, MFont *spec, MFont *request, int max_size)
+{
+  MFontList *list;
+  MSymbol id = mfont__id (spec);
+  MPlist *pl, *p;
+  int num, i;
+
+  pl = msymbol_get (id, M_font_list);
+  if (pl)
+    num = (int) msymbol_get (id, M_font_list_len);
+  else
+    {
+      pl = mplist ();
+      num = 0;
+      MPLIST_DO (p, frame->font_driver_list)
        {
-         if (rfont->info)
-           M17N_OBJECT_UNREF (rfont->info);
-         rfont->info = this_rfont->info;
-         M17N_OBJECT_REF (this_rfont->info);
-         rfont->status = this_rfont->status;
-         return (this_rfont->status > 0 ? 0 : -1);
+         if (spec->source == MFONT_SOURCE_X ? MPLIST_KEY (p) == Mx
+             : spec->source == MFONT_SOURCE_FT ? MPLIST_KEY (p) == Mfreetype
+             : 1)
+           {
+             MFontDriver *driver = MPLIST_VAL (p);
+             num += (driver->list) (frame, pl, spec, 0);
+           }
        }
+      msymbol_put (id, M_font_list, pl);
+      M17N_OBJECT_UNREF (pl);
+      msymbol_put (id, M_font_list_len, (void *) num);
     }
+  
+  if (num == 0)
+    return NULL;
 
-  return (rfont->driver->open) (rfont);
-}
+  MSTRUCT_MALLOC (list, MERROR_FONT);
+  MTABLE_MALLOC (list->fonts, num, MERROR_FONT);
+  for (i = 0; num > 0; num--, pl = MPLIST_NEXT (pl))
+    {
+      MFont *font = MPLIST_VAL (pl);
 
-void
-mfont__close (MRealizedFont *rfont)
-{
-  (rfont->driver->close) (rfont);
+      if (max_size == 0
+         || font->size == 0
+         || font->size < max_size)
+       {
+         list->fonts[i].font = font;
+         list->fonts[i].score
+           = spec == request ? 0 : font_score (font, request);
+         i++;
+       }
+    }
+  if (i == 0)
+    {
+      free (list->fonts);
+      free (list);
+      return NULL;
+    }
+  list->nfonts = i;
+  if (spec != request)
+    qsort (list->fonts, i, sizeof (MFontScore), compare_font_score);
+  list->object = *spec;
+  mfont__merge (&list->object, request, 0);
+  list->object.type = MFONT_TYPE_OBJECT;
+  return list;
 }
 
-void
-mfont__resize (MFont *spec, MFont *request)
+/** Open a font specified in FONT.  */
+
+MRealizedFont *
+mfont__open (MFrame *frame, MFont *font, MFont *spec)
 {
-  MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
-  MFontResize *resize;
-  MPlist *plist;
+  MFontDriver *driver;
+  MRealizedFont *rfont;
+
+  if (font->source == MFONT_SOURCE_UNDECIDED)
+    MFATAL (MERROR_FONT);
+  if (font->type != MFONT_TYPE_OBJECT)
+    MFATAL (MERROR_FONT);
+  for (rfont = MPLIST_VAL (frame->realized_font_list); rfont;
+       rfont = rfont->next)
+    {
+      driver = rfont->driver;
+      if (rfont->font == font
+         && mplist_find_by_value (frame->font_driver_list, driver))
+       break;
+    }
+
+  if (! rfont)
+    {
+      driver = mplist_get (frame->font_driver_list,
+                          font->source == MFONT_SOURCE_X ? Mx : Mfreetype);
+      if (! driver)
+       MFATAL (MERROR_FONT);
+    }
+  return (driver->open) (frame, font, spec, rfont);
+}
+
+void
+mfont__resize (MFont *spec, MFont *request)
+{
+  MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
+  MFontResize *resize;
+  MPlist *plist;
 
   if (! font_resize_list)
     load_font_resize_table ();
@@ -1021,8 +1441,7 @@ mfont__resize (MFont *spec, MFont *request)
            resize = (MFontResize *) MPLIST_VAL (plist);
            if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
              {
-               request->property[MFONT_SIZE]
-                 = request->property[MFONT_SIZE] * resize->resize / 100;
+               request->size = request->size * resize->resize / 100;
                return;
              }
            plist = MPLIST_NEXT (plist);
@@ -1033,46 +1452,66 @@ mfont__resize (MFont *spec, MFont *request)
       }
 }
 
-/* Return 1 if C is encodable, 0, if C is not encodable, -1 if it
-   can't be decided now.  */
 
 int
-mfont__encodable_p (MRealizedFont *rfont, MSymbol layouter_name, int c)
+mfont__has_char (MFrame *frame, MFont *font, MFont *spec, int c)
 {
   MFontEncoding *encoding;
+  unsigned code;
+  MFontDriver *driver;
 
-  if (layouter_name != Mnil)
-    return (mfont__flt_encode_char (layouter_name, c)
-           != MCHAR_INVALID_CODE);
-  if (! rfont->encoding)
-    rfont->encoding = find_encoding (&rfont->spec);
-  encoding = rfont->encoding;
-  if (! encoding->repertory_charset)
-    return -1;
-  return (ENCODE_CHAR (encoding->repertory_charset, c) != MCHAR_INVALID_CODE);
+  if (font->source == MFONT_SOURCE_UNDECIDED)
+    MFATAL (MERROR_FONT);
+  encoding = (font->encoding ? font->encoding : find_encoding (font));
+  if (! encoding->encoding_charset)
+    return 0;
+  if (encoding->repertory_charset)
+    {
+      code = ENCODE_CHAR (encoding->repertory_charset, c);
+      return (code != MCHAR_INVALID_CODE);
+    }
+  code = ENCODE_CHAR (encoding->encoding_charset, c);
+  if (code == MCHAR_INVALID_CODE)
+    return 0;
+  if (font->type == MFONT_TYPE_REALIZED)
+    driver = ((MRealizedFont *) font)->driver;
+  else
+    {
+      driver = mplist_get (frame->font_driver_list,
+                          font->source == MFONT_SOURCE_X ? Mx : Mfreetype);
+      if (! driver)
+       MFATAL (MERROR_FONT);
+    }
+  return (driver->has_char) (frame, font, spec, c, code);
 }
 
 unsigned
-mfont__encode_char (MRealizedFont *rfont, int c)
+mfont__encode_char (MFrame *frame, MFont *font, MFont *spec, int c)
 {
   MFontEncoding *encoding;
   unsigned code;
+  MFontDriver *driver;
 
-  if (rfont->layouter != Mnil)
-    return mfont__flt_encode_char (rfont->layouter, c);
-  if (! rfont->encoding)
-    rfont->encoding = find_encoding (&rfont->font);
-  encoding = rfont->encoding;
+  if (font->source == MFONT_SOURCE_UNDECIDED)
+    MFATAL (MERROR_FONT);
+  encoding = (font->encoding ? font->encoding : find_encoding (font));
   if (! encoding->encoding_charset)
     return MCHAR_INVALID_CODE;
+  if (encoding->repertory_charset)
+    return (ENCODE_CHAR (encoding->repertory_charset, c));
   code = ENCODE_CHAR (encoding->encoding_charset, c);
   if (code == MCHAR_INVALID_CODE)
     return MCHAR_INVALID_CODE;
-  if (! encoding->repertory_charset)
-    return (rfont->driver->encode_char) (rfont, c, code);
-  if (ENCODE_CHAR (encoding->repertory_charset, c) == MCHAR_INVALID_CODE)
-    return MCHAR_INVALID_CODE;
-  return code;
+  if (font->type == MFONT_TYPE_REALIZED)
+    driver = ((MRealizedFont *) font)->driver;
+  else
+    {
+      driver = mplist_get (frame->font_driver_list,
+                          font->source == MFONT_SOURCE_X ? Mx : Mfreetype);
+      if (! driver)
+       MFATAL (MERROR_FONT);
+    }
+  return (driver->encode_char) (frame, font, spec, code);
 }
 
 void
@@ -1095,6 +1534,8 @@ mfont__get_metric (MGlyphString *gstring, int from, int to)
 }
 
 
+/* KEY <= MFONT_REGISTRY */
+
 void
 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
 {
@@ -1117,14 +1558,201 @@ mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
 
 void
 mfont__set_spec (MFont *font, MSymbol *attrs,
-                unsigned short size, unsigned short resy)
+                unsigned size, unsigned short resy)
 {
   int i;
 
   for (i = 0; i <= MFONT_REGISTRY; i++)
     mfont__set_property (font, i, attrs[i]);
-  font->property[MFONT_SIZE] = size;
   font->property[MFONT_RESY] = resy;
+  font->size = size;
+}
+
+int
+mfont__parse_name_into_font (char *name, MSymbol format, MFont *font)
+{
+  int result = -1;
+
+  if (format == Mx || format == Mnil)
+    result = xlfd_parse_name (name, font);
+#ifdef HAVE_FONTCONFIG
+  if (format == Mfontconfig || (! result && format == Mnil))
+    result = mfont__ft_parse_name (name, font);
+#endif /* HAVE_FONTCONFIG */
+  return result;
+}
+
+MPlist *
+mfont__encoding_list (void)
+{
+  if (! font_encoding_list)
+    load_font_encoding_table ();
+  return font_encoding_list;
+}
+
+static void
+free_font_capability (void *object)
+{
+  MFontCapability *cap = object;
+  int i;
+  
+  if (cap->lang)
+    free (cap->lang);
+#ifdef HAVE_OTF
+  if (cap->script)
+    for (i = 0; i < MFONT_OTT_MAX; i++)
+      {
+       if (cap->features[i].str)
+         free (cap->features[i].str);
+       if (cap->features[i].tags)
+         free (cap->features[i].tags);
+      }
+#endif /* HAVE_OTF */
+  free (cap);
+}
+
+MFontCapability *
+mfont__get_capability (MSymbol sym)
+{
+  MFontCapability *cap = msymbol_get (sym, M_font_capability);
+  char *str, *p, *endp;
+  int i;
+
+  if (cap)
+    return cap;
+  str = MSYMBOL_NAME (sym);
+  if (str[0] != ':')
+    return NULL;
+  M17N_OBJECT (cap, free_font_capability, MERROR_FONT);
+  msymbol_put (sym, M_font_capability, cap);
+  M17N_OBJECT_UNREF (cap);
+  endp = str + MSYMBOL_NAMELEN (sym);
+  while (str < endp)
+    {
+      if (*str++ != ':')
+       continue;
+#ifdef HAVE_OTF
+      if (str[0] == 'o' && str[1] == 't' && str[2] == 'f' && str[3] == '=')
+       {
+         str += 4;
+         for (i = 0, p = str; i < 4 && p < endp; i++, p++);
+         if (i < 4)
+           break;
+         cap->script_tag = OTF_tag (str);
+         cap->script = find_script_from_otf_tag (cap->script_tag);
+         if (*p == '/')
+           {
+             for (i = 0, str = ++p; i < 4 && p < endp; i++, p++);
+             if (i < 4)
+               {
+                 cap->script = Mnil;
+                 break;
+               }
+             cap->langsys_tag = OTF_tag (str);
+           }
+         else
+           cap->langsys_tag = 0;
+
+         for (i = 0; i < MFONT_OTT_MAX; i++)
+           cap->features[i].nfeatures = -1;
+
+         while (*p == '=' || *p == '+')
+           {
+             int idx = *p == '=' ? MFONT_OTT_GSUB : MFONT_OTT_GPOS;
+
+             str = ++p;
+             while (p < endp && *p != '+') p++;
+             if (str < p)
+               {
+                 int n;
+                 /* We never have more than (p - str) tags.  */
+                 OTF_Tag *tags = alloca (sizeof (OTF_Tag) * (p - str));
+                 char *p0;
+
+                 cap->features[idx].str = malloc (p - str + 1);
+                 for (i = n = 0, p0 = str; str + i < p; i++)
+                   {
+                     cap->features[idx].str[i] = str[i];
+                     if (str[i] == ',' || str + i + 1 == p)
+                       {
+                         if (*p0 == '*')
+                           tags[n] = 0;
+                         else if (*p0 == '~')
+                           tags[n] = OTF_tag (p0 + 1) | 0x80000000;
+                         else
+                           tags[n] = OTF_tag (p0);
+                         n++;
+                         p0 = str + i + 1;
+                       }
+                   }
+                 cap->features[idx].str[i] = '\0';
+                 cap->features[idx].nfeatures = n;
+                 if (n > 0)
+                   {
+                     int size = sizeof (OTF_Tag) * n;
+
+                     cap->features[idx].tags = malloc (size);
+                     memcpy (cap->features[idx].tags, tags, size);
+                   }
+               }
+             else
+               {
+                 cap->features[idx].str = NULL;
+                 cap->features[idx].nfeatures = 0;
+               }
+           }
+
+         for (i = 0; i < MFONT_OTT_MAX; i++)
+           if (cap->features[i].nfeatures < 0)
+             {
+               cap->features[i].str = strdup ("*");
+               cap->features[i].nfeatures = 1;
+               cap->features[i].tags = malloc (sizeof (OTF_Tag));
+               cap->features[i].tags[0] = 0;
+             }
+         str = p;
+         continue;
+       }
+#endif /* HAVE_OTF */
+      if (str[0] == 'l' && str[1] == 'a' && str[2] == 'n' && str[3] == 'g'
+         && str[4] == '=')
+       {
+         int count;
+
+         str += 5;
+         for (p = str, count = 2; p < endp && *p != ':'; p++)
+           if (*p == ',')
+             count++;
+         MTABLE_MALLOC (cap->lang, count, MERROR_FONT);
+         for (p = str, count = 0; p < endp && *p != ':'; p++)
+           if (*p == ',')
+             {
+               MSymbol lang = msymbol__with_len (str, p - str), sym;
+
+               if (msymbol_get (lang, Miso639_2))
+                 cap->lang[count++] = lang;
+               else if ((sym = msymbol_get (lang, Miso639_1)) != Mnil)
+                 cap->lang[count++] = sym;
+               else if (msymbol_get (lang, Mlanguage))
+                 cap->lang[count++] = lang;
+               str = p + 1;
+             }
+         if (str < p)
+           cap->lang[count++] = msymbol__with_len (str, p - str);
+         cap->lang[count] = Mnil;
+         str = p;
+       }
+      else if (str[0] == 's' && str[1] == 'c' && str[2] == 'r' && str[3] == 'i'
+              && str[4] == 'p' && str[5] == 't' && str[6] == '=')
+       {
+         str += 7;
+         for (p = str; p < endp && *p != ':'; p++);
+         if (str < p)
+           cap->script = msymbol__with_len (str, p - str);
+         str = p;
+       }
+    }
+  return cap;
 }
 
 /*** @} */
@@ -1144,168 +1772,226 @@ mfont__set_spec (MFont *font, MSymbol *attrs,
 /*=*/
 
 /***en
-    @brief Key of font property specifying foundry
+    @brief Key of font property specifying foundry.
 
     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
     is used as a key of font property and face property.  The property
     value must be a symbol whose name is a foundry name of a font.  */
 /***ja
-    @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼
+    @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô ¤Ï <tt>"fondry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È
-    ¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó
-    ¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Mfoundry;
 
 /***en
-    @brief Key of font property specifying family
+    @brief Key of font property specifying family.
 
     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
     used as a key of font property and face property.  The property
     value must be a symbol whose name is a family name of a font.  */ 
 /***ja
-    @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼
+    @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô ¤Ï <tt>"family"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È
-    ¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó
-    ¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Mfamily;
 
 /***en
-    @brief Key of font property specifying weight
+    @brief Key of font property specifying weight.
 
     The variable #Mweight is a symbol of name <tt>"weight"</tt> and is
     used as a key of font property and face property.  The property
     value must be a symbol whose name is a weight name of a font (e.g
     "medium", "bold").  */ 
 /***ja
-    @brief weight ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼
+    @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô ¤Ï <tt>"weight"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È
-    ¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó
-    ¥È¤Î weight Ì¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê
-    ¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Mweight;
 
 /***en
-    @brief Key of font property specifying style
+    @brief Key of font property specifying style.
 
     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
     used as a key of font property and face property.  The property
     value must be a symbol whose name is a style name of a font (e.g
     "r", "i", "o").  */ 
 /***ja
-    @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼
+    @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô ¤Ï <tt>"style"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È
-    ¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó
-    ¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ
-    ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Mstyle;
 
 /***en
-    @brief Key of font property specifying stretch
+    @brief Key of font property specifying stretch.
 
     The variable #Mstretch is a symbol of name <tt>"stretch"</tt> and
     is used as a key of font property and face property.  The property
     value must be a symbol whose name is a stretch name of a font (e.g
     "normal", "condensed").  */ 
 /***ja
-    @brief stretch ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼
+    @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô ¤Ï <tt>"stretch"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó
-    ¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©
-    ¥ó¥È¤Î stretch Ì¾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó
-    ¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Mstretch;
 
 /***en
-    @brief Key of font property specifying additional style
+    @brief Key of font property specifying additional style.
 
     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
     is used as a key of font property and face property.  The property
     value must be a symbol whose name is an additional style name of a
     font (e.g "serif", "", "sans").  */ 
 /***ja
-    @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼
+    @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô ¤Ï <tt>"adstyle"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó
-    ¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©
-    ¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë
-    ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Madstyle;
 
 /***en
-    @brief Key of font property specifying registry
+    @brief Key of font property specifying registry.
 
     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
     and is used as a key of font property.  The property value must be
     a symbol whose name is a registry name a font registry
     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
 /***ja
-    @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼
+    @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô ¤Ï <tt>"registry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó
-    ¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©
-    ¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" Åù) ¤ò̾Á°¤È¤·
-    ¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" 
+    Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Mregistry;
 
 /***en
-    @brief Key of font property specifying size
+    @brief Key of font property specifying size.
 
     The variable #Msize is a symbol of name <tt>"size"</tt> and is
     used as a key of font property and face property.  The property
     value must be an integer specifying a font design size in the unit
     of 1/10 point (on 100 dpi display).  */ 
 /***ja
-    @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼
+    @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô ¤Ï <tt>"size"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×
-    ¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢100 dpi 
-    ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç
-    ¼¨¤¹À°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
+    ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
+    100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 
+    ¥Ý¥¤¥ó¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
     */
 
 MSymbol Msize;
 
 /***en
-    @brief Key of font property specifying resolution
+    @brief Key of font property specifying file name.
+
+    The variable #Mfontfile is a symbol of name <tt>"fontfile"</tt>
+    and is used as a key of font property.  The property value must be
+    a symbol whose name is a font file name.  */ 
+/***ja
+    @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
+    
+    ÊÑ¿ô #Mfontfile ¤Ï <tt>"fontfile"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
+    ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤
+    ¥ë̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¤È¤¹¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */
+
+MSymbol Mfontfile;
+
+/***en
+    @brief Key of font property specifying resolution.
 
     The variable #Mresolution is a symbol of name <tt>"resolution"</tt> and
     is used as a key of font property and face property.  The property
     value must be an integer to specifying a font resolution in the
     unit of dots per inch (dpi).  */ 
 /***ja
-    @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼
+    @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô ¤Ï <tt>"resolution"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©
-    ¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©
-    ¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£    */
 
 MSymbol Mresolution;
 
+/***en
+    @brief Symbol of name "fontconfig".
+
+    The variable #Mfontconfig is to be used as an argument of the
+    functions mfont_parse_name () and mfont_unparse_name ().  */
+/***ja
+    @brief "fontconfig" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
+
+    ÊÑ¿ô #Mfontconfig ¤Ï´Ø¿ô mfont_parse_name () ¤È mfont_unparse_name ()
+    ¤Î°ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£  */
+
+MSymbol Mfontconfig;
+
+/***en
+    @brief Symbol of name "x".
+
+    The variable #Mx is to be used for a value of <type> member of the
+    structure #MDrawGlyph to specify the type of <fontp> member is
+    actually (XFontStruct *).  */
+/***ja
+    @brief "x" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
+
+    ÊÑ¿ô #Mx ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
+    ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XFontStruct *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹.  */
+
+MSymbol Mx;
+
+/***en
+    @brief Symbol of name "freetype".
+
+    The variable #Mfreetype is to be used for a value of <type> member
+    of the structure #MDrawGlyph to specify the type of <fontp> member
+    is actually FT_Face.  */
+/***ja
+    @brief "freetype" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
+
+    ÊÑ¿ô #Mfreetype ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
+    ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï FT_Face ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£  */
+
+MSymbol Mfreetype;
+
+/***en
+    @brief Symbol of name "xft".
+
+    The variable #Mxft is to be used for a value of <type> member of the
+    structure #MDrawGlyph to specify the type of <fontp> member
+    is actually (XftFont *).  */
+/***ja
+    @brief  "xft" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
+
+    ÊÑ¿ô #Mxft ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
+    ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XftFont *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£  */
+
+MSymbol Mxft;
+
 /*=*/
 /*** @} */
 /*=*/
 
 /***en
-    @brief List of font files and directories that contain font files
+    @brief List of font files and directories that contain font files.
 
     The variable @c mfont_freetype_path is a plist of FreeType font
     files and directories that contain FreeType font files.  Key of
@@ -1323,29 +2009,27 @@ MSymbol Mresolution;
     If the m17n library is not configured to use the FreeType library,
     this variable is not used.  */
 /***ja
-    @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È
+    @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È.
 
-    ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë
-    ¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring ¤Ç¤¢
-    ¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
+    ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î 
+    plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring 
+    ¤Ç¤¢¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
 
-    ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ
-     ¿ô"M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
-     mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©
-     ¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢
-     mframe () ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê
-     ¤¤¡£¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó
-     ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
+    ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ¿ô 
+    "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
+    mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£
+    ¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢mframe () 
+    ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
+    ¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
 
-    m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì
-    ¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
+    m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
 
 MPlist *mfont_freetype_path;
 
 /*=*/
 
 /***en
-    @brief Create a new font
+    @brief Create a new font.
 
     The mfont () function creates a new font object that has no
     property.
@@ -1355,8 +2039,7 @@ MPlist *mfont_freetype_path;
 /***ja
     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
 
-    ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯
-    ¥È¤òºî¤ë¡£
+    ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
 
     @return
     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
@@ -1373,39 +2056,46 @@ mfont ()
 /*=*/
 
 /***en
-    @brief Create a new font from fontname.
+    @brief Create a font by parsing a fontname.
 
-    The mfont_from_name () function creates a new font object.  The
+    The mfont_parse_name () function creates a new font object.  The
     properties are extracted fontname $NAME.
 
-    How to extract properties is window system dependent.  The m17n-X
-    library parses $NAME as XLFD (X Logical Font Description).
+    $FORMAT specifies the format of $NAME.  If $FORMAT is #Mx, $NAME
+    is parsed as XLFD (X Logical Font Description).  If $FORMAT is
+    #Mfontconfig, $NAME is parsed as Fontconfig's textual
+    representation of font.  If $FORMAT is #Mnil, $NAME is at first
+    parsed as XLFD, and it it fails, parsed as Fontconfig's
+    representation.
 
     @return
     If the operation was successful, this function returns a pointer
     to the created font.  Otherwise it returns @c NULL.  */
 
 /***ja
-    @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë
+    @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
 
-    ´Ø¿ô mfont_from_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ
-    ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
+    ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ 
+    $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
 
-    ¤É¤Î¤è¤¦¤Ë¥×¥í¥Ñ¥Æ¥£¤ò¼è¤ê½Ð¤¹¤«¤Ï¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤Ë°Í¸¤¹¤ë¡£
-    m17n-X ¥é¥¤¥Ö¥é¥ê¤Î¾ì¹ç¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ
-    $NAME ¤ò²òÀϤ¹¤ë¡£
+    $FORMAT ¤Ï $NAME ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ØÄꤹ¤ë¡£$FORMAT ¤¬ #Mx ¤Ç¤¢¤ì¤Ð¡¢
+    $NAME ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
+    $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig 
+    ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD 
+    ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
 
     @return
-    ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_from_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î
-    ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
+    ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () 
+    ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
 
 MFont *
-mfont_from_name (char *name)
+mfont_parse_name (char *name, MSymbol format)
 {
   MFont template, *font;
-
-  if (mwin__parse_font_name (name, &template) < 0)
-    return NULL;
+  
+  MFONT_INIT (&template);
+  if (mfont__parse_name_into_font (name, format, &template) < 0)
+    MERROR (MERROR_FONT, NULL);
   MSTRUCT_CALLOC (font, MERROR_FONT);
   *font = template;
   return font;
@@ -1414,55 +2104,70 @@ mfont_from_name (char *name)
 /*=*/
 
 /***en
-    @brief Make a copy of a font.
+    @brief Create a fontname from a font.
+
+    The mfont_unparse_name () function creates a fontname string
+    from font $FONT according to $FORMAT.
+
+    $FORMAT must be #Mx or #Mfontconfig.  If it is #Mx, the fontname
+    is in XLFD (X Logical Font Description) format.  If it is
+    #Mfontconfig, the fontname is in the style of Fontconfig's text
+    representation.
+
+    @return
+    This function returns a newly allocated fontname string, which is
+    not freed unless the user explicitly does so by free ().  */
 
-    The mfont_copy () function returns a new copy of font $FONT.  */
 /***ja
-    @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
+    @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë.
 
-    ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
+    ´Ø¿ô mfont_unparse_name () ¤Ï ¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤ò¥Õ¥©¥ó¥È $FONT 
+    ¤ò¸µ¤Ë$FORMAT ¤Ë½¾¤Ã¤Æºî¤ë¡£
 
-MFont *
-mfont_copy (MFont *font)
+    $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤¢¤ë¡£
+    #Mx ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£
+    #Mfontconfig ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤¦¡£
+
+    @return 
+    ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢¥æ¡¼¥¶¤¬
+    free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
+
+char *
+mfont_unparse_name (MFont *font, MSymbol format)
 {
-  MFont *copy;
+  char *name;
 
-  MSTRUCT_MALLOC (copy, MERROR_FONT);
-  *copy = *font;
-  return copy;
+  if (format == Mx)
+    name = xlfd_unparse_name (font);
+#ifdef HAVE_FONTCONFIG
+  else if (format == Mfontconfig)
+    name = mfont__ft_unparse_name (font);
+
+#endif /* HAVE_FONTCONFIG */
+  else
+    MERROR (MERROR_FONT, NULL);
+  return name;
 }
 
 /*=*/
 
 /***en
-    @brief Create a fontname from a font.
-
-    The mfont_name () function creates a fontname string created from
-    font $FONT.
-
-    The syntax of fontname is window system dependent.  The m17n-X
-    library returns a fontname conforming to XLFD (X Logical Font
-    Description).
+    @brief Make a copy of a font.
 
-    @return
-    This function returns the created fontname string, which is not freed
-    unless the user explicitly does so by free ().  */
+    The mfont_copy () function returns a new copy of font $FONT.  */
 /***ja
-    @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
-
-    ´Ø¿ô mfont_name () ¤Ï¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤ò¥Õ¥©¥ó¥È
-    $FONT ¤ò¸µ¤Ëºî¤ë¡£
-
-    ¥Õ¥©¥ó¥È̾¤Îʸˡ¤Ï¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤Ë°Í¸¤¹¤ë¡£m17n-X ¥é¥¤¥Ö¥é¥ê
-    ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¥Õ¥©¥ó¥È̾¤òÊÖ¤¹¡£
+    @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
 
-    @return ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢¥æ¡¼¥¶
-    ¤¬ free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
+    ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
 
-char *
-mfont_name (MFont *font)
+MFont *
+mfont_copy (MFont *font)
 {
-  return mwin__build_font_name (font);
+  MFont *copy;
+
+  MSTRUCT_MALLOC (copy, MERROR_FONT);
+  *copy = *font;
+  return copy;
 }
 
 /*=*/
@@ -1474,42 +2179,37 @@ mfont_name (MFont *font)
     font $FONT.  $KEY must be one of the following symbols:
 
        @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
-       @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
+       @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mtype.
 
     @return
     If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
-    Madstyle, or @c Mregistry, this function returns the
+    Madstyle, @c Mregistry, or @c Mtype, this function returns the
     corresponding value as a symbol.  If the font does not have $KEY
     property, it returns @c Mnil.
-
     If $KEY is @c Msize or @c Mresolution, this function returns the
     corresponding value as an integer.  If the font does not have $KEY
     property, it returns 0.
-
     If $KEY is something else, it returns @c NULL and assigns an error
     code to the external variable #merror_code.  */
-
 /***ja
-    @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£ÃͤòÆÀ¤ë.
+    @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
 
-    ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ 
+    ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬
     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
     ¤Ð¤Ê¤é¤Ê¤¤¡£
 
        @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
-       @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
+       @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mtype.
 
     @return 
     $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
-    Madstyle, @c Mregistry ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃͤò¥·¥ó¥Ü¥ë¤È
-    ¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï @c Mnil ¤òÊÖ¤¹¡£
-    
-    $KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢ÁêÅö¤¹¤ëÃͤò
-    ¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï 0 ¤ò
-    ÊÖ¤¹¡£
-
-    $KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
-    #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
+    Madstyle, @c Mregistry, @c Mtype ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃͤò¥·
+    ¥ó¥Ü¥ë¤È¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï @c
+    Mnil ¤òÊÖ¤¹¡£$KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢
+    ÁêÅö¤¹¤ëÃͤò¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤
+    ¾ì¹ç¤Ë¤Ï 0 ¤òÊÖ¤¹¡£$KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢
+    ³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
 
 void *
 mfont_get_prop (MFont *font, MSymbol key)
@@ -1530,7 +2230,7 @@ mfont_get_prop (MFont *font, MSymbol key)
     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
   if (key == Msize)
     {
-      int size = font->property[MFONT_SIZE];
+      int size = font->size;
       return (void *) size;
     }
   if (key == Mresolution)
@@ -1538,7 +2238,8 @@ mfont_get_prop (MFont *font, MSymbol key)
       int resy = font->property[MFONT_RESY];
       return (void *) resy;
     }
-
+  if (key == Mfontfile)
+    return (void *) font->file;
   MERROR (MERROR_FONT, NULL);
 }
 
@@ -1556,18 +2257,17 @@ mfont_get_prop (MFont *font, MSymbol key)
 
     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
     Otherwise, $VAL must be a symbol.  */
-/***ja
-    @brief ¥Õ¥©¥ó¥È¤Ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÀßÄꤹ¤ë.
+ /***ja
+    @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
 
-    ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY ¤Ç¤¢¤ë¥×¥í
-    ¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢
-    ¤ë¡£
+    ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY 
+    ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
 
        @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
        @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
 
-    $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ
-    ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
+    $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL 
+    ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
 
 int
 mfont_put_prop (MFont *font, MSymbol key, void *val)
@@ -1589,12 +2289,16 @@ mfont_put_prop (MFont *font, MSymbol key, void *val)
   else if (key == Msize)
     {
       unsigned size = (unsigned) val;
-      font->property[MFONT_SIZE] = size;
+      font->size = size;
     }
   else if (key == Mresolution)
     {
       unsigned resy = (unsigned) val;
-      font->property[MFONT_RESY] =  resy;
+      font->property[MFONT_RESY] = resy;
+    }
+  else if (key == Mfontfile)
+    {
+      font->file = (MSymbol) val;
     }
   else
     MERROR (MERROR_FONT, -1);
@@ -1618,18 +2322,17 @@ mfont_put_prop (MFont *font, MSymbol key, void *val)
    property of lower priority is preferred to a font that has a
    different value for a property of higher priority.  */
 /***ja
-    @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÊÖ¤¹.
+    @brief ¥Õ¥©¥ó¥ÈÁªÂò¤ÎÍ¥ÀèÅÙ¤òÊÖ¤¹.
 
-    ´Ø¿ô mfont_selection_priority () ¤Ï6¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã
-    ¤ÆÊÖ¤¹¡£ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤ËÊÂ
-    ¤Ù¤¿¤â¤Î¤Ç¤¢¤ë¡£
+    ´Ø¿ô mfont_selection_priority () ¤Ï 6 ¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã¤ÆÊÖ¤¹¡£
+    ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤Ëʤ٤¿¤â¤Î¤Ç¤¢¤ë¡£
 
        @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
        @c Madstyle, @c Msize.
 
    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£
-   Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬°ã¤¦¥Õ¥©¥ó¥È¤ÈÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤Î
-   Ãͤ¬°ã¤¦¥Õ¥©¥ó¥È¤¬¤¢¤ë¾ì¹ç¡¢Á°¼Ô¤¬ÁªÂò¤µ¤ì¤ë¡£
+   ÌÜŪ¤Î¥Õ¥©¥ó¥È¤È¡¢¤½¤ì¤¾¤ì°ã¤¦¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Ê¤¤¥Õ¥©¥ó¥È¤¬¤¢¤Ã¤¿¾ì¹ç¡¢Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Ê¤¤¥Õ¥©¥ó¥È¡ÊÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Æ¤¤¤ë¥Õ¥©¥ó¥È¡Ë¤¬ÁªÂò¤µ¤ì¤ë¡£
+
    */
 
 MSymbol *
@@ -1680,8 +2383,8 @@ mfont_selection_priority ()
     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
 
     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
-    ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£³ÆÍ×ÁǤϰʲ¼¤Î¤¦¤Á¤Î¤É¤ì
-    ¤«¤Ç¤¢¤ê¡¢Á´¤Æ°Û¤Ê¤Ã¤Æ¤¤¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
+    ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£ÇÛÎó¤Ï°Ê²¼¤Î³ÆÍ×ÁǤòŬÀÚ
+    ¤Ê½çÈÖ¤Çʤ٤¿¤â¤Î¤Ç¤¢¤ë¡£
 
        @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
        @c Madstyle, @c Msize.
@@ -1693,7 +2396,7 @@ int
 mfont_set_selection_priority (MSymbol *keys)
 {
   int priority[FONT_SCORE_PRIORITY_SIZE];
-  int i, j;
+  int i, j, shift;
 
   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
     {
@@ -1724,6 +2427,20 @@ mfont_set_selection_priority (MSymbol *keys)
     }
   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
     font_score_priority[i] = priority[i];
+  /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
+     of a score is a flag for a scalable font (see the documentation
+     of font_score).  */
+  i = FONT_SCORE_PRIORITY_SIZE - 1;
+  for (shift = 1; i >= 0; i--)
+    {
+      font_score_shift_bits[font_score_priority[i]] = shift;
+      if (font_score_priority[i] == MFONT_SIZE)
+       shift += 16;
+      else if (font_score_priority[i] <= MFONT_FAMILY)
+       shift++;
+      else
+       shift += 2;
+    }
   return 0;
 }
 
@@ -1741,29 +2458,37 @@ mfont_set_selection_priority (MSymbol *keys)
 /***ja
     @brief ¥Õ¥©¥ó¥È¤òõ¤¹.
 
-    ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC ¤Ë¤â¤Ã
-    ¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
+    ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC 
+    ¤Ë¤â¤Ã¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
 
-    $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC ¤Ë¤É¤ì¤Û¤É¹ç¤Ã
-    ¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥¹¥³¥¢¤¬¾®¤µ
-    ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
+    $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC 
+    ¤Ë¤É¤ì¤Û¤É¹ç¤Ã¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£
+    ¥¹¥³¥¢¤¬¾®¤µ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
     */
 
 MFont *
-mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size)
+mfont_find (MFrame *frame, MFont *spec, int *score, int max_size)
 {
   MFont spec_copy;
-  MRealizedFont *rfont;
+  MFont *best;
+  MFontList *list;
 
   MFONT_INIT (&spec_copy);
+  spec_copy.property[MFONT_FAMILY] = spec->property[MFONT_FAMILY];
   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
+  spec_copy.capability = spec->capability;
+  spec_copy.file = spec->file;
 
-  rfont = mfont__select (frame, &spec_copy, spec, limited_size, Mnil);
-  if (!rfont)
+  list = mfont__list (frame, &spec_copy, spec, max_size);
+  if (! list)
     return NULL;
+
+  best = list->fonts[0].font;
   if (score)
-    *score = rfont->score;
-  return &rfont->font;
+    *score = list->fonts[0].score;
+  free (list->fonts);
+  free (list);
+  return best;
 }
 
 /*=*/
@@ -1784,24 +2509,20 @@ mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size)
     @return
     If the operation was successful, this function returns 0.
     Otherwise it returns -1 and assigns an error code to the external
-    variable @c merror_code.  */
+    variable #merror_code.  */
 /***ja
     @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë.
 
-    ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó
-    ¤òÀßÄꤹ¤ë¡£
+    ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó¤òÀßÄꤹ¤ë¡£
 
-    $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò
-    ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+    $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
 
-    $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó
-    ¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£@c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ
-    »ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤Ë
-    Ì䤤¹ç¤ï¤»¤ë¡£
+    $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+    @c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ»ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢³Æ¡¹¤Î¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤ËÌ䤤¹ç¤ï¤»¤ë¡£
 
     @return
-    ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°
-    ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
+    ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô
+    #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
 
 
 int
@@ -1846,6 +2567,200 @@ mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
   return 0;
 }
 
+/*=*/
+
+/***en
+    @brief Create a fontname from a font.
+
+    This function is obsolete.   Use mfont_unparse_name instead. */
+/***ja
+    @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
+
+    ¤³¤Î´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_unparse_name () ¤ò»ÈÍѤΤ³¤È¡£ */
+
+char *
+mfont_name (MFont *font)
+{
+  return mfont_unparse_name (font, Mx);
+}
+
+/*=*/
+
+/***en
+    @brief Create a new font from fontname.
+
+    This function is obsolete.  Use mfont_parse_name () instead.  */
+
+/***ja
+    @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë.
+
+    ¤³¤ì¤Ï´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_parse_name () ¤ò»ÈÍѤΤ³¤È¡£  */
+
+MFont *
+mfont_from_name (char *name)
+{
+  return mfont_parse_name (name, Mx);
+}
+
+/*=*/
+
+/***en
+    @brief Get resize information of a font.
+
+    The mfont_resize_ratio () function lookups the m17n database
+    \<font, reisize\> and returns a resizing ratio (in percentage) of
+    FONT.  For instance, if the return value is 150, that means that
+    the m17n library uses an 1.5 time bigger font than a specified
+    size.  */
+
+/***ja
+    @brief ¥Õ¥©¥ó¥È¤Î¥ê¥µ¥¤¥º¾ðÊó¤òÆÀ¤ë
+
+    ´Ø¿ô mfont_resize_ratio ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹ \<font, reisize\> 
+    ¤ò¸¡º÷¤·¡¢¥Õ¥©¥ó¥È FONT ¤Î¥ê¥µ¥¤¥º¤ÎÈæΨ¡Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¡Ë
+    ¤òÊÖ¤¹¡£¤¿¤È¤¨¤ÐÊÖ¤¹Ãͤ¬ 150 ¤Ç¤¢¤ì¤Ð¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ï»ØÄꤵ¤ì¤¿¥µ¥¤¥º¤Î 1.5 
+    ÇܤΥե©¥ó¥È¤ò»ÈÍѤ¹¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£ */
+
+int
+mfont_resize_ratio (MFont *font)
+{
+  MFont request = *font;
+
+  mfont__resize (font, &request);
+  return (font->size * 100 / request.size);
+}
+
+/*=*/
+
+/***en
+    @brief Get a list of fonts.
+
+    The mfont_list () functions returns a list of fonts available on
+    frame $FRAME.  $FONT, if not NULL, limits fonts to ones
+    that match with $FONT.  $LANGUAGE, if not @c Mnil, limits fonts to
+    ones that support $LANGUAGE.  $MAXNUM, if greater than 0, limits
+    the number of fonts.
+
+    @return
+    This function returns a plist whose keys are family names and
+    values are pointers to the object MFont.  The plist must be freed
+    by m17n_object_unref ().  If no font is found, it returns
+    NULL.  */
+
+/***ja
+    @brief ¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÆÀ¤ë
+
+    ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
+    $FONT ¤¬ NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
+    $LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò¥µ¥Ý¡¼¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
+    $MAXNUM ¤Ï¡¢0 ¤è¤êÂ礭¤¤¾ì¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£
+
+    @return 
+    ¤³¤Î´Ø¿ô¤Ï¥­¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Ê
+    plist ¤òÊÖ¤¹¡£plist ¤Ï m17n_object_unref () 
+    ¤Ç²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤ÐNULL ¤òÊÖ¤¹¡£  */
+
+MPlist *
+mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum)
+{
+  MPlist *plist, *pl;
+  MFontList *font_list;
+  int i;
+  MFont *work = NULL;
+  
+  if (language != Mnil)
+    {
+      /* ":lang=XXX" */
+      char *buf = alloca (MSYMBOL_NAMELEN (language) + 7);
+
+      sprintf (buf, ":lang=%s", MSYMBOL_NAME (language));
+      if (! font)
+       font = work = mfont ();
+      font->capability = msymbol (buf);
+    }
+
+  font_list = mfont__list (frame, font, font, 0);
+  if (work)
+    free (work);
+  if (! font_list)
+    return NULL;
+  if (font_list->nfonts == 0)
+    {
+      free (font_list);
+      return NULL;
+    }
+
+  plist = pl = mplist ();
+  for (i = 0; i < font_list->nfonts; i++)
+    {
+      MSymbol family = FONT_PROPERTY (font_list->fonts[i].font, MFONT_FAMILY);
+
+      if (family != Mnil)
+       pl = mplist_add (pl, family, font_list->fonts[i].font);
+    }
+  free (font_list);
+  return plist;
+}
+
+
+/*=*/
+
+/***en
+    @brief Check the usability of a font.
+
+    The function mfont_check () checkes if $FONT can be used for
+    $SCRIPT and RLANGUAGE in $FONTSET on $FRAME.
+
+    @return If the font is usable, return 1.  Otherwise return 0.
+ */
+
+int
+mfont_check (MFrame *frame, MFontset *fontset, MFont *font,
+            MSymbol script, MSymbol language)
+{
+  MFont spec;
+  MPlist *plist, *pl;
+  int result = 0;
+
+  if (! fontset)
+    fontset = frame->face->property[MFACE_FONTSET];
+
+  plist = mfontset_lookup (fontset, script, Mt, Mnil);
+  if (script != Mnil)
+    {
+      if (language == Mnil)
+       {
+         if (! mplist_find_by_key (plist, Mt))
+           /* No fallback fonts.  */
+           language = MPLIST_KEY (plist);
+       }
+      else if (! mplist_find_by_key (plist, language))
+       {
+         /* Try fallback fonts. */
+         if (mplist_find_by_key (plist, Mt))
+           language = Mnil;
+         else
+           /* No fallback fonts.  */
+           language = MPLIST_KEY (plist);
+       }
+
+      M17N_OBJECT_UNREF (plist);
+      plist = mfontset_lookup (fontset, script, language, Mnil);
+    }
+  MPLIST_DO (pl, plist)
+    {
+      spec = *(MFont *) MPLIST_VAL (pl);         
+      if (mfont__merge (&spec, font, 1) >= 0
+         && mfont__select (frame, &spec, 0))
+       {
+         result = 1;
+         break;
+       }
+    }
+  M17N_OBJECT_UNREF (plist);
+  return result;
+}
+
 /*** @} */
 
 /*** @addtogroup m17nDebug */
@@ -1853,7 +2768,7 @@ mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
 /*** @{ */
 
 /***en
-    @brief Dump a font
+    @brief Dump a font.
 
     The mdebug_dump_font () function prints font $FONT in a human readable
     way to the stderr.
@@ -1863,8 +2778,8 @@ mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
 /***ja
     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
 
-    ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr ¤Ë¿Í´Ö¤Ë²ÄÆɤÊ
-    ·Á¤Ç°õºþ¤¹¤ë¡£
+    ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr 
+    ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£
 
     @return
     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
@@ -1872,10 +2787,14 @@ mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
 MFont *
 mdebug_dump_font (MFont *font)
 {
-  char *name = mwin__build_font_name (font);
-
-  fprintf (stderr, "%s", name);
-  free (name);
+  char *name;
+  
+  name = mfont_unparse_name (font, Mx);
+  if (name)
+    {
+      fprintf (stderr, "%s", name);
+      free (name);
+    }
   return font;
 }