bug 499292 - hide fallback text for a short time while a font downloads. r=jdaggett a=beltzner

This commit is contained in:
Jonathan Kew 2011-01-05 21:48:48 +00:00
parent 7d920d8376
commit 448ebf5098
10 changed files with 249 additions and 42 deletions

View File

@ -1955,6 +1955,8 @@ gfxFontGroup::gfxFontGroup(const nsAString& aFamilies, const gfxFontStyle *aStyl
mUserFontSet = nsnull;
SetUserFontSet(aUserFontSet);
mSkipDrawing = PR_FALSE;
mPageLang = gfxPlatform::GetFontPrefLangFor(mStyle.language);
BuildFontList();
}
@ -2035,14 +2037,20 @@ gfxFontGroup::FindPlatformFont(const nsAString& aName,
gfxFontGroup *fontGroup = static_cast<gfxFontGroup*>(aClosure);
const gfxFontStyle *fontStyle = fontGroup->GetStyle();
PRBool needsBold;
gfxFontEntry *fe = nsnull;
// first, look up in the user font set
gfxUserFontSet *fs = fontGroup->GetUserFontSet();
if (fs) {
fe = fs->FindFontEntry(aName, *fontStyle, needsBold);
// if the fontSet matches the family, but the font has not yet finished
// loading (nor has its load timeout fired), the fontGroup should wait
// for the download, and not actually draw its text yet
PRBool waitForUserFont = PR_FALSE;
fe = fs->FindFontEntry(aName, *fontStyle, needsBold, waitForUserFont);
if (!fe && waitForUserFont) {
fontGroup->mSkipDrawing = PR_TRUE;
}
}
// nothing in the user font set ==> check system fonts
@ -2240,15 +2248,21 @@ gfxFontGroup::ForEachFontInternal(const nsAString& aFamilies,
ResolveData data(fc, gf, closure);
PRBool aborted = PR_FALSE, needsBold;
nsresult rv;
if (mUserFontSet && mUserFontSet->FindFontEntry(family, mStyle, needsBold)) {
PRBool waitForUserFont = PR_FALSE;
if (mUserFontSet &&
mUserFontSet->FindFontEntry(family, mStyle, needsBold,
waitForUserFont))
{
gfxFontGroup::FontResolverProc(family, &data);
rv = NS_OK;
} else {
if (waitForUserFont) {
mSkipDrawing = PR_TRUE;
}
gfxPlatform *pf = gfxPlatform::GetPlatform();
rv = pf->ResolveFontName(family,
gfxFontGroup::FontResolverProc,
&data, aborted);
gfxFontGroup::FontResolverProc,
&data, aborted);
}
if (NS_FAILED(rv) || aborted)
return PR_FALSE;
@ -2650,6 +2664,7 @@ gfxFontGroup::UpdateFontList()
// xxx - can probably improve this to detect when all fonts were found, so no need to update list
mFonts.Clear();
mUnderlineOffset = UNDERLINE_OFFSET_NOT_SET;
mSkipDrawing = PR_FALSE;
// bug 548184 - need to clean up FT2, OS/2 platform code to use BuildFontList
#if defined(XP_MACOSX) || defined(XP_WIN)
@ -3043,6 +3058,7 @@ gfxTextRun::gfxTextRun(const gfxTextRunFactory::Parameters *aParams, const void
#endif
mUserFontSetGeneration = mFontGroup->GetGeneration();
mSkipDrawing = mFontGroup->ShouldSkipDrawing();
}
gfxTextRun::~gfxTextRun()
@ -3472,6 +3488,21 @@ gfxTextRun::Draw(gfxContext *aContext, gfxPoint aPt,
NS_ASSERTION(aStart + aLength <= mCharacterCount, "Substring out of range");
gfxFloat direction = GetDirection();
if (mSkipDrawing) {
// We're waiting for a user font to finish downloading;
// but if the caller wants advance width, we need to compute it here
if (aAdvanceWidth) {
gfxTextRun::Metrics metrics = MeasureText(aStart, aLength,
gfxFont::LOOSE_INK_EXTENTS,
aContext, aProvider);
*aAdvanceWidth = metrics.mAdvanceWidth * direction;
}
// return without drawing
return;
}
gfxPoint pt = aPt;
// synthetic bolding draws glyphs twice ==> colors with opacity won't draw correctly unless first drawn without alpha
@ -4088,6 +4119,10 @@ gfxTextRun::CopyGlyphDataFrom(gfxTextRun *aSource, PRUint32 aStart,
NS_ASSERTION(aDest + aLength <= GetLength(),
"Destination substring out of range");
if (aSource->mSkipDrawing) {
mSkipDrawing = PR_TRUE;
}
// Copy base glyph data, and DetailedGlyph data where present
for (PRUint32 i = 0; i < aLength; ++i) {
CompressedGlyph g = aSource->mCharacterGlyphs[i + aStart];

View File

@ -2195,6 +2195,10 @@ private:
PRUint32 mCharacterCount;
PRUint32 mHashCode;
PRUint64 mUserFontSetGeneration; // user font set generation when text run created
PRBool mSkipDrawing; // true if the font group we used had a user font
// download that's in progress, so we should hide text
// until the download completes (or timeout fires)
};
class THEBES_API gfxFontGroup : public gfxTextRunFactory {
@ -2322,6 +2326,10 @@ public:
// caches need updating.
virtual void UpdateFontList();
PRBool ShouldSkipDrawing() const {
return mSkipDrawing;
}
protected:
nsString mFamilies;
gfxFontStyle mStyle;
@ -2335,8 +2343,12 @@ protected:
nsRefPtr<gfxFontFamily> mLastPrefFamily;
nsRefPtr<gfxFont> mLastPrefFont;
eFontPrefLang mLastPrefLang; // lang group for last pref font
PRBool mLastPrefFirstFont; // is this the first font in the list of pref fonts for this lang group?
eFontPrefLang mPageLang;
PRPackedBool mLastPrefFirstFont; // is this the first font in the list of pref fonts for this lang group?
PRPackedBool mSkipDrawing; // hide text while waiting for a font
// download to complete (or fallback
// timer to fire)
// Used for construction/destruction. Not intended to change the font set
// as invalidation of font lists and caches is not considered.

View File

@ -1095,9 +1095,12 @@ public:
explicit gfxFcFontSet(FcPattern *aPattern,
gfxUserFontSet *aUserFontSet)
: mSortPattern(aPattern), mUserFontSet(aUserFontSet),
mFcFontSet(SortPreferredFonts()), mFcFontsTrimmed(0),
mFcFontsTrimmed(0),
mHaveFallbackFonts(PR_FALSE)
{
PRBool waitForUserFont;
mFcFontSet = SortPreferredFonts(waitForUserFont);
mWaitingForUserFont = waitForUserFont;
}
// A reference is held by the FontSet.
@ -1118,8 +1121,12 @@ public:
FcPattern *GetFontPatternAt(PRUint32 i);
PRBool WaitingForUserFont() const {
return mWaitingForUserFont;
}
private:
nsReturnRef<FcFontSet> SortPreferredFonts();
nsReturnRef<FcFontSet> SortPreferredFonts(PRBool& aWaitForUserFont);
nsReturnRef<FcFontSet> SortFallbackFonts();
struct FontEntry {
@ -1167,13 +1174,17 @@ private:
// True iff fallback fonts are either stored in mFcFontSet or have been
// trimmed and added to mFonts (so that mFcFontSet is NULL).
PRPackedBool mHaveFallbackFonts;
// True iff there was a user font set with pending downloads,
// so the set may be updated when downloads complete
PRPackedBool mWaitingForUserFont;
};
// Find the FcPattern for an @font-face font suitable for CSS family |aFamily|
// and style |aStyle| properties.
static const nsTArray< nsCountedRef<FcPattern> >*
FindFontPatterns(gfxUserFontSet *mUserFontSet,
const nsACString &aFamily, PRUint8 aStyle, PRUint16 aWeight)
const nsACString &aFamily, PRUint8 aStyle, PRUint16 aWeight,
PRBool& aWaitForUserFont)
{
// Convert to UTF16
NS_ConvertUTF8toUTF16 utf16Family(aFamily);
@ -1188,13 +1199,15 @@ FindFontPatterns(gfxUserFontSet *mUserFontSet,
style.weight = aWeight;
gfxUserFcFontEntry *fontEntry = static_cast<gfxUserFcFontEntry*>
(mUserFontSet->FindFontEntry(utf16Family, style, needsBold));
(mUserFontSet->FindFontEntry(utf16Family, style, needsBold,
aWaitForUserFont));
// Accept synthetic oblique for italic and oblique.
if (!fontEntry && aStyle != FONT_STYLE_NORMAL) {
style.style = FONT_STYLE_NORMAL;
fontEntry = static_cast<gfxUserFcFontEntry*>
(mUserFontSet->FindFontEntry(utf16Family, style, needsBold));
(mUserFontSet->FindFontEntry(utf16Family, style, needsBold,
aWaitForUserFont));
}
if (!fontEntry)
@ -1270,8 +1283,10 @@ SizeIsAcceptable(FcPattern *aFont, double aRequestedSize)
// Sorting only the preferred fonts first usually saves having to sort through
// every font on the system.
nsReturnRef<FcFontSet>
gfxFcFontSet::SortPreferredFonts()
gfxFcFontSet::SortPreferredFonts(PRBool &aWaitForUserFont)
{
aWaitForUserFont = PR_FALSE;
gfxFontconfigUtils *utils = gfxFontconfigUtils::GetFontconfigUtils();
if (!utils)
return nsReturnRef<FcFontSet>();
@ -1350,8 +1365,13 @@ gfxFcFontSet::SortPreferredFonts()
PRUint16 thebesWeight =
gfxFontconfigUtils::GetThebesWeight(mSortPattern);
PRBool waitForUserFont;
familyFonts = FindFontPatterns(mUserFontSet, cssFamily,
thebesStyle, thebesWeight);
thebesStyle, thebesWeight,
waitForUserFont);
if (waitForUserFont) {
aWaitForUserFont = PR_TRUE;
}
}
}
@ -1860,6 +1880,7 @@ gfxPangoFontGroup::UpdateFontList()
mFontSets.Clear();
mUnderlineOffset = UNDERLINE_OFFSET_NOT_SET;
mCurrGeneration = newGeneration;
mSkipDrawing = PR_FALSE;
}
already_AddRefed<gfxFcFontSet>
@ -1889,6 +1910,8 @@ gfxPangoFontGroup::MakeFontSet(PangoLanguage *aLang, gfxFloat aSizeAdjustFactor,
nsRefPtr<gfxFcFontSet> fontset =
new gfxFcFontSet(pattern, mUserFontSet);
mSkipDrawing = fontset->WaitingForUserFont();
if (aMatchPattern)
aMatchPattern->steal(pattern);

View File

@ -73,7 +73,8 @@ gfxProxyFontEntry::gfxProxyFontEntry(const nsTArray<gfxFontFaceSrc>& aFontFaceSr
const nsTArray<gfxFontFeature>& aFeatureSettings,
PRUint32 aLanguageOverride,
gfxSparseBitSet *aUnicodeRanges)
: gfxFontEntry(NS_LITERAL_STRING("Proxy"), aFamily), mIsLoading(PR_FALSE)
: gfxFontEntry(NS_LITERAL_STRING("Proxy"), aFamily),
mLoadingState(NOT_LOADING)
{
mIsProxy = PR_TRUE;
mSrcList = aFontFaceSrcList;
@ -162,25 +163,32 @@ gfxUserFontSet::AddFontFace(const nsAString& aFamilyName,
gfxFontEntry*
gfxUserFontSet::FindFontEntry(const nsAString& aName,
const gfxFontStyle& aFontStyle,
PRBool& aNeedsBold)
PRBool& aNeedsBold,
PRBool& aWaitForUserFont)
{
aWaitForUserFont = PR_FALSE;
gfxMixedFontFamily *family = GetFamily(aName);
// no user font defined for this name
if (!family)
if (!family) {
return nsnull;
}
gfxFontEntry* fe = family->FindFontForStyle(aFontStyle, aNeedsBold);
// if not a proxy, font has already been loaded
if (!fe->mIsProxy)
if (!fe->mIsProxy) {
return fe;
}
gfxProxyFontEntry *proxyEntry = static_cast<gfxProxyFontEntry*> (fe);
// if currently loading, return null for now
if (proxyEntry->mIsLoading)
if (proxyEntry->mLoadingState > gfxProxyFontEntry::NOT_LOADING) {
aWaitForUserFont =
(proxyEntry->mLoadingState < gfxProxyFontEntry::LOADING_SLOWLY);
return nsnull;
}
// hasn't been loaded yet, start the load process
LoadStatus status;
@ -189,10 +197,13 @@ gfxUserFontSet::FindFontEntry(const nsAString& aName,
// if the load succeeded immediately, the font entry was replaced so
// search again
if (status == STATUS_LOADED)
if (status == STATUS_LOADED) {
return family->FindFontForStyle(aFontStyle, aNeedsBold);
}
// if either loading or an error occurred, return null
aWaitForUserFont =
(proxyEntry->mLoadingState < gfxProxyFontEntry::LOADING_SLOWLY);
return nsnull;
}
@ -568,14 +579,12 @@ gfxUserFontSet::OnLoadComplete(gfxFontEntry *aFontToLoad,
LoadStatus status;
status = LoadNext(pe);
if (status == STATUS_LOADED) {
// load may succeed if external font resource followed by
// local font, in this case need to bump generation
IncrementGeneration();
return PR_TRUE;
}
return PR_FALSE;
// 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 PR_TRUE;
}
@ -586,10 +595,13 @@ gfxUserFontSet::LoadNext(gfxProxyFontEntry *aProxyEntry)
NS_ASSERTION(aProxyEntry->mSrcIndex < numSrc, "already at the end of the src list for user font");
if (aProxyEntry->mIsLoading) {
aProxyEntry->mSrcIndex++;
if (aProxyEntry->mLoadingState == gfxProxyFontEntry::NOT_LOADING) {
aProxyEntry->mLoadingState = gfxProxyFontEntry::LOADING_STARTED;
} else {
aProxyEntry->mIsLoading = PR_TRUE;
// we were already loading; move to the next source,
// but don't reset state - if we've already timed out,
// that counts against the new download
aProxyEntry->mSrcIndex++;
}
// load each src entry in turn, until a local face is found or a download begins successfully

View File

@ -190,7 +190,8 @@ public:
// lookup a font entry for a given style, returns null if not loaded
gfxFontEntry *FindFontEntry(const nsAString& aName,
const gfxFontStyle& aFontStyle,
PRBool& aNeedsBold);
PRBool& aNeedsBold,
PRBool& aWaitForUserFont);
// initialize the process that loads external font data, which upon
// completion will call OnLoadComplete method
@ -211,14 +212,14 @@ public:
// incremented so that the change can be recognized
PRUint64 GetGeneration() { return mGeneration; }
// increment the generation on font load
void IncrementGeneration();
protected:
// for a given proxy font entry, attempt to load the next resource
// in the src list
LoadStatus LoadNext(gfxProxyFontEntry *aProxyEntry);
// increment the generation on font load
void IncrementGeneration();
gfxMixedFontFamily *GetFamily(const nsAString& aName) const;
// remove family
@ -249,9 +250,19 @@ public:
virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold);
PRPackedBool mIsLoading;
nsTArray<gfxFontFaceSrc> mSrcList;
PRUint32 mSrcIndex; // index of loading src item
// note that code depends on the ordering of these values!
enum LoadingState {
NOT_LOADING = 0, // not started to load any font resources yet
LOADING_STARTED, // loading has started; hide fallback font
LOADING_ALMOST_DONE, // timeout happened but we're nearly done,
// so keep hiding fallback font
LOADING_SLOWLY // timeout happened and we're not nearly done,
// so use the fallback font
};
LoadingState mLoadingState;
nsTArray<gfxFontFaceSrc> mSrcList;
PRUint32 mSrcIndex; // index of loading src item
};

View File

@ -337,7 +337,15 @@ nsHTMLContainerFrame::DisplayTextDecorations(nsDisplayListBuilder* aBuilder,
return NS_OK;
if (!IsVisibleForPainting(aBuilder))
return NS_OK;
// Hide text decorations if we're currently hiding @font-face fallback text
nsCOMPtr<nsIFontMetrics> fm;
nsresult rv = nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
NS_ENSURE_SUCCESS(rv, rv);
nsIThebesFontMetrics* tfm = static_cast<nsIThebesFontMetrics*>(fm.get());
if (tfm->GetThebesFontGroup()->ShouldSkipDrawing())
return NS_OK;
// Do standards mode painting of 'text-decoration's: under+overline
// behind children, line-through in front. For Quirks mode, see
// nsTextFrame::PaintTextDecorations. (See bug 1777.)
@ -353,25 +361,25 @@ nsHTMLContainerFrame::DisplayTextDecorations(nsDisplayListBuilder* aBuilder,
// shadow applied to them. So draw the shadows as part of the display
// list, underneath the text and all decorations.
if (GetStyleText()->mTextShadow) {
nsresult rv = aBelowTextDecorations->AppendNewToTop(new (aBuilder)
rv = aBelowTextDecorations->AppendNewToTop(new (aBuilder)
nsDisplayTextShadow(aBuilder, this, decorations, aLine));
NS_ENSURE_SUCCESS(rv, rv);
}
if (decorations & NS_STYLE_TEXT_DECORATION_UNDERLINE) {
nsresult rv = aBelowTextDecorations->AppendNewToTop(new (aBuilder)
rv = aBelowTextDecorations->AppendNewToTop(new (aBuilder)
nsDisplayTextDecoration(aBuilder, this, NS_STYLE_TEXT_DECORATION_UNDERLINE,
underColor, aLine));
NS_ENSURE_SUCCESS(rv, rv);
}
if (decorations & NS_STYLE_TEXT_DECORATION_OVERLINE) {
nsresult rv = aBelowTextDecorations->AppendNewToTop(new (aBuilder)
rv = aBelowTextDecorations->AppendNewToTop(new (aBuilder)
nsDisplayTextDecoration(aBuilder, this, NS_STYLE_TEXT_DECORATION_OVERLINE,
overColor, aLine));
NS_ENSURE_SUCCESS(rv, rv);
}
if (decorations & NS_STYLE_TEXT_DECORATION_LINE_THROUGH) {
nsresult rv = aAboveTextDecorations->AppendNewToTop(new (aBuilder)
rv = aAboveTextDecorations->AppendNewToTop(new (aBuilder)
nsDisplayTextDecoration(aBuilder, this, NS_STYLE_TEXT_DECORATION_LINE_THROUGH,
strikeColor, aLine));
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -4310,6 +4310,10 @@ nsTextFrame::PaintTextDecorations(gfxContext* aCtx, const gfxRect& aDirtyRect,
if (!decorations.HasDecorationlines())
return;
// Hide text decorations if we're currently hiding @font-face fallback text
if (aProvider.GetFontGroup()->ShouldSkipDrawing())
return;
gfxFont* firstFont = aProvider.GetFontGroup()->GetFontAt(0);
if (!firstFont)
return; // OOM
@ -4860,6 +4864,10 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
PropertyProvider& aProvider, nsTextPaintStyle& aTextPaintStyle,
SelectionDetails* aDetails, SelectionType aSelectionType)
{
// Hide text decorations if we're currently hiding @font-face fallback text
if (aProvider.GetFontGroup()->ShouldSkipDrawing())
return;
PRInt32 contentOffset = aProvider.GetStart().GetOriginalOffset();
PRInt32 contentLength = aProvider.GetOriginalLength();

View File

@ -54,6 +54,7 @@
#include "nsIChannelEventSink.h"
#include "nsIInterfaceRequestor.h"
#include "nsContentUtils.h"
#include "nsIPrefService.h"
#include "nsPresContext.h"
#include "nsIPresShell.h"
@ -89,11 +90,94 @@ nsFontFaceLoader::nsFontFaceLoader(gfxFontEntry *aFontToLoad, nsIURI *aFontURI,
nsFontFaceLoader::~nsFontFaceLoader()
{
if (mLoadTimer) {
mLoadTimer->Cancel();
mLoadTimer = nsnull;
}
if (mFontSet) {
mFontSet->RemoveLoader(this);
}
}
void
nsFontFaceLoader::StartedLoading(nsIStreamLoader *aStreamLoader)
{
PRInt32 loadTimeout = 3000;
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (prefs) {
prefs->GetIntPref("gfx.downloadable_fonts.fallback_delay", &loadTimeout);
}
if (loadTimeout > 0) {
mLoadTimer = do_CreateInstance("@mozilla.org/timer;1");
if (mLoadTimer) {
mLoadTimer->InitWithFuncCallback(LoadTimerCallback,
static_cast<void*>(this),
loadTimeout,
nsITimer::TYPE_ONE_SHOT);
}
} else {
gfxProxyFontEntry *pe =
static_cast<gfxProxyFontEntry*>(mFontEntry.get());
pe->mLoadingState = gfxProxyFontEntry::LOADING_SLOWLY;
}
mStreamLoader = aStreamLoader;
}
void
nsFontFaceLoader::LoadTimerCallback(nsITimer *aTimer, void *aClosure)
{
nsFontFaceLoader *loader = static_cast<nsFontFaceLoader*>(aClosure);
if (!loader->mFontEntry->mIsProxy) {
return;
}
gfxProxyFontEntry *pe =
static_cast<gfxProxyFontEntry*>(loader->mFontEntry.get());
bool updateUserFontSet = true;
// If the entry is loading, check whether it's >75% done; if so,
// we allow another timeout period before showing a fallback font.
if (pe->mLoadingState == gfxProxyFontEntry::LOADING_STARTED) {
PRInt32 contentLength;
loader->mChannel->GetContentLength(&contentLength);
PRUint32 numBytesRead;
loader->mStreamLoader->GetNumBytesRead(&numBytesRead);
if (contentLength > 0 &&
numBytesRead > 3 * (PRUint32(contentLength) >> 2))
{
// More than 3/4 the data has been downloaded, so allow 50% extra
// time and hope the remainder will arrive before the additional
// time expires.
pe->mLoadingState = gfxProxyFontEntry::LOADING_ALMOST_DONE;
PRUint32 delay;
loader->mLoadTimer->GetDelay(&delay);
loader->mLoadTimer->InitWithFuncCallback(LoadTimerCallback,
static_cast<void*>(loader),
delay >> 1,
nsITimer::TYPE_ONE_SHOT);
updateUserFontSet = false;
LOG(("fontdownloader (%p) 75%% done, resetting timer\n", loader));
}
}
// If the font is not 75% loaded, or if we've already timed out once
// before, we mark this entry as "loading slowly", so the fallback
// font will be used in the meantime, and tell the context to refresh.
if (updateUserFontSet) {
pe->mLoadingState = gfxProxyFontEntry::LOADING_SLOWLY;
nsPresContext *ctx = loader->mFontSet->GetPresContext();
NS_ASSERTION(ctx, "fontSet doesn't have a presContext?");
gfxUserFontSet *fontSet;
if (ctx && (fontSet = ctx->GetUserFontSet()) != nsnull) {
fontSet->IncrementGeneration();
ctx->UserFontSetUpdated();
LOG(("fontdownloader (%p) timeout reflow\n", loader));
}
}
}
NS_IMPL_ISUPPORTS1(nsFontFaceLoader, nsIStreamLoaderObserver)
NS_IMETHODIMP
@ -156,6 +240,10 @@ void
nsFontFaceLoader::Cancel()
{
mFontSet = nsnull;
if (mLoadTimer) {
mLoadTimer->Cancel();
mLoadTimer = nsnull;
}
mChannel->Cancel(NS_BINDING_ABORTED);
}
@ -343,6 +431,7 @@ nsUserFontSet::StartLoad(gfxFontEntry *aFontToLoad,
if (NS_SUCCEEDED(rv)) {
mLoaders.PutEntry(fontLoader);
fontLoader->StartedLoading(streamLoader);
}
return rv;

View File

@ -46,6 +46,7 @@
#include "nsIStreamLoader.h"
#include "nsIURI.h"
#include "nsIChannel.h"
#include "nsITimer.h"
#include "gfxUserFontSet.h"
#include "nsHashKeys.h"
#include "nsTHashtable.h"
@ -105,6 +106,10 @@ public:
void DropChannel() { mChannel = nsnull; }
void StartedLoading(nsIStreamLoader *aStreamLoader);
static void LoadTimerCallback(nsITimer *aTimer, void *aClosure);
static nsresult CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
nsIURI* aTargetURI,
nsISupports* aContext);
@ -114,6 +119,9 @@ private:
nsCOMPtr<nsIURI> mFontURI;
nsRefPtr<nsUserFontSet> mFontSet;
nsCOMPtr<nsIChannel> mChannel;
nsCOMPtr<nsITimer> mLoadTimer;
nsIStreamLoader *mStreamLoader;
};
#endif /* !defined(nsFontFaceLoader_h_) */

View File

@ -192,6 +192,7 @@ pref("gfx.color_management.display_profile", "");
pref("gfx.color_management.rendering_intent", 0);
pref("gfx.downloadable_fonts.enabled", true);
pref("gfx.downloadable_fonts.fallback_delay", 3000);
pref("gfx.downloadable_fonts.sanitize", true);
#ifdef XP_MACOSX
pref("gfx.downloadable_fonts.sanitize.preserve_otl_tables", false);