Copyright years udpated.
[m17n/m17n-lib.git] / src / font.c
index 9464327..be4a270 100644 (file)
@@ -1,5 +1,5 @@
 /* font.c -- font module.
-   Copyright (C) 2003, 2004
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
@@ -17,7 +17,7 @@
 
    You should have received a copy of the GNU Lesser General Public
    License along with the m17n library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    02111-1307, USA.  */
 
 /***en
     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 Mspacing.
 
     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 notation "xxx property of F" means the font property that
+    belongs to font F and whose key is @c Mxxx.
 
     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
@@ -90,7 +94,7 @@
     SLANT                                       style
     SETWIDTH_NAME                               stretch
     ADD_STYLE_NAME                              adstyle
-    POINT_SIZE                                  size
+    PIXEL_SIZE                                  size
     RESOLUTION_Y                                resolution
     CHARSET_REGISTRY-CHARSET_ENCODING           registry
 @endverbatim
     variable @c M17NDIR.  See the documentation of the variable for
     details.
 
-    If the m17n library is configured to use the fontconfig librray,
+    If the m17n library is configured to use the fontconfig library,
     in addition to #mfont_freetype_path, all fonts available via
     fontconfig are supported.
 
     @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 Mspacing
+
+    ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution 
+    ¤Î¾ì¹ç¡¢ÃͤÏÀ°¿ôÃͤǤ¢¤ê¡¢¥­¡¼¤¬¤½¤ì°Ê³°¤Î¾ì¹ç¡¢Ãͤϥ·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
+
+    ¡Ö¥Õ¥©¥ó¥È F ¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼¤¬ @c Mxxx 
+    ¤Ç¤¢¤ë¤â¤Î¡×¤Î¤³¤È¤ò´Êñ¤Ë¡ÖF ¤Î xxx ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£
 
-    ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¡¢
-    ÃͤÏÀ°¿ôÃͤǤ¢¤ê¡¢¥­¡¼¤¬¤½¤ì°Ê³°¤Î¾ì¹ç¡¢Ãͤϥ·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£¡Ö¥Õ¥©
-    ¥ó¥È 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) ¤Ç¤¢¤ë¡£  
+    type ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤ò»Ø¼¨¤·¡¢¸½ºß Mx ¤â¤·¤¯¤Ï
+    Mfreetype ¤Ç¤¢¤ë¡£
 
-    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò£²¤Ä¤ÎÌÜŪ¤ÇÍѤ¤¤Æ¤¤¤ë¡£¥¢
-    ¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¥Õ¥©¥ó¥È¤Î»ØÄê¤ò¼õ¤±¼è¤ëÌÜŪ¤È¡¢¥¢¥×¥ê
-    ¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤òÄ󼨤¹¤ëÌÜŪ¤Ç¤¢¤ë¡£¥¢¥×
-    ¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÂФ·¤ÆÄ󼨤ò¹Ô¤¦ºÝ¤Ë¤Ï¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£
-    ¤Ï¤¹¤Ù¤Æ¶ñÂÎŪ¤ÊÃͤò»ý¤Ä¡£
+    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò£²¤Ä¤ÎÌÜŪ¤ÇÍѤ¤¤Æ¤¤¤ë¡£¥¢¥×
+    ¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¥Õ¥©¥ó¥È¤Î»ØÄê¤ò¼õ¤±¼è¤ëÌÜŪ¤È¡¢¥¢¥×¥ê¥±¡¼
+    ¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤òÄ󼨤¹¤ëÌÜŪ¤Ç¤¢¤ë¡£¥¢¥×¥ê¥±¡¼
+    ¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÂФ·¤ÆÄ󼨤ò¹Ô¤¦ºÝ¤Ë¤Ï¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù
+    ¤Æ¶ñÂÎŪ¤ÊÃͤò»ý¤Ä¡£
 
     m17n ¥é¥¤¥Ö¥é¥ê¤Ï Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È¡¢FreeType¥Õ¥©¥ó¥È¡¢
     OpenType¥Õ¥©¥ó¥È¤Î£³¼ïÎà¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¡£
 
     <li> Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È
 
-    m17n X ¥é¥¤¥Ö¥é¥ê¤Ï¡¢X ¥µ¡¼¥Ð¤È X ¥Õ¥©¥ó¥È¥µ¡¼¥Ð¤¬¼è¤ê°·¤¦Á´¤Æ¤Î¥Õ¥©
-    ¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£XLFD ¤Î³Æ¥Õ¥£¡¼¥ë¥É¤È¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ÎÂбþ
-    ¤Ï°Ê²¼¤ÎÄ̤ꡣ¤³¤Îɽ¤Ë¤Ê¤¤¥Õ¥£¡¼¥ë¥É¤Ï̵»ë¤µ¤ì¤ë¡£
+    m17n X ¥é¥¤¥Ö¥é¥ê¤Ï¡¢X ¥µ¡¼¥Ð¤È X ¥Õ¥©¥ó¥È¥µ¡¼¥Ð¤¬¼è¤ê°·¤¦Á´¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£
+    XLFD ¤Î³Æ¥Õ¥£¡¼¥ë¥É¤È¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ÎÂбþ¤Ï°Ê²¼¤ÎÄ̤ꡣ¤³¤Îɽ¤Ë¤Ê¤¤¥Õ¥£¡¼¥ë¥É¤Ï̵»ë¤µ¤ì¤ë¡£
 
 @verbatim
     XLFD ¥Õ¥£¡¼¥ë¥É                             ¥×¥í¥Ñ¥Æ¥£
     SLANT                                       style
     SETWIDTH_NAME                               stretch
     ADD_STYLE_NAME                              adstyle
-    POINT_SIZE                                  size
+    PIXEL_SIZE                                  size
     RESOLUTION_Y                                resolution
     CHARSET_REGISTRY-CHARSET_ENCODING           registry
 @endverbatim
 
     <li> FreeType fonts
 
-    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë
-    ¤Ï¡¢FreeType ¤¬°·¤¦¤¹¤Ù¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£ÊÑ¿ô 
+    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢
+    FreeType ¤¬°·¤¦¤¹¤Ù¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£ÊÑ¿ô 
     #mfont_freetype_path ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤ÎÀßÄê¤È´Ä¶­ÊÑ¿ô @c M17NDIR 
     ¤Ë±þ¤¸¤Æ½é´ü²½¤µ¤ì¤ë¡£¾ÜºÙ¤ÏÊÑ¿ô¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
 
-    ¤â¤· m17n ¥é¥¤¥Ö¥é¥ê¤¬ fontconfig ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿
-    ¾ì¹ç¤Ë¤Ï¡¢#mfont_freetype_path ¤Ë²Ã¤¨¤Æ¡¢ fontconfig ¤Ç»ÈÍѲÄǽ¤Ê¥Õ¥©
-    ¥ó¥È¤â¤¹¤Ù¤Æ¥µ¥Ý¡¼¥È¤µ¤ì¤ë¡£
+    ¤â¤· m17n ¥é¥¤¥Ö¥é¥ê¤¬ fontconfig ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢
+    #mfont_freetype_path ¤Ë²Ã¤¨¤Æ¡¢ fontconfig ¤Ç»ÈÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤â¤¹¤Ù¤Æ¥µ¥Ý¡¼¥È¤µ¤ì¤ë¡£
 
     FreeType ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤Ï family ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£
     FreeType ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾¤Ï¡¢²¼¤Îɽ¤Î¤è¤¦¤Ë weight, style,
 
     ¾å¤Îɽ¤Ë¸½¤ï¤ì¤Ê¤¤¥¹¥¿¥¤¥ë̾¤Ï "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 ¥×¥í¥Ñ¥Æ¥£
 @endverbatim
 
     ¤·¤¿¤¬¤Ã¤Æ¡¢Æó¤Ä¤ÎÁȹ礻 (1 0) ¡¢(3 1) ¤ò»ý¤Ä¥Õ¥©¥ó¥È¤Ï¡¢¤½¤ì¤¾¤ì
-    registry ¥×¥í¥Ñ¥Æ¥£¤¬ 1-0, apple-roman, 3-1, unicode-bmp ¤Ç¤¢¤ë£´¤Ä
-    ¤Î¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ËÂбþ¤¹¤ë¡£
+    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 <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 
 #include "m17n-gui.h"
 #include "m17n-misc.h"
 #include "symbol.h"
 #include "plist.h"
 #include "charset.h"
+#include "language.h"
 #include "internal-gui.h"
 #include "font.h"
 #include "face.h"
+#include "fontset.h"
 
 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
   };
 
@@ -353,10 +363,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[] =
@@ -368,32 +378,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",
     "",
@@ -401,6 +420,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
@@ -440,31 +463,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.  */
 
