I''m looking at the FcFontSetSort code in fcmatch.c, line 893 in 2.3.93: if (nodeps[f]->score[MATCH_LANG_INDEX] < nPatternLang) Isn''t this an apples to oranges comparison? nodeps[f]->score[MATCH_LANG_INDEX] is either 0 for exact match 100 for language match, but possible region mismatch 200 for no match. nPatternLang is just the number of languages requested for coverage. The reason I''m asking is that on Solaris, locales are presented as ja_JP, en_US, etc. The fonts use ja, and en in this case, causing language matches to be scored 100 at best. By having 100 in the score value for language, I end up with no matches and all scores are reset to 1000 before the next quick sort. My basic question is: Is the line 893 correct? I''m looking at adding an extra line to the if statement above to fix this. int allow_close_match = FcFalse; /* * For Solaris, because of ja_JP, en_US, and such locales, exact matches * with font language support is sporatic. Check to see if we allow close * matches to count as the same as exact matches. */ FcPatternGetBool ( p, "allow_close_match", 0, &allow_close_match ); ... if (nodeps[f]->score[MATCH_LANG_INDEX] < nPatternLang || ( nodeps[f]->score[MATCH_LANG_INDEX] == 100 && allow_close_match )) or would it be OK to simplify this to: if (nodeps[f]->score[MATCH_LANG_INDEX] <= 100) Thanks in advance for any feedback, Jay
On Wed, 2006-01-11 at 13:49 -0800, Jay Hobson wrote:> I''m looking at the FcFontSetSort code in fcmatch.c, line 893 > in 2.3.93: > > if (nodeps[f]->score[MATCH_LANG_INDEX] < nPatternLang) > > Isn''t this an apples to oranges comparison?I''m trying to remember what this does; my recollection is that this comparison allows for exact matches among any of the requested languages to be equivalent to an exact match for the first language; note that scores are increased by one each time the match is further along in the pattern. This means that a pattern of the form ''en,ja'' will exactly match a ''ja'' font. I don''t exactly recall the details though. I do know that locales on essentially all other systems are of a similar form though, so any issues you''re seeing on Solaris should be present on Linux, BSD and other systems. -- keith.packard@intel.com -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part Url : http://lists.freedesktop.org/archives/fontconfig/attachments/20060112/66466cce/attachment.pgp
I''ve done some more digging on this, and I think that this code has some real problems. The values contained in nodeps[f]->score[MATCH_LANG_INDEX] are going to be: 0 if it was an exact match for the language 100 if it was a language match, but possible country missmatch 200 if it was not a match at all. (The values returned from FcCompareLang are indeed 0, 1, or 2, but these are multiplied by 100 before entered into score) This code always does exact matches only up until the number of languages requested for the set is above 100. (not realistic, but comparing score to number of languages requested seems odd anyway) The basic problem with the entire loop is that if there are no exact matches, as would be the case with ja_JP locale, then all of the fonts are rescored to an equally bad 1000 by this code, and fonts that don''t even support the language are being set as first priority. Here is the code diffs to fix the problem (fix for 2.3.2 stable release): 732c732 < int *patternLangSat; --- > FcBool *patternLangSat; 765c765 < patternLangSat = (int *) (nodeps + nnodes); --- > patternLangSat = (FcBool *) (nodeps + nnodes); 805,810c805,806 < patternLangSat[i] = 0; < < /* < * For Solaris, because of ja_JP, en_US, and such locales, exact matches < * with font language support is sporatic. < */ --- > patternLangSat[i] = FcFalse; > 818c814 < if (nodeps[f]->score[MATCH_LANG_INDEX] <= 100 ) --- > if (nodeps[f]->score[MATCH_LANG_INDEX] < nPatternLang) 824c820 < if (patternLangSat[i] != 1 && --- > if (!patternLangSat[i] && 830c826 < if (compare >= 0 && compare < 2 && ( patternLangSat[i] == 0 || compare + 1 < patternLangSat[i])) --- > if (compare >= 0 && compare < 2) 841c837 < patternLangSat[i] = (int)compare + 1; --- > patternLangSat[i] = FcTrue; This fix basically retains the information about exact vs. close match by using an int instead of a bool, and allows a close match to be stored if no exact match exists. If an exact match shows up later in the list, then store it also. Jay Keith Packard wrote:>On Wed, 2006-01-11 at 13:49 -0800, Jay Hobson wrote: > > >>I''m looking at the FcFontSetSort code in fcmatch.c, line 893 >>in 2.3.93: >> >> if (nodeps[f]->score[MATCH_LANG_INDEX] < nPatternLang) >> >>Isn''t this an apples to oranges comparison? >> >> > >I''m trying to remember what this does; my recollection is that this >comparison allows for exact matches among any of the requested languages >to be equivalent to an exact match for the first language; note that >scores are increased by one each time the match is further along in the >pattern. > >This means that a pattern of the form ''en,ja'' will exactly match a ''ja'' >font. > >I don''t exactly recall the details though. I do know that locales on >essentially all other systems are of a similar form though, so any >issues you''re seeing on Solaris should be present on Linux, BSD and >other systems. > > > >------------------------------------------------------------------------ > >_______________________________________________ >Fontconfig mailing list >Fontconfig@lists.freedesktop.org >http://lists.freedesktop.org/mailman/listinfo/fontconfig > >
On Fri, 2006-01-13 at 09:57 -0800, Jay Hobson wrote:> I''ve done some more digging on this, and I think that this code > has some real problems. > > The values contained in nodeps[f]->score[MATCH_LANG_INDEX] > are going to be: > > 0 if it was an exact match for the language > 100 if it was a language match, but possible country missmatch > 200 if it was not a match at all. > > (The values returned from FcCompareLang are indeed 0, 1, or 2, > but these are multiplied by 100 before entered into score) > > This code always does exact matches only up until the number > of languages requested for the set is above 100. (not realistic, > but comparing score to number of languages requested seems > odd anyway) > > The basic problem with the entire loop is that if there are no > exact matches, as would be the case with ja_JP locale, then > all of the fonts are rescored to an equally bad 1000 by this > code, and fonts that don''t even support the language are being > set as first priority.Did you look in the CVS history and try to understand why the code is as it is today? I''m reasonably sure it works as it does for a reason, but it certainly isn''t obvious to either of us today what precisely that is. I''m afraid I don''t have time until February to really examine this issue in the detail that it requires. -- keith.packard@intel.com -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part Url : http://lists.freedesktop.org/archives/fontconfig/attachments/20060113/59d05eb9/attachment.pgp