mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 998869 part 1 - build fontlist more lazily (non-linux). r=jfkthame
This commit is contained in:
parent
2a28d6d5eb
commit
938b6ce42d
@ -1627,11 +1627,7 @@ gfxFontGroup::BuildFontList()
|
||||
gfxFontEntry *fe = defaultFamily->FindFontForStyle(mStyle,
|
||||
needsBold);
|
||||
if (fe) {
|
||||
nsRefPtr<gfxFont> font = fe->FindOrMakeFont(&mStyle,
|
||||
needsBold);
|
||||
if (font) {
|
||||
mFonts.AppendElement(FamilyFace(defaultFamily, font));
|
||||
}
|
||||
mFonts.AppendElement(FamilyFace(defaultFamily, fe, needsBold));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1648,12 +1644,7 @@ gfxFontGroup::BuildFontList()
|
||||
gfxFontEntry *fe = families[i]->FindFontForStyle(mStyle,
|
||||
needsBold);
|
||||
if (fe) {
|
||||
nsRefPtr<gfxFont> font = fe->FindOrMakeFont(&mStyle,
|
||||
needsBold);
|
||||
if (font) {
|
||||
mFonts.AppendElement(FamilyFace(families[i], font));
|
||||
break;
|
||||
}
|
||||
mFonts.AppendElement(FamilyFace(families[i], fe, needsBold));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1670,18 +1661,19 @@ gfxFontGroup::BuildFontList()
|
||||
}
|
||||
}
|
||||
|
||||
if (!mStyle.systemFont) {
|
||||
uint32_t count = mFonts.Length();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
gfxFont* font = mFonts[i].Font();
|
||||
if (font->GetFontEntry()->mIsBadUnderlineFont) {
|
||||
gfxFloat first = mFonts[0].Font()->GetMetrics().underlineOffset;
|
||||
gfxFloat bad = font->GetMetrics().underlineOffset;
|
||||
mUnderlineOffset = std::min(first, bad);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// xxx comment this out for now
|
||||
// if (!mStyle.systemFont) {
|
||||
// uint32_t count = mFonts.Length();
|
||||
// for (uint32_t i = 0; i < count; ++i) {
|
||||
// gfxFont* font = mFonts[i].Font();
|
||||
// if (font->GetFontEntry()->mIsBadUnderlineFont) {
|
||||
// gfxFloat first = mFonts[0].Font()->GetMetrics().underlineOffset;
|
||||
// gfxFloat bad = font->GetMetrics().underlineOffset;
|
||||
// mUnderlineOffset = std::min(first, bad);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1730,10 +1722,7 @@ gfxFontGroup::FindPlatformFont(const nsAString& aName,
|
||||
|
||||
// add to the font group, unless it's already there
|
||||
if (fe && !HasFont(fe)) {
|
||||
nsRefPtr<gfxFont> font = fe->FindOrMakeFont(&mStyle, needsBold);
|
||||
if (font) {
|
||||
mFonts.AppendElement(FamilyFace(family, font));
|
||||
}
|
||||
mFonts.AppendElement(FamilyFace(family, fe, needsBold));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1742,8 +1731,9 @@ gfxFontGroup::HasFont(const gfxFontEntry *aFontEntry)
|
||||
{
|
||||
uint32_t count = mFonts.Length();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
if (mFonts[i].Font()->GetFontEntry() == aFontEntry)
|
||||
if (mFonts[i].FontEntry() == aFontEntry) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -2376,24 +2366,27 @@ gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel,
|
||||
}
|
||||
|
||||
already_AddRefed<gfxFont>
|
||||
gfxFontGroup::TryAllFamilyMembers(gfxFontFamily* aFamily, uint32_t aCh)
|
||||
gfxFontGroup::FindNonItalicFaceForChar(gfxFontFamily* aFamily, uint32_t aCh)
|
||||
{
|
||||
NS_ASSERTION(mStyle.style != NS_FONT_STYLE_NORMAL,
|
||||
"should only be called in the italic/oblique case");
|
||||
|
||||
if (!aFamily->TestCharacterMap(aCh)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Note that we don't need the actual runScript in matchData for
|
||||
// gfxFontFamily::SearchAllFontsForChar, it's only used for the
|
||||
// system-fallback case. So we can just set it to 0 here.
|
||||
GlobalFontMatch matchData(aCh, 0, &mStyle);
|
||||
aFamily->SearchAllFontsForChar(&matchData);
|
||||
gfxFontEntry *fe = matchData.mBestMatch;
|
||||
if (!fe) {
|
||||
gfxFontStyle regularStyle = mStyle;
|
||||
regularStyle.style = NS_FONT_STYLE_NORMAL;
|
||||
bool needsBold;
|
||||
gfxFontEntry *fe = aFamily->FindFontForStyle(regularStyle, needsBold);
|
||||
if (!fe->HasCharacter(aCh)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool needsBold = mStyle.weight >= 600 && !fe->IsBold();
|
||||
nsRefPtr<gfxFont> font = fe->FindOrMakeFont(&mStyle, needsBold);
|
||||
if (!font->Valid()) {
|
||||
return nullptr;
|
||||
}
|
||||
return font.forget();
|
||||
}
|
||||
|
||||
@ -2410,18 +2403,24 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
|
||||
bool isVarSelector = gfxFontUtils::IsVarSelector(aCh);
|
||||
|
||||
if (!isJoinControl && !wasJoinCauser && !isVarSelector) {
|
||||
nsRefPtr<gfxFont> firstFont = mFonts[0].Font();
|
||||
nsRefPtr<gfxFont> firstFont = GetFontAt(0);
|
||||
if (firstFont->HasCharacter(aCh)) {
|
||||
*aMatchType = gfxTextRange::kFontGroup;
|
||||
return firstFont.forget();
|
||||
}
|
||||
// It's possible that another font in the family (e.g. regular face,
|
||||
// where the requested style was italic) will support the character
|
||||
nsRefPtr<gfxFont> font = TryAllFamilyMembers(mFonts[0].Family(), aCh);
|
||||
if (font) {
|
||||
*aMatchType = gfxTextRange::kFontGroup;
|
||||
return font.forget();
|
||||
|
||||
// If italic, test the regular face to see if it supports the character.
|
||||
// Only do this for platform fonts, not userfonts.
|
||||
if (mStyle.style != NS_FONT_STYLE_NORMAL &&
|
||||
!firstFont->GetFontEntry()->IsUserFont()) {
|
||||
nsRefPtr<gfxFont> font =
|
||||
FindNonItalicFaceForChar(mFonts[0].Family(), aCh);
|
||||
if (font) {
|
||||
*aMatchType = gfxTextRange::kFontGroup;
|
||||
return font.forget();
|
||||
}
|
||||
}
|
||||
|
||||
// we don't need to check the first font again below
|
||||
++nextIndex;
|
||||
}
|
||||
@ -2461,16 +2460,30 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
|
||||
// 1. check remaining fonts in the font group
|
||||
uint32_t fontListLength = FontListLength();
|
||||
for (uint32_t i = nextIndex; i < fontListLength; i++) {
|
||||
nsRefPtr<gfxFont> font = mFonts[i].Font();
|
||||
if (font->HasCharacter(aCh)) {
|
||||
*aMatchType = gfxTextRange::kFontGroup;
|
||||
return font.forget();
|
||||
nsRefPtr<gfxFont> font;
|
||||
|
||||
// test the font entry, build font if needed
|
||||
gfxFontEntry *fe = mFonts[i].FontEntry();
|
||||
if (fe->HasCharacter(aCh)) {
|
||||
font = mFonts[i].Font();
|
||||
if (!font) {
|
||||
font = fe->FindOrMakeFont(&mStyle, mFonts[i].NeedsBold());
|
||||
mFonts[i].SetFont(font);
|
||||
}
|
||||
if (font->Valid()) {
|
||||
*aMatchType = gfxTextRange::kFontGroup;
|
||||
return font.forget();
|
||||
}
|
||||
}
|
||||
|
||||
font = TryAllFamilyMembers(mFonts[i].Family(), aCh);
|
||||
if (font) {
|
||||
*aMatchType = gfxTextRange::kFontGroup;
|
||||
return font.forget();
|
||||
// If italic, test the regular face to see if it supports the character.
|
||||
// Only do this for platform fonts, not userfonts.
|
||||
if (mStyle.style != NS_FONT_STYLE_NORMAL && !fe->IsUserFont()) {
|
||||
font = FindNonItalicFaceForChar(mFonts[i].Family(), aCh);
|
||||
if (font) {
|
||||
*aMatchType = gfxTextRange::kFontGroup;
|
||||
return font.forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -723,27 +723,6 @@ private:
|
||||
|
||||
class gfxFontGroup : public gfxTextRunFactory {
|
||||
public:
|
||||
class FamilyFace {
|
||||
public:
|
||||
FamilyFace() { }
|
||||
|
||||
FamilyFace(gfxFontFamily* aFamily, gfxFont* aFont)
|
||||
: mFamily(aFamily), mFont(aFont)
|
||||
{
|
||||
NS_ASSERTION(aFont, "font pointer must not be null");
|
||||
NS_ASSERTION(!aFamily ||
|
||||
aFamily->ContainsFace(aFont->GetFontEntry()),
|
||||
"font is not a member of the given family");
|
||||
}
|
||||
|
||||
gfxFontFamily* Family() const { return mFamily.get(); }
|
||||
gfxFont* Font() const { return mFont.get(); }
|
||||
|
||||
private:
|
||||
nsRefPtr<gfxFontFamily> mFamily;
|
||||
nsRefPtr<gfxFont> mFont;
|
||||
};
|
||||
|
||||
static void Shutdown(); // platform must call this to release the languageAtomService
|
||||
|
||||
gfxFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
|
||||
@ -760,10 +739,17 @@ public:
|
||||
NS_ASSERTION(!mUserFontSet || mCurrGeneration == GetGeneration(),
|
||||
"Whoever was caching this font group should have "
|
||||
"called UpdateFontList on it");
|
||||
NS_ASSERTION(mFonts.Length() > uint32_t(i) && mFonts[i].Font(),
|
||||
NS_ASSERTION(mFonts.Length() > uint32_t(i) &&
|
||||
(mFonts[i].Font() || mFonts[i].FontEntry()),
|
||||
"Requesting a font index that doesn't exist");
|
||||
|
||||
return mFonts[i].Font();
|
||||
nsRefPtr<gfxFont> font = mFonts[i].Font();
|
||||
if (!font) {
|
||||
gfxFontEntry *fe = mFonts[i].FontEntry();
|
||||
font = fe->FindOrMakeFont(&mStyle, mFonts[i].NeedsBold());
|
||||
mFonts[i].SetFont(font);
|
||||
}
|
||||
return font.get();
|
||||
}
|
||||
|
||||
// Returns the first font in the font-group that has an OpenType MATH table,
|
||||
@ -913,6 +899,116 @@ public:
|
||||
nsTArray<nsString>& aGenericFamilies);
|
||||
|
||||
protected:
|
||||
class FamilyFace {
|
||||
public:
|
||||
FamilyFace() : mFamily(nullptr), mFontEntry(nullptr),
|
||||
mNeedsBold(false), mFontCreated(false)
|
||||
{ }
|
||||
|
||||
FamilyFace(gfxFontFamily* aFamily, gfxFont* aFont)
|
||||
: mFamily(aFamily), mNeedsBold(false), mFontCreated(true)
|
||||
{
|
||||
NS_ASSERTION(aFont, "font pointer must not be null");
|
||||
NS_ASSERTION(!aFamily ||
|
||||
aFamily->ContainsFace(aFont->GetFontEntry()),
|
||||
"font is not a member of the given family");
|
||||
mFont = aFont;
|
||||
NS_ADDREF(aFont);
|
||||
}
|
||||
|
||||
FamilyFace(gfxFontFamily* aFamily, gfxFontEntry* aFontEntry,
|
||||
bool aNeedsBold)
|
||||
: mFamily(aFamily), mNeedsBold(aNeedsBold), mFontCreated(false)
|
||||
{
|
||||
NS_ASSERTION(aFontEntry, "font entry pointer must not be null");
|
||||
NS_ASSERTION(!aFamily ||
|
||||
aFamily->ContainsFace(aFontEntry),
|
||||
"font is not a member of the given family");
|
||||
mFontEntry = aFontEntry;
|
||||
NS_ADDREF(aFontEntry);
|
||||
}
|
||||
|
||||
FamilyFace(const FamilyFace& aOtherFamilyFace)
|
||||
: mFamily(aOtherFamilyFace.mFamily),
|
||||
mNeedsBold(aOtherFamilyFace.mNeedsBold),
|
||||
mFontCreated(aOtherFamilyFace.mFontCreated)
|
||||
{
|
||||
if (mFontCreated) {
|
||||
mFont = aOtherFamilyFace.mFont;
|
||||
NS_ADDREF(mFont);
|
||||
} else {
|
||||
mFontEntry = aOtherFamilyFace.mFontEntry;
|
||||
NS_IF_ADDREF(mFontEntry);
|
||||
}
|
||||
}
|
||||
|
||||
~FamilyFace()
|
||||
{
|
||||
if (mFontCreated) {
|
||||
NS_RELEASE(mFont);
|
||||
} else {
|
||||
NS_IF_RELEASE(mFontEntry);
|
||||
}
|
||||
}
|
||||
|
||||
FamilyFace& operator=(const FamilyFace& aOther)
|
||||
{
|
||||
if (mFontCreated) {
|
||||
NS_RELEASE(mFont);
|
||||
} else {
|
||||
NS_IF_RELEASE(mFontEntry);
|
||||
}
|
||||
|
||||
mFamily = aOther.mFamily;
|
||||
mNeedsBold = aOther.mNeedsBold;
|
||||
mFontCreated = aOther.mFontCreated;
|
||||
|
||||
if (mFontCreated) {
|
||||
mFont = aOther.mFont;
|
||||
NS_ADDREF(mFont);
|
||||
} else {
|
||||
mFontEntry = aOther.mFontEntry;
|
||||
NS_IF_ADDREF(mFontEntry);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
gfxFontFamily* Family() const { return mFamily.get(); }
|
||||
gfxFont* Font() const {
|
||||
return mFontCreated ? mFont : nullptr;
|
||||
}
|
||||
|
||||
gfxFontEntry* FontEntry() const {
|
||||
return mFontCreated ? mFont->GetFontEntry() : mFontEntry;
|
||||
}
|
||||
|
||||
bool NeedsBold() const { return mNeedsBold; }
|
||||
|
||||
void SetFont(gfxFont* aFont)
|
||||
{
|
||||
NS_ASSERTION(aFont, "font pointer must not be null");
|
||||
NS_ADDREF(aFont);
|
||||
if (mFontCreated) {
|
||||
NS_RELEASE(mFont);
|
||||
} else {
|
||||
NS_IF_RELEASE(mFontEntry);
|
||||
}
|
||||
mFont = aFont;
|
||||
mFontCreated = true;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<gfxFontFamily> mFamily;
|
||||
// either a font or a font entry exists
|
||||
union {
|
||||
gfxFont* mFont;
|
||||
gfxFontEntry* mFontEntry;
|
||||
};
|
||||
bool mNeedsBold : 1;
|
||||
bool mFontCreated : 1;
|
||||
};
|
||||
|
||||
mozilla::FontFamilyList mFamilyList;
|
||||
gfxFontStyle mStyle;
|
||||
nsTArray<FamilyFace> mFonts;
|
||||
@ -975,10 +1071,11 @@ protected:
|
||||
int32_t aRunScript);
|
||||
|
||||
// Helper for font-matching:
|
||||
// see if aCh is supported in any of the faces from aFamily;
|
||||
// if so return the best style match, else return null.
|
||||
already_AddRefed<gfxFont> TryAllFamilyMembers(gfxFontFamily* aFamily,
|
||||
uint32_t aCh);
|
||||
// When matching the italic case, allow use of the regular face
|
||||
// if it supports a character but the italic one doesn't.
|
||||
// Return null if regular face doesn't support aCh
|
||||
already_AddRefed<gfxFont>
|
||||
FindNonItalicFaceForChar(gfxFontFamily* aFamily, uint32_t aCh);
|
||||
|
||||
// helper methods for looking up fonts
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user