@@ -525,8 +523,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:
@@ -607,48 +606,77 @@ 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]))));
+}
+
+void
+OTF_tag_name (OTF_Tag tag, char *name)
+{
+  name[0] = (char) (tag >> 24);
+  name[1] = (char) ((tag >> 16) & 0xFF);
+  name[2] = (char) ((tag >> 8) & 0xFF);
+  name[3] = (char) (tag & 0xFF);
+  name[4] = '\0';
+}
+#endif /* not HAVE_OTF */
+
 /* XLFD parser/generator */
 
 /** Indices to each field of split font name.  */
@@ -673,14 +701,15 @@ enum xlfd_field_idx
   };
 
 static int
-xlfd_parse_name (char *name, MFont *font)
+xlfd_parse_name (const char *name, MFont *font)
 {
   char *field[XLFD_FIELD_MAX];
-  unsigned short size, resy;
-  MSymbol attrs[MFONT_PROPERTY_MAX];
+  unsigned short resy, avgwidth;
+  unsigned size;
   char copy[513];
   int i;
   char *p;
+  MSymbol sym;
 
   if (name[0] != '-')
     return -1;
@@ -708,7 +737,11 @@ xlfd_parse_name (char *name, MFont *font)
     field[i++] = NULL;
 
   resy = field[XLFD_RESY] ? atoi (field[XLFD_RESY]) : 0;
-  if (! field[XLFD_PIXEL])
+  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] == '[')
     {
@@ -725,32 +758,53 @@ xlfd_parse_name (char *name, MFont *font)
   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);
+  if (field[XLFD_FOUNDRY])
+    {
+      sym = msymbol (field[XLFD_FOUNDRY]);
+      if (! sym)
+       sym = msymbol ("Nil");
+      mfont__set_property (font, MFONT_FOUNDRY, sym);
+    }
+  if (field[XLFD_FAMILY])
+    {
+      sym = msymbol (field[XLFD_FAMILY]);
+      if (! sym)
+       sym = msymbol ("Nil");
+      mfont__set_property (font, MFONT_FAMILY, sym);
+    }
+  if (field[XLFD_WEIGHT])
+    mfont__set_property (font, MFONT_WEIGHT, msymbol (field[XLFD_WEIGHT]));
+  if (field[XLFD_SLANT])
+    mfont__set_property (font, MFONT_STYLE, msymbol (field[XLFD_SLANT]));
+  if (field[XLFD_SWIDTH])
+    mfont__set_property (font, MFONT_STRETCH, msymbol (field[XLFD_SWIDTH]));
+  if (field[XLFD_ADSTYLE])
+    mfont__set_property (font, MFONT_ADSTYLE, msymbol (field[XLFD_ADSTYLE]));
+  font->property[MFONT_RESY] = resy;
+  font->size = size;
+  if (field[XLFD_SPACING])
+    font->spacing
+      = ((field[XLFD_SPACING][0] == 'p' || field[XLFD_SPACING][0] == 'P')
+        ? MFONT_SPACING_PROPORTIONAL
+        : (field[XLFD_SPACING][0] == 'm' || field[XLFD_SPACING][0] == 'M')
+        ? MFONT_SPACING_MONO : MFONT_SPACING_CHARCELL);
+  if (field[XLFD_REGISTRY])
+    mfont__set_property (font, MFONT_REGISTRY, msymbol (field[XLFD_REGISTRY]));
+  font->type = MFONT_TYPE_SPEC;
+  font->source = MFONT_SOURCE_X;
   return 0;
 }
 
 static char *
-xlfd_unparse_name (MFont *font)
+xlfd_unparse_name (MFont *font, int full_xlfd)
 {
   MSymbol prop[7];
   char name[513];
   char *str[7];
   int len, i;
-  unsigned short size, resy;
+  char spacing;
+  int size, resy;
+  int all_nil = 1;
 
   prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
   prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
@@ -765,6 +819,7 @@ xlfd_unparse_name (MFont *font)
        {
          str[i] = msymbol_name (prop[i]);
          len += strlen (str[i]);
+         all_nil = 0;
        }
       else
        {
@@ -772,34 +827,240 @@ xlfd_unparse_name (MFont *font)
          len++;
        }
     }
+  spacing = (font->spacing == MFONT_SPACING_UNDECIDED ? '*'
+            : font->spacing == MFONT_SPACING_PROPORTIONAL ? 'p'
+            : font->spacing == MFONT_SPACING_MONO ? 'm'
+            : 'c');
+
   if ((len
-       + 12                    /* 12 dashes */
-       + 3                     /* 3 asterisks */
+       + 13                    /* 13 dashes */
+       + 2                     /* 2 asterisks */
        + 30                    /* 3 integers (each 10 digits) */
+       + 1                     /* 1 spacing char */
        + 1)                    /* '\0' terminal */
       > 513)
     return NULL;
 
