mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-03 23:30:46 +00:00
bug 617905 pt 1 - refactor gfxFont::InitTextRun so that all platforms benefit from splitting huge text runs. r=karlt a=joe
This commit is contained in:
parent
d4322f4982
commit
bd9aea4565
@ -150,6 +150,7 @@ public: // new functions
|
||||
return &entry->mData;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual PRBool InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
@ -158,7 +159,6 @@ public: // new functions
|
||||
PRInt32 aRunScript,
|
||||
PRBool aPreferPlatformShaping = PR_FALSE);
|
||||
|
||||
protected:
|
||||
void FillGlyphDataForChar(PRUint32 ch, CachedGlyphData *gd);
|
||||
|
||||
void AddRange(gfxTextRun *aTextRun, const PRUnichar *str, PRUint32 offset, PRUint32 len);
|
||||
|
@ -1435,13 +1435,12 @@ gfxFont::Measure(gfxTextRun *aTextRun,
|
||||
// behavior on long runs with no whitespace.
|
||||
|
||||
PRBool
|
||||
gfxFont::InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript,
|
||||
PRBool aPreferPlatformShaping)
|
||||
gfxFont::SplitAndInitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript)
|
||||
{
|
||||
PRBool ok;
|
||||
|
||||
@ -1492,27 +1491,9 @@ gfxFont::InitTextRun(gfxContext *aContext,
|
||||
}
|
||||
}
|
||||
|
||||
if (mHarfBuzzShaper && !aPreferPlatformShaping) {
|
||||
if (gfxPlatform::GetPlatform()->UseHarfBuzzLevel() >=
|
||||
gfxUnicodeProperties::ScriptShapingLevel(aRunScript)) {
|
||||
ok = mHarfBuzzShaper->InitTextRun(aContext, aTextRun, aString,
|
||||
aRunStart, thisRunLength,
|
||||
aRunScript);
|
||||
}
|
||||
}
|
||||
ok = InitTextRun(aContext, aTextRun, aString,
|
||||
aRunStart, thisRunLength, aRunScript);
|
||||
|
||||
if (!ok) {
|
||||
if (!mPlatformShaper) {
|
||||
CreatePlatformShaper();
|
||||
NS_ASSERTION(mPlatformShaper, "no platform shaper available!");
|
||||
}
|
||||
if (mPlatformShaper) {
|
||||
ok = mPlatformShaper->InitTextRun(aContext, aTextRun, aString,
|
||||
aRunStart, thisRunLength,
|
||||
aRunScript);
|
||||
}
|
||||
}
|
||||
|
||||
aRunStart += thisRunLength;
|
||||
aRunLength -= thisRunLength;
|
||||
} while (ok && aRunLength > 0);
|
||||
@ -1521,6 +1502,41 @@ gfxFont::InitTextRun(gfxContext *aContext,
|
||||
return ok;
|
||||
}
|
||||
|
||||
PRBool
|
||||
gfxFont::InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript,
|
||||
PRBool aPreferPlatformShaping)
|
||||
{
|
||||
PRBool ok = PR_FALSE;
|
||||
|
||||
if (mHarfBuzzShaper && !aPreferPlatformShaping) {
|
||||
if (gfxPlatform::GetPlatform()->UseHarfBuzzLevel() >=
|
||||
gfxUnicodeProperties::ScriptShapingLevel(aRunScript)) {
|
||||
ok = mHarfBuzzShaper->InitTextRun(aContext, aTextRun, aString,
|
||||
aRunStart, aRunLength,
|
||||
aRunScript);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
if (!mPlatformShaper) {
|
||||
CreatePlatformShaper();
|
||||
NS_ASSERTION(mPlatformShaper, "no platform shaper available!");
|
||||
}
|
||||
if (mPlatformShaper) {
|
||||
ok = mPlatformShaper->InitTextRun(aContext, aTextRun, aString,
|
||||
aRunStart, aRunLength,
|
||||
aRunScript);
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
gfxGlyphExtents *
|
||||
gfxFont::GetOrCreateGlyphExtents(PRUint32 aAppUnitsPerDevUnit) {
|
||||
PRUint32 i;
|
||||
@ -2359,10 +2375,6 @@ gfxFontGroup::MakeTextRun(const PRUnichar *aString, PRUint32 aLength,
|
||||
return textRun;
|
||||
}
|
||||
|
||||
#define SMALL_GLYPH_RUN 128 // preallocated size of our auto arrays for per-glyph data;
|
||||
// some testing indicates that 90%+ of glyph runs will fit
|
||||
// without requiring a separate allocation
|
||||
|
||||
void
|
||||
gfxFontGroup::InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
@ -2376,23 +2388,21 @@ gfxFontGroup::InitTextRun(gfxContext *aContext,
|
||||
PRUint32 runStart = 0, runLimit = aLength;
|
||||
PRInt32 runScript = HB_SCRIPT_LATIN;
|
||||
while (scriptRuns.Next(runStart, runLimit, runScript)) {
|
||||
InitTextRun(aContext, aTextRun, aString, aLength,
|
||||
runStart, runLimit, runScript);
|
||||
InitScriptRun(aContext, aTextRun, aString, aLength,
|
||||
runStart, runLimit, runScript);
|
||||
}
|
||||
|
||||
// Is this actually necessary? Without it, gfxTextRun::CopyGlyphDataFrom may assert
|
||||
// "Glyphruns not coalesced", but does that matter?
|
||||
aTextRun->SortGlyphRuns();
|
||||
}
|
||||
|
||||
void
|
||||
gfxFontGroup::InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aTotalLength,
|
||||
PRUint32 aScriptRunStart,
|
||||
PRUint32 aScriptRunEnd,
|
||||
PRInt32 aRunScript)
|
||||
gfxFontGroup::InitScriptRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aTotalLength,
|
||||
PRUint32 aScriptRunStart,
|
||||
PRUint32 aScriptRunEnd,
|
||||
PRInt32 aRunScript)
|
||||
{
|
||||
gfxFont *mainFont = mFonts[0].get();
|
||||
|
||||
@ -2412,9 +2422,9 @@ gfxFontGroup::InitTextRun(gfxContext *aContext,
|
||||
runStart, (matchedLength > 0));
|
||||
if (matchedFont) {
|
||||
// do glyph layout and record the resulting positioned glyphs
|
||||
if (!matchedFont->InitTextRun(aContext, aTextRun, aString,
|
||||
runStart, matchedLength,
|
||||
aRunScript)) {
|
||||
if (!matchedFont->SplitAndInitTextRun(aContext, aTextRun, aString,
|
||||
runStart, matchedLength,
|
||||
aRunScript)) {
|
||||
// glyph layout failed! treat as missing glyphs
|
||||
matchedFont = nsnull;
|
||||
}
|
||||
|
@ -1186,18 +1186,15 @@ public:
|
||||
return mFontEntry->GetUVSGlyph(aCh, aVS);
|
||||
}
|
||||
|
||||
// Default simply calls m[Platform|HarfBuzz]Shaper->InitTextRun().
|
||||
// Override if the font class wants to give special handling
|
||||
// to shaper failure.
|
||||
// Returns PR_FALSE if shaping failed (though currently we
|
||||
// don't have any good way to handle that situation).
|
||||
virtual PRBool InitTextRun(gfxContext *aContext,
|
||||
// call the (virtual) InitTextRun method to do glyph generation/shaping,
|
||||
// limiting the length of text passed by processing the run in multiple
|
||||
// segments if necessary
|
||||
PRBool SplitAndInitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript,
|
||||
PRBool aPreferPlatformShaping = PR_FALSE);
|
||||
PRInt32 aRunScript);
|
||||
|
||||
protected:
|
||||
nsRefPtr<gfxFontEntry> mFontEntry;
|
||||
@ -1248,6 +1245,19 @@ protected:
|
||||
// some fonts have bad metrics, this method sanitize them.
|
||||
// if this font has bad underline offset, aIsBadUnderlineFont should be true.
|
||||
void SanitizeMetrics(gfxFont::Metrics *aMetrics, PRBool aIsBadUnderlineFont);
|
||||
|
||||
// Default simply calls m[Platform|HarfBuzz]Shaper->InitTextRun().
|
||||
// Override if the font class wants to give special handling
|
||||
// to shaper failure.
|
||||
// Returns PR_FALSE if shaping failed (though currently we
|
||||
// don't have any good way to handle that situation).
|
||||
virtual PRBool InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript,
|
||||
PRBool aPreferPlatformShaping = PR_FALSE);
|
||||
};
|
||||
|
||||
// proportion of ascent used for x-height, if unable to read value from font
|
||||
@ -2232,21 +2242,22 @@ protected:
|
||||
// you should call this with the *first* bad font.
|
||||
void InitMetricsForBadFont(gfxFont* aBadFont);
|
||||
|
||||
// Set up the textrun glyphs, by finding script and font ranges
|
||||
// and calling each font's InitTextRun() as appropriate
|
||||
// Set up the textrun glyphs for an entire text run:
|
||||
// find script runs, and then call InitScriptRun for each
|
||||
void InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aLength);
|
||||
|
||||
// InitTextRun helper to handle a single script run
|
||||
void InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aTotalLength,
|
||||
PRUint32 aScriptRunStart,
|
||||
PRUint32 aScriptRunEnd,
|
||||
PRInt32 aRunScript);
|
||||
// InitTextRun helper to handle a single script run, by finding font ranges
|
||||
// and calling each font's InitTextRun() as appropriate
|
||||
void InitScriptRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aTotalLength,
|
||||
PRUint32 aScriptRunStart,
|
||||
PRUint32 aScriptRunEnd,
|
||||
PRInt32 aRunScript);
|
||||
|
||||
/* If aResolveGeneric is true, then CSS/Gecko generic family names are
|
||||
* replaced with preferred fonts.
|
||||
|
@ -76,6 +76,14 @@ public:
|
||||
/* required for MathML to suppress effects of ClearType "padding" */
|
||||
virtual gfxFont* CopyWithAntialiasOption(AntialiasOption anAAOption);
|
||||
|
||||
virtual PRBool ProvidesHintedWidths() const { return PR_TRUE; }
|
||||
|
||||
// get hinted glyph width in pixels as 16.16 fixed-point value
|
||||
virtual PRInt32 GetHintedGlyphWidth(gfxContext *aCtx, PRUint16 aGID);
|
||||
|
||||
protected:
|
||||
virtual void CreatePlatformShaper();
|
||||
|
||||
/* override to check for uniscribe failure and fall back to GDI */
|
||||
virtual PRBool InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
@ -85,14 +93,6 @@ public:
|
||||
PRInt32 aRunScript,
|
||||
PRBool aPreferPlatformShaping = PR_FALSE);
|
||||
|
||||
virtual PRBool ProvidesHintedWidths() const { return PR_TRUE; }
|
||||
|
||||
// get hinted glyph width in pixels as 16.16 fixed-point value
|
||||
virtual PRInt32 GetHintedGlyphWidth(gfxContext *aCtx, PRUint16 aGID);
|
||||
|
||||
protected:
|
||||
virtual void CreatePlatformShaper();
|
||||
|
||||
void Initialize(); // creates metrics and Cairo fonts
|
||||
|
||||
void FillLogFont(LOGFONTW& aLogFont, gfxFloat aSize);
|
||||
|
@ -57,14 +57,6 @@ public:
|
||||
ATSFontRef GetATSFontRef() const { return mATSFont; }
|
||||
CGFontRef GetCGFontRef() const { return mCGFont; }
|
||||
|
||||
virtual PRBool InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript,
|
||||
PRBool aPreferPlatformShaping = PR_FALSE);
|
||||
|
||||
/* overrides for the pure virtual methods in gfxFont */
|
||||
virtual const gfxFont::Metrics& GetMetrics() {
|
||||
return mMetrics;
|
||||
@ -83,6 +75,15 @@ public:
|
||||
protected:
|
||||
virtual void CreatePlatformShaper();
|
||||
|
||||
// override to prefer CoreText shaping with fonts that depend on AAT
|
||||
virtual PRBool InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript,
|
||||
PRBool aPreferPlatformShaping = PR_FALSE);
|
||||
|
||||
void InitMetrics();
|
||||
void InitMetricsFromATSMetrics();
|
||||
|
||||
|
@ -696,6 +696,15 @@ public:
|
||||
static already_AddRefed<gfxFcFont>
|
||||
GetOrMakeFont(FcPattern *aRequestedPattern, FcPattern *aFontPattern);
|
||||
|
||||
// The PangoFont returned is owned by the gfxFcFont
|
||||
PangoFont *GetPangoFont() {
|
||||
if (!mPangoFont) {
|
||||
MakePangoFont();
|
||||
}
|
||||
return mPangoFont;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual PRBool InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
@ -709,14 +718,6 @@ public:
|
||||
PRUint32 aRunStart, PRUint32 aRunLength,
|
||||
PangoScript aScript);
|
||||
|
||||
// The PangoFont returned is owned by the gfxFcFont
|
||||
PangoFont *GetPangoFont() {
|
||||
if (!mPangoFont) {
|
||||
MakePangoFont();
|
||||
}
|
||||
return mPangoFont;
|
||||
}
|
||||
|
||||
private:
|
||||
static already_AddRefed<gfxFcFont> GetOrMakeFont(FcPattern *aPattern);
|
||||
gfxFcFont(cairo_scaled_font_t *aCairoFont, gfxFcFontEntry *aFontEntry,
|
||||
|
Loading…
x
Reference in New Issue
Block a user