mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1062058 part 3 - make userfont entry a container of the platform font entry. r=heycam
This commit is contained in:
parent
4152f3896a
commit
b59e49acf6
@ -1333,6 +1333,27 @@ gfxFontFamily::CheckForSimpleFamily()
|
||||
mIsSimpleFamily = true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
gfxFontFamily::ContainsFace(gfxFontEntry* aFontEntry) {
|
||||
uint32_t i, numFonts = mAvailableFonts.Length();
|
||||
for (i = 0; i < numFonts; i++) {
|
||||
if (mAvailableFonts[i] == aFontEntry) {
|
||||
return true;
|
||||
}
|
||||
// userfonts contain the actual real font entry
|
||||
if (mAvailableFonts[i]->mIsUserFontContainer) {
|
||||
gfxUserFontEntry* ufe =
|
||||
static_cast<gfxUserFontEntry*>(mAvailableFonts[i].get());
|
||||
if (ufe->GetPlatformFontEntry() == aFontEntry) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint32_t
|
||||
StyleDistance(gfxFontEntry *aFontEntry,
|
||||
bool anItalic, int16_t aStretch)
|
||||
@ -5041,8 +5062,13 @@ gfxFontGroup::FindPlatformFont(const nsAString& aName,
|
||||
family = mUserFontSet->LookupFamily(aName);
|
||||
if (family) {
|
||||
bool waitForUserFont = false;
|
||||
fe = mUserFontSet->FindFontEntry(family, mStyle,
|
||||
needsBold, waitForUserFont);
|
||||
gfxUserFontEntry* userFontEntry = nullptr;
|
||||
userFontEntry = mUserFontSet->FindUserFontEntry(family, mStyle,
|
||||
needsBold,
|
||||
waitForUserFont);
|
||||
if (userFontEntry) {
|
||||
fe = userFontEntry->GetPlatformFontEntry();
|
||||
}
|
||||
if (!fe && waitForUserFont) {
|
||||
mSkipDrawing = true;
|
||||
}
|
||||
@ -5052,7 +5078,7 @@ gfxFontGroup::FindPlatformFont(const nsAString& aName,
|
||||
|
||||
// Not known in the user font set ==> check system fonts
|
||||
if (!family) {
|
||||
gfxPlatformFontList *fontList = gfxPlatformFontList::PlatformFontList();
|
||||
gfxPlatformFontList* fontList = gfxPlatformFontList::PlatformFontList();
|
||||
family = fontList->FindFamily(aName, mStyle.systemFont);
|
||||
if (family) {
|
||||
fe = family->FindFontForStyle(mStyle, needsBold);
|
||||
|
@ -557,9 +557,9 @@ public:
|
||||
bool mFixedPitch : 1;
|
||||
bool mIsValid : 1;
|
||||
bool mIsBadUnderlineFont : 1;
|
||||
bool mIsUserFontContainer : 1;
|
||||
bool mIsDataUserFont : 1;
|
||||
bool mIsLocalUserFont : 1;
|
||||
bool mIsUserFontContainer : 1; // userfont entry
|
||||
bool mIsDataUserFont : 1; // platform font entry (data)
|
||||
bool mIsLocalUserFont : 1; // platform font entry (local)
|
||||
bool mStandardFace : 1;
|
||||
bool mSymbolFont : 1;
|
||||
bool mIgnoreGDEF : 1;
|
||||
@ -932,16 +932,10 @@ public:
|
||||
virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
|
||||
FontListSizes* aSizes) const;
|
||||
|
||||
#ifdef DEBUG
|
||||
// Only used for debugging checks - does a linear search
|
||||
bool ContainsFace(gfxFontEntry* aFontEntry) {
|
||||
uint32_t i, numFonts = mAvailableFonts.Length();
|
||||
for (i = 0; i < numFonts; i++) {
|
||||
if (mAvailableFonts[i] == aFontEntry) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool ContainsFace(gfxFontEntry* aFontEntry);
|
||||
#endif
|
||||
|
||||
void SetSkipSpaceFeatureCheck(bool aSkipCheck) {
|
||||
mSkipDefaultFeatureSpaceCheck = aSkipCheck;
|
||||
|
@ -812,16 +812,27 @@ FindFontPatterns(gfxUserFontSet *mUserFontSet,
|
||||
gfxUserFcFontEntry *fontEntry = nullptr;
|
||||
gfxFontFamily *family = mUserFontSet->LookupFamily(utf16Family);
|
||||
if (family) {
|
||||
fontEntry = static_cast<gfxUserFcFontEntry*>
|
||||
(mUserFontSet->FindFontEntry(family, style, needsBold,
|
||||
aWaitForUserFont));
|
||||
gfxUserFontEntry* userFontEntry =
|
||||
mUserFontSet->FindUserFontEntry(family, style, needsBold,
|
||||
aWaitForUserFont);
|
||||
if (userFontEntry) {
|
||||
fontEntry = static_cast<gfxUserFcFontEntry*>
|
||||
(userFontEntry->GetPlatformFontEntry());
|
||||
}
|
||||
|
||||
// Accept synthetic oblique for italic and oblique.
|
||||
// xxx - this isn't really ideal behavior, for docs that only use a
|
||||
// single italic face it will also pull down the normal face
|
||||
// and probably never use it
|
||||
if (!fontEntry && aStyle != NS_FONT_STYLE_NORMAL) {
|
||||
style.style = NS_FONT_STYLE_NORMAL;
|
||||
fontEntry = static_cast<gfxUserFcFontEntry*>
|
||||
(mUserFontSet->FindFontEntry(family, style, needsBold,
|
||||
aWaitForUserFont));
|
||||
userFontEntry = mUserFontSet->FindUserFontEntry(family, style,
|
||||
needsBold,
|
||||
aWaitForUserFont);
|
||||
if (userFontEntry) {
|
||||
fontEntry = static_cast<gfxUserFcFontEntry*>
|
||||
(userFontEntry->GetPlatformFontEntry());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1009,7 +1020,7 @@ gfxFcFontSet::SortPreferredFonts(bool &aWaitForUserFont)
|
||||
}
|
||||
|
||||
// User fonts are already filtered by slant (but not size) in
|
||||
// mUserFontSet->FindFontEntry().
|
||||
// mUserFontSet->FindUserFontEntry().
|
||||
if (requestedSize != -1.0 && !SizeIsAcceptable(font, requestedSize))
|
||||
continue;
|
||||
|
||||
|
@ -27,10 +27,10 @@
|
||||
using namespace mozilla;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModuleInfo *
|
||||
PRLogModuleInfo*
|
||||
gfxUserFontSet::GetUserFontsLog()
|
||||
{
|
||||
static PRLogModuleInfo *sLog;
|
||||
static PRLogModuleInfo* sLog;
|
||||
if (!sLog)
|
||||
sLog = PR_NewLogModule("userfonts");
|
||||
return sLog;
|
||||
@ -65,7 +65,7 @@ public:
|
||||
return p;
|
||||
}
|
||||
|
||||
bool WriteRaw(const void *data, size_t length) {
|
||||
bool WriteRaw(const void* data, size_t length) {
|
||||
if ((mOff + length > mLength) ||
|
||||
(mLength > std::numeric_limits<size_t>::max() - mOff)) {
|
||||
if (mLength == mLimit) {
|
||||
@ -111,14 +111,14 @@ private:
|
||||
|
||||
// TODO: support for unicode ranges not yet implemented
|
||||
|
||||
gfxUserFontEntry::gfxUserFontEntry(gfxUserFontSet *aFontSet,
|
||||
gfxUserFontEntry::gfxUserFontEntry(gfxUserFontSet* aFontSet,
|
||||
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
|
||||
uint32_t aWeight,
|
||||
int32_t aStretch,
|
||||
uint32_t aItalicStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet *aUnicodeRanges)
|
||||
gfxSparseBitSet* aUnicodeRanges)
|
||||
: gfxFontEntry(NS_LITERAL_STRING("userfont")),
|
||||
mLoadingState(NOT_LOADING),
|
||||
mUnsupportedFormat(false),
|
||||
@ -148,7 +148,7 @@ gfxUserFontEntry::Matches(const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
|
||||
uint32_t aItalicStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet *aUnicodeRanges)
|
||||
gfxSparseBitSet* aUnicodeRanges)
|
||||
{
|
||||
// XXX font entries don't distinguish italic from oblique (bug 543715)
|
||||
bool isItalic =
|
||||
@ -165,16 +165,19 @@ gfxUserFontEntry::Matches(const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
|
||||
}
|
||||
|
||||
gfxFont*
|
||||
gfxUserFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold)
|
||||
gfxUserFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle, bool aNeedsBold)
|
||||
{
|
||||
NS_NOTREACHED("should only be creating a gfxFont"
|
||||
" with an actual platform font entry");
|
||||
|
||||
// userfont entry is a container, can't create font from the container
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
class gfxOTSContext : public ots::OTSContext {
|
||||
public:
|
||||
gfxOTSContext(gfxUserFontFamily *aFamily, gfxUserFontEntry *aUserFontEntry)
|
||||
: mFamily(aFamily), mUserFontEntry(aUserFontEntry) {}
|
||||
gfxOTSContext(gfxUserFontEntry* aUserFontEntry)
|
||||
: mUserFontEntry(aUserFontEntry) {}
|
||||
|
||||
virtual ots::TableAction GetTableAction(uint32_t aTag) MOZ_OVERRIDE {
|
||||
// preserve Graphite, color glyph and SVG tables
|
||||
@ -191,7 +194,7 @@ public:
|
||||
return ots::TABLE_ACTION_DEFAULT;
|
||||
}
|
||||
|
||||
virtual void Message(const char *format, ...) MSGFUNC_FMT_ATTR MOZ_OVERRIDE {
|
||||
virtual void Message(const char* format, ...) MSGFUNC_FMT_ATTR MOZ_OVERRIDE {
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
@ -202,19 +205,17 @@ public:
|
||||
|
||||
va_end(va);
|
||||
|
||||
mUserFontEntry->mFontSet->LogMessage(mFamily, mUserFontEntry, buf);
|
||||
mUserFontEntry->mFontSet->LogMessage(mUserFontEntry, buf);
|
||||
}
|
||||
|
||||
private:
|
||||
gfxUserFontFamily *mFamily;
|
||||
gfxUserFontEntry *mUserFontEntry;
|
||||
gfxUserFontEntry* mUserFontEntry;
|
||||
};
|
||||
|
||||
// Call the OTS library to sanitize an sfnt before attempting to use it.
|
||||
// Returns a newly-allocated block, or nullptr in case of fatal errors.
|
||||
const uint8_t*
|
||||
gfxUserFontEntry::SanitizeOpenTypeData(gfxUserFontFamily *aFamily,
|
||||
const uint8_t* aData,
|
||||
gfxUserFontEntry::SanitizeOpenTypeData(const uint8_t* aData,
|
||||
uint32_t aLength,
|
||||
uint32_t& aSaneLength,
|
||||
bool aIsCompressed)
|
||||
@ -223,7 +224,7 @@ gfxUserFontEntry::SanitizeOpenTypeData(gfxUserFontFamily *aFamily,
|
||||
ExpandingMemoryStream output(aIsCompressed ? aLength * 2 : aLength,
|
||||
1024 * 1024 * 256);
|
||||
|
||||
gfxOTSContext otsContext(aFamily, this);
|
||||
gfxOTSContext otsContext(this);
|
||||
|
||||
if (otsContext.Process(&output, aData, aLength)) {
|
||||
aSaneLength = output.Tell();
|
||||
@ -310,8 +311,7 @@ CopyWOFFMetadata(const uint8_t* aFontData,
|
||||
}
|
||||
|
||||
gfxUserFontEntry::LoadStatus
|
||||
gfxUserFontEntry::LoadNext(gfxUserFontFamily *aFamily,
|
||||
bool& aLocalRulesUsed)
|
||||
gfxUserFontEntry::LoadNext()
|
||||
{
|
||||
uint32_t numSrc = mSrcList.Length();
|
||||
|
||||
@ -336,12 +336,12 @@ gfxUserFontEntry::LoadNext(gfxUserFontFamily *aFamily,
|
||||
// src local ==> lookup and load immediately
|
||||
|
||||
if (currSrc.mIsLocal) {
|
||||
gfxFontEntry *fe =
|
||||
gfxFontEntry* fe =
|
||||
gfxPlatform::GetPlatform()->LookupLocalFont(currSrc.mLocalName,
|
||||
mWeight,
|
||||
mStretch,
|
||||
mItalic);
|
||||
aLocalRulesUsed = true;
|
||||
mFontSet->SetLocalRulesUsed();
|
||||
if (fe) {
|
||||
LOG(("fontset (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n",
|
||||
mFontSet, mSrcIndex,
|
||||
@ -355,7 +355,7 @@ gfxUserFontEntry::LoadNext(gfxUserFontFamily *aFamily,
|
||||
// a private window as there's no issue of caching resources;
|
||||
// local fonts are just available all the time.
|
||||
StoreUserFontData(fe, false, nsString(), nullptr, 0);
|
||||
mFontSet->ReplaceFontEntry(aFamily, this, fe);
|
||||
mPlatformFontEntry = fe;
|
||||
return STATUS_LOADED;
|
||||
} else {
|
||||
LOG(("fontset (%p) [src %d] failed local: (%s) for (%s)\n",
|
||||
@ -370,7 +370,7 @@ gfxUserFontEntry::LoadNext(gfxUserFontFamily *aFamily,
|
||||
if (gfxPlatform::GetPlatform()->IsFontFormatSupported(currSrc.mURI,
|
||||
currSrc.mFormatFlags)) {
|
||||
|
||||
nsIPrincipal *principal = nullptr;
|
||||
nsIPrincipal* principal = nullptr;
|
||||
bool bypassCache;
|
||||
nsresult rv = mFontSet->CheckFontLoad(&currSrc, &principal,
|
||||
&bypassCache);
|
||||
@ -378,13 +378,13 @@ gfxUserFontEntry::LoadNext(gfxUserFontFamily *aFamily,
|
||||
if (NS_SUCCEEDED(rv) && principal != nullptr) {
|
||||
if (!bypassCache) {
|
||||
// see if we have an existing entry for this source
|
||||
gfxFontEntry *fe = gfxUserFontSet::
|
||||
gfxFontEntry* fe = gfxUserFontSet::
|
||||
UserFontCache::GetFont(currSrc.mURI,
|
||||
principal,
|
||||
this,
|
||||
mFontSet->GetPrivateBrowsing());
|
||||
if (fe) {
|
||||
mFontSet->ReplaceFontEntry(aFamily, this, fe);
|
||||
mPlatformFontEntry = fe;
|
||||
return STATUS_LOADED;
|
||||
}
|
||||
}
|
||||
@ -400,7 +400,7 @@ gfxUserFontEntry::LoadNext(gfxUserFontFamily *aFamily,
|
||||
&loadDoesntSpin);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && loadDoesntSpin) {
|
||||
uint8_t *buffer = nullptr;
|
||||
uint8_t* buffer = nullptr;
|
||||
uint32_t bufferLength = 0;
|
||||
|
||||
// sync load font immediately
|
||||
@ -408,10 +408,10 @@ gfxUserFontEntry::LoadNext(gfxUserFontFamily *aFamily,
|
||||
bufferLength);
|
||||
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
LoadFont(aFamily, buffer, bufferLength)) {
|
||||
LoadFont(buffer, bufferLength)) {
|
||||
return STATUS_LOADED;
|
||||
} else {
|
||||
mFontSet->LogMessage(aFamily, this,
|
||||
mFontSet->LogMessage(this,
|
||||
"font load failed",
|
||||
nsIScriptError::errorFlag,
|
||||
rv);
|
||||
@ -419,7 +419,7 @@ gfxUserFontEntry::LoadNext(gfxUserFontFamily *aFamily,
|
||||
|
||||
} else {
|
||||
// otherwise load font async
|
||||
rv = mFontSet->StartLoad(aFamily, this, &currSrc);
|
||||
rv = mFontSet->StartLoad(this, &currSrc);
|
||||
bool loadOK = NS_SUCCEEDED(rv);
|
||||
|
||||
if (loadOK) {
|
||||
@ -434,14 +434,14 @@ gfxUserFontEntry::LoadNext(gfxUserFontFamily *aFamily,
|
||||
#endif
|
||||
return STATUS_LOADING;
|
||||
} else {
|
||||
mFontSet->LogMessage(aFamily, this,
|
||||
mFontSet->LogMessage(this,
|
||||
"download failed",
|
||||
nsIScriptError::errorFlag,
|
||||
rv);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mFontSet->LogMessage(aFamily, this, "download not allowed",
|
||||
mFontSet->LogMessage(this, "download not allowed",
|
||||
nsIScriptError::errorFlag, rv);
|
||||
}
|
||||
} else {
|
||||
@ -455,7 +455,7 @@ gfxUserFontEntry::LoadNext(gfxUserFontFamily *aFamily,
|
||||
}
|
||||
|
||||
if (mUnsupportedFormat) {
|
||||
mFontSet->LogMessage(aFamily, this, "no supported format found",
|
||||
mFontSet->LogMessage(this, "no supported format found",
|
||||
nsIScriptError::warningFlag);
|
||||
}
|
||||
|
||||
@ -467,11 +467,10 @@ gfxUserFontEntry::LoadNext(gfxUserFontFamily *aFamily,
|
||||
return STATUS_END_OF_LIST;
|
||||
}
|
||||
|
||||
gfxFontEntry*
|
||||
gfxUserFontEntry::LoadFont(gfxUserFontFamily *aFamily,
|
||||
const uint8_t* aFontData, uint32_t &aLength)
|
||||
bool
|
||||
gfxUserFontEntry::LoadFont(const uint8_t* aFontData, uint32_t &aLength)
|
||||
{
|
||||
gfxFontEntry *fe = nullptr;
|
||||
gfxFontEntry* fe = nullptr;
|
||||
|
||||
gfxUserFontType fontType =
|
||||
gfxFontUtils::DetermineFontDataType(aFontData, aLength);
|
||||
@ -488,10 +487,10 @@ gfxUserFontEntry::LoadFont(gfxUserFontFamily *aFamily,
|
||||
// if necessary. The original data in aFontData is left unchanged.
|
||||
uint32_t saneLen;
|
||||
const uint8_t* saneData =
|
||||
SanitizeOpenTypeData(aFamily, aFontData, aLength, saneLen,
|
||||
SanitizeOpenTypeData(aFontData, aLength, saneLen,
|
||||
fontType == GFX_USERFONT_WOFF);
|
||||
if (!saneData) {
|
||||
mFontSet->LogMessage(aFamily, this, "rejected by sanitizer");
|
||||
mFontSet->LogMessage(this, "rejected by sanitizer");
|
||||
}
|
||||
if (saneData) {
|
||||
// The sanitizer ensures that we have a valid sfnt and a usable
|
||||
@ -510,7 +509,7 @@ gfxUserFontEntry::LoadFont(gfxUserFontFamily *aFamily,
|
||||
saneData,
|
||||
saneLen);
|
||||
if (!fe) {
|
||||
mFontSet->LogMessage(aFamily, this, "not usable by platform");
|
||||
mFontSet->LogMessage(this, "not usable by platform");
|
||||
}
|
||||
}
|
||||
|
||||
@ -541,7 +540,7 @@ gfxUserFontEntry::LoadFont(gfxUserFontFamily *aFamily,
|
||||
uint32_t(mFontSet->mGeneration)));
|
||||
}
|
||||
#endif
|
||||
mFontSet->ReplaceFontEntry(aFamily, this, fe);
|
||||
mPlatformFontEntry = fe;
|
||||
gfxUserFontSet::UserFontCache::CacheFont(fe);
|
||||
} else {
|
||||
#ifdef PR_LOGGING
|
||||
@ -560,14 +559,57 @@ gfxUserFontEntry::LoadFont(gfxUserFontFamily *aFamily,
|
||||
// sanitized copy
|
||||
NS_Free((void*)aFontData);
|
||||
|
||||
return fe;
|
||||
return fe != nullptr;
|
||||
}
|
||||
|
||||
// This is called when a font download finishes.
|
||||
// Ownership of aFontData passes in here, and the font set must
|
||||
// ensure that it is eventually deleted via NS_Free().
|
||||
bool
|
||||
gfxUserFontEntry::OnLoadComplete(const uint8_t* aFontData, uint32_t aLength,
|
||||
nsresult aDownloadStatus)
|
||||
{
|
||||
// forget about the loader, as we no longer potentially need to cancel it
|
||||
// if the entry is obsoleted
|
||||
mLoader = nullptr;
|
||||
|
||||
// download successful, make platform font using font data
|
||||
if (NS_SUCCEEDED(aDownloadStatus)) {
|
||||
bool loaded = LoadFont(aFontData, aLength);
|
||||
aFontData = nullptr;
|
||||
|
||||
if (loaded) {
|
||||
mFontSet->IncrementGeneration();
|
||||
return true;
|
||||
}
|
||||
|
||||
} else {
|
||||
// download failed
|
||||
mFontSet->LogMessage(this,
|
||||
"download failed", nsIScriptError::errorFlag,
|
||||
aDownloadStatus);
|
||||
}
|
||||
|
||||
if (aFontData) {
|
||||
moz_free((void*)aFontData);
|
||||
}
|
||||
|
||||
// error occurred, load next src
|
||||
LoadNext();
|
||||
|
||||
// We ignore the status returned by LoadNext();
|
||||
// even if loading failed, we need to bump the font-set generation
|
||||
// and return true in order to trigger reflow, so that fallback
|
||||
// will be used where the text was "masked" by the pending download
|
||||
mFontSet->IncrementGeneration();
|
||||
return true;
|
||||
}
|
||||
|
||||
gfxUserFontSet::gfxUserFontSet()
|
||||
: mFontFamilies(4), mLocalRulesUsed(false)
|
||||
{
|
||||
IncrementGeneration();
|
||||
gfxPlatformFontList *fp = gfxPlatformFontList::PlatformFontList();
|
||||
gfxPlatformFontList* fp = gfxPlatformFontList::PlatformFontList();
|
||||
if (fp) {
|
||||
fp->AddUserFontSet(this);
|
||||
}
|
||||
@ -575,7 +617,7 @@ gfxUserFontSet::gfxUserFontSet()
|
||||
|
||||
gfxUserFontSet::~gfxUserFontSet()
|
||||
{
|
||||
gfxPlatformFontList *fp = gfxPlatformFontList::PlatformFontList();
|
||||
gfxPlatformFontList* fp = gfxPlatformFontList::PlatformFontList();
|
||||
if (fp) {
|
||||
fp->RemoveUserFontSet(this);
|
||||
}
|
||||
@ -686,36 +728,43 @@ gfxUserFontSet::FindExistingUserFontEntry(
|
||||
|
||||
void
|
||||
gfxUserFontSet::AddFontFace(const nsAString& aFamilyName,
|
||||
gfxFontEntry *aFontEntry)
|
||||
gfxUserFontEntry* aUserFontEntry)
|
||||
{
|
||||
gfxUserFontFamily* family = GetFamily(aFamilyName);
|
||||
family->AddFontEntry(aFontEntry);
|
||||
family->AddFontEntry(aUserFontEntry);
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
if (LOG_ENABLED()) {
|
||||
LOG(("userfonts (%p) added \"%s\" (%p)",
|
||||
this, NS_ConvertUTF16toUTF8(aFamilyName).get(), aFontEntry));
|
||||
this, NS_ConvertUTF16toUTF8(aFamilyName).get(), aUserFontEntry));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
gfxFontEntry*
|
||||
gfxUserFontSet::FindFontEntry(gfxFontFamily *aFamily,
|
||||
const gfxFontStyle& aFontStyle,
|
||||
bool& aNeedsBold,
|
||||
bool& aWaitForUserFont)
|
||||
gfxUserFontEntry*
|
||||
gfxUserFontSet::FindUserFontEntry(gfxFontFamily* aFamily,
|
||||
const gfxFontStyle& aFontStyle,
|
||||
bool& aNeedsBold,
|
||||
bool& aWaitForUserFont)
|
||||
{
|
||||
aWaitForUserFont = false;
|
||||
gfxUserFontFamily *family = static_cast<gfxUserFontFamily*>(aFamily);
|
||||
gfxUserFontFamily* family = static_cast<gfxUserFontFamily*>(aFamily);
|
||||
|
||||
gfxFontEntry* fe = family->FindFontForStyle(aFontStyle, aNeedsBold);
|
||||
|
||||
NS_ASSERTION(!fe || fe->mIsUserFontContainer,
|
||||
"should only have userfont entries in userfont families");
|
||||
|
||||
// if not a userfont entry, font has already been loaded
|
||||
if (!fe->mIsUserFontContainer) {
|
||||
return fe;
|
||||
if (!fe || !fe->mIsUserFontContainer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gfxUserFontEntry *userFontEntry = static_cast<gfxUserFontEntry*> (fe);
|
||||
gfxUserFontEntry* userFontEntry = static_cast<gfxUserFontEntry*> (fe);
|
||||
|
||||
if (userFontEntry->GetPlatformFontEntry()) {
|
||||
return userFontEntry;
|
||||
}
|
||||
|
||||
// if currently loading, return null for now
|
||||
if (userFontEntry->mLoadingState > gfxUserFontEntry::NOT_LOADING) {
|
||||
@ -729,12 +778,11 @@ gfxUserFontSet::FindFontEntry(gfxFontFamily *aFamily,
|
||||
|
||||
// NOTE that if all sources in the entry fail, this will delete userFontEntry,
|
||||
// so we cannot use it again if status==STATUS_END_OF_LIST
|
||||
status = userFontEntry->LoadNext(family, mLocalRulesUsed);
|
||||
status = userFontEntry->LoadNext();
|
||||
|
||||
// if the load succeeded immediately, the font entry was replaced so
|
||||
// search again
|
||||
// if the load succeeded immediately, return
|
||||
if (status == gfxUserFontEntry::STATUS_LOADED) {
|
||||
return family->FindFontForStyle(aFontStyle, aNeedsBold);
|
||||
return userFontEntry;
|
||||
}
|
||||
|
||||
// check whether we should wait for load to complete before painting
|
||||
@ -746,51 +794,6 @@ gfxUserFontSet::FindFontEntry(gfxFontFamily *aFamily,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This is called when a font download finishes.
|
||||
// Ownership of aFontData passes in here, and the font set must
|
||||
// ensure that it is eventually deleted via NS_Free().
|
||||
bool
|
||||
gfxUserFontSet::OnLoadComplete(gfxUserFontFamily *aFamily,
|
||||
gfxUserFontEntry *aUserFontEntry,
|
||||
const uint8_t* aFontData, uint32_t aLength,
|
||||
nsresult aDownloadStatus)
|
||||
{
|
||||
// forget about the loader, as we no longer potentially need to cancel it
|
||||
// if the entry is obsoleted
|
||||
aUserFontEntry->mLoader = nullptr;
|
||||
|
||||
// download successful, make platform font using font data
|
||||
if (NS_SUCCEEDED(aDownloadStatus)) {
|
||||
gfxFontEntry *fe = aUserFontEntry->LoadFont(aFamily, aFontData, aLength);
|
||||
aFontData = nullptr;
|
||||
|
||||
if (fe) {
|
||||
IncrementGeneration();
|
||||
return true;
|
||||
}
|
||||
|
||||
} else {
|
||||
// download failed
|
||||
LogMessage(aFamily, aUserFontEntry,
|
||||
"download failed", nsIScriptError::errorFlag,
|
||||
aDownloadStatus);
|
||||
}
|
||||
|
||||
if (aFontData) {
|
||||
moz_free((void*)aFontData);
|
||||
}
|
||||
|
||||
// error occurred, load next src
|
||||
(void)aUserFontEntry->LoadNext(aFamily, mLocalRulesUsed);
|
||||
|
||||
// We ignore the status returned by LoadNext();
|
||||
// even if loading failed, we need to bump the font-set generation
|
||||
// and return true in order to trigger reflow, so that fallback
|
||||
// will be used where the text was "masked" by the pending download
|
||||
IncrementGeneration();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
gfxUserFontSet::IncrementGeneration()
|
||||
{
|
||||
@ -832,33 +835,6 @@ gfxUserFontSet::GetFamily(const nsAString& aFamilyName)
|
||||
return family;
|
||||
}
|
||||
|
||||
struct FindFamilyCallbackData {
|
||||
gfxFontEntry *mFontEntry;
|
||||
gfxFontFamily *mFamily;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
FindFamilyCallback(const nsAString& aName,
|
||||
gfxUserFontFamily* aFamily,
|
||||
void* aUserArg)
|
||||
{
|
||||
FindFamilyCallbackData *d = static_cast<FindFamilyCallbackData*>(aUserArg);
|
||||
if (aFamily->ContainsFace(d->mFontEntry)) {
|
||||
d->mFamily = aFamily;
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
gfxFontFamily*
|
||||
gfxUserFontSet::FindFamilyFor(gfxFontEntry* aFontEntry) const
|
||||
{
|
||||
FindFamilyCallbackData d = { aFontEntry, nullptr };
|
||||
mFontFamilies.EnumerateRead(FindFamilyCallback, &d);
|
||||
return d.mFamily;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// gfxUserFontSet::UserFontCache - re-use platform font entries for user fonts
|
||||
// across pages/fontsets rather than instantiating new platform fonts.
|
||||
@ -932,7 +908,7 @@ gfxUserFontSet::UserFontCache::Flusher::Observe(nsISupports* aSubject,
|
||||
}
|
||||
|
||||
static bool
|
||||
IgnorePrincipal(nsIURI *aURI)
|
||||
IgnorePrincipal(nsIURI* aURI)
|
||||
{
|
||||
nsresult rv;
|
||||
bool inherits = false;
|
||||
@ -945,7 +921,7 @@ IgnorePrincipal(nsIURI *aURI)
|
||||
bool
|
||||
gfxUserFontSet::UserFontCache::Entry::KeyEquals(const KeyTypePointer aKey) const
|
||||
{
|
||||
const gfxFontEntry *fe = aKey->mFontEntry;
|
||||
const gfxFontEntry* fe = aKey->mFontEntry;
|
||||
// CRC32 checking mode
|
||||
if (mLength || aKey->mLength) {
|
||||
if (aKey->mLength != mLength ||
|
||||
@ -986,7 +962,7 @@ gfxUserFontSet::UserFontCache::Entry::KeyEquals(const KeyTypePointer aKey) const
|
||||
}
|
||||
|
||||
void
|
||||
gfxUserFontSet::UserFontCache::CacheFont(gfxFontEntry *aFontEntry,
|
||||
gfxUserFontSet::UserFontCache::CacheFont(gfxFontEntry* aFontEntry,
|
||||
EntryPersistence aPersistence)
|
||||
{
|
||||
NS_ASSERTION(aFontEntry->mFamilyName.Length() != 0,
|
||||
@ -997,7 +973,7 @@ gfxUserFontSet::UserFontCache::CacheFont(gfxFontEntry *aFontEntry,
|
||||
nsCOMPtr<nsIObserverService> obs =
|
||||
mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
Flusher *flusher = new Flusher;
|
||||
Flusher* flusher = new Flusher;
|
||||
obs->AddObserver(flusher, "cacheservice:empty-cache",
|
||||
false);
|
||||
obs->AddObserver(flusher, "last-pb-context-exited", false);
|
||||
@ -1005,7 +981,7 @@ gfxUserFontSet::UserFontCache::CacheFont(gfxFontEntry *aFontEntry,
|
||||
}
|
||||
}
|
||||
|
||||
gfxUserFontData *data = aFontEntry->mUserFontData;
|
||||
gfxUserFontData* data = aFontEntry->mUserFontData;
|
||||
if (data->mLength) {
|
||||
MOZ_ASSERT(aPersistence == kPersistent);
|
||||
MOZ_ASSERT(!data->mPrivate);
|
||||
@ -1016,7 +992,7 @@ gfxUserFontSet::UserFontCache::CacheFont(gfxFontEntry *aFontEntry,
|
||||
// For data: URIs, the principal is ignored; anyone who has the same
|
||||
// data: URI is able to load it and get an equivalent font.
|
||||
// Otherwise, the principal is used as part of the cache key.
|
||||
nsIPrincipal *principal;
|
||||
nsIPrincipal* principal;
|
||||
if (IgnorePrincipal(data->mURI)) {
|
||||
principal = nullptr;
|
||||
} else {
|
||||
@ -1033,7 +1009,7 @@ gfxUserFontSet::UserFontCache::CacheFont(gfxFontEntry *aFontEntry,
|
||||
}
|
||||
|
||||
void
|
||||
gfxUserFontSet::UserFontCache::ForgetFont(gfxFontEntry *aFontEntry)
|
||||
gfxUserFontSet::UserFontCache::ForgetFont(gfxFontEntry* aFontEntry)
|
||||
{
|
||||
if (!sUserFonts) {
|
||||
// if we've already deleted the cache (i.e. during shutdown),
|
||||
@ -1054,17 +1030,17 @@ gfxUserFontSet::UserFontCache::ForgetFont(gfxFontEntry *aFontEntry)
|
||||
}
|
||||
|
||||
gfxFontEntry*
|
||||
gfxUserFontSet::UserFontCache::GetFont(nsIURI *aSrcURI,
|
||||
nsIPrincipal *aPrincipal,
|
||||
gfxUserFontEntry *aUserFontEntry,
|
||||
bool aPrivate)
|
||||
gfxUserFontSet::UserFontCache::GetFont(nsIURI* aSrcURI,
|
||||
nsIPrincipal* aPrincipal,
|
||||
gfxUserFontEntry* aUserFontEntry,
|
||||
bool aPrivate)
|
||||
{
|
||||
if (!sUserFonts) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Ignore principal when looking up a data: URI.
|
||||
nsIPrincipal *principal;
|
||||
nsIPrincipal* principal;
|
||||
if (IgnorePrincipal(aSrcURI)) {
|
||||
principal = nullptr;
|
||||
} else {
|
||||
|
@ -91,21 +91,14 @@ public:
|
||||
|
||||
virtual ~gfxUserFontFamily() { }
|
||||
|
||||
// Add the given font entry to the end of the family's list.
|
||||
// Any earlier occurrence is removed, so this has the effect of "advancing"
|
||||
// the entry to the end of the list.
|
||||
void AddFontEntry(gfxFontEntry *aFontEntry) {
|
||||
// We append to mAvailableFonts -before- searching for and removing
|
||||
// any existing reference to avoid the risk that we'll remove the last
|
||||
// reference to the font entry, and thus delete it.
|
||||
// add the given font entry to the end of the family's list
|
||||
void AddFontEntry(gfxFontEntry* aFontEntry) {
|
||||
// keep ref while removing existing entry
|
||||
nsRefPtr<gfxFontEntry> fe = aFontEntry;
|
||||
// remove existing entry, if already present
|
||||
mAvailableFonts.RemoveElement(aFontEntry);
|
||||
mAvailableFonts.AppendElement(aFontEntry);
|
||||
uint32_t i = mAvailableFonts.Length() - 1;
|
||||
while (i > 0) {
|
||||
if (mAvailableFonts[--i] == aFontEntry) {
|
||||
mAvailableFonts.RemoveElementAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (aFontEntry->mFamilyName.IsEmpty()) {
|
||||
aFontEntry->mFamilyName = Name();
|
||||
} else {
|
||||
@ -120,35 +113,6 @@ public:
|
||||
ResetCharacterMap();
|
||||
}
|
||||
|
||||
// Replace userfont entry in the family's list with aRealFontEntry.
|
||||
void ReplaceFontEntry(gfxFontEntry *aUserFontEntry,
|
||||
gfxFontEntry *aRealFontEntry) {
|
||||
uint32_t numFonts = mAvailableFonts.Length();
|
||||
uint32_t i;
|
||||
for (i = 0; i < numFonts; i++) {
|
||||
gfxFontEntry *fe = mAvailableFonts[i];
|
||||
if (fe == aUserFontEntry) {
|
||||
// Note that this may delete aUserFontEntry, if there's no
|
||||
// other reference to it except from its family.
|
||||
mAvailableFonts[i] = aRealFontEntry;
|
||||
if (aRealFontEntry->mFamilyName.IsEmpty()) {
|
||||
aRealFontEntry->mFamilyName = Name();
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
nsString thisName = Name();
|
||||
nsString entryName = aRealFontEntry->mFamilyName;
|
||||
ToLowerCase(thisName);
|
||||
ToLowerCase(entryName);
|
||||
MOZ_ASSERT(thisName.Equals(entryName));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(i < numFonts, "font entry not found in family!");
|
||||
ResetCharacterMap();
|
||||
}
|
||||
|
||||
// Remove all font entries from the family
|
||||
void DetachFontEntries() {
|
||||
mAvailableFonts.Clear();
|
||||
@ -211,8 +175,9 @@ public:
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges);
|
||||
|
||||
// add in a font face for which we have the gfxFontEntry already
|
||||
void AddFontFace(const nsAString& aFamilyName, gfxFontEntry* aFontEntry);
|
||||
// add in a font face for which we have the gfxUserFontEntry already
|
||||
void AddFontFace(const nsAString& aFamilyName,
|
||||
gfxUserFontEntry* aUserFontEntry);
|
||||
|
||||
// Whether there is a face with this family name
|
||||
bool HasFamily(const nsAString& aFamilyName) const
|
||||
@ -226,47 +191,22 @@ public:
|
||||
|
||||
// Lookup a font entry for a given style, returns null if not loaded.
|
||||
// aFamily must be a family returned by our LookupFamily method.
|
||||
gfxFontEntry *FindFontEntry(gfxFontFamily *aFamily,
|
||||
const gfxFontStyle& aFontStyle,
|
||||
bool& aNeedsBold,
|
||||
bool& aWaitForUserFont);
|
||||
|
||||
// Find a family (possibly one of several!) that owns the given entry.
|
||||
// This may be somewhat expensive, as it enumerates all the fonts in
|
||||
// the set. Currently used only by the Linux (gfxPangoFontGroup) backend,
|
||||
// which does not directly track families in the font group's list.
|
||||
gfxFontFamily *FindFamilyFor(gfxFontEntry *aFontEntry) const;
|
||||
gfxUserFontEntry* FindUserFontEntry(gfxFontFamily* aFamily,
|
||||
const gfxFontStyle& aFontStyle,
|
||||
bool& aNeedsBold,
|
||||
bool& aWaitForUserFont);
|
||||
|
||||
// check whether the given source is allowed to be loaded;
|
||||
// returns the Principal (for use in the key when caching the loaded font),
|
||||
// and whether the load should bypass the cache (force-reload).
|
||||
virtual nsresult CheckFontLoad(const gfxFontFaceSrc *aFontFaceSrc,
|
||||
nsIPrincipal **aPrincipal,
|
||||
bool *aBypassCache) = 0;
|
||||
virtual nsresult CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
|
||||
nsIPrincipal** aPrincipal,
|
||||
bool* aBypassCache) = 0;
|
||||
|
||||
// initialize the process that loads external font data, which upon
|
||||
// completion will call OnLoadComplete method
|
||||
virtual nsresult StartLoad(gfxUserFontFamily *aFamily,
|
||||
gfxUserFontEntry *aUserFontEntry,
|
||||
const gfxFontFaceSrc *aFontFaceSrc) = 0;
|
||||
|
||||
// when download has been completed, pass back data here
|
||||
// aDownloadStatus == NS_OK ==> download succeeded, error otherwise
|
||||
// returns true if platform font creation sucessful (or local()
|
||||
// reference was next in line)
|
||||
// Ownership of aFontData is passed in here; the font set must
|
||||
// ensure that it is eventually deleted with NS_Free().
|
||||
bool OnLoadComplete(gfxUserFontFamily *aFamily,
|
||||
gfxUserFontEntry *aUserFontEntry,
|
||||
const uint8_t* aFontData, uint32_t aLength,
|
||||
nsresult aDownloadStatus);
|
||||
|
||||
// Replace a userfont entry with a real fontEntry; this is implemented in
|
||||
// nsUserFontSet in order to keep track of the entry corresponding
|
||||
// to each @font-face rule.
|
||||
virtual void ReplaceFontEntry(gfxUserFontFamily *aFamily,
|
||||
gfxUserFontEntry *aUserFontEntry,
|
||||
gfxFontEntry *aFontEntry) = 0;
|
||||
virtual nsresult StartLoad(gfxUserFontEntry* aUserFontEntry,
|
||||
const gfxFontFaceSrc* aFontFaceSrc) = 0;
|
||||
|
||||
// generation - each time a face is loaded, generation is
|
||||
// incremented so that the change can be recognized
|
||||
@ -293,21 +233,21 @@ public:
|
||||
// If aPersistence is Persistent, the entry will remain in the cache
|
||||
// across cacheservice:empty-cache notifications. This is used for
|
||||
// "preloaded hidden fonts" on FxOS.
|
||||
static void CacheFont(gfxFontEntry *aFontEntry,
|
||||
static void CacheFont(gfxFontEntry* aFontEntry,
|
||||
EntryPersistence aPersistence = kDiscardable);
|
||||
|
||||
// The given gfxFontEntry is being destroyed, so remove any record that
|
||||
// refers to it.
|
||||
static void ForgetFont(gfxFontEntry *aFontEntry);
|
||||
static void ForgetFont(gfxFontEntry* aFontEntry);
|
||||
|
||||
// Return the gfxFontEntry corresponding to a given URI and principal,
|
||||
// and the features of the given userfont entry, or nullptr if none is available.
|
||||
// The aPrivate flag is set for requests coming from private windows,
|
||||
// so we can avoid leaking fonts cached in private windows mode out to
|
||||
// normal windows.
|
||||
static gfxFontEntry* GetFont(nsIURI *aSrcURI,
|
||||
nsIPrincipal *aPrincipal,
|
||||
gfxUserFontEntry *aUserFontEntry,
|
||||
static gfxFontEntry* GetFont(nsIURI* aSrcURI,
|
||||
nsIPrincipal* aPrincipal,
|
||||
gfxUserFontEntry* aUserFontEntry,
|
||||
bool aPrivate);
|
||||
|
||||
// Clear everything so that we don't leak URIs and Principals.
|
||||
@ -339,7 +279,7 @@ public:
|
||||
struct Key {
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal; // use nullptr with data: URLs
|
||||
gfxFontEntry *mFontEntry;
|
||||
gfxFontEntry* mFontEntry;
|
||||
uint32_t mCRC32;
|
||||
uint32_t mLength;
|
||||
bool mPrivate;
|
||||
@ -452,7 +392,7 @@ public:
|
||||
// The "real" font entry corresponding to this downloaded font.
|
||||
// The font entry MUST notify the cache when it is destroyed
|
||||
// (by calling Forget()).
|
||||
gfxFontEntry *mFontEntry;
|
||||
gfxFontEntry* mFontEntry;
|
||||
|
||||
// Whether this font was loaded from a private window.
|
||||
bool mPrivate;
|
||||
@ -461,9 +401,13 @@ public:
|
||||
EntryPersistence mPersistence;
|
||||
};
|
||||
|
||||
static nsTHashtable<Entry> *sUserFonts;
|
||||
static nsTHashtable<Entry>* sUserFonts;
|
||||
};
|
||||
|
||||
void SetLocalRulesUsed() {
|
||||
mLocalRulesUsed = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Protected destructor, to discourage deletion outside of Release():
|
||||
virtual ~gfxUserFontSet();
|
||||
@ -472,15 +416,14 @@ protected:
|
||||
virtual bool GetPrivateBrowsing() = 0;
|
||||
|
||||
// parse data for a data URL
|
||||
virtual nsresult SyncLoadFontData(gfxUserFontEntry *aFontToLoad,
|
||||
const gfxFontFaceSrc *aFontFaceSrc,
|
||||
virtual nsresult SyncLoadFontData(gfxUserFontEntry* aFontToLoad,
|
||||
const gfxFontFaceSrc* aFontFaceSrc,
|
||||
uint8_t* &aBuffer,
|
||||
uint32_t &aBufferLength) = 0;
|
||||
|
||||
// report a problem of some kind (implemented in nsUserFontSet)
|
||||
virtual nsresult LogMessage(gfxUserFontFamily *aFamily,
|
||||
gfxUserFontEntry *aUserFontEntry,
|
||||
const char *aMessage,
|
||||
virtual nsresult LogMessage(gfxUserFontEntry* aUserFontEntry,
|
||||
const char* aMessage,
|
||||
uint32_t aFlags = nsIScriptError::errorFlag,
|
||||
nsresult aStatus = NS_OK) = 0;
|
||||
|
||||
@ -530,14 +473,14 @@ public:
|
||||
STATUS_END_OF_LIST
|
||||
};
|
||||
|
||||
gfxUserFontEntry(gfxUserFontSet *aFontSet,
|
||||
gfxUserFontEntry(gfxUserFontSet* aFontSet,
|
||||
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
|
||||
uint32_t aWeight,
|
||||
int32_t aStretch,
|
||||
uint32_t aItalicStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet *aUnicodeRanges);
|
||||
gfxSparseBitSet* aUnicodeRanges);
|
||||
|
||||
virtual ~gfxUserFontEntry();
|
||||
|
||||
@ -548,29 +491,35 @@ public:
|
||||
uint32_t aItalicStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet *aUnicodeRanges);
|
||||
gfxSparseBitSet* aUnicodeRanges);
|
||||
|
||||
virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold);
|
||||
virtual gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle, bool aNeedsBold);
|
||||
|
||||
gfxFontEntry* GetPlatformFontEntry() { return mPlatformFontEntry; }
|
||||
|
||||
// when download has been completed, pass back data here
|
||||
// aDownloadStatus == NS_OK ==> download succeeded, error otherwise
|
||||
// returns true if platform font creation sucessful (or local()
|
||||
// reference was next in line)
|
||||
// Ownership of aFontData is passed in here; the font set must
|
||||
// ensure that it is eventually deleted with NS_Free().
|
||||
bool OnLoadComplete(const uint8_t* aFontData, uint32_t aLength,
|
||||
nsresult aDownloadStatus);
|
||||
|
||||
protected:
|
||||
const uint8_t* SanitizeOpenTypeData(gfxUserFontFamily *aFamily,
|
||||
const uint8_t* aData,
|
||||
const uint8_t* SanitizeOpenTypeData(const uint8_t* aData,
|
||||
uint32_t aLength,
|
||||
uint32_t& aSaneLength,
|
||||
bool aIsCompressed);
|
||||
|
||||
// Attempt to load the next resource in the src list.
|
||||
// aLocalRules is set to true if an attempt was made to load a
|
||||
// local() font was loaded, and left as it is otherwise.
|
||||
LoadStatus LoadNext(gfxUserFontFamily *aFamily,
|
||||
bool& aLocalRulesUsed);
|
||||
LoadStatus LoadNext();
|
||||
|
||||
// helper method for creating a platform font
|
||||
// returns font entry if platform font creation successful
|
||||
// returns true if platform font creation successful
|
||||
// Ownership of aFontData is passed in here; the font must
|
||||
// ensure that it is eventually deleted with NS_Free().
|
||||
gfxFontEntry* LoadFont(gfxUserFontFamily *aFamily,
|
||||
const uint8_t* aFontData, uint32_t &aLength);
|
||||
bool LoadFont(const uint8_t* aFontData, uint32_t &aLength);
|
||||
|
||||
// store metadata and src details for current src into aFontEntry
|
||||
void StoreUserFontData(gfxFontEntry* aFontEntry,
|
||||
@ -592,10 +541,11 @@ protected:
|
||||
LoadingState mLoadingState;
|
||||
bool mUnsupportedFormat;
|
||||
|
||||
nsRefPtr<gfxFontEntry> mPlatformFontEntry;
|
||||
nsTArray<gfxFontFaceSrc> mSrcList;
|
||||
uint32_t mSrcIndex; // index of loading src item
|
||||
nsFontFaceLoader *mLoader; // current loader for this entry, if any
|
||||
gfxUserFontSet *mFontSet; // font-set to which the userfont entry belongs
|
||||
nsFontFaceLoader* mLoader; // current loader for this entry, if any
|
||||
gfxUserFontSet* mFontSet; // font-set to which the userfont entry belongs
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
||||
|
@ -55,13 +55,11 @@ GetFontDownloaderLog()
|
||||
#define LOG_ENABLED() PR_LOG_TEST(GetFontDownloaderLog(), PR_LOG_DEBUG)
|
||||
|
||||
|
||||
nsFontFaceLoader::nsFontFaceLoader(gfxUserFontFamily* aFontFamily,
|
||||
gfxUserFontEntry* aUserFontEntry,
|
||||
nsFontFaceLoader::nsFontFaceLoader(gfxUserFontEntry* aUserFontEntry,
|
||||
nsIURI* aFontURI,
|
||||
nsUserFontSet* aFontSet,
|
||||
nsIChannel* aChannel)
|
||||
: mFontFamily(aFontFamily),
|
||||
mFontEntry(aUserFontEntry),
|
||||
: mUserFontEntry(aUserFontEntry),
|
||||
mFontURI(aFontURI),
|
||||
mFontSet(aFontSet),
|
||||
mChannel(aChannel)
|
||||
@ -70,8 +68,8 @@ nsFontFaceLoader::nsFontFaceLoader(gfxUserFontFamily* aFontFamily,
|
||||
|
||||
nsFontFaceLoader::~nsFontFaceLoader()
|
||||
{
|
||||
if (mFontEntry) {
|
||||
mFontEntry->mLoader = nullptr;
|
||||
if (mUserFontEntry) {
|
||||
mUserFontEntry->mLoader = nullptr;
|
||||
}
|
||||
if (mLoadTimer) {
|
||||
mLoadTimer->Cancel();
|
||||
@ -96,7 +94,7 @@ nsFontFaceLoader::StartedLoading(nsIStreamLoader* aStreamLoader)
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
} else {
|
||||
mFontEntry->mLoadingState = gfxUserFontEntry::LOADING_SLOWLY;
|
||||
mUserFontEntry->mLoadingState = gfxUserFontEntry::LOADING_SLOWLY;
|
||||
}
|
||||
mStreamLoader = aStreamLoader;
|
||||
}
|
||||
@ -111,7 +109,7 @@ nsFontFaceLoader::LoadTimerCallback(nsITimer* aTimer, void* aClosure)
|
||||
return;
|
||||
}
|
||||
|
||||
gfxUserFontEntry* ufe = loader->mFontEntry.get();
|
||||
gfxUserFontEntry* ufe = loader->mUserFontEntry.get();
|
||||
bool updateUserFontSet = true;
|
||||
|
||||
// If the entry is loading, check whether it's >75% done; if so,
|
||||
@ -209,14 +207,14 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
|
||||
}
|
||||
}
|
||||
|
||||
// The userFontSet is responsible for freeing the downloaded data
|
||||
// The userFontEntry is responsible for freeing the downloaded data
|
||||
// (aString) when finished with it; the pointer is no longer valid
|
||||
// after OnLoadComplete returns.
|
||||
// This is called even in the case of a failed download (HTTP 404, etc),
|
||||
// as there may still be data to be freed (e.g. an error page),
|
||||
// and we need the fontSet to initiate loading the next source.
|
||||
bool fontUpdate = mFontSet->OnLoadComplete(mFontFamily, mFontEntry, aString,
|
||||
aStringLen, aStatus);
|
||||
bool fontUpdate = mUserFontEntry->OnLoadComplete(aString,
|
||||
aStringLen, aStatus);
|
||||
|
||||
// when new font loaded, need to reflow
|
||||
if (fontUpdate) {
|
||||
@ -239,8 +237,8 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
|
||||
void
|
||||
nsFontFaceLoader::Cancel()
|
||||
{
|
||||
mFontEntry->mLoadingState = gfxUserFontEntry::NOT_LOADING;
|
||||
mFontEntry->mLoader = nullptr;
|
||||
mUserFontEntry->mLoadingState = gfxUserFontEntry::NOT_LOADING;
|
||||
mUserFontEntry->mLoader = nullptr;
|
||||
mFontSet = nullptr;
|
||||
if (mLoadTimer) {
|
||||
mLoadTimer->Cancel();
|
||||
@ -319,8 +317,7 @@ nsUserFontSet::RemoveLoader(nsFontFaceLoader* aLoader)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsUserFontSet::StartLoad(gfxUserFontFamily* aFamily,
|
||||
gfxUserFontEntry* aUserFontEntry,
|
||||
nsUserFontSet::StartLoad(gfxUserFontEntry* aUserFontEntry,
|
||||
const gfxFontFaceSrc* aFontFaceSrc)
|
||||
{
|
||||
nsresult rv;
|
||||
@ -354,7 +351,7 @@ nsUserFontSet::StartLoad(gfxUserFontFamily* aFamily,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<nsFontFaceLoader> fontLoader =
|
||||
new nsFontFaceLoader(aFamily, aUserFontEntry, aFontFaceSrc->mURI, this, channel);
|
||||
new nsFontFaceLoader(aUserFontEntry, aFontFaceSrc->mURI, this, channel);
|
||||
|
||||
if (!fontLoader)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -474,11 +471,7 @@ nsUserFontSet::UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules)
|
||||
// even after the oldRules array is deleted.
|
||||
size_t count = oldRules.Length();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
gfxFontEntry* fe = oldRules[i].mFontEntry;
|
||||
if (!fe->mIsUserFontContainer) {
|
||||
continue;
|
||||
}
|
||||
gfxUserFontEntry* userFontEntry = static_cast<gfxUserFontEntry*>(fe);
|
||||
gfxUserFontEntry* userFontEntry = oldRules[i].mUserFontEntry;
|
||||
nsFontFaceLoader* loader = userFontEntry->mLoader;
|
||||
if (loader) {
|
||||
loader->Cancel();
|
||||
@ -554,7 +547,7 @@ nsUserFontSet::InsertRule(nsCSSFontFaceRule* aRule, uint8_t aSheetType,
|
||||
}
|
||||
}
|
||||
|
||||
AddFontFace(fontfamily, ruleRec.mFontEntry);
|
||||
AddFontFace(fontfamily, ruleRec.mUserFontEntry);
|
||||
mRules.AppendElement(ruleRec);
|
||||
aOldRules.RemoveElementAt(i);
|
||||
// note the set has been modified if an old rule was skipped to find
|
||||
@ -568,10 +561,10 @@ nsUserFontSet::InsertRule(nsCSSFontFaceRule* aRule, uint8_t aSheetType,
|
||||
|
||||
// this is a new rule:
|
||||
FontFaceRuleRecord ruleRec;
|
||||
ruleRec.mFontEntry =
|
||||
ruleRec.mUserFontEntry =
|
||||
FindOrCreateFontFaceFromRule(fontfamily, aRule, aSheetType);
|
||||
|
||||
if (!ruleRec.mFontEntry) {
|
||||
if (!ruleRec.mUserFontEntry) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -582,7 +575,7 @@ nsUserFontSet::InsertRule(nsCSSFontFaceRule* aRule, uint8_t aSheetType,
|
||||
// returned by FindOrCreateFontFaceFromRule that was already stored on the
|
||||
// family, gfxUserFontFamily::AddFontEntry(), which AddFontFace calls,
|
||||
// will automatically remove the earlier occurrence of the same userfont entry.
|
||||
AddFontFace(fontfamily, ruleRec.mFontEntry);
|
||||
AddFontFace(fontfamily, ruleRec.mUserFontEntry);
|
||||
|
||||
mRules.AppendElement(ruleRec);
|
||||
|
||||
@ -590,7 +583,7 @@ nsUserFontSet::InsertRule(nsCSSFontFaceRule* aRule, uint8_t aSheetType,
|
||||
aFontSetModified = true;
|
||||
}
|
||||
|
||||
already_AddRefed<gfxFontEntry>
|
||||
already_AddRefed<gfxUserFontEntry>
|
||||
nsUserFontSet::FindOrCreateFontFaceFromRule(const nsAString& aFamilyName,
|
||||
nsCSSFontFaceRule* aRule,
|
||||
uint8_t aSheetType)
|
||||
@ -759,28 +752,23 @@ nsUserFontSet::FindOrCreateFontFaceFromRule(const nsAString& aFamilyName,
|
||||
return entry.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsUserFontSet::ReplaceFontEntry(gfxUserFontFamily* aFamily,
|
||||
gfxUserFontEntry* aUserFontEntry,
|
||||
gfxFontEntry* aFontEntry)
|
||||
{
|
||||
// aUserFontEntry is being supplanted by the "real" font aFontEntry, so we need to
|
||||
// update any rules that refer to it. Note that there may be multiple rules
|
||||
// that refer to the same userfont entry - e.g. if a stylesheet was loaded multiple
|
||||
// times, so that several identical @font-face rules are present.
|
||||
for (uint32_t i = 0; i < mRules.Length(); ++i) {
|
||||
if (mRules[i].mFontEntry == aUserFontEntry) {
|
||||
mRules[i].mFontEntry = aFontEntry;
|
||||
}
|
||||
}
|
||||
aFamily->ReplaceFontEntry(aUserFontEntry, aFontEntry);
|
||||
}
|
||||
|
||||
nsCSSFontFaceRule*
|
||||
nsUserFontSet::FindRuleForEntry(gfxFontEntry* aFontEntry)
|
||||
{
|
||||
NS_ASSERTION(!aFontEntry->mIsUserFontContainer, "only platform font entries");
|
||||
for (uint32_t i = 0; i < mRules.Length(); ++i) {
|
||||
if (mRules[i].mFontEntry == aFontEntry) {
|
||||
if (mRules[i].mUserFontEntry->GetPlatformFontEntry() == aFontEntry) {
|
||||
return mRules[i].mContainer.mRule;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCSSFontFaceRule*
|
||||
nsUserFontSet::FindRuleForUserFontEntry(gfxUserFontEntry* aUserFontEntry)
|
||||
{
|
||||
for (uint32_t i = 0; i < mRules.Length(); ++i) {
|
||||
if (mRules[i].mUserFontEntry == aUserFontEntry) {
|
||||
return mRules[i].mContainer.mRule;
|
||||
}
|
||||
}
|
||||
@ -788,11 +776,10 @@ nsUserFontSet::FindRuleForEntry(gfxFontEntry* aFontEntry)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsUserFontSet::LogMessage(gfxUserFontFamily* aFamily,
|
||||
gfxUserFontEntry* aUserFontEntry,
|
||||
const char* aMessage,
|
||||
uint32_t aFlags,
|
||||
nsresult aStatus)
|
||||
nsUserFontSet::LogMessage(gfxUserFontEntry* aUserFontEntry,
|
||||
const char* aMessage,
|
||||
uint32_t aFlags,
|
||||
nsresult aStatus)
|
||||
{
|
||||
nsCOMPtr<nsIConsoleService>
|
||||
console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
||||
@ -861,7 +848,7 @@ nsUserFontSet::LogMessage(gfxUserFontFamily* aFamily,
|
||||
#endif
|
||||
|
||||
// try to give the user an indication of where the rule came from
|
||||
nsCSSFontFaceRule* rule = FindRuleForEntry(aUserFontEntry);
|
||||
nsCSSFontFaceRule* rule = FindRuleForUserFontEntry(aUserFontEntry);
|
||||
nsString href;
|
||||
nsString text;
|
||||
nsresult rv;
|
||||
|
@ -34,8 +34,7 @@ public:
|
||||
|
||||
// starts loading process, creating and initializing a nsFontFaceLoader obj
|
||||
// returns whether load process successfully started or not
|
||||
nsresult StartLoad(gfxUserFontFamily* aFamily,
|
||||
gfxUserFontEntry* aFontToLoad,
|
||||
nsresult StartLoad(gfxUserFontEntry* aFontToLoad,
|
||||
const gfxFontFaceSrc* aFontFaceSrc) MOZ_OVERRIDE;
|
||||
|
||||
// Called by nsFontFaceLoader when the loader has completed normally.
|
||||
@ -46,10 +45,7 @@ public:
|
||||
|
||||
nsPresContext* GetPresContext() { return mPresContext; }
|
||||
|
||||
virtual void ReplaceFontEntry(gfxUserFontFamily* aFamily,
|
||||
gfxUserFontEntry* aUserFontEntry,
|
||||
gfxFontEntry* aFontEntry) MOZ_OVERRIDE;
|
||||
|
||||
// search for @font-face rule that matches a platform font entry
|
||||
nsCSSFontFaceRule* FindRuleForEntry(gfxFontEntry* aFontEntry);
|
||||
|
||||
protected:
|
||||
@ -62,7 +58,7 @@ protected:
|
||||
// so that we can update the set without having to throw away
|
||||
// all the existing fonts.
|
||||
struct FontFaceRuleRecord {
|
||||
nsRefPtr<gfxFontEntry> mFontEntry;
|
||||
nsRefPtr<gfxUserFontEntry> mUserFontEntry;
|
||||
nsFontFaceRuleContainer mContainer;
|
||||
};
|
||||
|
||||
@ -70,13 +66,12 @@ protected:
|
||||
nsTArray<FontFaceRuleRecord>& oldRules,
|
||||
bool& aFontSetModified);
|
||||
|
||||
already_AddRefed<gfxFontEntry> FindOrCreateFontFaceFromRule(
|
||||
already_AddRefed<gfxUserFontEntry> FindOrCreateFontFaceFromRule(
|
||||
const nsAString& aFamilyName,
|
||||
nsCSSFontFaceRule* aRule,
|
||||
uint8_t aSheetType);
|
||||
|
||||
virtual nsresult LogMessage(gfxUserFontFamily* aFamily,
|
||||
gfxUserFontEntry* aUserFontEntry,
|
||||
virtual nsresult LogMessage(gfxUserFontEntry* aUserFontEntry,
|
||||
const char* aMessage,
|
||||
uint32_t aFlags = nsIScriptError::errorFlag,
|
||||
nsresult aStatus = NS_OK) MOZ_OVERRIDE;
|
||||
@ -94,6 +89,9 @@ protected:
|
||||
|
||||
virtual void DoRebuildUserFontSet() MOZ_OVERRIDE;
|
||||
|
||||
// search for @font-face rule that matches a userfont font entry
|
||||
nsCSSFontFaceRule* FindRuleForUserFontEntry(gfxUserFontEntry* aUserFontEntry);
|
||||
|
||||
nsPresContext* mPresContext; // weak reference
|
||||
|
||||
// Set of all loaders pointing to us. These are not strong pointers,
|
||||
@ -107,8 +105,7 @@ protected:
|
||||
class nsFontFaceLoader : public nsIStreamLoaderObserver
|
||||
{
|
||||
public:
|
||||
nsFontFaceLoader(gfxUserFontFamily* aFontFamily,
|
||||
gfxUserFontEntry* aFontToLoad, nsIURI* aFontURI,
|
||||
nsFontFaceLoader(gfxUserFontEntry* aFontToLoad, nsIURI* aFontURI,
|
||||
nsUserFontSet* aFontSet, nsIChannel* aChannel);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -133,8 +130,7 @@ protected:
|
||||
virtual ~nsFontFaceLoader();
|
||||
|
||||
private:
|
||||
nsRefPtr<gfxUserFontFamily> mFontFamily;
|
||||
nsRefPtr<gfxUserFontEntry> mFontEntry;
|
||||
nsRefPtr<gfxUserFontEntry> mUserFontEntry;
|
||||
nsCOMPtr<nsIURI> mFontURI;
|
||||
nsRefPtr<nsUserFontSet> mFontSet;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
|
Loading…
Reference in New Issue
Block a user