-  size = (int) mfont_get_prop (font, Msize);
-  if ((size % 10) < 5)
-    size /= 10;
-  else
-    size = size / 10 + 1;
   resy = (int) mfont_get_prop (font, Mresolution);
+  size = font->size;
+  if (size >= 0)
+    {
+      if (font->multiple_sizes)
+       {
+         for (size = 0; size < 24; size++)
+           if (font->size & (1 << size))
+             break;
+         size += 6;
+       }
+      else if ((size % 10) < 5)
+       size /= 10;
+      else
+       size = size / 10 + 1;
+    }
+  else
+    size = - size;
+
+  if (full_xlfd)
+    {
+      if (font->size >= 0)
+       sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-%c-*-%s",
+                str[0], str[1], str[2], str[3], str[4], str[5],
+                size, resy, resy, spacing, str[6]);
+      else
+       sprintf (name, "-%s-%s-%s-%s-%s-%s-*-%d-%d-%d-%c-*-%s",
+                str[0], str[1], str[2], str[3], str[4], str[5],
+                size, resy, resy, spacing, str[6]);
+    }
+  else if (all_nil && size == 0)
+    sprintf (name, "*");
+  else
+    {
+      char *p = name;
+
+      p += sprintf (p, "-%s", str[0]);
+      for (i = 1; i < 6; i++)
+       if (p[-1] != '*' || str[i][0] != '*')
+         p += sprintf (p, "-%s", str[i]);
+      if (p[-1] != '*' || font->size > 0)
+       {
+         if (font->size > 0)
+           p += sprintf (p, "-%d-*", size);
+         else
+           p += sprintf (p, "-*");
+       }
+      if (str[6][0] != '*')
+       sprintf (p, "-%s", str[6]);
+    }
 
-  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)
+           {
+             if (font->multiple_sizes)
+               {
+                 int j, closest = 23;
+
+                 for (j = 23; j >= 0; j--)
+                   if (font->size & (1 << j))
+                     {
+                       closest = j;
+                       if (request->size >= (j + 6) * 10)
+                         break;
+                     }
+                 val = request->size - (closest + 6) * 10;
+               }
+             else
+               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;
+}
+
+static MSymbol
+merge_capability (MSymbol capability, MSymbol key, MSymbol val, int overwrite)
+{
+  MFontCapability *cap = NULL;
+  char *lang = NULL, *script = NULL, *otf = NULL, *buf, *p;
+  int lang_len = 0, script_len = 0, otf_len = 0;
+
+  if (key == Mlanguage)
+    lang = MSYMBOL_NAME (val), lang_len = MSYMBOL_NAMELEN (val) + 6;
+  else if (key == Mscript)
+    script = MSYMBOL_NAME (val), script_len = MSYMBOL_NAMELEN (val) + 7;
+  else if (key == Motf)
+    otf = MSYMBOL_NAME (val), otf_len = MSYMBOL_NAMELEN (val) + 5;
+  else
+    return capability;
+
+  if (capability != Mnil)
+    {
+      cap = mfont__get_capability (capability);
+      if (! overwrite)
+       {
+         if (cap->language)
+           lang = NULL;
+         if (cap->script)
+           script = NULL;
+         if (cap->script_tag)
+           otf = NULL;
+         if (! lang && !script && !otf)
+           return capability;
+       }
+    }
+
+  if (! lang && cap && cap->language)
+    {
+      lang_len = MSYMBOL_NAMELEN (cap->language);
+      lang = MSYMBOL_NAME (cap->language);
+    }
+  if (! script && cap && cap->script != Mnil)
+    {
+      script_len = MSYMBOL_NAMELEN (cap->script);
+      script = MSYMBOL_NAME (cap->script);
+    }
+  if (! otf && cap && cap->script_tag)
+    {
+      int i;
+
+      otf_len = 4;                     /* for script_tag */
+      if (cap->langsys_tag)
+       otf_len += 5;           /* for "/XXXX */
+      for (i = 0; i < MFONT_OTT_MAX; i++)
+       if (cap->features[i].str)
+         otf_len += strlen (cap->features[i].str) + 1; /* for "[=+]..." */
+      otf = p = alloca (otf_len + 1);
+      OTF_tag_name (cap->script_tag, otf);
+      p += 4;
+      if (cap->langsys_tag)
+       {
+         *p++ = '/';
+         OTF_tag_name (cap->langsys_tag, p);
+         p += 4;
+       }
+      if (cap->features[MFONT_OTT_GSUB].str)
+       p += sprintf (p, "=%s", cap->features[MFONT_OTT_GSUB].str);
+      if (cap->features[MFONT_OTT_GPOS].str)
+       p += sprintf (p, "=%s", cap->features[MFONT_OTT_GSUB].str);
+    }
+  buf = p = alloca (lang_len + script_len + otf_len + 1);
+  if (lang_len)
+    p += sprintf (p, ":lang=%s", lang);
+  if (script_len)
+    p += sprintf (p, ":script=%s", script);
+  if (otf_len)
+    p += sprintf (p, ":otf=%s", otf);
+  return msymbol (buf);
+}
+
 \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;
@@ -816,11 +1077,26 @@ mfont__init ()
   Mregistry = msymbol ("registry");
   mfont__property_table[MFONT_REGISTRY].property = Mregistry;
 
+  Mspacing = msymbol ("spacing");
   Msize = msymbol ("size");
   Mresolution = msymbol ("resolution");
+  Mmax_advance = msymbol ("max-advance");
+  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");
+
+  Motf = msymbol ("otf");
+
   /* The first entry of each mfont__property_table must be Mnil so
      that actual properties get positive numeric numbers.  */
   for (i = 0; i <= MFONT_REGISTRY; i++)
@@ -840,57 +1116,68 @@ 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;
+           }
        }
     }
 
   /* 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
   if (mfont__ft_init () < 0)
     return -1;
 #endif /* HAVE_FREETYPE */
-  if (mfont__flt_init () < 0)
-    return -1;
 
   return 0;
 }
@@ -901,7 +1188,6 @@ mfont__fini ()
   MPlist *plist;
   int i;
 
-  mfont__flt_fini ();
 #ifdef HAVE_FREETYPE
   mfont__ft_fini ();
 #endif /* HAVE_FREETYPE */
@@ -924,63 +1210,76 @@ mfont__fini ()
       M17N_OBJECT_UNREF (font_encoding_list);
       font_encoding_list = NULL;
     }
+
   for (i = 0; i <= MFONT_REGISTRY; i++)
     MLIST_FREE1 (&mfont__property_table[i], names);
 }
 
