mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 382542. fix problems with font fallback and font variations. r=vlad/jdaggett
This commit is contained in:
parent
8851b96936
commit
1156635031
@ -210,7 +210,7 @@ public:
|
||||
|
||||
class gfxWindowsFont : public gfxFont {
|
||||
public:
|
||||
gfxWindowsFont(const nsAString& aName, const gfxFontStyle *aFontStyle);
|
||||
gfxWindowsFont(const nsAString& aName, const gfxFontStyle *aFontStyle, FontEntry *aFontEntry);
|
||||
virtual ~gfxWindowsFont();
|
||||
|
||||
virtual const gfxFont::Metrics& GetMetrics();
|
||||
|
@ -85,6 +85,7 @@ public:
|
||||
|
||||
/* Find a FontFamily/FontEntry object that represents a font on your system given a name */
|
||||
FontFamily *FindFontFamily(const nsAString& aName);
|
||||
FontEntry *FindFontEntry(FontFamily *aFontFamily, const gfxFontStyle *aFontStyle);
|
||||
FontEntry *FindFontEntry(const nsAString& aName, const gfxFontStyle *aFontStyle);
|
||||
|
||||
PRBool GetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<FontEntry> > *array);
|
||||
|
@ -115,14 +115,12 @@ struct DCFromContext {
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
gfxWindowsFont::gfxWindowsFont(const nsAString& aName, const gfxFontStyle *aFontStyle)
|
||||
gfxWindowsFont::gfxWindowsFont(const nsAString& aName, const gfxFontStyle *aFontStyle, FontEntry *aFontEntry)
|
||||
: gfxFont(aName, aFontStyle),
|
||||
mFont(nsnull), mAdjustedSize(0.0), mScriptCache(nsnull),
|
||||
mFontFace(nsnull), mScaledFont(nsnull),
|
||||
mMetrics(nsnull)
|
||||
mMetrics(nsnull), mFontEntry(aFontEntry)
|
||||
{
|
||||
// XXX we should work to get this passed in rather than having to find it again.
|
||||
mFontEntry = gfxWindowsPlatform::GetPlatform()->FindFontEntry(aName, aFontStyle);
|
||||
NS_ASSERTION(mFontEntry, "Unable to find font entry for font. Something is whack.");
|
||||
|
||||
mFont = MakeHFONT(); // create the HFONT, compute metrics, etc
|
||||
@ -419,7 +417,7 @@ GetOrMakeFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle)
|
||||
{
|
||||
nsRefPtr<gfxFont> font = gfxFontCache::GetCache()->Lookup(aFontEntry->GetName(), aStyle);
|
||||
if (!font) {
|
||||
font = new gfxWindowsFont(aFontEntry->GetName(), aStyle);
|
||||
font = new gfxWindowsFont(aFontEntry->GetName(), aStyle, aFontEntry);
|
||||
if (!font)
|
||||
return nsnull;
|
||||
gfxFontCache::GetCache()->AddNew(font);
|
||||
@ -621,9 +619,7 @@ SetupDCFont(HDC dc, gfxWindowsFont *aFont)
|
||||
|
||||
/* GetGlyphIndices is buggy for bitmap and vector fonts,
|
||||
so send them to uniscribe */
|
||||
TEXTMETRIC metrics;
|
||||
GetTextMetrics(dc, &metrics);
|
||||
if ((metrics.tmPitchAndFamily & (TMPF_TRUETYPE)) == 0)
|
||||
if (!aFont->GetFontEntry()->mTrueType)
|
||||
return PR_FALSE;
|
||||
|
||||
return PR_TRUE;
|
||||
|
@ -145,6 +145,8 @@ gfxWindowsPlatform::FontEnumProc(const ENUMLOGFONTEXW *lpelfe,
|
||||
|
||||
if (metrics.ntmFlags & NTM_TYPE1)
|
||||
fe->mIsType1 = PR_TRUE;
|
||||
if (metrics.ntmFlags & (NTM_PS_OPENTYPE | NTM_TT_OPENTYPE))
|
||||
fe->mTrueType = PR_TRUE;
|
||||
|
||||
// mark the charset bit
|
||||
fe->mCharset[metrics.tmCharSet] = 1;
|
||||
@ -552,57 +554,48 @@ gfxWindowsPlatform::FindFontForCharProc(nsStringHashKey::KeyType aKey,
|
||||
nsRefPtr<FontFamily>& aFontFamily,
|
||||
void* userArg)
|
||||
{
|
||||
// XXX Improve this to look at the variations to find a better font
|
||||
nsRefPtr<FontEntry> aFontEntry = aFontFamily->mVariations[0];
|
||||
|
||||
// bitmap fonts suck
|
||||
if (aFontEntry->IsCrappyFont())
|
||||
return PL_DHASH_NEXT;
|
||||
|
||||
FontSearch *data = (FontSearch*)userArg;
|
||||
|
||||
PRUint32 ch = data->ch;
|
||||
const PRUint32 ch = data->ch;
|
||||
|
||||
for (PRUint32 i = 0; i < aFontFamily->mVariations.Length(); ++i) {
|
||||
PRInt32 rank = 0;
|
||||
nsRefPtr<FontEntry> fe = GetPlatform()->FindFontEntry(aFontFamily, data->fontToMatch->GetStyle());
|
||||
|
||||
nsRefPtr<FontEntry> fe = aFontFamily->mVariations[i];
|
||||
// skip over non-unicode and bitmap fonts and fonts that don't have
|
||||
// the code point we're looking for
|
||||
if (fe->IsCrappyFont() || !fe->mCharacterMap.test(ch))
|
||||
return PL_DHASH_NEXT;
|
||||
|
||||
if (fe->mCharacterMap.test(ch)) {
|
||||
// fonts that claim to support the range are more
|
||||
// likely to be "better fonts" than ones that don't... (in theory)
|
||||
if (fe->SupportsRange(gfxFontUtils::CharRangeBit(ch)))
|
||||
rank += 1;
|
||||
} else {
|
||||
// if we didn't match any characters don't bother wasting more time.
|
||||
continue;
|
||||
}
|
||||
PRInt32 rank = 0;
|
||||
// fonts that claim to support the range are more
|
||||
// likely to be "better fonts" than ones that don't... (in theory)
|
||||
if (fe->SupportsRange(gfxFontUtils::CharRangeBit(ch)))
|
||||
rank += 1;
|
||||
|
||||
if (fe->SupportsLangGroup(data->fontToMatch->GetStyle()->langGroup))
|
||||
rank += 10;
|
||||
if (fe->SupportsLangGroup(data->fontToMatch->GetStyle()->langGroup))
|
||||
rank += 2;
|
||||
|
||||
if (fe->mWindowsFamily == data->fontToMatch->GetFontEntry()->mWindowsFamily)
|
||||
rank += 5;
|
||||
if (fe->mWindowsPitch == data->fontToMatch->GetFontEntry()->mWindowsFamily)
|
||||
rank += 5;
|
||||
if (fe->mWindowsFamily == data->fontToMatch->GetFontEntry()->mWindowsFamily)
|
||||
rank += 3;
|
||||
if (fe->mWindowsPitch == data->fontToMatch->GetFontEntry()->mWindowsFamily)
|
||||
rank += 3;
|
||||
|
||||
/* italic */
|
||||
const PRBool italic = (data->fontToMatch->GetStyle()->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) ? PR_TRUE : PR_FALSE;
|
||||
if (fe->mItalic == italic)
|
||||
rank += 55;
|
||||
/* italic */
|
||||
const PRBool italic = (data->fontToMatch->GetStyle()->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) ? PR_TRUE : PR_FALSE;
|
||||
if (fe->mItalic != italic)
|
||||
rank += 3;
|
||||
|
||||
/* weight */
|
||||
PRInt8 baseWeight, weightDistance;
|
||||
data->fontToMatch->GetStyle()->ComputeWeightAndOffset(&baseWeight, &weightDistance);
|
||||
PRUint16 targetWeight = (baseWeight * 100) + (weightDistance * 100);
|
||||
if (fe->mWeight == targetWeight)
|
||||
rank += 50;
|
||||
/* weight */
|
||||
PRInt8 baseWeight, weightDistance;
|
||||
data->fontToMatch->GetStyle()->ComputeWeightAndOffset(&baseWeight, &weightDistance);
|
||||
if (fe->mWeight == (baseWeight * 100) + (weightDistance * 100))
|
||||
rank += 2;
|
||||
else if (fe->mWeight == data->fontToMatch->GetFontEntry()->mWeight)
|
||||
rank += 1;
|
||||
|
||||
if (rank > data->matchRank ||
|
||||
(rank == data->matchRank && Compare(fe->GetName(), data->bestMatch->GetName()) > 0)) {
|
||||
data->bestMatch = fe;
|
||||
data->matchRank = rank;
|
||||
}
|
||||
if (rank > data->matchRank ||
|
||||
(rank == data->matchRank && Compare(fe->GetName(), data->bestMatch->GetName()) > 0)) {
|
||||
data->bestMatch = fe;
|
||||
data->matchRank = rank;
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
@ -659,6 +652,12 @@ gfxWindowsPlatform::FindFontEntry(const nsAString& aName, const gfxFontStyle *aF
|
||||
if (!ff)
|
||||
return nsnull;
|
||||
|
||||
return FindFontEntry(ff, aFontStyle);
|
||||
}
|
||||
|
||||
FontEntry *
|
||||
gfxWindowsPlatform::FindFontEntry(FontFamily *aFontFamily, const gfxFontStyle *aFontStyle)
|
||||
{
|
||||
PRUint8 bestMatch = 0;
|
||||
nsRefPtr<FontEntry> matchFE;
|
||||
const PRBool italic = (aFontStyle->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) ? PR_TRUE : PR_FALSE;
|
||||
@ -666,10 +665,10 @@ gfxWindowsPlatform::FindFontEntry(const nsAString& aName, const gfxFontStyle *aF
|
||||
// build up an array of weights that match the italicness we're looking for
|
||||
nsAutoTArray<nsRefPtr<FontEntry>, 10> weightList;
|
||||
weightList.AppendElements(10);
|
||||
for (PRInt32 i = 0; i < ff->mVariations.Length(); i++) {
|
||||
nsRefPtr<FontEntry> fe = ff->mVariations[i];
|
||||
for (PRInt32 i = 0; i < aFontFamily->mVariations.Length(); i++) {
|
||||
nsRefPtr<FontEntry> fe = aFontFamily->mVariations[i];
|
||||
const PRUint8 weight = (fe->mWeight / 100) - 1;
|
||||
if (italic == fe->mItalic)
|
||||
if (fe->mItalic == italic)
|
||||
weightList[weight] = fe;
|
||||
}
|
||||
|
||||
@ -709,16 +708,19 @@ gfxWindowsPlatform::FindFontEntry(const nsAString& aName, const gfxFontStyle *aF
|
||||
if (matchFE = weightList[j])
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (!matchFE) {
|
||||
NS_ASSERTION(italic, "Italic isn't set. This is bad");
|
||||
// We should only ever hit this code in the case where we're looking for an
|
||||
// italic font and there is no face for one, so ask for a match for a normal one.
|
||||
// The font rendering code can still specify italic and Windows will
|
||||
// do synthetic italic
|
||||
// Not having a match can occur in 2 ways:
|
||||
// The font only has an italic face and we're looking for a normal one.
|
||||
// The font has no italic face and we're looking for italic.
|
||||
// So search for the opposite of what we're looking for
|
||||
gfxFontStyle style(*aFontStyle);
|
||||
style.style = FONT_STYLE_NORMAL;
|
||||
matchFE = FindFontEntry(aName, &style);
|
||||
if (aFontStyle->style == FONT_STYLE_NORMAL)
|
||||
style.style = FONT_STYLE_ITALIC;
|
||||
else
|
||||
style.style = FONT_STYLE_NORMAL;
|
||||
|
||||
matchFE = FindFontEntry(aFontFamily, &style);
|
||||
}
|
||||
return matchFE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user