use fontconfig for font lookup misses and cache the results

This commit is contained in:
Stuart Parmenter 2008-04-20 04:34:04 -07:00
parent 5b9f368553
commit ae3f3df546
4 changed files with 101 additions and 16 deletions

View File

@ -874,8 +874,10 @@ gfxFontGroup::ForEachFontInternal(const nsAString& aFamilies,
genericFamily.SetIsVoid(PR_TRUE);
}
}
if (!family.IsEmpty()) {
if (generic) {
ForEachFontInternal(family, lang, PR_FALSE, aResolveFontName, fc, closure);
} else if (!family.IsEmpty()) {
NS_LossyConvertUTF16toASCII gf(genericFamily);
if (aResolveFontName) {
ResolveData data(fc, gf, closure);

View File

@ -311,6 +311,7 @@ gfxFontconfigUtils::UpdateFontListInternal(PRBool aForce)
for (PRInt32 i = 0; i < mAliasForMultiFonts.Count(); i++) {
nsRefPtr<gfxFontNameList> fonts = new gfxFontNameList;
nsCAutoString fontname(*mAliasForMultiFonts.CStringAt(i));
printf("Alias %s\n", fontname.get());
rv = GetResolvedFonts(fontname, fonts);
if (NS_FAILED(rv))
return rv;

View File

@ -173,8 +173,9 @@ gfxQtFontGroup::FontCallback(const nsAString& fontName,
{
nsStringArray *sa = static_cast<nsStringArray*>(closure);
if (sa->IndexOf(fontName) < 0) {
if (!fontName.IsEmpty() && sa->IndexOf(fontName) < 0) {
sa->AppendString(fontName);
printf(" - %s\n", NS_ConvertUTF16toUTF8(fontName).get());
}
return PR_TRUE;
@ -211,10 +212,20 @@ gfxQtFontGroup::gfxQtFontGroup(const nsAString& families,
const gfxFontStyle *aStyle)
: gfxFontGroup(families, aStyle)
{
printf("Looking for %s\n", NS_ConvertUTF16toUTF8(families).get());
nsStringArray familyArray;
ForEachFont(FontCallback, &familyArray);
if (familyArray.Count() == 0) {
nsAutoString prefFamilies;
gfxQtPlatform::GetPlatform()->GetPrefFonts(aStyle->langGroup.get(), prefFamilies, nsnull);
if (!prefFamilies.IsEmpty()) {
ForEachFont(prefFamilies, aStyle->langGroup, FontCallback, &familyArray);
}
}
if (familyArray.Count() == 0) {
printf("failde to find a font. sadface\n");
// We want to get rid of this entirely at some point, but first we need real lists of fonts.
QFont defaultFont;
QFontInfo fi (defaultFont);
familyArray.AppendString(nsDependentString(static_cast<const PRUnichar *>(fi.family().utf16())));
@ -618,12 +629,10 @@ gfxQtFontGroup::AddRange(gfxTextRun *aTextRun, gfxQtFont *font, const PRUnichar
NS_ASSERTION(!IsInvalidChar(ch), "Invalid char detected");
FT_UInt gid = FT_Get_Char_Index(face, ch); // find the glyph id
PRInt32 advance = 0;
#if 0
if (gid == font->GetSpaceGlyph()) {
advance = (int)(font->GetMetrics().spaceWidth * appUnitsPerDevUnit);
} else
#endif
if (gid == 0) {
} else if (gid == 0) {
advance = -1; // trigger the missing glyphs case below
} else {
// find next character and its glyph -- in case they exist
@ -669,16 +678,12 @@ gfxQtFontGroup::AddRange(gfxTextRun *aTextRun, gfxQtFont *font, const PRUnichar
if (advance >= 0 &&
gfxTextRun::CompressedGlyph::IsSimpleAdvance(advance) &&
gfxTextRun::CompressedGlyph::IsSimpleGlyphID(gid))
{
//printf("simple glyph ");
gfxTextRun::CompressedGlyph::IsSimpleGlyphID(gid)) {
aTextRun->SetSimpleGlyph(i, g.SetSimpleGlyph(advance, gid));
} else if (gid == 0) {
//printf("missing glyph ");
// gid = 0 only happens when the glyph is missing from the font
aTextRun->SetMissingGlyph(i, ch);
} else {
//printf("complex glyph ");
gfxTextRun::DetailedGlyph details;
details.mGlyphID = gid;
NS_ASSERTION(details.mGlyphID == gid, "Seriously weird glyph ID detected!");
@ -688,8 +693,6 @@ gfxQtFontGroup::AddRange(gfxTextRun *aTextRun, gfxQtFont *font, const PRUnichar
g.SetComplex(aTextRun->IsClusterStart(i), PR_TRUE, 1);
aTextRun->SetGlyphs(i, g, &details);
}
}
cairo_ft_scaled_font_unlock_face(font->CairoScaledFont());

View File

@ -74,6 +74,7 @@ static void do_qt_pixmap_unref (void *data)
typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
static FontTable *gPlatformFonts = NULL;
static FontTable *gPlatformFontAliases = NULL;
static FT_Library gPlatformFTLibrary = NULL;
@ -87,6 +88,8 @@ gfxQtPlatform::gfxQtPlatform()
gPlatformFonts = new FontTable();
gPlatformFonts->Init(100);
gPlatformFontAliases = new FontTable();
gPlatformFontAliases->Init(100);
UpdateFontList();
InitDPI();
@ -99,6 +102,8 @@ gfxQtPlatform::~gfxQtPlatform()
delete gPlatformFonts;
gPlatformFonts = NULL;
delete gPlatformFontAliases;
gPlatformFontAliases = NULL;
cairo_debug_reset_static_data();
@ -276,8 +281,82 @@ gfxQtPlatform::ResolveFontName(const nsAString& aFontName,
void *aClosure,
PRBool& aAborted)
{
return sFontconfigUtils->ResolveFontName(aFontName, aCallback,
aClosure, aAborted);
nsAutoString name(aFontName);
ToLowerCase(name);
nsRefPtr<FontFamily> ff;
if (gPlatformFonts->Get(name, &ff) ||
gPlatformFontAliases->Get(name, &ff)) {
aAborted = !(*aCallback)(ff->mName, aClosure);
return NS_OK;
}
printf("failed to resolve name: %s\n", NS_ConvertUTF16toUTF8(name).get());
nsCAutoString utf8Name = NS_ConvertUTF16toUTF8(aFontName);
FcPattern *npat = FcPatternCreate();
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
FcObjectSet *nos = FcObjectSetBuild(FC_FAMILY, NULL);
FcFontSet *nfs = FcFontList(NULL, npat, nos);
for (int k = 0; k < nfs->nfont; k++) {
FcChar8 *str;
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
ToLowerCase(altName);
if (gPlatformFonts->Get(altName, &ff)) {
printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
gPlatformFontAliases->Put(name, ff);
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
goto DONE;
}
}
FcPatternDestroy(npat);
FcObjectSetDestroy(nos);
FcFontSetDestroy(nfs);
{
printf("Using FcFontSort. Sad.\n");
npat = FcPatternCreate();
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
FcPatternDel(npat, FC_LANG);
FcConfigSubstitute(NULL, npat, FcMatchPattern);
FcDefaultSubstitute(npat);
nos = FcObjectSetBuild(FC_FAMILY, NULL);
nfs = FcFontList(NULL, npat, nos);
FcResult fresult;
FcPattern *match = FcFontMatch(NULL, npat, &fresult);
printf("%d\n", (int)fresult);
if (match)
FcFontSetAdd(nfs, match);
for (int k = 0; k < nfs->nfont; k++) {
FcChar8 *str;
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
ToLowerCase(altName);
if (gPlatformFonts->Get(altName, &ff)) {
printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
gPlatformFontAliases->Put(name, ff);
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
goto DONE;
}
}
}
DONE:
FcPatternDestroy(npat);
FcObjectSetDestroy(nos);
FcFontSetDestroy(nfs);
return NS_OK;
}
nsresult