-void
-mfont__free_realized (MRealizedFont *rfont)
-{
-  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 + 9 + 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 (font->spacing)
+    p += sprintf (p, "-%X", font->spacing);
+  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)
+    {
+      MRealizedFont *rfont;
+
+      if (font->type != MFONT_TYPE_REALIZED)
+       return (font->capability == Mnil);
+      rfont = (MRealizedFont *) font;
+      return (rfont->driver->check_capability
+             && (rfont->driver->check_capability (rfont, spec->capability)
+                 >= 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])
@@ -988,6 +1287,49 @@ 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->spacing)
+    dst->spacing = src->spacing;
+  else if (error_on_conflict
+          && src->spacing
+          && dst->spacing != src->spacing)
+    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)
@@ -996,10 +1338,14 @@ 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->multiple_sizes = 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;
 }
 
 
@@ -1009,6 +1355,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);
@@ -1019,182 +1366,274 @@ 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)
+
+MFont *
+mfont__select (MFrame *frame, MFont *font, int max_size)
+{
+  MFontDriver *driver;
+
+  if (font->type == MFONT_TYPE_FAILURE)
+    return NULL;
+  if (font->type != MFONT_TYPE_SPEC)
+    return font;
+  if (font->source == MFONT_SOURCE_UNDECIDED)
+    {
+      if (font->file != Mnil || font->capability != Mnil)
+       font->source = MFONT_SOURCE_FT;
+      else if (font->property[MFONT_REGISTRY])
+       {
+         MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
+         char *reg = MSYMBOL_NAME (registry);
+
+         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 (font->source != MFONT_SOURCE_FT)
+    {
+      driver = mplist_get (frame->font_driver_list, Mx);
+      if (driver)
+       return (driver->select) (frame, font, max_size);
+    }
+  driver = mplist_get (frame->font_driver_list, Mfreetype);
+  if (! driver)
+    return NULL;
+  return (driver->select) (frame, font, max_size);
+}
+
+
+int
+mfont__available (MFrame *frame, MFont *font)
+{
+  return -1;
+}
+
+static int
+compare_font_score (const void *e1, const void *e2)
+{
+  MFontScore *s1 = (MFontScore *) e1, *s2 = (MFontScore *) e2;
+
+  return (s1->font->for_full_width == s2->font->for_full_width
+         ? s1->score > s2->score
+         : s1->font->for_full_width);
+}
+
+void
+mdebug_dump_font_list (MFontList *font_list)
 {
-  MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
-  MPlist *plist;
-  MRealizedFont *best;
   int i;
-  int mdebug_mask = MDEBUG_FONT;
 
-  if (registry == Mnil)
-    registry = Mt;
+  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;
+
+  for (; rfont; rfont = next)
+    {
+      next = rfont->next;
+      M17N_OBJECT_UNREF (rfont->info);
+      free (rfont);
+      rfont = next;
+    }
+}
 
-  MPLIST_DO (plist, frame->realized_font_list)
+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
     {
-      best = MPLIST_VAL (plist);
-      if (MPLIST_KEY (plist) == registry
-         && ! memcmp (&best->spec, spec, sizeof (MFont))
-         && ! memcmp (&best->request, request, sizeof (MFont)))
+      pl = mplist ();
+      num = 0;
+      MPLIST_DO (p, frame->font_driver_list)
        {
-         if (best->layouter != layouter)
+         if (spec->source == MFONT_SOURCE_X ? MPLIST_KEY (p) == Mx
+             : spec->source == MFONT_SOURCE_FT ? MPLIST_KEY (p) == Mfreetype
+             : 1)
            {
-             MRealizedFont *copy;
-
-             MSTRUCT_MALLOC (copy, MERROR_FONT);
-             *copy = *best;
-             copy->layouter = layouter;
-             mplist_add (frame->realized_font_list, registry, copy);
-             if (copy->info)
-               M17N_OBJECT_REF (copy->info);
-             best = copy;
+             MFontDriver *driver = MPLIST_VAL (p);
+             num += (driver->list) (frame, pl, spec, 0);
            }
-         return best;
        }
+      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;
 
-  MDEBUG_PUSH_TIME ();
-  best = NULL;
-  MPLIST_DO (plist, frame->font_driver_list)
+  MSTRUCT_MALLOC (list, MERROR_FONT);
+  MTABLE_MALLOC (list->fonts, num, MERROR_FONT);
+  for (i = 0; num > 0; num--, pl = MPLIST_NEXT (pl))
     {
-      MFontDriver *driver = MPLIST_VAL (plist);
-      MRealizedFont *this
-       = (driver->select) (frame, spec, request, limited_size);
+      MFont *font = MPLIST_VAL (pl), *adjusted = font;
 
-      if (this)
+      if (max_size == 0
+         || font->size == 0
+         || font->size < max_size)
        {
-         this->driver = driver;
-         if (! best
-             || this->score < best->score)
+         list->fonts[i].font = font;
+         if (spec == request)
+           list->fonts[i].score = 0;
+         else
            {
-             if (best)
-               mfont__free_realized (best);
-             best = this;
-             if (this->score == 0)
-               break;
+             int resize_ratio;
+             MFont resized;
+
+             if (font->size > 0
+                 && (resize_ratio = mfont_resize_ratio (font)) != 100)
+               {
+                 resized = *font;
+                 resized.size = font->size * 100 / resize_ratio;
+                 adjusted = &resized;
+               }
+             list->fonts[i].score = font_score (adjusted, request);
            }
-         else
-           mfont__free_realized (this);
+         i++;
        }
     }
-
-  if (mdebug__flag & mdebug_mask)
+  if (i == 0)
     {
-      char buf1[256], buf2[256];
-      MFont font = *spec;
+      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;
+}
 
-      for (i = 0; i < MFONT_PROPERTY_MAX; i++)
-       if (! font.property[i])
-         font.property[i] = request->property[i];
-      gen_font_name (buf2, &font);
+/** Open a font specified in FONT.  */
 
-      if (best)
-       MDEBUG_PRINT_TIME ("FONT", 
-                          (stderr, " to select <%s> (%x)from <%s>.",
-                           gen_font_name (buf1, &best->font),
-                           best->score,
-                           buf2));
-      else
-       MDEBUG_PRINT_TIME ("FONT", (stderr, " to fail to find <%s>.", buf2));
-      MDEBUG_POP_TIME ();
+MRealizedFont *
+mfont__open (MFrame *frame, MFont *font, MFont *spec)
+{
+  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 (! best)
-    return NULL;
-  best->layouter = layouter;
-  mplist_add (frame->realized_font_list, registry, best);
-  return best;
+  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);
 }
 
-
-/** Open a font specified in RFONT.  Return 0 if successfully
-    opened, otherwise return -1.  */
-
 int
-mfont__open (MRealizedFont *rfont)
+mfont__has_char (MFrame *frame, MFont *font, MFont *spec, int c)
 {
-  return (rfont->driver->open) (rfont);
-}
+  MFontEncoding *encoding;
+  unsigned code;
+  MFontDriver *driver;
 
-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 ();
-  if (! MPLIST_TAIL_P (font_resize_list))
-    while (1)
-      {
-       plist = font_resize_list;
-       while (registry ? (plist = mplist_find_by_key (plist, registry))
-              : plist)
-         {
-           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;
-               return;
-             }
-           plist = MPLIST_NEXT (plist);
-         }
-       if (registry == Mt)
-         break;
-       registry = Mt;
-      }
-}
-
-/* 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)
-{
-  MFontEncoding *encoding;
-
-  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 (font->source == MFONT_SOURCE_X && 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
@@ -1203,19 +1642,99 @@ mfont__get_metric (MGlyphString *gstring, int from, int to)
   MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
   MRealizedFont *rfont = from_g->rface->rfont;
 
-  for (g = from_g; g != to_g; g++)
-    if (g->rface->rfont != rfont)
+  for (g = from_g; ; g++)
+    if (g == to_g || g->rface->rfont != rfont)
       {
        int idx = GLYPH_INDEX (g);
 
        (rfont->driver->find_metric) (rfont, gstring, from, idx);
-       from_g = g;
+       while (from_g < g)
+         {
+           from_g->g.xadv >>= 6;
+           from_g->g.yadv >>= 6;
+           from_g->g.xoff >>= 6;
+           from_g->g.yoff >>= 6;
+           from_g->g.ascent >>= 6;
+           from_g->g.descent >>= 6;
+           from_g->g.lbearing >>= 6;
+           from_g->g.rbearing >>= 6;
+           from_g++;
+         }
+       if (g == to_g)
+         break;
        rfont = g->rface->rfont;
        from = idx;
       }
-  (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
 }
 
+int
+mfont__get_glyph_id (MFLTFont *font, MFLTGlyphString *gstring,
+                    int from, int to)
+{
+  MFont *mfont = (MFont *) ((MFLTFontForRealized *) font)->rfont;
+  MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
+  MFontEncoding *encoding;
+  MFontDriver *driver = NULL;
+  MGlyph *glyphs = (MGlyph *) gstring->glyphs;
+  int result = 0;
+
+  encoding = mfont->encoding ? mfont->encoding : find_encoding (mfont);
+  for (; from < to; from++)
+    {
+      MGlyph *g = glyphs + from;
+
+      if (g->g.encoded)
+       continue;
+      if (mfont->source == MFONT_SOURCE_X && encoding->repertory_charset)
+       g->g.code = ENCODE_CHAR (encoding->repertory_charset, g->g.c);
+      else
+       {
+         unsigned code;
+
+         if (encoding->encoding_charset)
+           code = ENCODE_CHAR (encoding->encoding_charset, g->g.c);
+         else
+           code = g->g.code;
+
+         if (code != MCHAR_INVALID_CODE)
+           {
+             if (! driver)
+               {
+                 if (mfont->type == MFONT_TYPE_REALIZED)
+                   driver = rfont->driver;
+                 else
+                   {
+                     driver = mplist_get (rfont->frame->font_driver_list,
+                                          mfont->source == MFONT_SOURCE_X
+                                          ? Mx : Mfreetype);
+                     if (! driver)
+                       MFATAL (MERROR_FONT);
+                   }
+               }
+             g->g.code = (driver->encode_char) (rfont->frame, rfont->font,
+                                                mfont, code);
+           }
+       }
+      g->g.encoded = 1;
+      if (g->g.code == MCHAR_INVALID_CODE)
+       result = -1;
+    }
+  return result;
+}
+
+int
+mfont__get_metrics (MFLTFont *font, MFLTGlyphString *gstring,
+                   int from, int to)
+{
+  MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
+  MGlyphString gstr;
+
+  gstr.glyphs = (MGlyph *) gstring->glyphs;
+  (rfont->driver->find_metric) (rfont, &gstr, from, to);
+  return 0;
+}
+
+/* KEY <= MFONT_REGISTRY */
 
 void
 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
