diff -urNp fontconfig-2.3.2.orig/src/fccache.c fontconfig-2.3.2/src/fccache.c --- fontconfig-2.3.2.orig/src/fccache.c 2005-05-27 23:33:50.000000000 +0800 +++ fontconfig-2.3.2/src/fccache.c 2005-05-28 11:25:57.000000000 +0800 @@ -310,7 +310,7 @@ FcCacheFontSetAdd (FcFontSet *set, frozen = FcPatternFreeze (font); ret = (frozen != 0); if (ret) - ret = FcFontSetAdd (set, frozen); + ret = FcFontSetAddSort (set, frozen); } FcPatternDestroy (font); } diff -urNp fontconfig-2.3.2.orig/src/fccfg.c fontconfig-2.3.2/src/fccfg.c --- fontconfig-2.3.2.orig/src/fccfg.c 2005-05-27 23:33:50.000000000 +0800 +++ fontconfig-2.3.2/src/fccfg.c 2005-05-28 15:49:55.000000000 +0800 @@ -414,6 +414,42 @@ FcConfigGetCache (FcConfig *config) return config->cache; } +/* Add by Firefly(firefly@firefly.idv.tw) +*/ +static void +FcMakeFakeStyle(FcFontSet *s, + FcPattern *srcpat, + int weight, + int slant, + FcChar8 *style) +{ + FcMatrix matrix; + matrix.xx = 1; + matrix.xy = 0.3; + matrix.yx = 0; + matrix.yy = 1; + FcPattern *duppat = FcPatternDuplicate(srcpat); + if (duppat) + { + FcPatternDel(duppat, FC_WEIGHT); + FcPatternAddInteger(duppat, FC_WEIGHT, weight); + FcPatternDel(duppat, FC_SLANT); + FcPatternAddInteger(duppat, FC_SLANT, slant); + FcPatternDel(duppat, FC_STYLE); + FcPatternAddString(duppat, FC_STYLE, style); + if (slant > FC_SLANT_ROMAN) + { + FcPatternAddMatrix(duppat, FC_MATRIX, &matrix); + } + if (weight > FC_WEIGHT_MEDIUM) + { + FcPatternAddBool(duppat, FC_EMBOLDEN, FcTrue); + } + if (!FcFontSetAddSort(s, duppat)) + FcPatternDestroy(duppat); + } +} + FcFontSet * FcConfigGetFonts (FcConfig *config, FcSetName set) @@ -434,6 +470,107 @@ FcConfigSetFonts (FcConfig *config, { if (config->fonts[set]) FcFontSetDestroy (config->fonts[set]); + + /* Add by Firefly(firefly@firefly.idv.tw) */ + #define ST_ITALIC 0 + #define ST_BOLD 1 + #define ST_BOLD_ITALIC 2 + FcBool scalable; + FcPattern *pat; + FcChar8 *family; + int slant, weight; + int f; + + /* 在这里加fonts值的判断 */ + if (fonts == 0) { + config->fonts[set] = fonts; + return; + } + + for (f = 0; f < fonts->nfont; f++) + { + pat = fonts->fonts[f]; + if (FcPatternGetString(pat, FC_FAMILY, 0, &family) == FcResultMatch && + FcPatternGetInteger(pat, FC_SLANT, 0, &slant) == FcResultMatch && + FcPatternGetInteger(pat, FC_WEIGHT, 0, &weight) == FcResultMatch && + FcPatternGetBool(pat, FC_SCALABLE, 0, &scalable) == FcResultMatch && + slant == FC_SLANT_ROMAN && weight <= FC_WEIGHT_MEDIUM && scalable) + { + FcChar8 *cmpName; + FcBool styles[] = {FcFalse, FcFalse, FcFalse}; + int cmpweight, cmpslant; + int i = f + 1; + while (i < fonts->nfont && FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &cmpName) == FcResultMatch && strcmp(family, cmpName) == 0) + { + if (FcPatternGetInteger(fonts->fonts[i], FC_WEIGHT, 0, &cmpweight) != FcResultMatch) + cmpweight = 0; + if (FcPatternGetInteger(fonts->fonts[i], FC_SLANT, 0, &cmpslant) != FcResultMatch) + cmpslant = 0; + if (cmpweight <= FC_WEIGHT_MEDIUM && cmpslant >= FC_SLANT_ITALIC) + styles[ST_ITALIC] = FcTrue; + else if (cmpweight > FC_WEIGHT_MEDIUM && cmpslant < FC_SLANT_ITALIC) + styles[ST_BOLD] = FcTrue; + else if (cmpweight > FC_WEIGHT_MEDIUM && cmpslant >= FC_SLANT_ITALIC) + styles[ST_BOLD_ITALIC] = FcTrue; + i++; + } + + if (!styles[ST_BOLD_ITALIC]) + FcMakeFakeStyle(fonts, pat, FC_WEIGHT_BOLD, FC_SLANT_ITALIC, "Bold Italic"); + + if (!styles[ST_ITALIC]) + FcMakeFakeStyle(fonts, pat, weight, FC_SLANT_ITALIC, "Italic"); + + if (!styles[ST_BOLD]) + FcMakeFakeStyle(fonts, pat, FC_WEIGHT_BOLD, slant, "Bold"); + } + } + + FcChar8 *lang = getenv("LANG"); + if (!lang) lang = "en_US"; + FcBool isenglishenv = (strncasecmp(lang, "en", 2) == 0) ? FcTrue : FcFalse; + + if (config->familyOutput == FC_FAMILYOUTPUT_ENGLISHONLY || + (config->familyOutput == FC_FAMILYOUTPUT_AUTO && isenglishenv)) + { + config->fonts[set] = fonts; + return; + } + + FcChar8 *origName, *otherName; + FcPattern *dupPattern; + int totFonts = fonts->nfont; + for (f=0 ; f < totFonts ; f++) + { + if (FcPatternGetString(fonts->fonts[f], FC_FAMILY, 0, &origName) != FcResultMatch) + origName = 0; + if (FcPatternGetString(fonts->fonts[f], FC_FAMILY, 1, &otherName) != FcResultMatch) + otherName = 0; + if (config->familyOutput == FC_FAMILYOUTPUT_AUTO && origName && otherName) + { + dupPattern = FcPatternDuplicate(fonts->fonts[f]); + if (dupPattern) + { + FcPatternDel(dupPattern, FC_FAMILY); + FcPatternAddString(dupPattern, FC_FAMILY, otherName); + FcPatternAddString(dupPattern, FC_FAMILY, origName); + FcPatternDestroy(fonts->fonts[f]); + fonts->fonts[f] = dupPattern; + } + } + if (config->familyOutput == FC_FAMILYOUTPUT_ANY && otherName) + { + dupPattern = FcPatternDuplicate(fonts->fonts[f]); + if (dupPattern) + { + FcPatternDel(dupPattern, FC_FAMILY); + FcPatternAddString(dupPattern, FC_FAMILY, otherName); + if (!FcFontSetAdd(fonts, dupPattern)) + FcPatternDestroy(dupPattern); + } + } + } + config->fonts[set] = fonts; } diff -urNp fontconfig-2.3.2.orig/src/fcdir.c fontconfig-2.3.2/src/fcdir.c --- fontconfig-2.3.2.orig/src/fcdir.c 2005-05-27 23:33:50.000000000 +0800 +++ fontconfig-2.3.2/src/fcdir.c 2005-05-28 11:28:10.000000000 +0800 @@ -143,7 +143,7 @@ FcFileScanConfig (FcFontSet *set, */ if (font && (!config || FcConfigAcceptFont (config, font))) { - if (!FcFontSetAdd (set, font)) + if (!FcFontSetAddSort (set, font)) { FcPatternDestroy (font); font = 0; diff -urNp fontconfig-2.3.2.orig/src/fcfs.c fontconfig-2.3.2/src/fcfs.c --- fontconfig-2.3.2.orig/src/fcfs.c 2005-05-27 23:33:50.000000000 +0800 +++ fontconfig-2.3.2/src/fcfs.c 2005-05-28 11:18:59.000000000 +0800 @@ -80,3 +80,113 @@ FcFontSetAdd (FcFontSet *s, FcPattern *f s->fonts[s->nfont++] = font; return FcTrue; } + + +/* Add by Firefly(firefly@firefly.idv.tw) */ +static +FcChar8 * +_FcMakePatternString(FcPattern *p) +{ + FcChar8 *family, *foundry = 0; + int slant, weight; + FcBool scalable; + double pixel_size = 0; + + FcChar8 mkstr[256]; + + if (FcPatternGetString(p, FC_FAMILY, 0, &family) != FcResultMatch || + FcPatternGetInteger(p, FC_SLANT, 0, &slant) != FcResultMatch || + FcPatternGetInteger(p, FC_WEIGHT, 0, &weight) != FcResultMatch || + FcPatternGetBool(p, FC_SCALABLE, 0, &scalable) != FcResultMatch ) + return 0; + + if (!scalable && + FcPatternGetDouble(p, FC_PIXEL_SIZE, 0, &pixel_size) != FcResultMatch) + return 0; + + FcPatternGetString(p, FC_FOUNDRY, 0, &foundry); + + sprintf(mkstr, "%s,%s,%3d,%3d,%1d,%g", family, foundry, slant, weight, scalable, pixel_size); + return FcStrCopy(mkstr); +} + +FcBool +FcFontSetAddSort (FcFontSet *s, FcPattern *font) +{ + FcPattern **f; + int sfont; + + if (s->nfont == s->sfont) + { + sfont = s->sfont + 32; + if (s->fonts) + f = (FcPattern **) realloc (s->fonts, sfont * sizeof (FcPattern *)); + else + f = (FcPattern **) malloc (sfont * sizeof (FcPattern *)); + if (!f) + return FcFalse; + if (s->sfont) + FcMemFree (FC_MEM_FONTPTR, s->sfont * sizeof (FcPattern *)); + FcMemAlloc (FC_MEM_FONTPTR, sfont * sizeof (FcPattern *)); + s->sfont = sfont; + s->fonts = f; + } + + FcChar8 *srcstr = _FcMakePatternString(font); + + if (!srcstr) + return FcFalse; + + int top = 0; + int bottom = s->nfont -1; + int middle; + int compValue; + FcChar8 *cmpstr; + while (top <= bottom) + { + middle = (bottom + top) >> 1; + cmpstr = _FcMakePatternString(s->fonts[middle]); + if (!cmpstr) + { + break; + } + compValue = strcmp(srcstr, cmpstr); + FcStrFree(cmpstr); + + if (compValue == 0) + { + break; + } + + if (compValue < 0) + bottom = middle - 1; + else + top = middle + 1; + } + + FcStrFree(srcstr); + + if (top <= bottom) + { + FcLangSet *langset1, *langset2; + FcPatternGetLangSet(s->fonts[middle], FC_LANG, 0, &langset1); + FcPatternGetLangSet(font, FC_LANG, 0, &langset2); + if (FcLangSetEqual(langset1, langset2)) + { + FcPatternDestroy(font); + return FcTrue; + } + top = middle + 1; + } + + s->nfont++; + int i; + for (i= s->nfont; i > top; i--) + { + s->fonts[i] = s->fonts[i-1]; + } + s->fonts[top] = font; + + return FcTrue; +} + diff -urNp fontconfig-2.3.2.orig/src/fcint.h fontconfig-2.3.2/src/fcint.h --- fontconfig-2.3.2.orig/src/fcint.h 2005-05-27 23:33:50.000000000 +0800 +++ fontconfig-2.3.2/src/fcint.h 2005-05-28 15:39:39.000000000 +0800 @@ -104,6 +104,11 @@ typedef struct _FcSymbolic { #define FC_MEM_NUM 30 +/* Add by Firefly(firefly@firefly.idv.tw) */ +#define FC_FAMILYOUTPUT_AUTO 0 +#define FC_FAMILYOUTPUT_ENGLISHONLY 1 +#define FC_FAMILYOUTPUT_ANY 2 + typedef enum _FcValueBinding { FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame } FcValueBinding; @@ -381,6 +386,8 @@ struct _FcConfig { */ time_t rescanTime; /* last time information was scanned */ int rescanInterval; /* interval between scans */ + + int familyOutput; /*output family name*/ }; extern FcConfig *_fcConfig; @@ -596,6 +603,9 @@ const FcCharMap * FcFreeTypeGetPrivateMap (FT_Encoding encoding); /* fcfs.c */ +/* Add by Firefly(firefly@firefly.idv.tw) */ +FcBool +FcFontSetAddSort(FcFontSet *s, FcPattern *font); /* fcgram.y */ int FcConfigparse (void); diff -urNp fontconfig-2.3.2.orig/src/fcmatch.c fontconfig-2.3.2/src/fcmatch.c --- fontconfig-2.3.2.orig/src/fcmatch.c 2005-05-27 23:33:50.000000000 +0800 +++ fontconfig-2.3.2/src/fcmatch.c 2005-05-28 11:24:27.000000000 +0800 @@ -212,7 +212,7 @@ static FcMatcher _FcMatchers [] = { #define MATCH_SLANT 7 #define MATCH_SLANT_INDEX 8 - { FC_WEIGHT, FcCompareNumber, 9, 9 }, + { FC_WEIGHT, FcCompareNumber, 8, 8 }, #define MATCH_WEIGHT 8 #define MATCH_WEIGHT_INDEX 9 @@ -682,6 +682,7 @@ FcFontSetSort (FcConfig *config, FcBool *patternLangSat; FcValue patternLang; + trim = FcTrue; if (FcDebug () & FC_DBG_MATCH) { printf ("Sort "); diff -urNp fontconfig-2.3.2.orig/src/fcxml.c fontconfig-2.3.2/src/fcxml.c --- fontconfig-2.3.2.orig/src/fcxml.c 2005-05-27 23:33:50.000000000 +0800 +++ fontconfig-2.3.2/src/fcxml.c 2005-05-28 15:45:39.000000000 +0800 @@ -320,6 +320,7 @@ typedef enum _FcElement { FcElementCeil, FcElementRound, FcElementTrunc, + FcElementFamilyOutput, FcElementUnknown } FcElement; @@ -383,6 +384,7 @@ FcElementMap (const XML_Char *name) { "ceil", FcElementCeil }, { "round", FcElementRound }, { "trunc", FcElementTrunc }, + { "familyoutput", FcElementFamilyOutput }, { 0, 0 } }; @@ -1075,6 +1077,29 @@ FcParseRescan (FcConfigParse *parse) } } +/* Add by Firefly (firefly@firefly.idv.tw) + */ +static void +FcParseFamilyOutput (FcConfigParse *parse) +{ + int n = FcVStackElements (parse); + while (n-- > 0) + { + FcVStack *v = FcVStackFetch (parse, n); + if (v->tag == FcVStackConstant) + { + if (strcasecmp(v->u.string, "auto") == 0) + parse->config->familyOutput = FC_FAMILYOUTPUT_AUTO; + else if (strcasecmp(v->u.string, "englishonly") == 0) + parse->config->familyOutput = FC_FAMILYOUTPUT_ENGLISHONLY; + else if (strcasecmp(v->u.string, "any") == 0) + parse->config->familyOutput = FC_FAMILYOUTPUT_ANY; + } + else + FcConfigMessage (parse, FcSevereWarning, "non-const familyoutput"); + } +} + static void FcParseInt (FcConfigParse *parse) { @@ -2183,6 +2208,9 @@ FcEndElement(void *userData, const XML_C case FcElementTrunc: FcParseUnary (parse, FcOpTrunc); break; + case FcElementFamilyOutput: + FcParseFamilyOutput (parse); + break; case FcElementUnknown: break; }