Bug 499621. Fix synthetic bolding of downloadable fonts on Windows. r=jkew

This commit is contained in:
John Daggett 2009-07-23 11:22:24 -10:00
parent fe8a14ca9c
commit 228d54b988
6 changed files with 279 additions and 16 deletions

View File

@ -339,7 +339,8 @@ public:
FontEntry *GetFontEntry();
static already_AddRefed<gfxWindowsFont>
GetOrMakeFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle);
GetOrMakeFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle,
PRBool aNeedsBold = PR_FALSE);
protected:
HFONT MakeHFONT();
@ -402,7 +403,8 @@ public:
virtual gfxWindowsFont *GetFontAt(PRInt32 i);
void GroupFamilyListToArrayList(nsTArray<nsRefPtr<FontEntry> > *list);
void GroupFamilyListToArrayList(nsTArray<nsRefPtr<FontEntry> > *list,
nsTArray<PRPackedBool> *aNeedsBold);
void FamilyListToArrayList(const nsString& aFamilies,
const nsCString& aLangGroup,
nsTArray<nsRefPtr<FontEntry> > *list);
@ -429,6 +431,7 @@ private:
nsCString mGenericFamily;
nsTArray<nsRefPtr<FontEntry> > mFontEntries;
nsTArray<PRPackedBool> mFontNeedsBold;
const char *mItemLangGroup; // used by pref-lang handling code

View File