@@ -1237,32 +1756,183 @@ mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
   font->property[key] = numeric;
 }
 
-void
-mfont__set_spec (MFont *font, MSymbol *attrs,
-                unsigned short 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;
-}
-
 int
-mfont__parse_name_into_font (char *name, MSymbol format, MFont *font)
+mfont__parse_name_into_font (const 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))
+  if (format == Mfontconfig || (result < 0 && format == Mnil))
     result = mfont__ft_parse_name (name, font);
-#endif
+#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;
+  
+  if (cap->script_tag)
+    {
+      int i;
+      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);
+       }
+    }
+  free (cap);
+}
+
+MFontCapability *
+mfont__get_capability (MSymbol sym)
+{
+  MFontCapability *cap = msymbol_get (sym, M_font_capability);
+  char *str, *p, *endp;
+
+  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;
+      if (str[0] == 'o' && strncmp (str + 1, "tf=", 3) == 0)
+       {
+         char *beg;
+         MSymbol sym;
+         int i;
+
+         str += 4;
+         beg = str;
+         for (i = 0, p = str; i < 4 && p < endp; i++, p++);
+         if (i < 4)
+           break;
+         sym = msymbol__with_len (str, 4);
+         cap->script = mscript__from_otf_tag (sym);
+         if (cap->script == Mnil)
+           break;
+         cap->script_tag = OTF_tag (str);
+         if (*p == '/')
+           {
+             for (i = 0, str = ++p; i < 4 && p < endp; i++, p++);
+             if (i < 4)
+               {
+                 cap->script = Mnil;
+                 cap->script_tag = 0;
+                 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;
+             }
+         cap->otf = msymbol__with_len (beg, p - beg);
+         str = p;
+       }
+      else if (str[0] == 'l' && strncmp (str + 1, "ang=", 4) == 0)
+       {
+         str += 5;
+         for (p = str; p < endp && *p != ':'; p++);
+         if (str < p)
+           cap->language = msymbol__with_len (str, p - str);
+         str = p;
+       }
+      else if (str[0] == 's' && strncmp (str + 1, "cript=", 6) == 0)
+       {
+         str += 7;
+         for (p = str; p < endp && *p != ':'; p++);
+         if (str < p)
+           cap->script = msymbol__with_len (str, p - str);
+         str = p;
+       }
+    }
+  return cap;
+}
+
+int
+mfont__check_capability (MRealizedFont *rfont, MSymbol capability)
+{
+  return (rfont->driver->check_capability (rfont, capability));
+}
+
+
 /*** @} */
 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
 
