(Mdetail_text, minput_get_description, minput_get_commands)
[m17n/m17n-lib.git] / src / font.c
index 6d42b47..e4de266 100644 (file)
@@ -373,9 +373,9 @@ static char *common_weight[] =
     "light",
     "demilight",
     "book",
+    "regular",
     "normal",
     "medium",
-    "regular",
     "demibold",
     "bold",
     "extrabold",
@@ -384,7 +384,9 @@ static char *common_weight[] =
 static char *common_style[] =
   { "o",
     "i",
+    "slanted",
     "r",
+    "rslanted",
     "ri",
     "ro" };
 static char *common_stretch[] =
@@ -525,8 +527,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,45 +610,46 @@ 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;
+               }
+           }
+         return encoding;
+       }
+
+      if (registry && MPLIST_KEY (plist) != Mt)
+       {
+         plist = mplist_find_by_key (plist, registry);
+         if (! plist)
+           break;
+       }
+      else
+       plist = MPLIST_NEXT (plist);
+    }
   return &default_encoding;
 }
 
@@ -676,7 +680,7 @@ static int
 xlfd_parse_name (char *name, MFont *font)
 {
   char *field[XLFD_FIELD_MAX];
-  unsigned short size, resy;
+  unsigned short size, resy, avgwidth;
   MSymbol attrs[MFONT_PROPERTY_MAX];
   char copy[513];
   int i;
@@ -708,7 +712,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] == '[')
     {
@@ -821,6 +829,10 @@ mfont__init ()
 
   Mfontconfig = msymbol ("fontconfig");
 
+  Mx = msymbol ("x");
+  Mfreetype = msymbol ("freetype");
+  Mxft = msymbol ("xft");
+
   /* 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,8 +852,8 @@ 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);
        }
@@ -1246,6 +1258,14 @@ mfont__parse_name_into_font (char *name, MSymbol format, MFont *font)
   return result;
 }
 
+MPlist *
+mfont__encoding_list (void)
+{
+  if (! font_encoding_list)
+    load_font_encoding_table ();
+  return font_encoding_list;
+}
+
 /*** @} */
 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
 
@@ -1428,6 +1448,33 @@ MSymbol Mresolution;
 
 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 *).  */
+
+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.  */
+
+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 *).  */
+
+MSymbol Mxft;
+
 /*=*/
 /*** @} */
 /*=*/
@@ -2026,6 +2073,89 @@ mfont_from_name (char *name)
   return mfont_parse_name (name, Mx);
 }
 
+/*=*/
+
+/***en
+    @brief Get resize information of a font.
+
+    The mfont_resize_ratio () function lookups the m17n database
+    \<font, reisize\> and returns a resizing ratio (in percentage) of
+    FONT.  For instance, if the return value is 150, that means that
+    the m17n library uses an 1.5 time bigger font than a specified
+    size.  */
+
+/***ja
+    @brief ¥Õ¥©¥ó¥È¤Î¥ê¥µ¥¤¥º¾ðÊó¤òÆÀ¤ë
+
+    ´Ø¿ô mfont_resize_ratio ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹ \<font, reisize\> ¤ò¸¡
+    º÷¤·¡¢¥Õ¥©¥ó¥È FONT ¤Î¥ê¥µ¥¤¥º¤ÎÈæΨ¡Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¡Ë¤òÊÖ¤¹¡£¤¿¤È¤¨
+    ¤ÐÊÖÃͤ¬ 150 ¤Ç¤¢¤ì¤Ð¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ï»ØÄꤵ¤ì¤¿¥µ¥¤¥º¤Î 1.5 ÇܤÎ
+    ¥Õ¥©¥ó¥È¤ò»ÈÍѤ¹¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£ */
+
+int
+mfont_resize_ratio (MFont *font)
+{
+  MFont request = *font;
+
+  mfont__resize (font, &request);
+  return (font->property[MFONT_SIZE] * 100 / request.property[MFONT_SIZE]);
+}
+
+/*=*/
+
+/***en
+    @brief Get a list of fonts.
+
+    The mfont_list () functions returns a list of fonts available on
+    frame $FRAME.  $FONT, if not @c Mnil, limits fonts to ones
+    that match with $FONT.  $LANGUAGE, if not @c Mnil, limits fonts to
+    ones that support $LANGUAGE.  $MAXNUM, if greater than 0, limits
+    the number of fonts.
+
+    @return
+    This function returns a plist whose keys are family names and
+    values are pointers to the object MFont.  The plist must be freed
+    by m17n_object_unref ().  If no font is found, it returns
+    NULL.  */
+
+/***ja
+    @brief ¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÆÀ¤ë
+
+    ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È
+    ¤òÊÖ¤¹¡£ $FONT ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©
+    ¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£$LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò
+    ¥µ¥Ý¡¼¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£ $MAXNUM ¤Ï¡¢0 ¤è¤êÂç
+    ¤¤¾ì¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£
+
+    @return 
+    ¤³¤Î´Ø¿ô¤Ï¥­¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§
+    ¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Ê plist ¤òÊÖ¤¹¡£plist ¤Ï
+    m17n_object_unref () ¤Ç²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð
+    NULL ¤òÊÖ¤¹¡£  */
+
+MPlist *
+mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum)
+{
+  MPlist *plist = mplist (), *p;
+  int num = 0;
+  
+  MPLIST_DO (p, frame->font_driver_list)
+    {
+      MFontDriver *driver = MPLIST_VAL (p);
+
+      num += (driver->list) (frame, plist, font, language,
+                            maxnum > 0 ? maxnum - num : 0);
+      if (maxnum > 0 && num >= maxnum)
+       break;
+    }
+  if (MPLIST_TAIL_P (plist))
+    {
+      M17N_OBJECT_UNREF (plist);
+      plist = NULL;
+    }
+  return plist;
+}
+
 /*** @} */
 
 /*** @addtogroup m17nDebug */
@@ -2063,6 +2193,29 @@ mdebug_dump_font (MFont *font)
   return font;
 }
 
+void
+mdebug_dump_font_list (MFrame *frame, MSymbol family, MSymbol lang)
+{
+  MPlist *plist, *p;
+
+  if (family == Mnil)
+    plist = mfont_list (frame, NULL, lang, 0);
+  else
+    {
+      MFont font;
+
+      MFONT_INIT (&font);
+      mfont__set_property (&font, MFONT_FAMILY, family);
+      plist = mfont_list (frame, &font, lang, 0);
+    }
+  MPLIST_DO (p, plist)
+    {
+      mdebug_dump_font (MPLIST_VAL (p));
+      fprintf (stderr, "\n");
+    }
+  M17N_OBJECT_UNREF (plist);
+}
+
 /*** @} */
 
 /*