Bug 1182361 p3 - move generic lookup methods to platform fontlist. r=heycam

This commit is contained in:
John Daggett 2015-09-29 10:51:28 +09:00
Родитель 6d66c5e817
Коммит f2ee55e64a
4 изменённых файлов: 190 добавлений и 165 удалений

Просмотреть файл

@ -9,6 +9,8 @@
#include "gfxTextRun.h"
#include "gfxUserFontSet.h"
#include "nsGkAtoms.h"
#include "nsServiceManagerUtils.h"
#include "nsUnicharUtils.h"
#include "nsUnicodeRange.h"
#include "nsUnicodeProperties.h"
@ -801,6 +803,117 @@ gfxPlatformFontList::RemoveCmap(const gfxCharacterMap* aCharMap)
}
}
void
gfxPlatformFontList::ResolveGenericFontNames(FontFamilyType aGenericType,
nsIAtom *aLanguage,
nsTArray<nsString>& aGenericFamilies)
{
static const char kGeneric_serif[] = "serif";
static const char kGeneric_sans_serif[] = "sans-serif";
static const char kGeneric_monospace[] = "monospace";
static const char kGeneric_cursive[] = "cursive";
static const char kGeneric_fantasy[] = "fantasy";
// treat -moz-fixed as monospace
if (aGenericType == eFamily_moz_fixed) {
aGenericType = eFamily_monospace;
}
// type should be standard generic type at this point
NS_ASSERTION(aGenericType >= eFamily_serif &&
aGenericType <= eFamily_fantasy,
"standard generic font family type required");
// create the lang string
nsIAtom *langGroupAtom = nullptr;
nsAutoCString langGroupString;
if (aLanguage) {
if (!mLangService) {
mLangService = do_GetService(NS_LANGUAGEATOMSERVICE_CONTRACTID);
}
if (mLangService) {
nsresult rv;
langGroupAtom = mLangService->GetLanguageGroup(aLanguage, &rv);
}
}
if (!langGroupAtom) {
langGroupAtom = nsGkAtoms::Unicode;
}
langGroupAtom->ToUTF8String(langGroupString);
// map generic type to string
const char *generic = nullptr;
switch (aGenericType) {
case eFamily_serif:
generic = kGeneric_serif;
break;
case eFamily_sans_serif:
generic = kGeneric_sans_serif;
break;
case eFamily_monospace:
generic = kGeneric_monospace;
break;
case eFamily_cursive:
generic = kGeneric_cursive;
break;
case eFamily_fantasy:
generic = kGeneric_fantasy;
break;
default:
break;
}
if (!generic) {
return;
}
aGenericFamilies.Clear();
// load family for "font.name.generic.lang"
nsAutoCString prefFontName("font.name.");
prefFontName.Append(generic);
prefFontName.Append('.');
prefFontName.Append(langGroupString);
gfxFontUtils::AppendPrefsFontList(prefFontName.get(),
aGenericFamilies);
// if lang has pref fonts, also load fonts for "font.name-list.generic.lang"
if (!aGenericFamilies.IsEmpty()) {
nsAutoCString prefFontListName("font.name-list.");
prefFontListName.Append(generic);
prefFontListName.Append('.');
prefFontListName.Append(langGroupString);
gfxFontUtils::AppendPrefsFontList(prefFontListName.get(),
aGenericFamilies);
}
#if 0 // dump out generic mappings
printf("%s ===> ", prefFontName.get());
for (uint32_t k = 0; k < aGenericFamilies.Length(); k++) {
if (k > 0) printf(", ");
printf("%s", NS_ConvertUTF16toUTF8(aGenericFamilies[k]).get());
}
printf("\n");
#endif
}
void
gfxPlatformFontList::AddGenericFonts(mozilla::FontFamilyType aGenericType,
gfxFontStyle* aStyle,
nsTArray<gfxFontFamily*>& aFamilyList)
{
nsAutoTArray<nsString, 5> resolvedGenerics;
ResolveGenericFontNames(aGenericType, aStyle->language, resolvedGenerics);
uint32_t g = 0, numGenerics = resolvedGenerics.Length();
for (g = 0; g < numGenerics; g++) {
gfxFontFamily* family =
FindFamily(resolvedGenerics[g], aStyle->language, aStyle->systemFont);
if (family) {
aFamilyList.AppendElement(family);
}
}
}
void
gfxPlatformFontList::GetFontFamilyNames(nsTArray<nsString>& aFontFamilyNames)
{

Просмотреть файл

@ -14,10 +14,12 @@
#include "gfxFontInfoLoader.h"
#include "gfxFont.h"
#include "gfxPlatform.h"
#include "gfxFontFamilyList.h"
#include "nsIMemoryReporter.h"
#include "mozilla/Attributes.h"
#include "mozilla/MemoryReporting.h"
#include "nsILanguageAtomService.h"
class CharMapHashKey : public PLDHashEntryHdr
{
@ -199,6 +201,10 @@ public:
aLoaderState = (uint32_t) mState;
}
virtual void
AddGenericFonts(mozilla::FontFamilyType aGenericType, gfxFontStyle* aStyle,
nsTArray<gfxFontFamily*>& aFamilyList);
protected:
class MemoryReporter final : public nsIMemoryReporter
{
@ -287,6 +293,11 @@ protected:
void RebuildLocalFonts();
void
ResolveGenericFontNames(mozilla::FontFamilyType aGenericType,
nsIAtom *aLanguage,
nsTArray<nsString>& aGenericFamilies);
typedef nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> FontFamilyTable;
typedef nsRefPtrHashtable<nsStringHashKey, gfxFontEntry> FontEntryTable;
@ -360,6 +371,8 @@ protected:
uint32_t mFontlistInitCount; // num times InitFontList called
nsTHashtable<nsPtrHashKey<gfxUserFontSet> > mUserFontSetList;
nsCOMPtr<nsILanguageAtomService> mLangService;
};
#endif /* GFXPLATFORMFONTLIST_H_ */

Просмотреть файл

@ -1557,139 +1557,6 @@ gfxFontGroup::~gfxFontGroup()
{
}
void
gfxFontGroup::FindGenericFonts(FontFamilyType aGenericType,
nsIAtom *aLanguage)
{
nsAutoTArray<nsString, 5> resolvedGenerics;
ResolveGenericFontNames(aGenericType, aLanguage, resolvedGenerics);
uint32_t g = 0, numGenerics = resolvedGenerics.Length();
if (mTextPerf) {
mTextPerf->current.genericLookups++;
}
for (g = 0; g < numGenerics; g++) {
FindPlatformFont(resolvedGenerics[g], false);
}
}
/* static */ void
gfxFontGroup::ResolveGenericFontNames(FontFamilyType aGenericType,
nsIAtom *aLanguage,
nsTArray<nsString>& aGenericFamilies)
{
static const char kGeneric_serif[] = "serif";
static const char kGeneric_sans_serif[] = "sans-serif";
static const char kGeneric_monospace[] = "monospace";
static const char kGeneric_cursive[] = "cursive";
static const char kGeneric_fantasy[] = "fantasy";
// treat -moz-fixed as monospace
if (aGenericType == eFamily_moz_fixed) {
aGenericType = eFamily_monospace;
}
// type should be standard generic type at this point
NS_ASSERTION(aGenericType >= eFamily_serif &&
aGenericType <= eFamily_fantasy,
"standard generic font family type required");
// create the lang string
nsIAtom *langGroupAtom = nullptr;
nsAutoCString langGroupString;
if (aLanguage) {
if (!gLangService) {
CallGetService(NS_LANGUAGEATOMSERVICE_CONTRACTID, &gLangService);
}
if (gLangService) {
nsresult rv;
langGroupAtom = gLangService->GetLanguageGroup(aLanguage, &rv);
}
}
if (!langGroupAtom) {
langGroupAtom = nsGkAtoms::Unicode;
}
langGroupAtom->ToUTF8String(langGroupString);
// map generic type to string
const char *generic = nullptr;
switch (aGenericType) {
case eFamily_serif:
generic = kGeneric_serif;
break;
case eFamily_sans_serif:
generic = kGeneric_sans_serif;
break;
case eFamily_monospace:
generic = kGeneric_monospace;
break;
case eFamily_cursive:
generic = kGeneric_cursive;
break;
case eFamily_fantasy:
generic = kGeneric_fantasy;
break;
default:
break;
}
if (!generic) {
return;
}
aGenericFamilies.Clear();
// load family for "font.name.generic.lang"
nsAutoCString prefFontName("font.name.");
prefFontName.Append(generic);
prefFontName.Append('.');
prefFontName.Append(langGroupString);
gfxFontUtils::AppendPrefsFontList(prefFontName.get(),
aGenericFamilies);
// if lang has pref fonts, also load fonts for "font.name-list.generic.lang"
if (!aGenericFamilies.IsEmpty()) {
nsAutoCString prefFontListName("font.name-list.");
prefFontListName.Append(generic);
prefFontListName.Append('.');
prefFontListName.Append(langGroupString);
gfxFontUtils::AppendPrefsFontList(prefFontListName.get(),
aGenericFamilies);
}
#if 0 // dump out generic mappings
printf("%s ===> ", prefFontName.get());
for (uint32_t k = 0; k < aGenericFamilies.Length(); k++) {
if (k > 0) printf(", ");
printf("%s", NS_ConvertUTF16toUTF8(aGenericFamilies[k]).get());
}
printf("\n");
#endif
}
void gfxFontGroup::EnumerateFontList(nsIAtom *aLanguage)
{
// initialize fonts in the font family list
const nsTArray<FontFamilyName>& fontlist = mFamilyList.GetFontlist();
// lookup fonts in the fontlist
uint32_t i, numFonts = fontlist.Length();
for (i = 0; i < numFonts; i++) {
const FontFamilyName& name = fontlist[i];
if (name.IsNamed()) {
FindPlatformFont(name.mName, true);
} else {
FindGenericFonts(name.mType, aLanguage);
}
}
// if necessary, append default generic onto the end
if (mFamilyList.GetDefaultFontType() != eFamily_none &&
!mFamilyList.HasDefaultGeneric()) {
FindGenericFonts(mFamilyList.GetDefaultFontType(),
aLanguage);
}
}
void
gfxFontGroup::BuildFontList()
{
@ -1701,15 +1568,52 @@ gfxFontGroup::BuildFontList()
#elif defined(MOZ_WIDGET_QT)
enumerateFonts = false;
#endif
if (enumerateFonts) {
EnumerateFontList(mStyle.language);
if (!enumerateFonts) {
return;
}
// initialize fonts in the font family list
nsAutoTArray<gfxFontFamily*,4> fonts;
const nsTArray<FontFamilyName>& fontlist = mFamilyList.GetFontlist();
gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
// lookup fonts in the fontlist
uint32_t i, numFonts = fontlist.Length();
for (i = 0; i < numFonts; i++) {
gfxFontFamily* family;
const FontFamilyName& name = fontlist[i];
if (name.IsNamed()) {
family = FindPlatformFont(name.mName, true);
if (family) {
fonts.AppendElement(family);
}
} else {
pfl->AddGenericFonts(name.mType, &mStyle, fonts);
if (mTextPerf) {
mTextPerf->current.genericLookups++;
}
}
}
// if necessary, append default generic onto the end
if (mFamilyList.GetDefaultFontType() != eFamily_none &&
!mFamilyList.HasDefaultGeneric()) {
pfl->AddGenericFonts(mFamilyList.GetDefaultFontType(), &mStyle, fonts);
if (mTextPerf) {
mTextPerf->current.genericLookups++;
}
}
// build the fontlist from the specified families
numFonts = fonts.Length();
for (i = 0; i < numFonts; i++) {
AddFamilyToFontList(fonts[i]);
}
}
void
gfxFontFamily*
gfxFontGroup::FindPlatformFont(const nsAString& aName, bool aUseFontSet)
{
bool needsBold;
gfxFontFamily *family = nullptr;
if (aUseFontSet) {
@ -1730,21 +1634,26 @@ gfxFontGroup::FindPlatformFont(const nsAString& aName, bool aUseFontSet)
family = fontList->FindFamily(aName, mStyle.language, mStyle.systemFont);
}
// if family found, do style matching and add all font entries to mFonts
if (family) {
nsAutoTArray<gfxFontEntry*,4> fontEntryList;
family->FindAllFontsForStyle(mStyle, fontEntryList, needsBold);
// add these to the fontlist
uint32_t n = fontEntryList.Length();
for (uint32_t i = 0; i < n; i++) {
gfxFontEntry* fe = fontEntryList[i];
if (!HasFont(fe)) {
FamilyFace ff(family, fe, needsBold);
if (fe->mIsUserFontContainer) {
ff.CheckState(mSkipDrawing);
}
mFonts.AppendElement(ff);
return family;
}
void
gfxFontGroup::AddFamilyToFontList(gfxFontFamily* aFamily)
{
NS_ASSERTION(aFamily, "trying to add a null font family to fontlist");
nsAutoTArray<gfxFontEntry*,4> fontEntryList;
bool needsBold;
aFamily->FindAllFontsForStyle(mStyle, fontEntryList, needsBold);
// add these to the fontlist
uint32_t n = fontEntryList.Length();
for (uint32_t i = 0; i < n; i++) {
gfxFontEntry* fe = fontEntryList[i];
if (!HasFont(fe)) {
FamilyFace ff(aFamily, fe, needsBold);
if (fe->mIsUserFontContainer) {
ff.CheckState(mSkipDrawing);
}
mFonts.AppendElement(ff);
}
}
}

Просмотреть файл

@ -872,12 +872,6 @@ public:
gfxTextRun* GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel, uint32_t aFlags,
LazyReferenceContextGetter& aRefContextGetter);
// helper method for resolving generic font families
static void
ResolveGenericFontNames(mozilla::FontFamilyType aGenericType,
nsIAtom *aLanguage,
nsTArray<nsString>& aGenericFamilies);
protected:
// search through pref fonts for a character, return nullptr if no matching pref font
already_AddRefed<gfxFont> WhichPrefFontSupportsChar(uint32_t aCh);
@ -1117,15 +1111,11 @@ protected:
// helper methods for looking up fonts
// iterate over the fontlist, lookup names and expand generics
void EnumerateFontList(nsIAtom *aLanguage);
// expand a generic to a list of specific names based on prefs
void FindGenericFonts(mozilla::FontFamilyType aGenericType,
nsIAtom *aLanguage);
// lookup and add a font with a given name (i.e. *not* a generic!)
void FindPlatformFont(const nsAString& aName, bool aUseFontSet);
gfxFontFamily* FindPlatformFont(const nsAString& aName, bool aUseFontSet);
// do style selection and add entries to list
void AddFamilyToFontList(gfxFontFamily* aFamily);
static nsILanguageAtomService* gLangService;
};