@@ -1288,10 +1958,9 @@ mfont__parse_name_into_font (char *name, MSymbol format, MFont *font)
 /***ja
     @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
-    ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
-    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mfoundry ¤Ï <tt>"foundry"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Mfoundry;
 
@@ -1304,10 +1973,9 @@ MSymbol Mfoundry;
 /***ja
     @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
-    ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
-    ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Mfamily;
 
@@ -1321,11 +1989,9 @@ MSymbol Mfamily;
 /***ja
     @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
-    ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
-    ¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
-    ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Mweight;
 
@@ -1339,11 +2005,9 @@ MSymbol Mweight;
 /***ja
     @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
-    ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
-    ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
-    ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Mstyle;
 
@@ -1357,11 +2021,9 @@ MSymbol Mstyle;
 /***ja
     @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
-    ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
-    Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý
-    ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Mstretch;
 
@@ -1375,15 +2037,29 @@ MSymbol Mstretch;
 /***ja
     @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
-    ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
-    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý
-    ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Madstyle;
 
 /***en
+    @brief Key of font property specifying spacing.
+
+    The variable #Madstyle is a symbol of name <tt>"spacing"</tt> and
+    is used as a key of font property.  The property value must be a
+    symbol whose name specifies the spacing of a font (e.g "p" for
+    proportional, "m" for monospaced).  */ 
+/***ja
+    @brief spacing ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
+    
+    ÊÑ¿ô #Mspacing ¤Ï <tt>"spacing"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
+    ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¤Î spacing
+    ÆÃÀ­¤ò¼¨¤¹Ì¾Á° ("p", "m" Åù)¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£  */
+
+MSymbol Mspacing;
+
+/***en
     @brief Key of font property specifying registry.
 
     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
@@ -1393,11 +2069,10 @@ MSymbol Madstyle;
 /***ja
     @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó
-    ¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©
-    ¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" Åù) ¤ò̾Á°¤È¤·
-    ¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" 
+    Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
 
 MSymbol Mregistry;
 
@@ -1411,15 +2086,38 @@ MSymbol Mregistry;
 /***ja
     @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©
-    ¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
-    100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó
-    ¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
+    ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
+    100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 
+    ¥Ý¥¤¥ó¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
     */
 
 MSymbol Msize;
 
 /***en
+    @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.  */ 
+MSymbol Motf;
+
+/***en
+    @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
@@ -1429,22 +2127,78 @@ MSymbol Msize;
 /***ja
     @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
     
-    ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü
-    ¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é
-    ¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ô
-    ÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
-    */
+    ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
+    Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£    */
 
 MSymbol Mresolution;
 
 /***en
-    @brief Symobl of name "fontconfig".
+    @brief Key of font property specifying max advance width.
+
+    The variable #Mmax_advance is a symbol of name
+    <tt>"max-advance"</tt> and is used as a key of font property.  The
+    property value must be an integer specifying a font's max advance
+    value by pixels.  */ 
+
+MSymbol Mmax_advance;
+
+
+/***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;
+
 /*=*/
 /*** @} */
 /*=*/
@@ -1470,20 +2224,18 @@ MSymbol Mfontconfig;
 /***ja
     @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;
 
@@ -1500,8 +2252,7 @@ MPlist *mfont_freetype_path;
 /***ja
     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
 
-    ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯
-    ¥È¤òºî¤ë¡£
+    ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
 
     @return
     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
@@ -1537,21 +2288,21 @@ mfont ()
 /***ja
     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
 
-    ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ
-    ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
+    ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ 
+    $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
 
     $FORMAT ¤Ï $NAME ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ØÄꤹ¤ë¡£$FORMAT ¤¬ #Mx ¤Ç¤¢¤ì¤Ð¡¢
     $NAME ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
-    $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­
-    ¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD ¤Ë
-    ½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
+    $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig 
+    ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD 
+    ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
 
     @return
-    ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î
-    ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
+    ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () 
+    ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
 
 MFont *
-mfont_parse_name (char *name, MSymbol format)
+mfont_parse_name (const char *name, MSymbol format)
 {
   MFont template, *font;
   
@@ -1581,18 +2332,18 @@ mfont_parse_name (char *name, MSymbol format)
     not freed unless the user explicitly does so by free ().  */
 
 /***ja
-    @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
+    @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë.
 
-    ´Ø¿ô mfont_unparse_name () ¤Ï $FORMAT ¤Ë¤·¤¿¤¬¤Ã¤¿¥Õ¥©¥ó¥È̾¤Îʸ»ú
-    Îó¤ò¥Õ¥©¥ó¥È$FONT ¤ò¸µ¤Ëºî¤ë¡£
+    ´Ø¿ô mfont_unparse_name () ¤Ï ¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤ò¥Õ¥©¥ó¥È $FONT 
+    ¤ò¸µ¤Ë$FORMAT ¤Ë½¾¤Ã¤Æºî¤ë¡£
 
-    $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£#Mx ¤Ê¤é¤Ð¥Õ¥©
-    ¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£#Mfontconfig ¤Ê
-    ¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤¦¡£
+    $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤¢¤ë¡£
+    #Mx ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£
+    #Mfontconfig ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤¦¡£
 
     @return 
-    ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢
-    ¥æ¡¼¥¶¤¬ free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
+    ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢¥æ¡¼¥¶¤¬
+    free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
 
 char *
 mfont_unparse_name (MFont *font, MSymbol format)
@@ -1600,11 +2351,12 @@ mfont_unparse_name (MFont *font, MSymbol format)
   char *name;
 
   if (format == Mx)
-    name = xlfd_unparse_name (font);
+    name = xlfd_unparse_name (font, 1);
 #ifdef HAVE_FONTCONFIG
   else if (format == Mfontconfig)
     name = mfont__ft_unparse_name (font);
-#endif
+
+#endif /* HAVE_FONTCONFIG */
   else
     MERROR (MERROR_FONT, NULL);
   return name;
@@ -1639,43 +2391,52 @@ mfont_copy (MFont *font)
     The mfont_get_prop () function gets the value of $KEY property of
     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 Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
+       @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mspacing.
 
-    @return
-    If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
-    Madstyle, or @c Mregistry, 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 $FONT is a return value of mfont_find (), $KEY can also be one
+    of the following symbols:
+
+       @b Mfont_ascent, @b Mfont_descent, #Mmax_advance.
+
+    @return 
+    If $KEY is @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle,
+    @c Mstretch, @c Madstyle, @c Mregistry, or @c Mspacing, 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, @c Mresolution, @b Mfont_ascent, Mfont_descent, or
+    #Mmax_advance, 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 ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
 
-    ´Ø¿ô 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 Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
+       @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mspacing.
 
     @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 ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