@ -130,17 +130,26 @@ gfxFontEntry *gfxFontFamily::FindFontForStyle(const gfxFontStyle& aFontStyle, PR
gfxFontEntry *matchFE;
const PRInt8 absDistance = abs(weightDistance);
direction = (weightDistance >= 0) ? 1 : -1;
PRInt8 i, k;
for (i = matchBaseWeight, k = 0; i < 10 && i > 0; i += direction) {
PRInt8 i, wghtSteps = 0;
// account for synthetic bold in lighter case
// if lighter is applied with an inherited bold weight,
// and no actual bold faces exist, synthetic bold is used
// so the matched weight above is actually one step down already
if (weightDistance < 0 && baseWeight > 5 && matchBaseWeight < 6) {
wghtSteps = 1; // if no faces [600, 900] then synthetic bold at 700
}
for (i = matchBaseWeight; i < 10 && i > 0; i += direction) {
if (weightList[i]) {
matchFE = weightList[i];
k++;
wghtSteps++;
}
if (k > absDistance)
if (wghtSteps > absDistance)
break;
}
if (weightDistance > 0 && k <= absDistance) {
if (weightDistance > 0 && wghtSteps <= absDistance) {
aNeedsBold = PR_TRUE;
}

View File

@ -1101,8 +1101,17 @@ gfxWindowsFont::FillLogFont(gfxFloat aSize)
if (fe->mIsUserFont) {
if (fe->IsItalic())
isItalic = PR_FALSE; // avoid synthetic italic
if (fe->IsBold())
if (fe->IsBold()) {
weight = 400; // avoid synthetic bold
} else {
// determine whether synthetic bolding is needed
PRInt8 baseWeight, weightDistance;
GetStyle()->ComputeWeightAndOffset(&baseWeight, &weightDistance);
if ((weightDistance == 0 && baseWeight >= 6)
|| (weightDistance > 0)) {
weight = 700; // set to get GDI to synthetic bold this face
}
}
}
FontEntry::FillLogFont(&mLogFont, fe->Name(), fe->mFontType, isItalic,
@ -1207,12 +1216,27 @@ gfxWindowsFont::SetupCairoFont(gfxContext *aContext)
* except for OOM in which case we do nothing and return null.
*/
already_AddRefed<gfxWindowsFont>
gfxWindowsFont::GetOrMakeFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle)
gfxWindowsFont::GetOrMakeFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle,
PRBool aNeedsBold)
{
// because we know the FontEntry has the weight we really want, use it for matching
// things in the cache so we don't end up with things like 402 in there.
gfxFontStyle style(*aStyle);
style.weight = aFontEntry->mWeight;
if (aFontEntry->mIsUserFont && !aFontEntry->IsBold()) {
// determine whether synthetic bolding is needed
PRInt8 baseWeight, weightDistance;
aStyle->ComputeWeightAndOffset(&baseWeight, &weightDistance);
if ((weightDistance == 0 && baseWeight >= 6) || (weightDistance > 0 && aNeedsBold)) {
style.weight = 700; // set to get GDI to synthetic bold this face
} else {
style.weight = aFontEntry->mWeight;
}
} else {
style.weight = aFontEntry->mWeight;
}
// also pre-round the size if there is no size adjust
if (style.sizeAdjust == 0.0)
style.size = ROUND(style.size);
@ -1246,7 +1270,8 @@ AddFontNameToArray(const nsAString& aName,
void
gfxWindowsFontGroup::GroupFamilyListToArrayList(nsTArray<nsRefPtr<FontEntry> > *list)
gfxWindowsFontGroup::GroupFamilyListToArrayList(nsTArray<nsRefPtr<FontEntry> > *list,
nsTArray<PRPackedBool> *aNeedsBold)
{
nsAutoTArray<nsString, 15> fonts;
ForEachFont(AddFontNameToArray, &fonts);
@ -1257,7 +1282,7 @@ gfxWindowsFontGroup::GroupFamilyListToArrayList(nsTArray<nsRefPtr<FontEntry> > *
// first, look up in the user font set
gfxFontEntry *gfe;
PRBool needsBold;
PRBool needsBold = PR_FALSE;
if (mUserFontSet && (gfe = mUserFontSet->FindFontEntry(fonts[i], mStyle, needsBold))) {
// assume for now platform font if not SVG
fe = static_cast<FontEntry*> (gfe);
@ -1271,6 +1296,7 @@ gfxWindowsFontGroup::GroupFamilyListToArrayList(nsTArray<nsRefPtr<FontEntry> > *
// if found, add to the list
if (fe) {
list->AppendElement(fe);
aNeedsBold->AppendElement(static_cast<PRPackedBool>(needsBold));
}
}
}
@ -1314,7 +1340,7 @@ gfxWindowsFontGroup::GetFontAt(PRInt32 i)
if (!mFonts[i]) {
nsRefPtr<gfxWindowsFont> font =
gfxWindowsFont::GetOrMakeFont(mFontEntries[i], &mStyle);
gfxWindowsFont::GetOrMakeFont(mFontEntries[i], &mStyle, mFontNeedsBold[i]);
mFonts[i] = font;
}
@ -1335,6 +1361,7 @@ gfxWindowsFontGroup::UpdateFontList()
// xxx - can probably improve this to detect when all fonts were found, so no need to update list
mFonts.Clear();
mFontEntries.Clear();
mFontNeedsBold.Clear();
InitFontList();
mCurrGeneration = GetGeneration();
}
@ -1344,7 +1371,7 @@ gfxWindowsFontGroup::UpdateFontList()
void
gfxWindowsFontGroup::InitFontList()
{
GroupFamilyListToArrayList(&mFontEntries);
GroupFamilyListToArrayList(&mFontEntries, &mFontNeedsBold);
mFonts.AppendElements(mFontEntries.Length());
@ -1352,10 +1379,11 @@ gfxWindowsFontGroup::InitFontList()
// we'll surely need them anyway.
while (mFontEntries.Length() > 0) {
nsRefPtr<gfxWindowsFont> font =
gfxWindowsFont::GetOrMakeFont(mFontEntries[0], &mStyle);
gfxWindowsFont::GetOrMakeFont(mFontEntries[0], &mStyle, mFontNeedsBold[0]);
if (!font->IsValid()) {
mFontEntries.RemoveElementAt(0);
mFonts.RemoveElementAt(0);
mFontNeedsBold.RemoveElementAt(0);
continue;
}
mFonts[0] = font;
@ -1394,6 +1422,7 @@ gfxWindowsFontGroup::InitFontList()
// just report false for all characters, so the fact that the font
// is bogus should not cause problems.
mFonts.AppendElements(mFontEntries.Length());
mFontNeedsBold.AppendElements(mFontEntries.Length());
}
// force the underline offset to get recalculated
@ -2400,7 +2429,7 @@ gfxWindowsFontGroup::WhichFontSupportsChar(const nsTArray<nsRefPtr<FontEntry> >&
continue;
if (fe->HasCharacter(ch)) {
nsRefPtr<gfxWindowsFont> font =
gfxWindowsFont::GetOrMakeFont(fe, &mStyle);
gfxWindowsFont::GetOrMakeFont(fe, &mStyle, mFontNeedsBold[i]);
// Check that the font is still usable.
if (!font->IsValid())
continue;

View File

@ -85,6 +85,7 @@ HTTP(..) == ex-unit-1-dynamic.html ex-unit-1-ref.html
== local-1.html local-1-ref.html
HTTP(..) == synthetic-weight-style.html synthetic-weight-style-ref.html
random-if(MOZ_WIDGET_TOOLKIT=="gtk2") HTTP(..) == synthetic-variations.html synthetic-variations-ref.html # bug 419962
# Leak test
HTTP(..) load 486974-1.html

View File

@ -0,0 +1,81 @@
<!DOCTYPE HTML>
<html><head>
<title>@font-face and synthetic rendering</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
@font-face {
font-family: test;
src: url(../fonts/mplus/mplus-1p-regular.ttf);
font-weight: normal;
}
body {
margin: 50px;
font-family: sans-serif;
font-size: 18pt;
}
table {
border-collapse: collapse;
}
#test1, #test2, #test3 { font-family: test, Times New Roman, Times, Bitstream Vera, serif; }
th, td {
padding-left: 1em;
padding-right: 1em;
text-align: left;
}
th { font-weight: normal; }
td { font-weight: bold; }
em { font-style: italic; }
</style>
</head><body>
<p>All lines should appear in a sans-serif face with proper bolding</p>
<table id="test1">
<tr class="w1"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w2"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w3"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w4"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w5"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w6"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w7"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w8"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w9"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
</table>
<table id="test2">
<tr class="w9"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w8"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w7"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w6"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w5"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w4"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w3"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w2"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w1"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
</table>
<table id="test3">
<tr class="w1"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w2"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w3"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w4"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w5"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w6"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w7"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w8"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w9"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
</table>
</body></html>

View File

@ -0,0 +1,140 @@
<!DOCTYPE HTML>
<html><head>
<title>@font-face and synthetic rendering</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
@font-face {
font-family: test1;
src: url(../fonts/mplus/mplus-1p-regular.ttf);
font-weight: normal;
}
@font-face {
font-family: test2;
src: url(../fonts/mplus/mplus-1p-regular.ttf);
font-weight: normal;
}
@font-face {
font-family: test3;
src: url(../fonts/mplus/mplus-1p-thin.ttf);
font-weight: 100;
}
@font-face {
font-family: test3;
src: url(../fonts/mplus/mplus-1p-regular.ttf);
font-weight: 300;
}
body {
margin: 50px;
font-family: sans-serif;
font-size: 18pt;
}
table {
border-collapse: collapse;
}
.w1 { font-weight: 100; }
.w2 { font-weight: 200; }
.w3 { font-weight: 300; }
.w4 { font-weight: 400; }
.w5 { font-weight: 500; }
.w6 { font-weight: 600; }
.w7 { font-weight: 700; }
.w8 { font-weight: 800; }
.w9 { font-weight: 900; }
#test1 { font-family: test1, Times New Roman, Times, Bitstream Vera, serif; }
#test2 { font-family: test2, Times New Roman, Times, Bitstream Vera, serif; }
#test3 { font-family: test3, Times New Roman, Times, Bitstream Vera, serif; }
th, td {
font-weight: inherit;
padding-left: 1em;
padding-right: 1em;
text-align: left;
}
em { font-style: italic; }
#test1 .w1 td { font-weight: bolder; }
#test1 .w2 td { font-weight: bolder; }
#test1 .w3 td { font-weight: bolder; }
#test1 .w4 td { font-weight: bolder; }
#test1 .w5 td { font-weight: bolder; }
#test1 .w6 th { font-weight: lighter; }
#test1 .w7 th { font-weight: lighter; }
#test1 .w8 th { font-weight: lighter; }
#test1 .w9 th { font-weight: lighter; }
#test2 .w1 td { font-weight: bolder; }
#test2 .w2 td { font-weight: bolder; }
#test2 .w3 td { font-weight: bolder; }
#test2 .w4 td { font-weight: bolder; }
#test2 .w5 td { font-weight: bolder; }
#test2 .w6 th { font-weight: lighter; }
#test2 .w7 th { font-weight: lighter; }
#test2 .w8 th { font-weight: lighter; }
#test2 .w9 th { font-weight: lighter; }
#test3 .w1 th, #test3 .w1 td, #test3 .w1 td span { font-weight: bolder; }
#test3 .w2 th, #test3 .w2 td, #test3 .w2 td span { font-weight: bolder; }
#test3 .w3 td { font-weight: bolder; }
#test3 .w4 td { font-weight: bolder; }
#test3 .w5 td { font-weight: bolder; }
#test3 .w6 th { font-weight: lighter; }
#test3 .w7 th { font-weight: lighter; }
#test3 .w8 th { font-weight: lighter; }
#test3 .w9 th { font-weight: lighter; }
</style>
</head><body>
<p>All lines should appear in a sans-serif face with proper bolding</p>
<table id="test1">
<tr class="w1"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w2"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w3"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w4"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w5"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w6"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w7"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w8"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w9"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
</table>
<table id="test2">
<tr class="w9"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w8"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w7"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w6"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w5"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w4"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w3"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w2"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
<tr class="w1"><th>normal</th><th><em>italic</em></th><td>bold</td><td><em>bolditalic</em></td></tr>
</table>
<table id="test3">
<tr class="w1"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w2"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w3"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w4"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w5"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w6"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w7"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w8"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
<tr class="w9"><th><span>normal</span></th><th><span><em>italic</em></span></th><td><span>bold</span></td><td><span><em>bolditalic</em></span></td></tr>
</table>
</body></html>