From 7d9517d63092fffab25778304e05db4bb22cfc1b Mon Sep 17 00:00:00 2001 From: handa Date: Mon, 13 Sep 2004 02:09:08 +0000 Subject: [PATCH] (MFTtoProp): Member completely changed. (ft_to_prop): Adjusted for the above change. (ft_to_prop_size): Likewise. (set_font_info): Adjusted for the change of MFTtoProp. (fc_generic_family_list): New variable. (fc_list): Add special handling of generic font names. (mfont__ft_init): Adjusted for the change of MFTtoProp. Initialize fc_generic_family_list. (mfont__ft_fini): Don't free ft_to_prop. Free fc_generic_family_list. (FC_vs_M17N_font_prop): New type. (fc_weight_table, fc_slant_table, fc_width_table): New variables. (fc_decode_prop, fc_encode_prop): New functions. (mfont__ft_parse_name): Use fc_decode_prop. (mfont__ft_unparse_name): Use fc_encode_prop. --- src/font-ft.c | 243 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 151 insertions(+), 92 deletions(-) diff --git a/src/font-ft.c b/src/font-ft.c index 45fe673..2610839 100644 --- a/src/font-ft.c +++ b/src/font-ft.c @@ -57,12 +57,24 @@ static FT_Library ft_library; typedef struct { - MSymbol ft_style; - MSymbol weight, style, stretch; + char *ft_style; + int len; + enum MFontProperty prop; + char *val; } MFTtoProp; -static int ft_to_prop_size; -static MFTtoProp *ft_to_prop; +static MFTtoProp ft_to_prop[] = + { { "italic", 0, MFONT_STYLE, "i" }, + { "roman", 0, MFONT_STYLE, "r" }, + { "oblique", 0, MFONT_STYLE, "p" }, + { "regular", 0, MFONT_WEIGHT, "medium" }, + { "normal", 0, MFONT_WEIGHT, "medium" }, + /* We need this entry even if "bold" is in commone_weight[] to + handle such style names as "bolditalic" and "boldoblique". */ + { "bold", 0, MFONT_WEIGHT, "bold" }, + { "demi bold", 0, MFONT_WEIGHT, "demibold" }, + { "demi", 0, MFONT_WEIGHT, "demibold" } }; +static int ft_to_prop_size = sizeof ft_to_prop / sizeof ft_to_prop[0]; /** List of FreeType fonts. Keys are family names, values are plists contains fonts of the corresponding family. In the deeper plist, @@ -95,7 +107,6 @@ static MSymbol set_font_info (FT_Face ft_face, MFTInfo *ft_info, MSymbol family) { MFont *font = &ft_info->font; - MSymbol style; int len; char *buf, *p; MPlist *charmap_list; @@ -115,6 +126,10 @@ set_font_info (FT_Face ft_face, MFTInfo *ft_info, MSymbol family) family = msymbol (buf); } mfont__set_property (font, MFONT_FAMILY, family); + mfont__set_property (font, MFONT_WEIGHT, msymbol ("medium")); + mfont__set_property (font, MFONT_STYLE, msymbol ("r")); + mfont__set_property (font, MFONT_STRETCH, msymbol ("normal")); + mfont__set_property (font, MFONT_ADSTYLE, msymbol ("")); if (ft_face->style_name) { @@ -124,28 +139,37 @@ set_font_info (FT_Face ft_face, MFTInfo *ft_info, MSymbol family) for (p = buf; *p; p++) if (*p >= 'A' && *p <= 'Z') *p += 'a' - 'A'; - style = msymbol (buf); - for (i = 0; i < ft_to_prop_size; i++) - if (ft_to_prop[i].ft_style == style) - { - mfont__set_property (font, MFONT_WEIGHT, ft_to_prop[i].weight); - mfont__set_property (font, MFONT_STYLE, ft_to_prop[i].style); - mfont__set_property (font, MFONT_STRETCH, ft_to_prop[i].stretch); - break; - } - } - else - i = ft_to_prop_size; + p = buf; + while (*p && (*p < 'a' || *p > 'z')) p++; + while (*p) + { + for (i = 0; i < ft_to_prop_size; i++) + if (! strncmp (ft_to_prop[i].ft_style, p, ft_to_prop[i].len)) + { + mfont__set_property (font, ft_to_prop[i].prop, + msymbol (ft_to_prop[i].val)); + p += ft_to_prop[i].len; + break; + } + if (i == ft_to_prop_size) + { + char *p1 = p + 1; + MSymbol sym; - if (i == ft_to_prop_size) - { - mfont__set_property (font, MFONT_WEIGHT, msymbol ("medium")); - mfont__set_property (font, MFONT_STYLE, msymbol ("r")); - mfont__set_property (font, MFONT_STRETCH, msymbol ("normal")); + while (*p1 >= 'a' && *p1 <= 'z') p1++; + sym = msymbol__with_len (p, p1 - p); + for (i = MFONT_WEIGHT; i <= MFONT_STYLE; i++) + if (msymbol_get (sym, mfont__property_table[i].property)) + { + mfont__set_property (font, i, sym); + break; + } + p = p1; + } + while (*p && (*p < 'a' || *p > 'z')) p++; + } } - mfont__set_property (font, MFONT_ADSTYLE, msymbol ("")); - charmap_list = mplist (); mplist_add (charmap_list, Mt, (void *) -1); for (i = 0; i < ft_face->num_charmaps; i++) @@ -273,6 +297,8 @@ add_font_info (char *filename, MSymbol family) #ifdef HAVE_FONTCONFIG +static MPlist *fc_generic_family_list; + static void fc_list (MSymbol family) { @@ -302,17 +328,22 @@ fc_list (MSymbol family) (FcChar8 *) (msymbol_name (family))); os = FcObjectSetBuild (FC_FILE, NULL); fs = FcFontList (fc_config, pattern, os); - if (fs) + if (fs->nfont == 0 + && family != Mnil + && mplist_get (fc_generic_family_list, family) + && FcConfigSubstitute (fc_config, pattern, FcMatchPattern) == FcTrue) + { + FcFontSetDestroy (fs); + fs = FcFontList (fc_config, pattern, os); + } + for (i = 0; i < fs->nfont; i++) { char *filename; - for (i = 0; i < fs->nfont; i++) - { - FcPatternGetString (fs->fonts[i], FC_FILE, 0, (FcChar8 **) &filename); - add_font_info (filename, family); - } - FcFontSetDestroy (fs); + FcPatternGetString (fs->fonts[i], FC_FILE, 0, (FcChar8 **) &filename); + add_font_info (filename, family); } + FcFontSetDestroy (fs); FcObjectSetDestroy (os); FcPatternDestroy (pattern); } @@ -735,46 +766,29 @@ MFontDriver mfont__ft_driver = int mfont__ft_init () { - struct { - char *ft_style; - char *weight, *style, *stretch; - } ft_to_prop_name[] = - { { "regular", "medium", "r", "normal" }, - { "medium", "medium", "r", "normal" }, - { "normal", "medium", "r", "normal" }, - { "italic", "medium", "i", "normal" }, - { "bold", "bold", "r", "normal" }, - { "bolditalic", "bold", "i", "normal" }, - { "bold italic", "bold", "i", "normal" }, - { "narrow", "medium", "r", "condensed" }, - { "narrow italic", "medium", "i", "condensed" }, - { "narrow bold", "bold", "r", "condensed" }, - { "narrow bold italic", "bold", "i", "condensed" }, - { "black", "black", "r", "normal" }, - { "black italic", "black", "i", "normal" }, - { "oblique", "medium", "o", "normal" }, - { "boldoblique", "bold", "o", "normal" }, - { "bold oblique", "bold", "o", "normal" } }; int i; if (FT_Init_FreeType (&ft_library) != 0) MERROR (MERROR_FONT_FT, -1); - ft_to_prop_size = sizeof (ft_to_prop_name) / sizeof (ft_to_prop_name[0]); - MTABLE_MALLOC (ft_to_prop, ft_to_prop_size, MERROR_FONT_FT); for (i = 0; i < ft_to_prop_size; i++) - { - ft_to_prop[i].ft_style = msymbol (ft_to_prop_name[i].ft_style); - ft_to_prop[i].weight = msymbol (ft_to_prop_name[i].weight); - ft_to_prop[i].style = msymbol (ft_to_prop_name[i].style); - ft_to_prop[i].stretch = msymbol (ft_to_prop_name[i].stretch); - } + ft_to_prop[i].len = strlen (ft_to_prop[i].ft_style); Municode_bmp = msymbol ("unicode-bmp"); Municode_full = msymbol ("unicode-full"); Miso10646_1 = msymbol ("iso10646-1"); Miso8859_1 = msymbol ("iso8859-1"); +#ifdef HAVE_FONTCONFIG + fc_generic_family_list = mplist (); + mplist_push (fc_generic_family_list, msymbol ("serif"), Mt); + mplist_push (fc_generic_family_list, msymbol ("sans-serif"), Mt); + mplist_push (fc_generic_family_list, msymbol ("monospace"), Mt); + mplist_push (fc_generic_family_list, msymbol ("sans"), Mt); + mplist_push (fc_generic_family_list, msymbol ("sans serif"), Mt); + mplist_push (fc_generic_family_list, msymbol ("mono"), Mt); +#endif + return 0; } @@ -798,43 +812,92 @@ mfont__ft_fini () M17N_OBJECT_UNREF (ft_font_list); ft_font_list = NULL; } - free (ft_to_prop); FT_Done_FreeType (ft_library); all_fonts_scaned = 0; + +#ifdef HAVE_FONTCONFIG + m17n_object_unref (fc_generic_family_list); +#endif + } #ifdef HAVE_FONTCONFIG +typedef struct +{ + int fc_value; + char *m17n_value; +} FC_vs_M17N_font_prop; + +static FC_vs_M17N_font_prop fc_weight_table[] = + { { FC_WEIGHT_ULTRALIGHT, "extralight" }, + { FC_WEIGHT_LIGHT, "light" }, + { FC_WEIGHT_NORMAL, "normal" }, + { FC_WEIGHT_MEDIUM, "medium" }, + { FC_WEIGHT_DEMIBOLD, "demibold" }, + { FC_WEIGHT_EXTRABOLD, "extrabold" }, + { FC_WEIGHT_BLACK, "black" }, + { FC_WEIGHT_MEDIUM, NULL } }; + +static FC_vs_M17N_font_prop fc_slant_table[] = + { { FC_SLANT_ROMAN, "r" }, + { FC_SLANT_ITALIC, "i" }, + { FC_SLANT_OBLIQUE, "o" }, + { FC_SLANT_ROMAN, NULL } }; + +static FC_vs_M17N_font_prop fc_width_table[] = + { { FC_WIDTH_CONDENSED, "condensed" }, + { FC_WIDTH_SEMIEXPANDED, "semicondensed" }, + { FC_WIDTH_NORMAL, "normal" }, + { FC_WIDTH_SEMIEXPANDED, "semiexpanded" }, + { FC_WIDTH_EXPANDED, "expanded" }, + { FC_WIDTH_NORMAL, NULL } }; + + +static MSymbol +fc_decode_prop (int val, FC_vs_M17N_font_prop *table) +{ + int i; + + for (i = 0; table[i].m17n_value; i++) + if (val <= table[i].fc_value) + msymbol ("table[i].m17n_value"); + return msymbol ("table[i - 1].m17n_value"); +} + +static int +fc_encode_prop (char *name, FC_vs_M17N_font_prop *table) +{ + int i; + + for (i = 0; table[i].m17n_value && strcmp (name, table[i].m17n_value); i++); + return table[i].fc_value; +} + int mfont__ft_parse_name (char *name, MFont *font) { FcPattern *pat = FcNameParse ((FcChar8 *) name); - FcResult result; FcChar8 *str; + int val; double size; if (! pat) return -1; - if ((result = FcPatternGetString (pat, FC_FOUNDRY, 0, &str)) == FcResultMatch) + if (FcPatternGetString (pat, FC_FOUNDRY, 0, &str) == FcResultMatch) mfont__set_property (font, MFONT_FOUNDRY, msymbol ((char *) str)); - if ((result = FcPatternGetString (pat, FC_FAMILY, 0, &str)) == FcResultMatch) + if (FcPatternGetString (pat, FC_FAMILY, 0, &str) == FcResultMatch) mfont__set_property (font, MFONT_FAMILY, msymbol ((char *) str)); - if ((result = FcPatternGetString (pat, FC_STYLE, 0, &str)) == FcResultMatch) - { - MSymbol style = msymbol ((char *) str); - int i; - - for (i = 0; i < ft_to_prop_size; i++) - if (ft_to_prop[i].ft_style == style) - { - mfont__set_property (font, MFONT_WEIGHT, ft_to_prop[i].weight); - mfont__set_property (font, MFONT_STYLE, ft_to_prop[i].style); - mfont__set_property (font, MFONT_STRETCH, ft_to_prop[i].stretch); - break; - } - } - if ((result = FcPatternGetDouble (pat, FC_PIXEL_SIZE, 0, &size)) - == FcResultMatch) + if (FcPatternGetInteger (pat, FC_WEIGHT, 0, &val) == FcResultMatch) + mfont__set_property (font, MFONT_WEIGHT, + fc_decode_prop (val, fc_weight_table)); + if (FcPatternGetInteger (pat, FC_SLANT, 0, &val) == FcResultMatch) + mfont__set_property (font, MFONT_STYLE, + fc_decode_prop (val, fc_slant_table)); + if (FcPatternGetInteger (pat, FC_WIDTH, 0, &val) == FcResultMatch) + mfont__set_property (font, MFONT_STRETCH, + fc_decode_prop (val, fc_width_table)); + if (FcPatternGetDouble (pat, FC_PIXEL_SIZE, 0, &size) == FcResultMatch) font->property[MFONT_SIZE] = size * 10; FcPatternDestroy (pat); return 0; @@ -846,24 +909,20 @@ mfont__ft_unparse_name (MFont *font) FcPattern *pat = FcPatternCreate (); MSymbol sym, weight, style, stretch; char *name; - int i; if ((sym = (MSymbol) FONT_PROPERTY (font, MFONT_FOUNDRY)) != Mnil) FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) MSYMBOL_NAME (sym)); if ((sym = (MSymbol) FONT_PROPERTY (font, MFONT_FAMILY)) != Mnil) FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) MSYMBOL_NAME (sym)); - if ((weight = (MSymbol) FONT_PROPERTY (font, MFONT_WEIGHT)) == Mnil) - weight = msymbol ("medium"); - if ((style = (MSymbol) FONT_PROPERTY (font, MFONT_STYLE)) == Mnil) - style = msymbol ("r"); - if ((stretch = (MSymbol) FONT_PROPERTY (font, MFONT_STRETCH)) == Mnil) - stretch = msymbol ("normal"); - for (i = 0; i < ft_to_prop_size; i++) - if (ft_to_prop[i].weight == weight - && ft_to_prop[i].style == style - && ft_to_prop[i].stretch == stretch) - FcPatternAddString (pat, FC_STYLE, - (FcChar8 *) MSYMBOL_NAME (ft_to_prop[i].ft_style)); + if ((weight = (MSymbol) FONT_PROPERTY (font, MFONT_WEIGHT)) != Mnil) + FcPatternAddInteger (pat, FC_WEIGHT, fc_encode_prop (MSYMBOL_NAME (weight), + fc_weight_table)); + if ((style = (MSymbol) FONT_PROPERTY (font, MFONT_STYLE)) != Mnil) + FcPatternAddInteger (pat, FC_SLANT, fc_encode_prop (MSYMBOL_NAME (style), + fc_slant_table)); + if ((stretch = (MSymbol) FONT_PROPERTY (font, MFONT_STRETCH)) != Mnil) + FcPatternAddInteger (pat, FC_WIDTH, fc_encode_prop (MSYMBOL_NAME (stretch), + fc_width_table)); name = (char *) FcNameUnparse (pat); FcPatternDestroy (pat); return name; -- 1.7.10.4