+    $KEY ¤¬ @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c
+    Mstretch, @c Madstyle, @c Mregistry, @c Mspacing ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢
+    ÁêÅö¤¹¤ëÃͤò¥·¥ó¥Ü¥ë¤È¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤
+    ¾ì¹ç¤Ë¤Ï@c Mnil ¤òÊÖ¤¹¡£$KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î
+    ¾ì¹ç¤Ë¤Ï¡¢ÁêÅö¤¹¤ëÃͤò¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£
+    ¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï 0 ¤òÊÖ¤¹¡£$KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c
+    NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
 
 void *
 mfont_get_prop (MFont *font, MSymbol key)
 {
+  MRealizedFont *rfont = NULL;
+
+  if (font->type == MFONT_TYPE_REALIZED)
+    rfont = (MRealizedFont *) font;
+
   if (key == Mfoundry)
     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
   if (key == Mfamily)
@@ -1692,7 +2453,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)
@@ -1700,7 +2461,35 @@ mfont_get_prop (MFont *font, MSymbol key)
       int resy = font->property[MFONT_RESY];
       return (void *) resy;
     }
+  if (key == Mlanguage || key == Mscript || key == Motf)
+    {
+      MFontCapability *cap;
+
+      if (! font->capability)
+       return NULL;
+      cap = mfont__get_capability (font->capability);
+      if (key == Mlanguage)
+       return cap->language;
+      if (key == Mscript)
+       return cap->script;
+      return cap->otf;
+    }
 
+  if (key == Mfontfile)
+    return (void *) font->file;
+  if (key == Mspacing)
+    return (font->spacing == MFONT_SPACING_UNDECIDED ? Mnil
+           : msymbol (font->spacing == MFONT_SPACING_PROPORTIONAL ? "p"
+                      : font->spacing == MFONT_SPACING_MONO ? "m" : "c"));
+  if (rfont)
+    {
+      if (key == Mfont_ascent)
+       return (void *) rfont->ascent;
+      if (key == Mfont_descent)
+       return (void *) rfont->descent;
+      if (key == Mmax_advance)
+       return (void *) rfont->max_advance;
+    }
   MERROR (MERROR_FONT, NULL);
 }
 
@@ -1713,23 +2502,26 @@ mfont_get_prop (MFont *font, MSymbol key)
     $KEY and value is $VAL to font $FONT.  $KEY must be one of the
     following symbols:
 
-       @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
+       @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
        @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
 
     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
-    Otherwise, $VAL must be a symbol.  */
-/***ja
+    Otherwise, $VAL must be a symbol of a property value name.  But,
+    if the name is "nil", a symbol of name "Nil" must be
+    specified.  */
+ /***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 Mfoundry, @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 ¤Ï¥×¥í¥Ñ¥Æ¥£ÃͤÎ̾Á°¤Î¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ
+    ¤Ï¤Ê¤é¤Ê¤¤¡£¤¿¤À¤·¤â¤·¤½¤Î̾Á°¤¬ "nil" ¤Î¾ì¹ç¤Ï¡¢Ì¾Á°¤¬ "Nil" ¤Î¥·
+    ¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
 
 int
 mfont_put_prop (MFont *font, MSymbol key, void *val)
@@ -1750,13 +2542,22 @@ mfont_put_prop (MFont *font, MSymbol key, void *val)
     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
   else if (key == Msize)
     {
-      unsigned size = (unsigned) val;
-      font->property[MFONT_SIZE] = size;
+      int size = (int) val;
+      font->size = size;
     }
   else if (key == Mresolution)
     {
       unsigned resy = (unsigned) val;
-      font->property[MFONT_RESY] =  resy;
+      font->property[MFONT_RESY] = resy;
+    }
+  else if (key == Mlanguage || key == Mscript || key == Motf)
+    {
+      font->capability = merge_capability (font->capability,
+                                          key, (MSymbol) val, 1);
+    }
+  else if (key == Mfontfile)
+    {
+      font->file = (MSymbol) val;
     }
   else
     MERROR (MERROR_FONT, -1);
@@ -1780,18 +2581,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 *
@@ -1842,8 +2642,8 @@ mfont_selection_priority ()
     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
 
     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
-    ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£³ÆÍ×ÁǤϰʲ¼¤Î¤¦¤Á¤Î¤É¤ì
-    ¤«¤Ç¤¢¤ê¡¢Á´¤Æ°Û¤Ê¤Ã¤Æ¤¤¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
+    ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£ÇÛÎó¤Ï°Ê²¼¤Î³ÆÍ×ÁǤòŬÀÚ
+    ¤Ê½çÈÖ¤Çʤ٤¿¤â¤Î¤Ç¤¢¤ë¡£
 
        @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
        @c Madstyle, @c Msize.
@@ -1855,7 +2655,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++)
     {
@@ -1886,6 +2686,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;
 }
 
@@ -1903,29 +2717,52 @@ 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;
+  MFont *best;
+  MFontList *list;
   MRealizedFont *rfont;
+  MFont adjusted;
 
+  if (spec->size < 0)
+    {
+      double pt = - spec->size;
+
+      adjusted = *spec;
+      adjusted.size = pt * frame->dpi / 72.27 + 0.5;
+      spec = &adjusted;
+    }
   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);
+  spec_copy = *best;
+  mfont__merge (&spec_copy, spec, 0);
+  rfont = mfont__open (frame, best, spec);
+  if (! rfont)
+    return NULL;
+  return (MFont *) rfont;
 }
 
 /*=*/
@@ -1950,20 +2787,16 @@ mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size)
 /***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
@@ -2033,16 +2866,315 @@ mfont_name (MFont *font)
     This function is obsolete.  Use mfont_parse_name () instead.  */
 
 /***ja
-    @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
+    @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë.
 
     ¤³¤ì¤Ï´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_parse_name () ¤ò»ÈÍѤΤ³¤È¡£  */
 
 MFont *
