X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Ffont.c;h=b01dcc064c68a0292f2d86f8b5ad58e4809b4da2;hb=08e7cd818a87fafc460cc35dc3e62524def3fc94;hp=eb8665fbec61c1ba724fea638ace30e0307f83c7;hpb=7ebe3307e5ffe8fa4f5a3151a861ba5ad9625dc7;p=m17n%2Fm17n-lib.git diff --git a/src/font.c b/src/font.c index eb8665f..b01dcc0 100644 --- a/src/font.c +++ b/src/font.c @@ -1,5 +1,5 @@ /* font.c -- font module. - Copyright (C) 2003, 2004 + Copyright (C) 2003, 2004, 2005, 2006 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 @@ -328,6 +328,7 @@ #include #include #include +#include #include "m17n-gui.h" #include "m17n-misc.h" @@ -336,6 +337,7 @@ #include "symbol.h" #include "plist.h" #include "charset.h" +#include "language.h" #include "internal-gui.h" #include "font.h" #include "face.h" @@ -663,55 +665,17 @@ OTF_tag (char *name) | (! p[2] ? 0 : (p[2] << 8) | p[3])))); } -#endif /* not HAVE_OTF */ -static MPlist *otf_script_list; - -static int -load_otf_script_list () +void +OTF_tag_name (OTF_Tag tag, char *name) { - 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; + 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'; } - -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); -} - +#endif /* not HAVE_OTF */ /* XLFD parser/generator */ @@ -745,6 +709,7 @@ xlfd_parse_name (const char *name, MFont *font) char copy[513]; int i; char *p; + MSymbol sym; if (name[0] != '-') return -1; @@ -794,9 +759,19 @@ xlfd_parse_name (const char *name, MFont *font) size = atoi (field[XLFD_PIXEL]) * 10; if (field[XLFD_FOUNDRY]) - mfont__set_property (font, MFONT_FOUNDRY, msymbol (field[XLFD_FOUNDRY])); + { + sym = msymbol (field[XLFD_FOUNDRY]); + if (! sym) + sym = msymbol ("Nil"); + mfont__set_property (font, MFONT_FOUNDRY, sym); + } if (field[XLFD_FAMILY]) - mfont__set_property (font, MFONT_FAMILY, msymbol (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]) @@ -821,14 +796,15 @@ xlfd_parse_name (const char *name, MFont *font) } 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; char spacing; - unsigned short size, resy; + int size, resy; + int all_nil = 1; prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry); prop[1] = (MSymbol) mfont_get_prop (font, Mfamily); @@ -843,6 +819,7 @@ xlfd_unparse_name (MFont *font) { str[i] = msymbol_name (prop[i]); len += strlen (str[i]); + all_nil = 0; } else { @@ -866,14 +843,55 @@ xlfd_unparse_name (MFont *font) resy = (int) mfont_get_prop (font, Mresolution); size = font->size; - if ((size % 10) < 5) - size /= 10; + 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 / 10 + 1; + 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-%c-*-%s", - str[0], str[1], str[2], str[3], str[4], str[5], - size, resy, resy, spacing, str[6]); return strdup (name); } @@ -894,7 +912,21 @@ font_score (MFont *font, MFont *request) { if (font->size && request->size) { - val = 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) @@ -937,6 +969,82 @@ font_score (MFont *font, MFont *request) 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); +} + /* Internal API */ @@ -972,8 +1080,6 @@ mfont__init () Mspacing = msymbol ("spacing"); Msize = msymbol ("size"); Mresolution = msymbol ("resolution"); - Mascent = msymbol ("ascent"); - Mdescent = msymbol ("descent"); Mmax_advance = msymbol ("max-advance"); Mfontfile = msymbol ("fontfile"); @@ -989,6 +1095,8 @@ mfont__init () 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++) @@ -1070,8 +1178,6 @@ mfont__init () if (mfont__ft_init () < 0) return -1; #endif /* HAVE_FREETYPE */ - if (mfont__flt_init () < 0) - return -1; return 0; } @@ -1082,7 +1188,6 @@ mfont__fini () MPlist *plist; int i; - mfont__flt_fini (); #ifdef HAVE_FREETYPE mfont__ft_fini (); #endif /* HAVE_FREETYPE */ @@ -1105,11 +1210,6 @@ 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); @@ -1166,8 +1266,17 @@ int mfont__match_p (MFont *font, MFont *spec, int prop) { if (spec->capability != font->capability - && spec->capability != Mnil && font->capability != Mnil) - return 0; + && 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; @@ -1231,6 +1340,7 @@ mfont__set_spec_from_face (MFont *spec, MFace *face) mfont__set_property (spec, i, face->property[i]); 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; @@ -1322,7 +1432,11 @@ mfont__available (MFrame *frame, MFont *font) static int compare_font_score (const void *e1, const void *e2) { - return (((MFontScore *) e1)->score > ((MFontScore *) e2)->score); + 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 @@ -1389,15 +1503,29 @@ mfont__list (MFrame *frame, MFont *spec, MFont *request, int max_size) MTABLE_MALLOC (list->fonts, num, MERROR_FONT); for (i = 0; num > 0; num--, pl = MPLIST_NEXT (pl)) { - MFont *font = MPLIST_VAL (pl); + MFont *font = MPLIST_VAL (pl), *adjusted = font; if (max_size == 0 || font->size == 0 || font->size < max_size) { list->fonts[i].font = font; - list->fonts[i].score - = spec == request ? 0 : font_score (font, request); + 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++; } } @@ -1447,37 +1575,6 @@ mfont__open (MFrame *frame, MFont *font, MFont *spec) return (driver->open) (frame, font, spec, rfont); } -void -mfont__resize (MFont *spec, MFont *request) -{ - MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY); - MFontResize *resize; - MPlist *plist; - - if (! font_resize_list) - load_font_resize_table (); - 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->size = request->size * resize->resize / 100; - return; - } - plist = MPLIST_NEXT (plist); - } - if (registry == Mt) - break; - registry = Mt; - } -} - - int mfont__has_char (MFrame *frame, MFont *font, MFont *spec, int c) { @@ -1522,7 +1619,7 @@ mfont__encode_char (MFrame *frame, MFont *font, MFont *spec, int c) encoding = (font->encoding ? font->encoding : find_encoding (font)); if (! encoding->encoding_charset) return MCHAR_INVALID_CODE; - if (encoding->repertory_charset) + 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) @@ -1545,19 +1642,91 @@ 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; + + encoding = mfont->encoding ? mfont->encoding : find_encoding (mfont); + for (; from < to; from++) + { + MGlyph *g = glyphs + from; + + if (g->g.encoded) + continue; + if (! encoding->encoding_charset) + g->g.code = MCHAR_INVALID_CODE; + else if (mfont->source == MFONT_SOURCE_X && encoding->repertory_charset) + g->g.code = ENCODE_CHAR (encoding->repertory_charset, g->g.c); + else + { + g->g.code = ENCODE_CHAR (encoding->encoding_charset, g->g.c); + if (g->g.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, + g->g.code); + } + } + g->g.encoded = 1; + } + return 0; +} + +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 */ @@ -1607,20 +1776,18 @@ static void free_font_capability (void *object) { MFontCapability *cap = object; - int i; - if (cap->lang) - free (cap->lang); -#ifdef HAVE_OTF - if (cap->script) - for (i = 0; i < MFONT_OTT_MAX; i++) - { - if (cap->features[i].str) - free (cap->features[i].str); - if (cap->features[i].tags) - free (cap->features[i].tags); - } -#endif /* HAVE_OTF */ + 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); } @@ -1629,7 +1796,6 @@ mfont__get_capability (MSymbol sym) { MFontCapability *cap = msymbol_get (sym, M_font_capability); char *str, *p, *endp; - int i; if (cap) return cap; @@ -1644,21 +1810,29 @@ mfont__get_capability (MSymbol sym) { if (*str++ != ':') continue; -#ifdef HAVE_OTF - if (str[0] == 'o' && str[1] == 't' && str[2] == 'f' && str[3] == '=') + 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); - 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; + cap->script_tag = 0; break; } cap->langsys_tag = OTF_tag (str); @@ -1723,40 +1897,18 @@ mfont__get_capability (MSymbol sym) cap->features[i].tags = malloc (sizeof (OTF_Tag)); cap->features[i].tags[0] = 0; } + cap->otf = msymbol__with_len (beg, p - beg); str = p; - continue; } -#endif /* HAVE_OTF */ - if (str[0] == 'l' && str[1] == 'a' && str[2] == 'n' && str[3] == 'g' - && str[4] == '=') + else if (str[0] == 'l' && strncmp (str + 1, "ang=", 4) == 0) { - 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; - } + for (p = str; p < endp && *p != ':'; p++); if (str < p) - cap->lang[count++] = msymbol__with_len (str, p - str); - cap->lang[count] = Mnil; + cap->language = msymbol__with_len (str, p - str); str = p; } - else if (str[0] == 's' && str[1] == 'c' && str[2] == 'r' && str[3] == 'i' - && str[4] == 'p' && str[5] == 't' && str[6] == '=') + else if (str[0] == 's' && strncmp (str + 1, "cript=", 6) == 0) { str += 7; for (p = str; p < endp && *p != ':'; p++); @@ -1768,6 +1920,13 @@ mfont__get_capability (MSymbol sym) return cap; } +int +mfont__check_capability (MRealizedFont *rfont, MSymbol capability) +{ + return (rfont->driver->check_capability (rfont, capability)); +} + + /*** @} */ #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ @@ -1935,6 +2094,14 @@ 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. */ +MSymbol Motf; + +/***en + @brief Key of font property specifying file name. + + 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 ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼. @@ -1961,24 +2128,6 @@ MSymbol Mfontfile; MSymbol Mresolution; /***en - @brief Key of font property specifying ascent. - - The variable #Mascent is a symbol of name "ascent" and is - used as a key of font property. The property value must be an - integer specifying a font ascent value by pixels. */ - -MSymbol Mascent; - -/***en - @brief Key of font property specifying descent. - - The variable #Mdescent is a symbol of name "descent" and - is used as a key of font property. The property value must be an - integer specifying a font's descent value by pixels. */ - -MSymbol Mdescent; - -/***en @brief Key of font property specifying max advance width. The variable #Mmax_advance is a symbol of name @@ -2196,7 +2345,7 @@ 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); @@ -2236,23 +2385,23 @@ 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 Mspacing. + @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, + @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mspacing. If $FONT is a return value of mfont_find (), $KEY can also be one of the following symbols: - @c Mascent, @c Mdescent, @c Mmax_advance. - - @return If $KEY is @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, @c Mascent, @c Mdescent, or @c 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. */ + #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 #merror_code. */ /***ja @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë. @@ -2261,16 +2410,16 @@ mfont_copy (MFont *font) $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$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, @c Mspacing. - @return $KEY ¤¬ @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 ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ + @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) @@ -2278,7 +2427,7 @@ mfont_get_prop (MFont *font, MSymbol key) MRealizedFont *rfont = NULL; if (font->type == MFONT_TYPE_REALIZED) - rfont = (MRealizedFont *) font, font = rfont->font; + rfont = (MRealizedFont *) font; if (key == Mfoundry) return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY); @@ -2304,6 +2453,20 @@ 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) @@ -2312,9 +2475,9 @@ mfont_get_prop (MFont *font, MSymbol key) : font->spacing == MFONT_SPACING_MONO ? "m" : "c")); if (rfont) { - if (key == Mascent) + if (key == Mfont_ascent) return (void *) rfont->ascent; - if (key == Mdescent) + if (key == Mfont_descent) return (void *) rfont->descent; if (key == Mmax_advance) return (void *) rfont->max_advance; @@ -2331,22 +2494,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. */ + 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) @@ -2367,7 +2534,7 @@ 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; + int size = (int) val; font->size = size; } else if (key == Mresolution) @@ -2375,6 +2542,11 @@ mfont_put_prop (MFont *font, MSymbol key, void *val) unsigned resy = (unsigned) val; 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; @@ -2552,7 +2724,16 @@ mfont_find (MFrame *frame, MFont *spec, int *score, int max_size) 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]; @@ -2568,7 +2749,9 @@ mfont_find (MFrame *frame, MFont *spec, int *score, int max_size) *score = list->fonts[0].score; free (list->fonts); free (list); - rfont = mfont__open (frame, best, best); + spec_copy = *best; + mfont__merge (&spec_copy, spec, 0); + rfont = mfont__open (frame, best, spec); if (! rfont) return NULL; return (MFont *) rfont; @@ -2707,10 +2890,29 @@ mfont_from_name (const char *name) int mfont_resize_ratio (MFont *font) { - MFont request = *font; + MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY); + MFontResize *resize; + MPlist *plist; - mfont__resize (font, &request); - return (font->size * 100 / request.size); + 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; } /*=*/ @@ -2724,6 +2926,10 @@ mfont_resize_ratio (MFont *font) 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 @@ -2733,15 +2939,21 @@ mfont_resize_ratio (MFont *font) /***ja @brief ¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÆÀ¤ë - ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£ - $FONT ¤¬ NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£ - $LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò¥µ¥Ý¡¼¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£ - $MAXNUM ¤Ï¡¢0 ¤è¤êÂ礭¤¤¾ì¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£ + ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤ò + ÊÖ¤¹¡£$FONT ¤¬ NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È + ¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£$LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò¥µ¥Ý¡¼ + ¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£$MAXNUM ¤Ï¡¢0 ¤è¤êÂ礭¤¤¾ì + ¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£ + + ¤¿¤À¤·¡¢°ú¿ô $LANGUAGE ¤ÏµìÈǤȤÎÀ°¹çÀ­¤Î¤¿¤á¤À¤±¤Ë¤¢¤ê¡¢¤½¤Î»ÈÍÑ¤Ï + ´«¤á¤é¤ì¤Ê¤¤¡£¥Õ¥©¥ó¥È¤Î #Mlanguage ¥×¥í¥Ñ¥Æ¥£¤ò»È¤¦¤Ù¤­¤Ç¤¢¤ë¡£¤â + ¤· $FONT ¤¬¤¹¤Ç¤Ë¤³¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ã¤Æ¤¤¤¿¤é¡¢°ú¿ô $LANGUAGE ¤Ï̵ + @return - ¤³¤Î´Ø¿ô¤Ï¥­¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Ê - plist ¤òÊÖ¤¹¡£plist ¤Ï m17n_object_unref () - ¤Ç²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤ÐNULL ¤òÊÖ¤¹¡£ */ + ¤³¤Î´Ø¿ô¤Ï¥­¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î + ¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Êplist ¤òÊÖ¤¹¡£plist ¤Ï m17n_object_unref () ¤Ç + ²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤ÐNULL ¤òÊÖ¤¹¡£ */ MPlist * mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum) @@ -2749,22 +2961,25 @@ mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum) MPlist *plist, *pl; MFontList *font_list; int i; - MFont *work = NULL; + MFont spec; - if (language != Mnil) + if (font) + spec = *font; + else + MFONT_INIT (&spec); + + if (spec.size < 0) { - /* ":lang=XXX" */ - char *buf = alloca (MSYMBOL_NAMELEN (language) + 7); + double pt = - spec.size; - sprintf (buf, ":lang=%s", MSYMBOL_NAME (language)); - if (! font) - font = work = mfont (); - font->capability = msymbol (buf); + spec.size = pt * frame->dpi / 72.27 + 0.5; } - font_list = mfont__list (frame, font, font, 0); - if (work) - free (work); + 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) @@ -2785,63 +3000,170 @@ mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum) 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 function mfont_check () checkes if $FONT can be used for - $SCRIPT and RLANGUAGE in $FONTSET on $FRAME. + 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, MFont *font, - MSymbol script, MSymbol language) +mfont_check (MFrame *frame, MFontset *fontset, + MSymbol script, MSymbol language, MFont *font) { - MFont spec; - MPlist *plist, *pl; - int result = 0; + 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); +} - plist = mfontset_lookup (fontset, script, Mt, Mnil); - if (script != Mnil) - { - if (language == Mnil) - { - if (! mplist_find_by_key (plist, Mt)) - /* No fallback fonts. */ - language = MPLIST_KEY (plist); - } - else if (! mplist_find_by_key (plist, language)) - { - /* Try fallback fonts. */ - if (mplist_find_by_key (plist, Mt)) - language = Mnil; - else - /* No fallback fonts. */ - language = MPLIST_KEY (plist); - } +/*=*/ - M17N_OBJECT_UNREF (plist); - plist = mfontset_lookup (fontset, script, language, Mnil); - } - MPLIST_DO (pl, plist) +/***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) { - spec = *(MFont *) MPLIST_VAL (pl); - if (mfont__merge (&spec, font, 1) >= 0 - && mfont__select (frame, &spec, 0)) - { - result = 1; - break; - } + MFontDriver *driver = MPLIST_VAL (p); + MRealizedFont *rfont; + + if (driver->encapsulate + && (rfont = driver->encapsulate (frame, data_type, data))) + return (MFont *) rfont; } - M17N_OBJECT_UNREF (plist); - return result; + + 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; } /*** @} */ @@ -2872,12 +3194,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; }