X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Ffont.c;h=6ab8c20670d83d1de5c9147f0f628b3610c645ab;hb=051688596a161b1da8f44a3b80ff2aa9a16cf83d;hp=fa395083150c7e42838a63cd3b394858fff6e04d;hpb=81b778b62f74aff7afc1a09312862c4a3a8e4a99;p=m17n%2Fm17n-lib.git diff --git a/src/font.c b/src/font.c index fa39508..6ab8c20 100644 --- a/src/font.c +++ b/src/font.c @@ -22,7 +22,7 @@ /***en @addtogroup m17nFont - @brief Font object + @brief Font object. The m17n GUI API represents a font by an object of the type @c MFont. A font can have @e font @e properties. Like other types @@ -30,12 +30,13 @@ 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 font property that belongs to font F and whose key is @c + Mxxx" may be shortened to "the xxx property of F". The value of a foundry property is a symbol representing font foundry information, e.g. adobe, misc, etc. @@ -62,7 +63,10 @@ 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 @@ -101,11 +105,15 @@ The m17n library, if configured to use the FreeType library, supports all fonts that can be handled by the FreeType library. - The variable #mfont_freetype_path is initialized properly accoding - to the configuration of the m17n librayr and the environment + The variable #mfont_freetype_path is initialized properly according + to the configuration of the m17n library and the environment variable @c M17NDIR. See the documentation of the variable for details. + If the m17n library is configured to use the fontconfig library, + in addition to #mfont_freetype_path, all fonts available via + fontconfig are supported. + The family name of a FreeType font corresponds to the family property. Style names of FreeType fonts correspond to the weight, style, and stretch properties as below. @@ -123,6 +131,8 @@ Narrow Bold Italic bold i condensed Black black r normal Black Italic black i normal + Oblique medium o normal + BoldOblique bold o normal @endverbatim Style names not listed in the above table are treated as @@ -165,43 +175,147 @@ /***ja @addtogroup m17nFont - @brief ¥Õ¥©¥ó¥È¤È¤Ï¡¢¸Ä¡¹¤Î¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È¤ËÂбþ¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë + @brief ¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È. - m17n-win API ¤Ë¤ª¤±¤ë @e ¥Õ¥©¥ó¥È ¤È¤Ï¡¢@c MFont ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È - ¤Ç¤¢¤ê¡¢¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à°Í¸¤Î @e ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È ¤È°ìÂаì¤ËÂÐ - ±þÉÕ¤±¤é¤ì¤ë¡£¥Õ¥©¥ó¥È¤Ï¸ÇÄê¸Ä¿ô¤Î @e ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¡£ - ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¥­¡¼¤ÈÃͤ«¤é¤Ê¤ë¡£¥­¡¼¤Ï¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ + m17n GUI API ¤Ï¥Õ¥©¥ó¥È¤ò @c MFont ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æɽ¸½¤¹¤ë¡£ + ¥Õ¥©¥ó¥È¤Ï @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 ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£ + + foundry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢adobe, misc + Åù¤Î¥Õ¥©¥ó¥È¤Î³«È¯¸µ¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ + + family ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢times, helvetica + Åù¤Î¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ + + weight ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, bold Åù¤ÎÂÀ¤µ¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ + + style ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, italic + Åù¤Î¥¹¥¿¥¤¥ë¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ + + stretch ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, semicondensed + Åù¤Îʸ»úÉý¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ + + adstyle ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢serif, sans-serif + Åù¤ÎÃê¾ÝŪ¤Ê¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ + + registry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢iso10646, iso8895-1 + Åù¤Î¥ì¥¸¥¹¥È¥ê¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ + + size ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤òɽ¤ï¤¹À°¿ôÃͤǤ¢¤ê¡¢ + ñ°Ì¤Ï1/10 ¥Ý¥¤¥ó¥È¤Ç¤¢¤ë¡£ + + resolution ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢ÁÛÄꤵ¤ì¤Æ¤¤¤ë¥Ç¥Ð¥¤¥¹¤Î²òÁüÅÙ¤òɽ¤ï¤¹ + À°¿ôÃͤǤ¢¤ê¡¢Ã±°Ì¤Ïdots per inch (dpi) ¤Ç¤¢¤ë¡£ + + type ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤ò»Ø¼¨¤·¡¢¸½ºß Mx ¤â¤·¤¯¤Ï + Mfreetype ¤Ç¤¢¤ë¡£ + + m17n ¥é¥¤¥Ö¥é¥ê¤Ï¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò£²¤Ä¤ÎÌÜŪ¤ÇÍѤ¤¤Æ¤¤¤ë¡£¥¢¥× + ¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¥Õ¥©¥ó¥È¤Î»ØÄê¤ò¼õ¤±¼è¤ëÌÜŪ¤È¡¢¥¢¥×¥ê¥±¡¼ + ¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤òÄ󼨤¹¤ëÌÜŪ¤Ç¤¢¤ë¡£¥¢¥×¥ê¥±¡¼ + ¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÂФ·¤ÆÄ󼨤ò¹Ô¤¦ºÝ¤Ë¤Ï¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù + ¤Æ¶ñÂÎŪ¤ÊÃͤò»ý¤Ä¡£ + + m17n ¥é¥¤¥Ö¥é¥ê¤Ï Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È¡¢FreeType¥Õ¥©¥ó¥È¡¢ + OpenType¥Õ¥©¥ó¥È¤Î£³¼ïÎà¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¡£ + + - Resolution ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢ÁÛÄꤵ¤ì¤Æ¤¤¤ë¥Ç¥Ð¥¤¥¹¤Î²òÁüÅÙ¤ò ɽ¤ï - ¤¹¡£Ã±°Ì¤Ï dots per inch (dpi) ¤Ç¤¢¤ë¡£ */ +*/ /*=*/ @@ -225,17 +339,20 @@ #include "internal-gui.h" #include "font.h" #include "face.h" +#include "fontset.h" + +MPlist *mfont__driver_list; -MFontDriver *mfont__driver_list[MFONT_TYPE_MAX]; +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 }; @@ -244,10 +361,10 @@ static int font_score_priority[] = /* Indexed by a font property MFONT_XXX, and the value is how many bits to shift the difference of property values. */ -static int font_score_shift_bits[MFONT_PROPERTY_MAX]; +static int font_score_shift_bits[MFONT_SIZE + 1]; /** Predefined symbols for each font property. The order is important - because the function score_font () decides how well a font matches + because the function font_score () decides how well a font matches with a spec by checking how close the index is. */ static char *common_foundry[] = @@ -259,32 +376,41 @@ static char *common_family[] = "helvetica", "times" }; static char *common_weight[] = - { "ultralight", + { "thin" + "ultralight", "extralight", "light", "demilight", "book", + "regular", "normal", "medium", - "regular", "demibold", + "semibold", "bold", "extrabold", "ultrabold", - "black" }; + "black", + "heavy" }; static char *common_style[] = { "o", "i", + "slanted", "r", + "rslanted", "ri", "ro" }; static char *common_stretch[] = - { "condensed", + { "ultracondensed", + "extracondensed", + "condensed", "narrow", "semicondensed", "normal", "semiexpanded", - "expanded" }; + "expanded", + "extraexpanded", + "ultraexpanded" }; static char *common_adstyle[] = { "serif", "", @@ -292,6 +418,10 @@ static char *common_adstyle[] = static char *common_registry[] = { "iso8859-1" }; +static unsigned short font_weight_regular; +static unsigned short font_weight_normal; +static unsigned short font_weight_medium; + /* Table containing all the data above. */ struct MFontCommonNames @@ -331,31 +461,6 @@ MFontPropertyTable mfont__property_table[MFONT_REGISTRY + 1]; msymbol_put((symbol), mfont__property_table[(n)].property, \ (void *) (numeric)) -static char * -gen_font_name (char *buf, MFont *font) -{ - char size[16]; - int i; - - buf[0] = '\0'; - for (i = 0; i <= MFONT_REGISTRY; i++) - if (FONT_PROPERTY (font, i) != Mnil) - { - char *name = msymbol_name (FONT_PROPERTY (font, i)); - - if (name[0]) - { - if (i > 0) - strcat (buf, ","); - strcat (buf, name); - } - } - sprintf (size, ",%d", font->property[MFONT_SIZE] / 10); - strcat (buf, size); - return buf; -} - - /* Font selector. */ @@ -416,8 +521,9 @@ load_font_encoding_table () encoding->repertory_name = MPLIST_SYMBOL (elt); if (registry == Mnil) - registry = Mt; - pl = mplist_add (pl, registry, encoding); + mplist_push (font_encoding_list, Mt, encoding); + else + pl = mplist_add (pl, registry, encoding); continue; warning: @@ -498,56 +604,397 @@ find_encoding (MFont *font) if (! font_encoding_list) load_font_encoding_table (); - if (! MPLIST_TAIL_P (font_encoding_list)) - while (1) - { - plist = font_encoding_list; - while (registry ? (plist = mplist_find_by_key (plist, registry)) - : plist) - { - encoding = (MFontEncoding *) MPLIST_VAL (plist); - if (mfont__match_p (font, &encoding->spec, MFONT_ADSTYLE)) - { - if (! encoding->encoding_charset) - encoding->encoding_charset - = MCHARSET (encoding->encoding_name); - if (! encoding->encoding_charset) - { - mplist_pop (plist); - continue; - } - if (encoding->repertory_name == encoding->encoding_name) - encoding->repertory_charset = encoding->encoding_charset; - else if (encoding->repertory_name != Mnil) - { - encoding->repertory_charset - = MCHARSET (encoding->repertory_name); - if (! encoding->repertory_charset) - { - mplist_pop (plist); - continue; - } - } - return encoding; - } - else - plist = MPLIST_NEXT (plist); - } - if (registry == Mnil || registry == Mt) - break; - registry = Mt; - } + plist = font_encoding_list; + while (! MPLIST_TAIL_P (plist)) + { + encoding = (MFontEncoding *) MPLIST_VAL (plist); + if (mfont__match_p (font, &encoding->spec, MFONT_REGISTRY)) + { + if (encoding->encoding_name != Mnil + && ! encoding->encoding_charset) + { + encoding->encoding_charset = MCHARSET (encoding->encoding_name); + if (! encoding->encoding_charset) + { + mplist_pop (plist); + continue; + } + } + if (encoding->repertory_name == encoding->encoding_name) + encoding->repertory_charset = encoding->encoding_charset; + else if (encoding->repertory_name != Mnil) + { + encoding->repertory_charset + = MCHARSET (encoding->repertory_name); + if (! encoding->repertory_charset) + { + mplist_pop (plist); + continue; + } + } + font->encoding = encoding; + return encoding; + } + + if (registry && MPLIST_KEY (plist) != Mt) + { + plist = mplist_find_by_key (plist, registry); + if (! plist) + break; + } + else + plist = MPLIST_NEXT (plist); + } + font->encoding = &default_encoding; return &default_encoding; } +#ifndef HAVE_OTF +static OTF_Tag +OTF_tag (char *name) +{ + unsigned char *p = (unsigned char *) name; + + if (! name) + return (OTF_Tag) 0; + return (OTF_Tag) ((p[0] << 24) + | (! p[1] ? 0 + : ((p[1] << 16) + | (! p[2] ? 0 + : (p[2] << 8) | p[3])))); +} +#endif /* not HAVE_OTF */ + +static MPlist *otf_script_list; + +static int +load_otf_script_list () +{ + MDatabase *mdb; + MPlist *plist, *pl; + + otf_script_list = mplist (); + mdb = mdatabase_find (msymbol ("standard"), Mscript, msymbol ("otf"), Mnil); + if (! mdb + || ! (plist = mdatabase_load (mdb))) + MERROR (MERROR_FONT, -1); + MPLIST_DO (pl, plist) + { + MPlist *p; + MSymbol script, otf_script; + OTF_Tag tag; + + if (! MPLIST_PLIST_P (pl)) + continue; + p = MPLIST_PLIST (pl); + if (! MPLIST_SYMBOL_P (p)) + continue; + script = MPLIST_SYMBOL (p); + p = MPLIST_NEXT (p); + if (! MPLIST_SYMBOL_P (p)) + continue; + otf_script = MPLIST_SYMBOL (p); + tag = OTF_tag (MSYMBOL_NAME (otf_script)); + mplist_push (otf_script_list, script, (void *) tag); + } + M17N_OBJECT_UNREF (plist); + return 0; +} + +static MSymbol +find_script_from_otf_tag (OTF_Tag tag) +{ + MPlist *plist; + + if (! otf_script_list) + load_otf_script_list (); + plist = mplist_find_by_value (otf_script_list, (void *) tag); + return (plist ? MPLIST_KEY (plist) : Mnil); +} + +/* XLFD parser/generator */ + +/** Indices to each field of split font name. */ + +enum xlfd_field_idx + { + XLFD_FOUNDRY, + XLFD_FAMILY, + XLFD_WEIGHT, + XLFD_SLANT, + XLFD_SWIDTH, + XLFD_ADSTYLE, + XLFD_PIXEL, + XLFD_POINT, + XLFD_RESX, + XLFD_RESY, + XLFD_SPACING, + XLFD_AVGWIDTH, + XLFD_REGISTRY, /* This contains ENCODING. */ + /* anchor */ + XLFD_FIELD_MAX + }; + +static int +xlfd_parse_name (const char *name, MFont *font) +{ + char *field[XLFD_FIELD_MAX]; + unsigned short resy, avgwidth; + unsigned size; + char copy[513]; + int i; + char *p; + MSymbol sym; + + if (name[0] != '-') + return -1; + + field[0] = copy; + for (i = 1, p = copy, name++; *name; p++, name++) + { + if (p - copy > 512) + return -1; + if (*name == '-' + && i < XLFD_FIELD_MAX) + { + *p = '\0'; + if (field[i - 1][0] == '*') + field[i - 1] = NULL; + field[i++] = p + 1; + } + else + *p = tolower (*name); + } + *p = '\0'; + if (field[i - 1][0] == '*') + field[i - 1] = NULL; + while (i < XLFD_FIELD_MAX) + field[i++] = NULL; + + resy = field[XLFD_RESY] ? atoi (field[XLFD_RESY]) : 0; + avgwidth = ((field[XLFD_AVGWIDTH] && isdigit (field[XLFD_AVGWIDTH][0])) + ? atoi (field[XLFD_AVGWIDTH]) : 1); + if (! avgwidth) + size = 0; + else if (! field[XLFD_PIXEL]) + size = field[XLFD_POINT] ? atoi (field[XLFD_POINT]) * resy / 72 : 0; + else if (field[XLFD_PIXEL][0] == '[') + { + /* The pixel size field specifies a transformation matrix of the + form "[A B C D]". The XLFD spec says that the scalar value N + for the pixel size is equivalent to D. */ + char *p0 = field[XLFD_PIXEL] + 1, *p1; + double d; + + for (i = 0; i < 4; i++, p0 = p1) + d = strtod (p0, &p1); + size = d * 10; + } + else + size = atoi (field[XLFD_PIXEL]) * 10; + + 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, int full_xlfd) +{ + MSymbol prop[7]; + char name[513]; + char *str[7]; + int len, i; + char spacing; + int size, resy; + + prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry); + prop[1] = (MSymbol) mfont_get_prop (font, Mfamily); + prop[2] = (MSymbol) mfont_get_prop (font, Mweight); + prop[3] = (MSymbol) mfont_get_prop (font, Mstyle); + prop[4] = (MSymbol) mfont_get_prop (font, Mstretch); + prop[5] = (MSymbol) mfont_get_prop (font, Madstyle); + prop[6] = (MSymbol) mfont_get_prop (font, Mregistry); + for (len = 0, i = 0; i < 7; i++) + { + if (prop[i] != Mnil) + { + str[i] = msymbol_name (prop[i]); + len += strlen (str[i]); + } + else + { + str[i] = "*"; + len++; + } + } + spacing = (font->spacing == MFONT_SPACING_UNDECIDED ? '*' + : font->spacing == MFONT_SPACING_PROPORTIONAL ? 'p' + : font->spacing == MFONT_SPACING_MONO ? 'm' + : 'c'); + + if ((len + + 13 /* 13 dashes */ + + 2 /* 2 asterisks */ + + 30 /* 3 integers (each 10 digits) */ + + 1 /* 1 spacing char */ + + 1) /* '\0' terminal */ + > 513) + return NULL; + + resy = (int) mfont_get_prop (font, Mresolution); + size = font->size; + if (size >= 0) + { + 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 + { + 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]); + } + + return strdup (name); +} + +/* Compare FONT with REQUEST and return how much they differs. */ + +static int +font_score (MFont *font, MFont *request) +{ + int score = 0; + int i = FONT_SCORE_PRIORITY_SIZE; + + while (--i >= 0) + { + enum MFontProperty prop = font_score_priority[i]; + int val; + + if (prop == MFONT_SIZE) + { + if (font->size && request->size) + { + val = font->size - request->size; + if (val) + { + if (val < 0) + val = - val; + if (val >= 0x10000) + val = 0xFFFF; + score |= (val << font_score_shift_bits[MFONT_SIZE]); + } + } + } + else if (font->property[prop] && request->property[prop] + && font->property[prop] != request->property[prop]) + { + if (prop <= MFONT_FAMILY) + val = 1; + else if (prop == MFONT_WEIGHT) + { + unsigned short v1 = font->property[prop]; + unsigned short v2 = request->property[prop]; + + if (v1 == font_weight_regular || v1 == font_weight_normal) + v1 = font_weight_medium; + if (v2 == font_weight_regular || v2 == font_weight_normal) + v2 = font_weight_medium; + val = v1 > v2 ? v1 - v2 : v2 - v1; + } + else + { + val = font->property[prop] - request->property[prop]; + if (val < 0) + val = - val; + if (val > 3) + val = 3; + } + score |= val << font_score_shift_bits[prop]; + } + } + if (request->file != Mnil && request->file != font->file) + score |= 40000000; + return score; +} /* 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; @@ -564,8 +1011,23 @@ 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"); /* The first entry of each mfont__property_table must be Mnil so that actual properties get positive numeric numbers. */ @@ -586,51 +1048,62 @@ mfont__init () if (sym == Mnil) return -1; - if (msymbol_put(sym, mfont__property_table[i].property, - (void *) (j + 1)) < 0) + if (msymbol_put (sym, mfont__property_table[i].property, + (void *) (j + 1)) < 0) return -1; - MLIST_APPEND1 (&mfont__property_table[i], names, sym, MERROR_FONT); + MLIST_APPEND1 (&mfont__property_table[i], names, sym, + MERROR_FONT); + if (i == MFONT_WEIGHT) + { + if (sym == regular) + font_weight_regular = j + 1; + else if (sym == normal) + font_weight_normal = j + 1; + else if (sym == medium) + font_weight_medium = j + 1; + } } } - memset (mfont__driver_list, 0, sizeof mfont__driver_list); - /* Here, SHIFT starts from 1, not 0. This is because the lowest bit of a score is a flag for a scalable font (see the documentation - of mfont_score). */ + of font_score). */ i = FONT_SCORE_PRIORITY_SIZE - 1; for (shift = 1; i >= 0; i--) { font_score_shift_bits[font_score_priority[i]] = shift; if (font_score_priority[i] == MFONT_SIZE) shift += 16; + else if (font_score_priority[i] <= MFONT_FAMILY) + shift++; else shift += 2; } MFONT_INIT (&default_encoding.spec); - default_encoding.encoding_name = Mnil; - default_encoding.encoding_charset = NULL; + default_encoding.encoding_name = Municode_full; + default_encoding.encoding_charset = mcharset__unicode; default_encoding.repertory_name = Mnil; default_encoding.repertory_charset = NULL; { char *path, *buf; int bufsize; + USE_SAFE_ALLOCA; mfont_freetype_path = mplist (); bufsize = strlen (M17NDIR) + 7; - buf = alloca (bufsize); + SAFE_ALLOCA (buf, bufsize); sprintf (buf, "%s/fonts", M17NDIR); mplist_add (mfont_freetype_path, Mstring, strdup (buf)); path = getenv ("M17NDIR"); if (path) { - i = strlen (path) + 7; - if (i > bufsize) - buf = alloca (i); + bufsize = strlen (path) + 7; + SAFE_ALLOCA (buf, bufsize); sprintf (buf, "%s/fonts", path); mplist_push (mfont_freetype_path, Mstring, strdup (buf)); } + SAFE_FREE (buf); } #ifdef HAVE_FREETYPE @@ -672,64 +1145,72 @@ mfont__fini () M17N_OBJECT_UNREF (font_encoding_list); font_encoding_list = NULL; } + if (otf_script_list) + { + M17N_OBJECT_UNREF (otf_script_list); + otf_script_list = NULL; + } + for (i = 0; i <= MFONT_REGISTRY; i++) MLIST_FREE1 (&mfont__property_table[i], names); } -void -mfont__free_realized (MRealizedFont *rfont) -{ - if (rfont->info) - M17N_OBJECT_UNREF (rfont->info); - free (rfont); -} - -/* Compare FONT with REQUEST and return how much they differs. If - FONT does not match with SPEC, return -1. */ - -int -mfont__score (MFont *font, MFont *spec, MFont *request, int limited_size) +MSymbol +mfont__id (MFont *font) { - int score = 0; - int i = FONT_SCORE_PRIORITY_SIZE; - - while (--i >= 0) + char *buf, *p; + int i; + int file_len = (font->file == Mnil ? 0 : MSYMBOL_NAMELEN (font->file)); + int capability_len = (font->capability == Mnil ? 0 + : MSYMBOL_NAMELEN (font->capability)); + int total_len = MFONT_PROPERTY_MAX * 5 + 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 && font->capability != Mnil) + return 0; + if (spec->file != font->file + && spec->file != Mnil && font->file != Mnil) + return 0; for (; prop >= 0; prop--) if (spec->property[prop] && font->property[prop] && font->property[prop] != spec->property[prop]) @@ -737,20 +1218,65 @@ 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. */ -void -mfont__set_spec_from_face (MFont *spec, MFace *face) +int +mfont__merge (MFont *dst, MFont *src, int error_on_conflict) { int i; - 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_RESY] = 0; - spec->property[MFONT_TYPE] = 0; -} + 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) +{ + int i; + + for (i = 0; i <= MFONT_ADSTYLE; i++) + mfont__set_property (spec, i, face->property[i]); + spec->property[MFONT_REGISTRY] = 0; + spec->property[MFONT_RESY] = 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; +} extern MSymbol @@ -759,6 +1285,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); @@ -769,209 +1296,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) -{ - MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY); - MPlist *realized_font_list; - MRealizedFont *best_font[MFONT_TYPE_MAX], *best; - int best_index; - int i; - int mdebug_mask = MDEBUG_FONT; - if (registry == Mnil) - registry = Mt; +MFont * +mfont__select (MFrame *frame, MFont *font, int max_size) +{ + MFontDriver *driver; - MPLIST_DO (realized_font_list, frame->realized_font_list) + if (font->type == MFONT_TYPE_FAILURE) + return NULL; + if (font->type != MFONT_TYPE_SPEC) + return font; + if (font->source == MFONT_SOURCE_UNDECIDED) { - best = MPLIST_VAL (realized_font_list); - if (MPLIST_KEY (realized_font_list) == registry - && ! memcmp (&best->spec, spec, sizeof (MFont)) - && ! memcmp (&best->request, request, sizeof (MFont))) + if (font->file != Mnil || font->capability != Mnil) + font->source = MFONT_SOURCE_FT; + else if (font->property[MFONT_REGISTRY]) { - if (best->layouter != layouter) - { - MRealizedFont *copy; - - MSTRUCT_MALLOC (copy, MERROR_FONT); - *copy = *best; - copy->layouter = layouter; - if (copy->info) - M17N_OBJECT_REF (copy->info); - mplist_add (frame->realized_font_list, registry, copy); - best = copy; - } - return best; - } - } + MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY); + char *reg = MSYMBOL_NAME (registry); - MDEBUG_PUSH_TIME (); - best = NULL; - best_index = -1; - for (i = 0; i < MFONT_TYPE_MAX; i++) - { - MFontDriver *driver = mfont__driver_list[i]; - - best_font[i] = (driver - ? (driver->select) (frame, spec, request, limited_size) - : NULL); - if (best_font[i] - && (best_index < 0 - || best_font[best_index]->score < best_font[i]->score)) - best_index = i; + 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; + } } - for (i = 0; i < MFONT_TYPE_MAX; i++) + if (font->source != MFONT_SOURCE_FT) { - if (i == best_index) - best = best_font[i]; - else if (best_font[i]) - free (best_font[i]); + 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); +} - if (mdebug__flag & mdebug_mask) - { - char buf1[256], buf2[256]; - MFont font = *spec; - - for (i = 0; i < MFONT_PROPERTY_MAX; i++) - if (! font.property[i]) - font.property[i] = request->property[i]; - gen_font_name (buf2, &font); - - if (best) - MDEBUG_PRINT_TIME ("FONT", - (stderr, " to select <%s> from <%s>.", - gen_font_name (buf1, &best->font), - buf2)); - else - MDEBUG_PRINT_TIME ("FONT", (stderr, " to fail to find <%s>.", buf2)); - MDEBUG_POP_TIME (); - } - if (! best) - return NULL; - best->layouter = layouter; - mplist_add (frame->realized_font_list, registry, best); - return best; +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; -/** Open a font specified in RFONT. Return 0 if successfully - opened, otherwise return -1. */ + return (s1->font->for_full_width == s2->font->for_full_width + ? s1->score > s2->score + : s1->font->for_full_width); +} -int -mfont__open (MRealizedFont *rfont) +void +mdebug_dump_font_list (MFontList *font_list) { - MPlist *realized_font_list; - MSymbol registry = FONT_PROPERTY (&rfont->font, MFONT_REGISTRY); + int i; + + 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"); + } +} - if (rfont->status) - mdebug_hook (); +void +mfont__free_realized (MRealizedFont *rfont) +{ + MRealizedFont *next; - MPLIST_DO (realized_font_list, rfont->frame->realized_font_list) + for (; rfont; rfont = next) { - MRealizedFont *this_rfont = MPLIST_VAL (realized_font_list); + next = rfont->next; + M17N_OBJECT_UNREF (rfont->info); + free (rfont); + rfont = next; + } +} - if (this_rfont->status != 0 - && MPLIST_KEY (realized_font_list) == registry - && ! memcmp (&this_rfont->font, &rfont->font, sizeof (MFont))) +MFontList * +mfont__list (MFrame *frame, MFont *spec, MFont *request, int max_size) +{ + MFontList *list; + MSymbol id = mfont__id (spec); + MPlist *pl, *p; + int num, i; + + pl = msymbol_get (id, M_font_list); + if (pl) + num = (int) msymbol_get (id, M_font_list_len); + else + { + pl = mplist (); + num = 0; + MPLIST_DO (p, frame->font_driver_list) { - if (rfont->info) - M17N_OBJECT_UNREF (rfont->info); - rfont->info = this_rfont->info; - M17N_OBJECT_REF (this_rfont->info); - rfont->status = this_rfont->status; - return (this_rfont->status > 0 ? 0 : -1); + if (spec->source == MFONT_SOURCE_X ? MPLIST_KEY (p) == Mx + : spec->source == MFONT_SOURCE_FT ? MPLIST_KEY (p) == Mfreetype + : 1) + { + MFontDriver *driver = MPLIST_VAL (p); + num += (driver->list) (frame, pl, spec, 0); + } } + msymbol_put (id, M_font_list, pl); + M17N_OBJECT_UNREF (pl); + msymbol_put (id, M_font_list_len, (void *) num); } + + if (num == 0) + return NULL; - return (rfont->driver->open) (rfont); -} + MSTRUCT_MALLOC (list, MERROR_FONT); + MTABLE_MALLOC (list->fonts, num, MERROR_FONT); + for (i = 0; num > 0; num--, pl = MPLIST_NEXT (pl)) + { + MFont *font = MPLIST_VAL (pl), *adjusted = font; -void -mfont__close (MRealizedFont *rfont) -{ - (rfont->driver->close) (rfont); + if (max_size == 0 + || font->size == 0 + || font->size < max_size) + { + list->fonts[i].font = font; + if (spec == request) + list->fonts[i].score = 0; + else + { + 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); + } + i++; + } + } + if (i == 0) + { + free (list->fonts); + free (list); + return NULL; + } + list->nfonts = i; + if (spec != request) + qsort (list->fonts, i, sizeof (MFontScore), compare_font_score); + list->object = *spec; + mfont__merge (&list->object, request, 0); + list->object.type = MFONT_TYPE_OBJECT; + return list; } -void -mfont__resize (MFont *spec, MFont *request) +/** Open a font specified in FONT. */ + +MRealizedFont * +mfont__open (MFrame *frame, MFont *font, MFont *spec) { - MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY); - MFontResize *resize; - MPlist *plist; + MFontDriver *driver; + MRealizedFont *rfont; - if (! font_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; - } -} + 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; + } -/* Return 1 if C is encodable, 0, if C is not encodable, -1 if it - can't be decided now. */ + 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); +} int -mfont__encodable_p (MRealizedFont *rfont, MSymbol layouter_name, int c) +mfont__has_char (MFrame *frame, MFont *font, MFont *spec, int c) { MFontEncoding *encoding; + unsigned code; + MFontDriver *driver; - if (layouter_name != Mnil) - return (mfont__flt_encode_char (layouter_name, c) - != MCHAR_INVALID_CODE); - if (! rfont->encoding) - rfont->encoding = find_encoding (&rfont->spec); - encoding = rfont->encoding; - if (! encoding->repertory_charset) - return -1; - return (ENCODE_CHAR (encoding->repertory_charset, c) != MCHAR_INVALID_CODE); + if (font->source == MFONT_SOURCE_UNDECIDED) + MFATAL (MERROR_FONT); + encoding = (font->encoding ? font->encoding : find_encoding (font)); + if (! encoding->encoding_charset) + return 0; + if (encoding->repertory_charset) + { + code = ENCODE_CHAR (encoding->repertory_charset, c); + return (code != MCHAR_INVALID_CODE); + } + code = ENCODE_CHAR (encoding->encoding_charset, c); + if (code == MCHAR_INVALID_CODE) + return 0; + if (font->type == MFONT_TYPE_REALIZED) + driver = ((MRealizedFont *) font)->driver; + else + { + driver = mplist_get (frame->font_driver_list, + font->source == MFONT_SOURCE_X ? Mx : Mfreetype); + if (! driver) + MFATAL (MERROR_FONT); + } + return (driver->has_char) (frame, font, spec, c, code); } unsigned -mfont__encode_char (MRealizedFont *rfont, int c) +mfont__encode_char (MFrame *frame, MFont *font, MFont *spec, int c) { MFontEncoding *encoding; unsigned code; + MFontDriver *driver; - if (rfont->layouter != Mnil) - return mfont__flt_encode_char (rfont->layouter, c); - if (! rfont->encoding) - rfont->encoding = find_encoding (&rfont->font); - encoding = rfont->encoding; + if (font->source == MFONT_SOURCE_UNDECIDED) + MFATAL (MERROR_FONT); + encoding = (font->encoding ? font->encoding : find_encoding (font)); if (! encoding->encoding_charset) return MCHAR_INVALID_CODE; + if (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 @@ -994,6 +1586,8 @@ mfont__get_metric (MGlyphString *gstring, int from, int to) } +/* KEY <= MFONT_REGISTRY */ + void mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val) { @@ -1014,18 +1608,198 @@ 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 +mfont__parse_name_into_font (const char *name, MSymbol format, MFont *font) { - int i; + int result = -1; + + if (format == Mx || format == Mnil) + result = xlfd_parse_name (name, font); +#ifdef HAVE_FONTCONFIG + if (format == Mfontconfig || (result < 0 && format == Mnil)) + result = mfont__ft_parse_name (name, font); +#endif /* HAVE_FONTCONFIG */ + return result; +} - for (i = 0; i <= MFONT_REGISTRY; i++) - mfont__set_property (font, i, attrs[i]); - font->property[MFONT_SIZE] = size; - font->property[MFONT_RESY] = resy; +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->lang) + free (cap->lang); + if (cap->script) + { + 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' && str[1] == 't' && str[2] == 'f' && str[3] == '=') + { + int i; + + str += 4; + for (i = 0, p = str; i < 4 && p < endp; i++, p++); + if (i < 4) + break; + cap->script_tag = OTF_tag (str); + cap->script = find_script_from_otf_tag (cap->script_tag); + if (*p == '/') + { + for (i = 0, str = ++p; i < 4 && p < endp; i++, p++); + if (i < 4) + { + cap->script = Mnil; + break; + } + cap->langsys_tag = OTF_tag (str); + } + else + cap->langsys_tag = 0; + + for (i = 0; i < MFONT_OTT_MAX; i++) + cap->features[i].nfeatures = -1; + + while (*p == '=' || *p == '+') + { + int idx = *p == '=' ? MFONT_OTT_GSUB : MFONT_OTT_GPOS; + + str = ++p; + while (p < endp && *p != '+') p++; + if (str < p) + { + int n; + /* We never have more than (p - str) tags. */ + OTF_Tag *tags = alloca (sizeof (OTF_Tag) * (p - str)); + char *p0; + + cap->features[idx].str = malloc (p - str + 1); + for (i = n = 0, p0 = str; str + i < p; i++) + { + cap->features[idx].str[i] = str[i]; + if (str[i] == ',' || str + i + 1 == p) + { + if (*p0 == '*') + tags[n] = 0; + else if (*p0 == '~') + tags[n] = OTF_tag (p0 + 1) | 0x80000000; + else + tags[n] = OTF_tag (p0); + n++; + p0 = str + i + 1; + } + } + cap->features[idx].str[i] = '\0'; + cap->features[idx].nfeatures = n; + if (n > 0) + { + int size = sizeof (OTF_Tag) * n; + + cap->features[idx].tags = malloc (size); + memcpy (cap->features[idx].tags, tags, size); + } + } + else + { + cap->features[idx].str = NULL; + cap->features[idx].nfeatures = 0; + } + } + + for (i = 0; i < MFONT_OTT_MAX; i++) + if (cap->features[i].nfeatures < 0) + { + cap->features[i].str = strdup ("*"); + cap->features[i].nfeatures = 1; + cap->features[i].tags = malloc (sizeof (OTF_Tag)); + cap->features[i].tags[0] = 0; + } + str = p; + } + else if (str[0] == 'l' && str[1] == 'a' && str[2] == 'n' && str[3] == 'g' + && str[4] == '=') + { + int count; + + str += 5; + for (p = str, count = 2; p < endp && *p != ':'; p++) + if (*p == ',') + count++; + MTABLE_MALLOC (cap->lang, count, MERROR_FONT); + for (p = str, count = 0; p < endp && *p != ':'; p++) + if (*p == ',') + { + MSymbol lang = msymbol__with_len (str, p - str), sym; + + if (msymbol_get (lang, Miso639_2)) + cap->lang[count++] = lang; + else if ((sym = msymbol_get (lang, Miso639_1)) != Mnil) + cap->lang[count++] = sym; + else if (msymbol_get (lang, Mlanguage)) + cap->lang[count++] = lang; + str = p + 1; + } + if (str < p) + cap->lang[count++] = msymbol__with_len (str, p - str); + cap->lang[count] = Mnil; + str = p; + } + else if (str[0] == 's' && str[1] == 'c' && str[2] == 'r' && str[3] == 'i' + && str[4] == 'p' && str[5] == 't' && str[6] == '=') + { + str += 7; + for (p = str; p < endp && *p != ':'; p++); + if (str < p) + cap->script = msymbol__with_len (str, p - str); + str = p; + } + } + return cap; } +int +mfont__check_capability (MRealizedFont *rfont, MSymbol capability) +{ + return (rfont->driver->check_capability (rfont, capability)); +} + + /*** @} */ #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ @@ -1048,25 +1822,27 @@ mfont__set_spec (MFont *font, MSymbol *attrs, The variable #Mfoundry is a symbol of name "foundry" and is used as a key of font property and face property. The property value must be a symbol whose name is a foundry name of a font. */ +/***ja + @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼. + + ÊÑ¿ô #Mfoundry ¤Ï "fonudry" + ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ + Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */ MSymbol Mfoundry; /***en - @brief Key of font property specifying foundry. + @brief Key of font property specifying family. The variable #Mfamily is a symbol of name "family" and is used as a key of font property and face property. The property value must be a symbol whose name is a family name of a font. */ - /***ja - @brief ¥Õ¥©¥ó¥È¤Î family ¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¤¿¤á¤Î¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë @c Mfamily ¤Ï "family" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥©¥ó - ¥È¤Î family ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë´Ø¿ô mfont_get_prop () ¤Î°ú - ¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£ - - ¤Þ¤¿¤³¤Î¥·¥ó¥Ü¥ë¤Ï¡¢¥Õ¥§¡¼¥¹Á´ÂΤˤª¤±¤ë¥Ç¥Õ¥©¥ë¥È¤Î family ¤ò»ØÄê - ¤¹¤ëºÝ¤Ë¡¢¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ¤â»È¤ï¤ì¤ë¡£ */ + @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼. + + ÊÑ¿ô #Mfamily ¤Ï "family" + ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ + Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */ MSymbol Mfamily; @@ -1077,16 +1853,12 @@ MSymbol Mfamily; used as a key of font property and face property. The property value must be a symbol whose name is a weight name of a font (e.g "medium", "bold"). */ - /***ja - @brief ¥Õ¥©¥ó¥È¤Î weight ¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¤¿¤á¤Î¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë @c Mweight ¤Ï "weight" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥©¥ó - ¥È¤Î weight ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë´Ø¿ô mfont_get_prop () ¤Î°ú - ¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£ - - ¤Þ¤¿¤³¤Î¥·¥ó¥Ü¥ë¤Ï¡¢¥Õ¥§¡¼¥¹Á´ÂΤˤª¤±¤ë¥Ç¥Õ¥©¥ë¥È¤Î weight ¤ò»ØÄê - ¤¹¤ëºÝ¤Ë¡¢¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ¤â»È¤ï¤ì¤ë¡£ */ + @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼. + + ÊÑ¿ô #Mweight ¤Ï "weight" + ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ + Ãͤϡ¢¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */ MSymbol Mweight; @@ -1097,16 +1869,12 @@ MSymbol Mweight; used as a key of font property and face property. The property value must be a symbol whose name is a style name of a font (e.g "r", "i", "o"). */ - /***ja - @brief ¥Õ¥©¥ó¥È¤Î style ¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¤¿¤á¤Î¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë @c Mstyle ¤Ï "style" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥©¥ó¥È - ¤Î style ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë´Ø¿ô mfont_get_prop () ¤Î°ú¿ô¤È - ¤·¤Æ»È¤ï¤ì¤ë¡£ - - ¤Þ¤¿¤³¤Î¥·¥ó¥Ü¥ë¤Ï¡¢¥Õ¥§¡¼¥¹Á´ÂΤˤª¤±¤ë¥Ç¥Õ¥©¥ë¥È¤Î style ¤ò»ØÄê - ¤¹¤ëºÝ¤Ë¡¢¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ¤â»È¤ï¤ì¤ë¡£ */ + @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼. + + ÊÑ¿ô #Mstyle ¤Ï "style" + ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ + Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */ MSymbol Mstyle; @@ -1117,16 +1885,12 @@ MSymbol Mstyle; is used as a key of font property and face property. The property value must be a symbol whose name is a stretch name of a font (e.g "normal", "condensed"). */ - /***ja - @brief ¥Õ¥©¥ó¥È¤Î stretch ¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¤¿¤á¤Î¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë @c Mstretch ¤Ï "stretch" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥© - ¥ó¥È¤Î stretch ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë´Ø¿ô mfont_get_prop () ¤Î - °ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£ - - ¤Þ¤¿¤³¤Î¥·¥ó¥Ü¥ë¤Ï¡¢¥Õ¥§¡¼¥¹Á´ÂΤˤª¤±¤ë¥Ç¥Õ¥©¥ë¥È¤Î stretch ¤ò»Ø - Äꤹ¤ëºÝ¤Ë¡¢¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ¤â»È¤ï¤ì¤ë¡£ */ + @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼. + + ÊÑ¿ô #Mstretch ¤Ï "stretch" + ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ + Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */ MSymbol Mstretch; @@ -1137,18 +1901,30 @@ MSymbol Mstretch; is used as a key of font property and face property. The property value must be a symbol whose name is an additional style name of a font (e.g "serif", "", "sans"). */ - /***ja - @brief ¥Õ¥©¥ó¥È¤Î adstyle ¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¤¿¤á¤Î¥·¥ó¥Ü¥ë + @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼. + + ÊÑ¿ô #Madstyle ¤Ï "adstyle" + ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ + Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle ̾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */ + +MSymbol Madstyle; - ¥·¥ó¥Ü¥ë @c Madstyle ¤Ï "adstyle" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥© - ¥ó¥È¤Î adstyle ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë´Ø¿ô mfont_get_prop () ¤Î - °ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£ +/***en + @brief Key of font property specifying spacing. - ¤Þ¤¿¤³¤Î¥·¥ó¥Ü¥ë¤Ï¡¢¥Õ¥§¡¼¥¹Á´ÂΤˤª¤±¤ë¥Ç¥Õ¥©¥ë¥È¤Î adstyle ¤ò»Ø - Äꤹ¤ëºÝ¤Ë¡¢¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ»È¤ï¤ì¤ë¡£ */ + The variable #Madstyle is a symbol of name "spacing" 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 ¤Ï "spacing" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ + ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¤Î spacing + ÆÃÀ­¤ò¼¨¤¹Ì¾Á° ("p", "m" Åù)¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */ -MSymbol Madstyle; +MSymbol Mspacing; /***en @brief Key of font property specifying registry. @@ -1157,13 +1933,13 @@ MSymbol Madstyle; and is used as a key of font property. The property value must be a symbol whose name is a registry name a font registry (e.g. "iso8859-1", "jisx0208.1983-0"). */ - /***ja - @brief ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ registry ¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë @c Mregistry ¤Ï "registry" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥© - ¥ó¥È¤Î registry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë¡¢´Ø¿ô mfont_get_prop () - ¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£ */ + @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼. + + ÊÑ¿ô #Mregistry ¤Ï "registry" + ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ + Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" + Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */ MSymbol Mregistry; @@ -1174,34 +1950,113 @@ MSymbol Mregistry; used as a key of font property and face property. The property value must be an integer specifying a font design size in the unit of 1/10 point (on 100 dpi display). */ - /***ja - @brief ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ size ¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë + @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼. + + ÊÑ¿ô #Msize ¤Ï "size" + ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢ + 100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 + ¥Ý¥¤¥ó¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£ + */ - ¥·¥ó¥Ü¥ë @c Msize ¤Ï "size" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥©¥ó¥È¤Î size ¥×¥í - ¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë´Ø¿ô mfont_get_prop () ¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£ +MSymbol Msize; - ¤Þ¤¿¤³¤Î¥·¥ó¥Ü¥ë¤Ï¡¢¥Õ¥§¡¼¥¹Á´ÂΤˤª¤±¤ë¥Ç¥Õ¥©¥ë¥È¤Î size ¤ò»ØÄꤹ - ¤ëºÝ¤Ë¡¢¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ»È¤ï¤ì¤ë¡£ */ +/***en + @brief Key of font property specifying file name. -MSymbol Msize; + The variable #Mfontfile is a symbol of name "fontfile" + 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 ¤Ï "fontfile" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢ + ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤ + ¥ë̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¤È¤¹¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */ + +MSymbol Mfontfile; /***en @brief Key of font property specifying resolution. - The variable #Mresolution is a symbol of name "size" and + The variable #Mresolution is a symbol of name "resolution" and is used as a key of font property and face property. The property value must be an integer to specifying a font resolution in the unit of dots per inch (dpi). */ +/***ja + @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼. + + ÊÑ¿ô #Mresolution ¤Ï "resolution" + ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ + Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) ñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£ */ + +MSymbol Mresolution; + +/***en + @brief Key of font property specifying max advance width. + + The variable #Mmax_advance is a symbol of name + "max-advance" 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 ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ resolution ¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë + @brief "fontconfig" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë. - ¥·¥ó¥Ü¥ë @c Mresolution ¤Ï "resolution" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢ - ¥Õ¥©¥ó¥È¤Î resolution ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë¡¢´Ø¿ô - mfont_get_prop () ¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£ */ + ÊÑ¿ô #Mfontconfig ¤Ï´Ø¿ô mfont_parse_name () ¤È mfont_unparse_name () + ¤Î°ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ */ -MSymbol Mresolution; +MSymbol Mfontconfig; + +/***en + @brief Symbol of name "x". + + The variable #Mx is to be used for a value of member of the + structure #MDrawGlyph to specify the type of member is + actually (XFontStruct *). */ +/***ja + @brief "x" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë. + + ÊÑ¿ô #Mx ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð + ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XFontStruct *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹. */ + +MSymbol Mx; + +/***en + @brief Symbol of name "freetype". + + The variable #Mfreetype is to be used for a value of member + of the structure #MDrawGlyph to specify the type of member + is actually FT_Face. */ +/***ja + @brief "freetype" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë. + + ÊÑ¿ô #Mfreetype ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð + ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï FT_Face ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£ */ + +MSymbol Mfreetype; + +/***en + @brief Symbol of name "xft". + + The variable #Mxft is to be used for a value of member of the + structure #MDrawGlyph to specify the type of member + is actually (XftFont *). */ +/***ja + @brief "xft" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë. + + ÊÑ¿ô #Mxft ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð + ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XftFont *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£ */ + +MSymbol Mxft; /*=*/ /*** @} */ @@ -1225,6 +2080,21 @@ MSymbol Mresolution; If the m17n library is not configured to use the FreeType library, this variable is not used. */ +/***ja + @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È. + + ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î + plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring + ¤Ç¤¢¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£ + + ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ¿ô + "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£ + mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£ + ¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢mframe () + ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ + ¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ + + m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */ MPlist *mfont_freetype_path; @@ -1238,7 +2108,13 @@ MPlist *mfont_freetype_path; @return This function returns a pointer to the created font object. */ +/***ja + @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë. + + ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£ + @return + ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ */ MFont * mfont () @@ -1252,38 +2128,46 @@ mfont () /*=*/ /***en - @brief Create a new font from fontname. + @brief Create a font by parsing a fontname. - The mfont_from_name () function creates a new font object. The + The mfont_parse_name () function creates a new font object. The properties are extracted fontname $NAME. - How to extract properties is window system dependent. The m17n-X - library parses $NAME as XLFD (X Logical Font Description). + $FORMAT specifies the format of $NAME. If $FORMAT is #Mx, $NAME + is parsed as XLFD (X Logical Font Description). If $FORMAT is + #Mfontconfig, $NAME is parsed as Fontconfig's textual + representation of font. If $FORMAT is #Mnil, $NAME is at first + parsed as XLFD, and it it fails, parsed as Fontconfig's + representation. @return If the operation was successful, this function returns a pointer to the created font. Otherwise it returns @c NULL. */ /***ja - @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë + @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë. - ´Ø¿ô mfont_from_name () ¤Ï¥Õ¥©¥ó¥È̾ $NAME ¤ò²òÀϤ·¡¢¿·¤·¤¤¥Õ¥©¥ó - ¥È¤òºî¤ë¡£ + ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ + $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£ - ¥Õ¥©¥ó¥È̾¤Îʸˡ¤Ï¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤Ë°Í¸¤¹¤ë¡£m17n-X ¥é¥¤¥Ö¥é¥ê - ¤Î¾ì¹ç¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£ + $FORMAT ¤Ï $NAME ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ØÄꤹ¤ë¡£$FORMAT ¤¬ #Mx ¤Ç¤¢¤ì¤Ð¡¢ + $NAME ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£ + $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig + ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD + ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£ @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_from_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î - ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$NAME ¤Î²òÀϤ˼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£ */ + ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () + ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */ MFont * -mfont_from_name (char *name) +mfont_parse_name (const char *name, MSymbol format) { MFont template, *font; - - if (mwin__parse_font_name (name, &template) < 0) - return NULL; + + MFONT_INIT (&template); + if (mfont__parse_name_into_font (name, format, &template) < 0) + MERROR (MERROR_FONT, NULL); MSTRUCT_CALLOC (font, MERROR_FONT); *font = template; return font; @@ -1292,40 +2176,70 @@ mfont_from_name (char *name) /*=*/ /***en - @brief Return a copy of a font. + @brief Create a fontname from a font. - The mfont_copy () function returns a new copy of $FONT. */ + The mfont_unparse_name () function creates a fontname string + from font $FONT according to $FORMAT. -MFont * -mfont_copy (MFont *font) + $FORMAT must be #Mx or #Mfontconfig. If it is #Mx, the fontname + is in XLFD (X Logical Font Description) format. If it is + #Mfontconfig, the fontname is in the style of Fontconfig's text + representation. + + @return + This function returns a newly allocated fontname string, which is + not freed unless the user explicitly does so by free (). */ + +/***ja + @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë. + + ´Ø¿ô mfont_unparse_name () ¤Ï ¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤ò¥Õ¥©¥ó¥È $FONT + ¤ò¸µ¤Ë$FORMAT ¤Ë½¾¤Ã¤Æºî¤ë¡£ + + $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤¢¤ë¡£ + #Mx ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£ + #Mfontconfig ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤¦¡£ + + @return + ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢¥æ¡¼¥¶¤¬ + free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£ */ + +char * +mfont_unparse_name (MFont *font, MSymbol format) { - MFont *copy; + char *name; - MSTRUCT_MALLOC (copy, MERROR_FONT); - *copy = *font; - return copy; + if (format == Mx) + name = xlfd_unparse_name (font, 1); +#ifdef HAVE_FONTCONFIG + else if (format == Mfontconfig) + name = mfont__ft_unparse_name (font); + +#endif /* HAVE_FONTCONFIG */ + else + MERROR (MERROR_FONT, NULL); + return name; } /*=*/ /***en - @brief Create a fontname from a font. - - The mfont_name () function creates a fontname string created from - $FONT. + @brief Make a copy of a font. - The syntax of fontname is window system dependent. The m17n-X - library returns a fontname conforming to XLFD (X Logical Font - Description). + The mfont_copy () function returns a new copy of font $FONT. */ +/***ja + @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë. - @return - This function returns the created fontname string, which is not freed - unless the user explicitly does so by free (). */ + ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */ -char * -mfont_name (MFont *font) +MFont * +mfont_copy (MFont *font) { - return mwin__build_font_name (font); + MFont *copy; + + MSTRUCT_MALLOC (copy, MERROR_FONT); + *copy = *font; + return copy; } /*=*/ @@ -1334,43 +2248,52 @@ mfont_name (MFont *font) @brief Get a property value of a font. The mfont_get_prop () function gets the value of $KEY property of - $FONT. $KEY must be one of the following symbols: + 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 $FONT is a return value of mfont_find (), $KEY can also be one + of the following symbols: - 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. + #Mfont_ascent, #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, #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 @c merror_code. */ - + code to the external variable #merror_code. */ + /***ja - @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£ÃͤòÆÀ¤ë + @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë. - ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ + ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì ¤Ð¤Ê¤é¤Ê¤¤¡£ - @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, - @c Madstyle, @c Mregistry, @c Msize, @c Mresolution. + @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, + @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mspacing. - @return - ¤â¤· $KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¡¢ - mfont_get_prop () ¤ÏÀ°¿ô¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¥¨¥é¡¼ - ¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨¥é¡¼ - ¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ + @return $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) @@ -1387,7 +2310,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) @@ -1395,7 +2318,21 @@ mfont_get_prop (MFont *font, MSymbol key) int resy = font->property[MFONT_RESY]; return (void *) resy; } - + 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); } @@ -1405,14 +2342,29 @@ mfont_get_prop (MFont *font, MSymbol key) @brief Put a property value to a font. The mfont_put_prop () function puts a font property whose key is - $KEY and value is $VAL to $FONT. $KEY must be one of the following - symbols: + $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 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 ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£ + + @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c Madstyle, @c Mregistry, @c Msize, @c Mresolution. - If $KEY is @c Msize of @c Mresolution, $VAL must be an integer. - Otherwise, $VAL must be a symbol. */ + $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ¤Ï + ¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥×¥í¥Ñ¥Æ¥£ÃͤÎ̾Á°¤Î¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ + ¤Ï¤Ê¤é¤Ê¤¤¡£¤¿¤À¤·¤â¤·¤½¤Î̾Á°¤¬ "nil" ¤Î¾ì¹ç¤Ï¡¢Ì¾Á°¤¬ "Nil" ¤Î¥· + ¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/ int mfont_put_prop (MFont *font, MSymbol key, void *val) @@ -1433,13 +2385,30 @@ 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) + { + char *langname = MSYMBOL_NAME ((MSymbol) val); + int len = MSYMBOL_NAMELEN ((MSymbol) val); + + if (len <= 3) + { + char buf[10]; + + sprintf (buf, ":lang=%s", langname); + font->capability = msymbol (buf); + } + } + else if (key == Mfontfile) + { + font->file = (MSymbol) val; } else MERROR (MERROR_FONT, -1); @@ -1462,6 +2431,19 @@ mfont_put_prop (MFont *font, MSymbol key, void *val) order of this array. A font that has a different value for a property of lower priority is preferred to a font that has a different value for a property of higher priority. */ +/***ja + @brief ¥Õ¥©¥ó¥ÈÁªÂò¤ÎÍ¥ÀèÅÙ¤òÊÖ¤¹. + + ´Ø¿ô mfont_selection_priority () ¤Ï 6 ¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã¤ÆÊÖ¤¹¡£ + ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤Ëʤ٤¿¤â¤Î¤Ç¤¢¤ë¡£ + + @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, + @c Madstyle, @c Msize. + + m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£ + ÌÜŪ¤Î¥Õ¥©¥ó¥È¤È¡¢¤½¤ì¤¾¤ì°ã¤¦¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Ê¤¤¥Õ¥©¥ó¥È¤¬¤¢¤Ã¤¿¾ì¹ç¡¢Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Ê¤¤¥Õ¥©¥ó¥È¡ÊÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Æ¤¤¤ë¥Õ¥©¥ó¥È¡Ë¤¬ÁªÂò¤µ¤ì¤ë¡£ + + */ MSymbol * mfont_selection_priority () @@ -1507,12 +2489,24 @@ mfont_selection_priority () See the documentation of the function mfont_selection_priority () for details. */ +/***ja + @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë. + + ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS + ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£ÇÛÎó¤Ï°Ê²¼¤Î³ÆÍ×ÁǤòŬÀÚ + ¤Ê½çÈÖ¤Çʤ٤¿¤â¤Î¤Ç¤¢¤ë¡£ + + @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, + @c Madstyle, @c Msize. + + ¾ÜºÙ¤Ï´Ø¿ô mfont_selection_priority () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£ + */ 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++) { @@ -1543,6 +2537,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; } @@ -1555,30 +2563,57 @@ mfont_set_selection_priority (MSymbol *keys) that matches best the specification $SPEC on frame $FRAME. $SCORE, if not NULL, must point to a place to store the score - value that indicates how well the found font matches to $SPEC. A + value that indicates how well the found font matches to $SPEC. The smaller score means a better match. */ - /***ja - @brief ¥Õ¥©¥ó¥È¤òõ¤¹ + @brief ¥Õ¥©¥ó¥È¤òõ¤¹. + + ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC + ¤Ë¤â¤Ã¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ - ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $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; } /*=*/ @@ -1586,12 +2621,12 @@ mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size) @brief Set encoding of a font. The mfont_set_encoding () function sets the encoding information - of $FONT. + of font $FONT. - If $ENCODING_NAME is be a symbol representing a charset that has - the same encoding as the font. + $ENCODING_NAME is a symbol representing a charset that has the + same encoding as the font. - If $REPERTORY_NAME @c Mnil or a symbol representing a charset that + $REPERTORY_NAME is @c Mnil or a symbol representing a charset that has the same repertory as the font. If it is @c Mnil, whether a specific character is supported by the font is asked to each font driver. @@ -1599,7 +2634,21 @@ mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size) @return If the operation was successful, this function returns 0. Otherwise it returns -1 and assigns an error code to the external - variable @c merror_code. */ + variable #merror_code. */ +/***ja + @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë. + + ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó¤òÀßÄꤹ¤ë¡£ + + $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ + + $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ + @c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ»ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢³Æ¡¹¤Î¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤ËÌ䤤¹ç¤ï¤»¤ë¡£ + + @return + ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô + #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ + int mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name) @@ -1643,6 +2692,196 @@ mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name) return 0; } +/*=*/ + +/***en + @brief Create a fontname from a font. + + This function is obsolete. Use mfont_unparse_name instead. */ +/***ja + @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë. + + ¤³¤Î´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_unparse_name () ¤ò»ÈÍѤΤ³¤È¡£ */ + +char * +mfont_name (MFont *font) +{ + return mfont_unparse_name (font, Mx); +} + +/*=*/ + +/***en + @brief Create a new font from fontname. + + This function is obsolete. Use mfont_parse_name () instead. */ + +/***ja + @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë. + + ¤³¤ì¤Ï´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_parse_name () ¤ò»ÈÍѤΤ³¤È¡£ */ + +MFont * +mfont_from_name (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 + \ 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 ¤Î¥ê¥µ¥¤¥º¤ÎÈæΨ¡Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¡Ë + ¤òÊÖ¤¹¡£¤¿¤È¤¨¤ÐÊÖ¤¹Ãͤ¬ 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. + + @return + This function returns a plist whose keys are family names and + values are pointers to the object MFont. The plist must be freed + by m17n_object_unref (). If no font is found, it returns + NULL. */ + +/***ja + @brief ¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÆÀ¤ë + + ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£ + $FONT ¤¬ NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£ + $LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò¥µ¥Ý¡¼¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£ + $MAXNUM ¤Ï¡¢0 ¤è¤êÂ礭¤¤¾ì¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£ + + @return + ¤³¤Î´Ø¿ô¤Ï¥­¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Ê + plist ¤òÊÖ¤¹¡£plist ¤Ï m17n_object_unref () + ¤Ç²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤ÐNULL ¤òÊÖ¤¹¡£ */ + +MPlist * +mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum) +{ + MPlist *plist, *pl; + MFontList *font_list; + int i; + MFont 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) + { + /* ":lang=XXX" */ + char *buf = alloca (MSYMBOL_NAMELEN (language) + 7); + + sprintf (buf, ":lang=%s", MSYMBOL_NAME (language)); + spec.capability = msymbol (buf); + } + + 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 Check the usability of a font. + + The function mfont_check () 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); +} + /*** @} */ /*** @addtogroup m17nDebug */ @@ -1650,21 +2889,47 @@ mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name) /*** @{ */ /***en - @brief Dump a font + @brief Dump a font. - The mdebug_dump_font () function prints $FONT in a human readable + The mdebug_dump_font () function prints font $FONT in a human readable way to the stderr. @return This function returns $FONT. */ +/***ja + @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë. + + ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr + ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ + + @return + ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£ */ MFont * mdebug_dump_font (MFont *font) { - char *name = mwin__build_font_name (font); - - fprintf (stderr, "%s", name); - free (name); + char *name; + + 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; }