-mfont_from_name (char *name)
+mfont_from_name (const 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)
+{
+  MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
+  MFontResize *resize;
+  MPlist *plist;
+
+  if (! font_resize_list)
+    load_font_resize_table ();
+  if (! MPLIST_TAIL_P (font_resize_list))
+    while (1)
+      {
+       plist = font_resize_list;
+       while (registry ? (plist = mplist_find_by_key (plist, registry))
+              : plist)
+         {
+           resize = (MFontResize *) MPLIST_VAL (plist);
+           if (mfont__match_p (font, &resize->spec, MFONT_ADSTYLE))
+             return resize->resize;
+           plist = MPLIST_NEXT (plist);
+         }
+       if (registry == Mt)
+         break;
+       registry = Mt;
+      }
+  return 100;
+}
+
+/*=*/
+
+/***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.
+
+    $LANGUAGE argument exists just for backward compatibility, and the
+    use is deprecated.  Use #Mlanguage font property instead.  If
+    $FONT already has #Mlanguage property, $LANGUAGE is ignored.
+
+    @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 ¤è¤êÂ礭¤¤¾ì
+    ¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£
+
+    ¤¿¤À¤·¡¢°ú¿ô $LANGUAGE ¤ÏµìÈǤȤÎÀ°¹çÀ­¤Î¤¿¤á¤À¤±¤Ë¤¢¤ê¡¢¤½¤Î»ÈÍѤÏ
+    ´«¤á¤é¤ì¤Ê¤¤¡£¥Õ¥©¥ó¥È¤Î #Mlanguage ¥×¥í¥Ñ¥Æ¥£¤ò»È¤¦¤Ù¤­¤Ç¤¢¤ë¡£¤â
+    ¤· $FONT ¤¬¤¹¤Ç¤Ë¤³¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ã¤Æ¤¤¤¿¤é¡¢°ú¿ô $LANGUAGE ¤Ï̵
+
+
+    @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 spec;
+  
+  if (font)
+    spec = *font;
+  else
+    MFONT_INIT (&spec);
+
+  if (spec.size < 0)
+    {
+      double pt = - spec.size;
+
+      spec.size = pt * frame->dpi / 72.27 + 0.5;
+    }
+
+  if (language != Mnil)
+    spec.capability = merge_capability (spec.capability, Mlanguage, language,
+                                       0);
+
+  font_list = mfont__list (frame, &spec, &spec, 0);
+  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 Get a list of font famiy names.
+
+    The mfont_list_family_names () functions returns a list of font
+    family names available on frame $FRAME.
+
+    @return
+
+    This function returns a plist whose keys are #Msymbol and values
+    are symbols representing font family names.  The elements are
+    sorted by alphabetical order.  The plist must be freed by
+    m17n_object_unref ().  If not font is found, it returns NULL.  */
+
+MPlist *
+mfont_list_family_names (MFrame *frame)
+{
+  MPlist *plist = mplist (), *p;
+
+  MPLIST_DO (p, frame->font_driver_list)
+    {
+      MFontDriver *driver = MPLIST_VAL (p);
+
+      (driver->list_family_names) (frame, plist);
+    }
+  return plist;
+}
+
+
+/*=*/
+
+/***en
+    @brief Check the usability of a font.
+
+    The mfont_check () function checkes if $FONT can be used for
+    $SCRIPT and $LANGUAGE in $FONTSET on $FRAME.
+
+    @return 
+    If the font is usable, return 1.  Otherwise return 0.
+ */
+
+int
+mfont_check (MFrame *frame, MFontset *fontset,
+            MSymbol script, MSymbol language, MFont *font)
+{
+  MRealizedFont *rfont;
+  int best, score;
+
+  if (! fontset)
+    fontset = frame->face->property[MFACE_FONTSET];
+  rfont = mfontset__get_font (frame, fontset, script, language, font, &best);
+  if (! rfont || ! best)
+    return 0;
+  score = font_score (&rfont->spec, font);
+  return (score == 0 ? 2 : 1);
+}
+
+/*=*/
+
+/***en
+    @brief Check is a font matches with a font spec.
+
+    The mfont_match_p () function checks if $FONT matches with the
+    font-spec $SPEC.
+
+    @return 
+    If the font matches, 1 is returned.  Otherwise 0 is returned.  */
+
+int
+mfont_match_p (MFont *font, MFont *spec)
+{
+  return mfont__match_p (font, spec, MFONT_REGISTRY);
+}
+
+/*=*/
+/***en
+    @brief Open a font.
+
+    The mfont_open () function opens $FONT on $FRAME, and returns a
+    realized font.
+
+    @return
+    If the font was successfully opened, a realized font is returned.
+    Otherwize NULL is returned.
+
+    @seealso
+    mfont_close ().  */
+
+
+MFont *
+mfont_open (MFrame *frame, MFont *font)
+{
+  enum MFontType font_type = font->type;
+
+  if (font_type == MFONT_TYPE_SPEC)
+    return mfont_find (frame, font, NULL, 0);
+  if (font_type == MFONT_TYPE_OBJECT)
+    return (MFont *) mfont__open (frame, font, font);
+  if (font_type == MFONT_TYPE_REALIZED)
+    return font;
+  MERROR (MERROR_FONT, NULL);
+}
+
+/*=*/
+/***en
+    @brief Encapusulate a font.
+
+    The mfont_encapsulate () functions realizes a font by
+    encapusulating data $DATA or type $DATA_TYPE on $FRAME.  Currently
+    $DATA_TAPE is #Mfontconfig or #Mfreetype, and $DATA points to an
+    object of FcPattern or FT_Face respectively.
+
+    @return
+    If the operation was successful, a realized font is returned.
+    Otherwise NULL is return.
+
+    @seealso
+    mfont_close ().  */
+
+
+MFont *
+mfont_encapsulate (MFrame *frame, MSymbol data_type, void *data)
+{
+  MPlist *p;
+
+  MPLIST_DO (p, frame->font_driver_list)
+    {
+      MFontDriver *driver = MPLIST_VAL (p);
+      MRealizedFont *rfont;
+
+      if (driver->encapsulate
+         && (rfont = driver->encapsulate (frame, data_type, data)))
+       return (MFont *) rfont;
+    }
+
+  return NULL;
+}
+
+/*=*/
+/***en
+    @brief Close a font.
+
+    The mfont_close () function close a realized font $FONT.  $FONT
+    must be opened previously by mfont_open () or mfont_encapsulate
+    ().
+
+    @return
+    If the operation was successful, 0 is returned.  Otherwise, -1 is
+    returned.
+
+    @seealso
+    mfont_open (), mfont_encapsulate ().  */
+
+int
+mfont_close (MFont *font)
+{
+  enum MFontType font_type = font->type;
+  MRealizedFont *rfont;
+
+  if (font_type != MFONT_TYPE_REALIZED)
+    MERROR (MERROR_FONT, -1);
+  rfont = (MRealizedFont *) font;
+  if (rfont->encapsulating
+      && rfont->driver->close)
+    rfont->driver->close (rfont);
+  return 0;
+}
+
 /*** @} */
 
 /*** @addtogroup m17nDebug */
@@ -2060,8 +3192,8 @@ mfont_from_name (char *name)
 /***ja
     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
 
-    ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr ¤Ë¿Í´Ö¤Ë²ÄÆɤÊ
-    ·Á¤Ç°õºþ¤¹¤ë¡£
+    ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr 
+    ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£
 
     @return
     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
@@ -2071,12 +3203,26 @@ mdebug_dump_font (MFont *font)
 {
   char *name;
   
-  name = mfont_unparse_name (font, Mx);
+  name = xlfd_unparse_name (font, 0);
   if (name)
     {
       fprintf (stderr, "%s", name);
       free (name);
     }
+  if (font->file != Mnil)
+    {
+      char *file = MSYMBOL_NAME (font->file);
+      char *lastslash = file, *p;
+
+      for (p = file; *p; p++)
+       if (*p == '/')
+         lastslash = p;
+      if (name)
+       fprintf (stderr, ",");
+      fprintf (stderr, "%s", lastslash + 1);
+    }
+  if (font->capability != Mnil)
+    fprintf (stderr, "%s", MSYMBOL_NAME (font->capability));
   return font;
 }