diff --git a/gfx/thebes/gfxFT2Fonts.h b/gfx/thebes/gfxFT2Fonts.h index c9f82932f9f9..46429f057e13 100644 --- a/gfx/thebes/gfxFT2Fonts.h +++ b/gfx/thebes/gfxFT2Fonts.h @@ -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); diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index 45acd72450b2..d522a2bf5f06 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -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; } diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index aff7554b79cd..4cc8c86926aa 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -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 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. diff --git a/gfx/thebes/gfxGDIFont.h b/gfx/thebes/gfxGDIFont.h index b1366bc14a94..902785d5c87e 100644 --- a/gfx/thebes/gfxGDIFont.h +++ b/gfx/thebes/gfxGDIFont.h @@ -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); diff --git a/gfx/thebes/gfxMacFont.h b/gfx/thebes/gfxMacFont.h index 4d8a9957f814..adbab4e0ac0f 100644 --- a/gfx/thebes/gfxMacFont.h +++ b/gfx/thebes/gfxMacFont.h @@ -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(); diff --git a/gfx/thebes/gfxPangoFonts.cpp b/gfx/thebes/gfxPangoFonts.cpp index dbe41b788d7c..1290ef00c532 100644 --- a/gfx/thebes/gfxPangoFonts.cpp +++ b/gfx/thebes/gfxPangoFonts.cpp @@ -696,6 +696,15 @@ public: static already_AddRefed 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 GetOrMakeFont(FcPattern *aPattern); gfxFcFont(cairo_scaled_font_t *aCairoFont, gfxFcFontEntry *aFontEntry,