diff --git a/mozilla/gfx/src/thebes/nsThebesFontMetrics.cpp b/mozilla/gfx/src/thebes/nsThebesFontMetrics.cpp index 2d9e1495666..1a5c30d25ff 100644 --- a/mozilla/gfx/src/thebes/nsThebesFontMetrics.cpp +++ b/mozilla/gfx/src/thebes/nsThebesFontMetrics.cpp @@ -275,9 +275,6 @@ public: StubPropertyProvider(const nscoord* aSpacing = nsnull) : mSpacing(aSpacing) {} - virtual void ForceRememberText() { - NS_ERROR("This shouldn't be called because we already asked the textrun to remember"); - } virtual void GetHyphenationBreaks(PRUint32 aStart, PRUint32 aLength, PRPackedBool* aBreakBefore) { NS_ERROR("This shouldn't be called because we never call BreakAndMeasureText"); diff --git a/mozilla/gfx/thebes/public/gfxAtsuiFonts.h b/mozilla/gfx/thebes/public/gfxAtsuiFonts.h index 20c0cb34f96..6e7f768f76c 100644 --- a/mozilla/gfx/thebes/public/gfxAtsuiFonts.h +++ b/mozilla/gfx/thebes/public/gfxAtsuiFonts.h @@ -56,7 +56,7 @@ public: virtual const gfxFont::Metrics& GetMetrics(); - float GetCharWidth(PRUnichar c); + float GetCharWidth(PRUnichar c, PRUint32 *aGlyphID = nsnull); float GetCharHeight(PRUnichar c); ATSUFontID GetATSUFontID() { return mATSUFontID; } @@ -68,6 +68,8 @@ public: virtual nsString GetUniqueName(); + virtual PRUint32 GetSpaceGlyph() { return mSpaceGlyph; } + protected: const gfxFontStyle *mFontStyle; @@ -82,6 +84,8 @@ protected: gfxFont::Metrics mMetrics; gfxFloat mAdjustedSize; + PRUint32 mSpaceGlyph; + void InitMetrics(ATSUFontID aFontID, ATSFontRef aFontRef); virtual void SetupCairoFont(cairo_t *aCR) @@ -99,17 +103,17 @@ public: virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle); virtual gfxTextRun *MakeTextRun(const PRUnichar* aString, PRUint32 aLength, - Parameters* aParams); + const Parameters* aParams, PRUint32 aFlags); virtual gfxTextRun *MakeTextRun(const PRUint8* aString, PRUint32 aLength, - Parameters* aParams); + const Parameters* aParams, PRUint32 aFlags); // When aWrapped is true, the string includes bidi control // characters. The first character will be LRO or LRO to force setting the // direction for all characters, the last character is PDF, and the // second to last character is a non-whitespace character --- to ensure // that there is no "trailing whitespace" in the string, see // http://weblogs.mozillazine.org/roc/archives/2007/02/superlaser_targ.html#comments - gfxTextRun *MakeTextRunInternal(const PRUnichar *aString, PRUint32 aLength, - PRBool aWrapped, Parameters *aParams); + void MakeTextRunInternal(const PRUnichar *aString, PRUint32 aLength, + PRBool aWrapped, gfxTextRun *aTextRun); ATSUFontFallbacks *GetATSUFontFallbacksPtr() { return &mFallbacks; } diff --git a/mozilla/gfx/thebes/public/gfxFont.h b/mozilla/gfx/thebes/public/gfxFont.h index f434d16525e..d602659428a 100644 --- a/mozilla/gfx/thebes/public/gfxFont.h +++ b/mozilla/gfx/thebes/public/gfxFont.h @@ -414,6 +414,9 @@ public: // Expiration tracking nsExpirationState *GetExpirationState() { return &mExpirationState; } + // Get the glyphID of a space + virtual PRUint32 GetSpaceGlyph() = 0; + protected: // The family name of the font nsString mName; @@ -491,8 +494,6 @@ public: gfxContext *mContext; // Pointer to arbitrary user data (which should outlive the textrun) void *mUserData; - // The language of the text, or null if not known - nsIAtom *mLangGroup; // A description of which characters have been stripped from the original // DOM string to produce the characters in the textrun. May be null // if that information is not relevant. @@ -503,24 +504,9 @@ public: PRUint32 mInitialBreakCount; // The ratio to use to convert device pixels to application layout units PRUint32 mAppUnitsPerDevUnit; - // Flags --- see above - PRUint32 mFlags; }; virtual ~gfxTextRunFactory() {} - - /** - * Create a gfxTextRun from Unicode text. The length is obtained from - * aParams->mSkipChars->GetCharCount(). - */ - virtual gfxTextRun *MakeTextRun(const PRUnichar *aString, PRUint32 aLength, - Parameters *aParams) = 0; - /** - * Create a gfxTextRun from 8-bit Unicode (UCS1?) text. The length is - * obtained from aParams->mSkipChars->GetCharCount(). - */ - virtual gfxTextRun *MakeTextRun(const PRUint8 *aString, PRUint32 aLength, - Parameters *aParams) = 0; }; /** @@ -542,15 +528,6 @@ public: * there are no line breaks. The textrun can record line breaks before or after * any given cluster. (Line breaks specified inside clusters are ignored.) * - * gfxTextRuns don't need to remember their text ... often it's enough just to - * convert text to glyphs and store glyphs plus some geometry data in packed - * form. However sometimes gfxTextRuns will want to get the original text back - * to handle some unusual situation. So gfxTextRuns have two modes: "not - * remembering text" (initial state) and "remembering text". A call to - * gfxTextRun::RememberText forces a transition from the former to latter state. - * The text is never forgotten. A gfxTextRun call that receives a PropertyProvider - * object may call ForceRememberText to request a transition to "remembering text". - * * It is important that zero-length substrings are handled correctly. This will * be on the test! * @@ -568,7 +545,7 @@ public: */ class THEBES_API gfxTextRun { public: - ~gfxTextRun() {} + virtual ~gfxTextRun(); typedef gfxFont::RunMetrics Metrics; @@ -595,15 +572,6 @@ public: // All coordinates are in layout/app units - /** - * This can be called to force gfxTextRun to remember the text used - * to create it and *never* call PropertyProvider::GetText again. - * - * Right now we don't implement these. - */ - void RememberText(const PRUnichar *aText, PRUint32 aLength) {} - void RememberText(const PRUint8 *aText, PRUint32 aLength) {} - /** * Set the potential linebreaks for a substring of the textrun. These are * the "allow break before" points. Initially, there are no potential @@ -631,16 +599,6 @@ public: */ class PropertyProvider { public: - /** - * Recover the text originally used to build the textrun. This should - * only be requested infrequently as it may be slow. If you need to - * call it a lot you should probably be saving the text in the text run - * itself. It just forces the textrun user to call RememberText on the - * text run. If you call this and RememberText doesn't get called, - * then something has failed and you should handle it. - */ - virtual void ForceRememberText() = 0; - // Detect hyphenation break opportunities in the given range; breaks // not at cluster boundaries will be ignored. virtual void GetHyphenationBreaks(PRUint32 aStart, PRUint32 aLength, @@ -757,7 +715,6 @@ public: */ virtual PRBool SetLineBreaks(PRUint32 aStart, PRUint32 aLength, PRBool aLineBreakBefore, PRBool aLineBreakAfter, - PropertyProvider *aProvider, gfxFloat *aAdvanceWidthDelta); /** @@ -823,13 +780,30 @@ public: PRBool IsRightToLeft() const { return (mFlags & gfxTextRunFactory::TEXT_IS_RTL) != 0; } gfxFloat GetDirection() const { return (mFlags & gfxTextRunFactory::TEXT_IS_RTL) ? -1.0 : 1.0; } void *GetUserData() const { return mUserData; } + void SetUserData(void *aUserData) { mUserData = aUserData; } PRUint32 GetFlags() const { return mFlags; } const gfxSkipChars& GetSkipChars() const { return mSkipChars; } PRUint32 GetAppUnitsPerDevUnit() const { return mAppUnitsPerDevUnit; } + gfxFontGroup *GetFontGroup() const { return mFontGroup; } + const PRUint8 *GetText8Bit() const + { return (mFlags & gfxTextRunFactory::TEXT_IS_8BIT) ? mText.mSingle : nsnull; } + const PRUnichar *GetTextUnicode() const + { return (mFlags & gfxTextRunFactory::TEXT_IS_8BIT) ? nsnull : mText.mDouble; } // The caller is responsible for initializing our glyphs after construction. // Initially all glyphs are such that GetCharacterGlyphs()[i].IsMissing() is true. - gfxTextRun(gfxTextRunFactory::Parameters *aParams, PRUint32 aLength); + // We take ownership of aText, which must have been allocated by new[] (it + // may be null if aLength is zero). + gfxTextRun(const gfxTextRunFactory::Parameters *aParams, const void *aText, + PRUint32 aLength, gfxFontGroup *aFontGroup, PRUint32 aFlags); + + // Clone this textrun, according to the given parameters. This textrun's + // glyph data is copied, so the text and length must be the same as this + // textrun's. If there's a problem, return null. Actual linebreaks will + // be set as per aParams; there will be no potential linebreaks. + // If successful, we take ownership of aText, which must have been allocated by new[]. + virtual gfxTextRun *Clone(const gfxTextRunFactory::Parameters *aParams, const void *aText, + PRUint32 aLength, gfxFontGroup *aFontGroup, PRUint32 aFlags); /** * This class records the information associated with a character in the @@ -1049,6 +1023,8 @@ public: return mGlyphRuns.Elements(); } + nsExpirationState *GetExpirationState() { return &mExpirationState; } + private: // **** general helpers **** @@ -1109,14 +1085,21 @@ private: // XXX this should be changed to a GlyphRun plus a maybe-null GlyphRun*, // for smaller size especially in the super-common one-glyphrun case nsAutoTArray mGlyphRuns; - - void *mUserData; - gfxSkipChars mSkipChars; - // This is actually an integer, but we keep it in float form to reduce - // the conversions required - PRUint32 mAppUnitsPerDevUnit; - PRUint32 mFlags; - PRUint32 mCharacterCount; + // When TEXT_IS_8BIT is set, we use mSingle, otherwise we use mDouble. + // When TEXT_IS_PERSISTENT is set, we don't own the text, otherwise we + // own the text and should delete it when we go away. + // This text is not null-terminated. + union { + const PRUint8 *mSingle; + const PRUnichar *mDouble; + } mText; + void *mUserData; + gfxFontGroup *mFontGroup; // addrefed + gfxSkipChars mSkipChars; + nsExpirationState mExpirationState; + PRUint32 mAppUnitsPerDevUnit; + PRUint32 mFlags; + PRUint32 mCharacterCount; }; class THEBES_API gfxFontGroup : public gfxTextRunFactory { @@ -1143,13 +1126,31 @@ public: virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle) = 0; - // These need to be repeated from gfxTextRunFactory because of C++'s - // hiding rules! - virtual gfxTextRun *MakeTextRun(const PRUnichar* aString, PRUint32 aLength, - Parameters* aParams) = 0; - // This function should set TEXT_IS_8BIT in aParams->mFlags. - virtual gfxTextRun *MakeTextRun(const PRUint8* aString, PRUint32 aLength, - Parameters* aParams) = 0; + /** + * Make a textrun for an empty string. This is fast; if you call it, + * don't bother caching the result. + */ + gfxTextRun *MakeEmptyTextRun(const Parameters *aParams, PRUint32 aFlags); + /** + * Make a textrun for a single ASCII space. This is fast; if you call it, + * don't bother caching the result. + */ + gfxTextRun *MakeSpaceTextRun(const Parameters *aParams, PRUint32 aFlags); + + /** + * Make a textrun for a given string. Takes ownership of aString unless + * aFlags & TEXT_IS_PERSISTENT --- in that case, the caller must destroy + * the textrun before aString dies. + */ + virtual gfxTextRun *MakeTextRun(const PRUnichar *aString, PRUint32 aLength, + const Parameters *aParams, PRUint32 aFlags) = 0; + /** + * Make a textrun for a given string. Takes ownership of aString unless + * aFlags & TEXT_IS_PERSISTENT --- in that case, the caller must destroy + * the textrun before aString dies. + */ + virtual gfxTextRun *MakeTextRun(const PRUint8 *aString, PRUint32 aLength, + const Parameters *aParams, PRUint32 aFlags) = 0; /* helper function for splitting font families on commas and * calling a function for each family to fill the mFonts array @@ -1168,31 +1169,10 @@ public: const nsString& GetFamilies() { return mFamilies; } - /** - * Special strings are strings that we might need to draw/measure but aren't - * actually substrings of DOM text. They never have extra spacing and - * aren't involved in breaking. - */ - enum SpecialString { - STRING_ELLIPSIS, - STRING_HYPHEN, - STRING_SPACE, - STRING_MAX = STRING_SPACE - }; - - // Get the textrun for the given special string. Ownership remains - // with this gfxFontGroup. Copy relevant parameters from the template textrun. - // SpecialString textruns do not use spacing and it's fine to pass null - // as the PropertyProvider* in their methods. - // This is stubbed out until we have full textrun support on all platforms. - gfxTextRun *GetSpecialStringTextRun(SpecialString aString, - gfxTextRun *aTemplate); - protected: nsString mFamilies; gfxFontStyle mStyle; nsTArray< nsRefPtr > mFonts; - nsAutoPtr mSpecialStrings[STRING_MAX + 1]; static PRBool ForEachFontInternal(const nsAString& aFamilies, const nsACString& aLangGroup, diff --git a/mozilla/gfx/thebes/public/gfxPangoFonts.h b/mozilla/gfx/thebes/public/gfxPangoFonts.h index 1b11d1f6537..0cf9acb598f 100644 --- a/mozilla/gfx/thebes/public/gfxPangoFonts.h +++ b/mozilla/gfx/thebes/public/gfxPangoFonts.h @@ -90,6 +90,12 @@ public: virtual nsString GetUniqueName(); + // Get the glyphID of a space + virtual PRUint32 GetSpaceGlyph() { + GetMetrics(); + return mSpaceGlyph; + } + protected: PangoFontDescription *mPangoFontDesc; PangoContext *mPangoCtx; @@ -99,15 +105,16 @@ protected: PangoFont *mGlyphTestingFont; cairo_scaled_font_t *mCairoFont; - PRBool mHasMetrics; - Metrics mMetrics; + PRBool mHasMetrics; + PRUint32 mSpaceGlyph; + Metrics mMetrics; gfxFloat mAdjustedSize; void RealizeFont(PRBool force = PR_FALSE); void RealizeXftFont(PRBool force = PR_FALSE); - void GetSize(const char *aString, PRUint32 aLength, gfxSize& inkSize, gfxSize& logSize); void RealizePangoFont(PRBool aForce = PR_FALSE); - void GetCharSize(const char aChar, gfxSize& aInkSize, gfxSize& aLogSize); + void GetCharSize(const char aChar, gfxSize& aInkSize, gfxSize& aLogSize, + PRUint32 *aGlyphID = nsnull); virtual void SetupCairoFont(cairo_t *aCR); }; @@ -124,9 +131,9 @@ public: // Create and initialize a textrun using Pango (or Xft) virtual gfxTextRun *MakeTextRun(const PRUnichar *aString, PRUint32 aLength, - Parameters *aParams); + const Parameters *aParams, PRUint32 aFlags); virtual gfxTextRun *MakeTextRun(const PRUint8 *aString, PRUint32 aLength, - Parameters *aParams); + const Parameters *aParams, PRUint32 aFlags); gfxPangoFont *GetFontAt(PRInt32 i) { return NS_STATIC_CAST(gfxPangoFont*, diff --git a/mozilla/gfx/thebes/public/gfxTextRunCache.h b/mozilla/gfx/thebes/public/gfxTextRunCache.h index 27c2714400f..c3fb7f9defc 100644 --- a/mozilla/gfx/thebes/public/gfxTextRunCache.h +++ b/mozilla/gfx/thebes/public/gfxTextRunCache.h @@ -91,6 +91,8 @@ protected: FontGroupAndStringT(gfxFontGroup *fg, const GenericString* str) : mFontGroup(fg), mString(str) { } + typedef typename RealString::char_type char_type; + FontGroupAndStringT(const FontGroupAndStringT& other) : mFontGroup(other.mFontGroup), mString(&mRealString) { @@ -101,6 +103,9 @@ protected: mRealString.Assign(*mString); mString = &mRealString; } + const char_type *GetRealString() { + return mRealString.get(); + } nsRefPtr mFontGroup; RealString mRealString; diff --git a/mozilla/gfx/thebes/public/gfxWindowsFonts.h b/mozilla/gfx/thebes/public/gfxWindowsFonts.h index d2b2d8f9ec1..61565e6a7dd 100644 --- a/mozilla/gfx/thebes/public/gfxWindowsFonts.h +++ b/mozilla/gfx/thebes/public/gfxWindowsFonts.h @@ -424,14 +424,20 @@ public: gfxContext *aContext, PRBool aDrawToPath, gfxPoint *aBaselineOrigin, Spacing *aSpacing); + virtual PRUint32 GetSpaceGlyph() { + ComputeMetrics(); + return mSpaceGlyph; + }; + protected: HFONT MakeHFONT(); cairo_font_face_t *MakeCairoFontFace(); cairo_scaled_font_t *MakeCairoScaledFont(); void FillLogFont(gfxFloat aSize, PRInt16 aWeight); - HFONT mFont; + HFONT mFont; gfxFloat mAdjustedSize; + PRUint32 mSpaceGlyph; private: void Destroy(); @@ -466,9 +472,9 @@ public: virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle); virtual gfxTextRun *MakeTextRun(const PRUnichar* aString, PRUint32 aLength, - Parameters* aParams); + const Parameters* aParams, PRUint32 aFlags); virtual gfxTextRun *MakeTextRun(const PRUint8* aString, PRUint32 aLength, - Parameters* aParams); + const Parameters* aParams, PRUint32 aFlags); const nsACString& GetGenericFamily() const { return mGenericFamily; diff --git a/mozilla/gfx/thebes/src/gfxAtsuiFonts.cpp b/mozilla/gfx/thebes/src/gfxAtsuiFonts.cpp index e6bee83e800..2cfc14facfd 100644 --- a/mozilla/gfx/thebes/src/gfxAtsuiFonts.cpp +++ b/mozilla/gfx/thebes/src/gfxAtsuiFonts.cpp @@ -182,11 +182,12 @@ gfxAtsuiFont::InitMetrics(ATSUFontID aFontID, ATSFontRef aFontRef) mMetrics.maxAdvance = atsMetrics.maxAdvanceWidth * size; + float xWidth = GetCharWidth('x'); if (atsMetrics.avgAdvanceWidth != 0.0) mMetrics.aveCharWidth = - PR_MIN(atsMetrics.avgAdvanceWidth * size, GetCharWidth('x')); + PR_MIN(atsMetrics.avgAdvanceWidth * size, xWidth); else - mMetrics.aveCharWidth = GetCharWidth('x'); + mMetrics.aveCharWidth = xWidth; mMetrics.underlineOffset = atsMetrics.underlinePosition * size; // ATSUI sometimes returns 0 for underline thickness, see bug 361576. @@ -198,7 +199,9 @@ gfxAtsuiFont::InitMetrics(ATSUFontID aFontID, ATSFontRef aFontRef) mMetrics.strikeoutOffset = mMetrics.xHeight / 2.0; mMetrics.strikeoutSize = mMetrics.underlineSize; - mMetrics.spaceWidth = GetCharWidth(' '); + PRUint32 glyphID; + mMetrics.spaceWidth = GetCharWidth(' ', &glyphID); + mSpaceGlyph = glyphID; #if 0 fprintf (stderr, "Font: %p size: %f", this, size); @@ -217,7 +220,7 @@ gfxAtsuiFont::GetUniqueName() } float -gfxAtsuiFont::GetCharWidth(PRUnichar c) +gfxAtsuiFont::GetCharWidth(PRUnichar c, PRUint32 *aGlyphID) { // this sucks. There is a faster way to go from a char -> glyphs, but it // requires using oodles of apple private interfaces. If we start caching @@ -236,6 +239,13 @@ gfxAtsuiFont::GetCharWidth(PRUnichar c) FixedToFloat(PR_MAX(trap.upperRight.x, trap.lowerRight.x)) - FixedToFloat(PR_MIN(trap.upperLeft.x, trap.lowerLeft.x)); + if (aGlyphID) { + ATSUGlyphInfoArray glyphInfo; + ByteCount bytes = sizeof(glyphInfo); + ATSUGetGlyphInfo(layout, 0, 1, &bytes, &glyphInfo); + *aGlyphID = glyphInfo.glyphs[0].glyphID; + } + ATSUDisposeTextLayout(layout); return f; @@ -412,25 +422,19 @@ SetupClusterBoundaries(gfxTextRun *aTextRun, const PRUnichar *aString) UCDisposeTextBreakLocator(&locator); } -gfxTextRun * +void gfxAtsuiFontGroup::MakeTextRunInternal(const PRUnichar *aString, PRUint32 aLength, - PRBool aWrapped, Parameters *aParams) + PRBool aWrapped, gfxTextRun *aTextRun) { // NS_ASSERTION(!(aParams->mFlags & TEXT_NEED_BOUNDING_BOX), // "Glyph extents not yet supported"); - - gfxTextRun *textRun = new gfxTextRun(aParams, aLength - (aWrapped ? 3 : 0)); - if (!textRun) - return nsnull; - const PRUnichar *realString = aString + (aWrapped ? 1 : 0); - textRun->RecordSurrogates(realString); - if (!(aParams->mFlags & TEXT_IS_8BIT)) { - SetupClusterBoundaries(textRun, realString); + aTextRun->RecordSurrogates(realString); + if (!(aTextRun->GetFlags() & TEXT_IS_8BIT)) { + SetupClusterBoundaries(aTextRun, realString); } - InitTextRun(textRun, aString, aLength, aWrapped); - return textRun; + InitTextRun(aTextRun, aString, aLength, aWrapped); } #define UNICODE_LRO 0x202d @@ -446,36 +450,46 @@ AppendDirectionalIndicator(PRUint32 aFlags, nsAString& aString) gfxTextRun * gfxAtsuiFontGroup::MakeTextRun(const PRUnichar *aString, PRUint32 aLength, - Parameters *aParams) + const Parameters *aParams, PRUint32 aFlags) { + gfxTextRun *textRun = new gfxTextRun(aParams, aString, aLength, this, aFlags); + if (!textRun) + return nsnull; + nsAutoString utf16; - AppendDirectionalIndicator(aParams->mFlags, utf16); + AppendDirectionalIndicator(aFlags, utf16); utf16.Append(aString, aLength); // Ensure that none of the whitespace in the run is considered "trailing" // by ATSUI's bidi algorithm utf16.Append('.'); utf16.Append(UNICODE_PDF); - return MakeTextRunInternal(utf16.get(), utf16.Length(), PR_TRUE, aParams); + MakeTextRunInternal(utf16.get(), utf16.Length(), PR_TRUE, textRun); + return textRun; } gfxTextRun * gfxAtsuiFontGroup::MakeTextRun(const PRUint8 *aString, PRUint32 aLength, - Parameters *aParams) + const Parameters *aParams, PRUint32 aFlags) { - aParams->mFlags |= TEXT_IS_8BIT; + NS_ASSERTION(aFlags & TEXT_IS_8BIT, "should be marked 8bit"); + gfxTextRun *textRun = new gfxTextRun(aParams, aString, aLength, this, aFlags); + if (!textRun) + return nsnull; + nsDependentCSubstring cString(reinterpret_cast(aString), reinterpret_cast(aString + aLength)); nsAutoString utf16; - PRBool wrapBidi = (aParams->mFlags & TEXT_IS_RTL) != 0; + PRBool wrapBidi = (aFlags & TEXT_IS_RTL) != 0; if (wrapBidi) { - AppendDirectionalIndicator(aParams->mFlags, utf16); + AppendDirectionalIndicator(aFlags, utf16); } AppendASCIItoUTF16(cString, utf16); if (wrapBidi) { utf16.Append('.'); utf16.Append(UNICODE_PDF); } - return MakeTextRunInternal(utf16.get(), utf16.Length(), wrapBidi, aParams); + MakeTextRunInternal(utf16.get(), utf16.Length(), wrapBidi, textRun); + return textRun; } gfxAtsuiFont* diff --git a/mozilla/gfx/thebes/src/gfxFont.cpp b/mozilla/gfx/thebes/src/gfxFont.cpp index 8152e6b4fd9..45d56cadc86 100644 --- a/mozilla/gfx/thebes/src/gfxFont.cpp +++ b/mozilla/gfx/thebes/src/gfxFont.cpp @@ -48,6 +48,7 @@ #include "gfxTypes.h" #include "gfxContext.h" #include "gfxFontMissingGlyphs.h" +#include "nsMathUtils.h" #include "cairo.h" #include "gfxFontTest.h" @@ -518,61 +519,37 @@ gfxFontGroup::FindGenericFontFromStyle(FontCreationCallback fc, } gfxTextRun * -gfxFontGroup::GetSpecialStringTextRun(SpecialString aString, - gfxTextRun *aTemplate) +gfxFontGroup::MakeEmptyTextRun(const Parameters *aParams, PRUint32 aFlags) { - NS_ASSERTION(aString <= gfxFontGroup::STRING_MAX, - "Bad special string index"); + aFlags |= TEXT_IS_8BIT | TEXT_IS_ASCII | TEXT_IS_PERSISTENT; + return new gfxTextRun(aParams, nsnull, 0, this, aFlags); +} - if (mSpecialStrings[aString] && - mSpecialStrings[aString]->GetAppUnitsPerDevUnit() == - aTemplate->GetAppUnitsPerDevUnit()) - return mSpecialStrings[aString]; - - static const PRUnichar unicodeHyphen = 0x2010; - static const PRUnichar unicodeEllipsis = 0x2026; +gfxTextRun * +gfxFontGroup::MakeSpaceTextRun(const Parameters *aParams, PRUint32 aFlags) +{ + aFlags |= TEXT_IS_8BIT | TEXT_IS_ASCII | TEXT_IS_PERSISTENT; static const PRUint8 space = ' '; - gfxTextRunFactory::Parameters params = { - nsnull, nsnull, nsnull, nsnull, nsnull, 0, - aTemplate->GetAppUnitsPerDevUnit(), TEXT_IS_PERSISTENT - }; - gfxTextRun* textRun; + gfxFont *font = GetFontAt(0); + PRUint32 spaceGlyph = font->GetSpaceGlyph(); + float spaceWidth = font->GetMetrics().spaceWidth; + PRUint32 spaceWidthAppUnits = NS_lroundf(spaceWidth*aParams->mAppUnitsPerDevUnit); + if (!spaceGlyph || + !gfxTextRun::CompressedGlyph::IsSimpleGlyphID(spaceGlyph) || + !gfxTextRun::CompressedGlyph::IsSimpleAdvance(spaceWidthAppUnits)) + return MakeTextRun(&space, 1, aParams, aFlags); - switch (aString) { - case STRING_HYPHEN: - textRun = MakeTextRun(&unicodeHyphen, 1, ¶ms); - break; - case STRING_ELLIPSIS: - textRun = MakeTextRun(&unicodeEllipsis, 1, ¶ms); - break; - default: - case STRING_SPACE: - textRun = MakeTextRun(&space, 1, ¶ms); - break; - } + nsAutoPtr textRun; + textRun = new gfxTextRun(aParams, &space, 1, this, aFlags); if (!textRun) return nsnull; - - if (textRun->CountMissingGlyphs() > 0) { - static const PRUint8 ASCIIEllipsis[] = {'.', '.', '.'}; - static const PRUint8 ASCIIHyphen = '-'; - - switch (aString) { - case STRING_ELLIPSIS: - textRun = MakeTextRun(ASCIIEllipsis, NS_ARRAY_LENGTH(ASCIIEllipsis), ¶ms); - break; - case STRING_HYPHEN: - textRun = MakeTextRun(&ASCIIHyphen, 1, ¶ms); - break; - default: - NS_WARNING("This font doesn't support the space character? That's messed up"); - break; - } - } - - mSpecialStrings[aString] = textRun; - return textRun; + if (NS_FAILED(textRun->AddGlyphRun(font, 0))) + return nsnull; + gfxTextRun::CompressedGlyph g; + g.SetSimpleGlyph(spaceWidthAppUnits, spaceGlyph); + textRun->SetCharacterGlyph(0, g); + return textRun.forget(); } gfxFontStyle::gfxFontStyle(PRUint8 aStyle, PRUint8 aVariant, @@ -637,20 +614,84 @@ gfxTextRun::GlyphRunIterator::NextRun() { return PR_TRUE; } -gfxTextRun::gfxTextRun(gfxTextRunFactory::Parameters *aParams, - PRUint32 aLength) +gfxTextRun::gfxTextRun(const gfxTextRunFactory::Parameters *aParams, const void *aText, + PRUint32 aLength, gfxFontGroup *aFontGroup, PRUint32 aFlags) : mUserData(aParams->mUserData), + mFontGroup(aFontGroup), mAppUnitsPerDevUnit(aParams->mAppUnitsPerDevUnit), - mFlags(aParams->mFlags), - mCharacterCount(aLength) + mFlags(aFlags), mCharacterCount(aLength) { + NS_ADDREF(mFontGroup); if (aParams->mSkipChars) { mSkipChars.TakeFrom(aParams->mSkipChars); } - mCharacterGlyphs = new CompressedGlyph[aLength]; - if (mCharacterGlyphs) { - memset(mCharacterGlyphs, 0, sizeof(CompressedGlyph)*aLength); + if (aLength > 0) { + mCharacterGlyphs = new CompressedGlyph[aLength]; + if (mCharacterGlyphs) { + memset(mCharacterGlyphs, 0, sizeof(CompressedGlyph)*aLength); + } } + if (mFlags & gfxTextRunFactory::TEXT_IS_8BIT) { + mText.mSingle = NS_STATIC_CAST(const PRUint8 *, aText); + } else { + mText.mDouble = NS_STATIC_CAST(const PRUnichar *, aText); + } +} + +gfxTextRun::~gfxTextRun() +{ + if (!(mFlags & gfxTextRunFactory::TEXT_IS_PERSISTENT)) { + if (mFlags & gfxTextRunFactory::TEXT_IS_8BIT) { + delete[] mText.mSingle; + } else { + delete[] mText.mDouble; + } + } + NS_RELEASE(mFontGroup); +} + +gfxTextRun * +gfxTextRun::Clone(const gfxTextRunFactory::Parameters *aParams, const void *aText, + PRUint32 aLength, gfxFontGroup *aFontGroup, PRUint32 aFlags) +{ + if (!mCharacterGlyphs) + return nsnull; + + nsAutoPtr textRun; + textRun = new gfxTextRun(aParams, aText, aLength, aFontGroup, aFlags); + if (!textRun || !textRun->mCharacterGlyphs) + return nsnull; + + PRUint32 i; + for (i = 0; i < mGlyphRuns.Length(); ++i) { + if (NS_FAILED(textRun->AddGlyphRun(mGlyphRuns[i].mFont, + mGlyphRuns[i].mCharacterOffset))) + return nsnull; + } + + for (i = 0; i < aLength; ++i) { + CompressedGlyph g = mCharacterGlyphs[i]; + g.SetCanBreakBefore(PR_FALSE); + textRun->mCharacterGlyphs[i] = g; + } + + if (mDetailedGlyphs) { + for (i = 0; i < aLength; ++i) { + DetailedGlyph *details = mDetailedGlyphs[i]; + if (details) { + PRUint32 glyphCount = 1; + while (!details[glyphCount - 1].mIsLastGlyph) { + ++glyphCount; + } + DetailedGlyph *dest = textRun->AllocateDetailedGlyphs(i, glyphCount); + if (!dest) + return nsnull; + memcpy(dest, details, sizeof(DetailedGlyph)*glyphCount); + } + } + } + + return textRun.forget(); } PRBool @@ -1368,7 +1409,6 @@ gfxTextRun::GetAdvanceWidth(PRUint32 aStart, PRUint32 aLength, PRBool gfxTextRun::SetLineBreaks(PRUint32 aStart, PRUint32 aLength, PRBool aLineBreakBefore, PRBool aLineBreakAfter, - PropertyProvider *aProvider, gfxFloat *aAdvanceWidthDelta) { // Do nothing because our shaping does not currently take linebreaks into diff --git a/mozilla/gfx/thebes/src/gfxPangoFonts.cpp b/mozilla/gfx/thebes/src/gfxPangoFonts.cpp index 33dbfdbf901..4d7c80838b4 100644 --- a/mozilla/gfx/thebes/src/gfxPangoFonts.cpp +++ b/mozilla/gfx/thebes/src/gfxPangoFonts.cpp @@ -94,6 +94,8 @@ #define FLOAT_PANGO_SCALE ((gfxFloat)PANGO_SCALE) +#define IS_MISSING_GLYPH(g) (((g) & 0x10000000) || (g) == 0x0FFFFFFF) + static PangoLanguage *GetPangoLanguage(const nsACString& aLangGroup); static void GetMozLanguage(const PangoLanguage *aLang, nsACString &aMozLang); @@ -472,7 +474,8 @@ gfxPangoFont::RealizePangoFont(PRBool aForce) } void -gfxPangoFont::GetCharSize(const char aChar, gfxSize& aInkSize, gfxSize& aLogSize) +gfxPangoFont::GetCharSize(char aChar, gfxSize& aInkSize, gfxSize& aLogSize, + PRUint32 *aGlyphID) { PangoAnalysis analysis; analysis.font = GetPangoFont(); @@ -483,7 +486,17 @@ gfxPangoFont::GetCharSize(const char aChar, gfxSize& aInkSize, gfxSize& aLogSize analysis.shape_engine = pango_font_find_shaper(analysis.font, analysis.language, aChar); PangoGlyphString *glstr = pango_glyph_string_new(); - pango_shape(&aChar, 1, &analysis, glstr); + pango_shape (&aChar, 1, &analysis, glstr); + + if (aGlyphID) { + *aGlyphID = 0; + if (glstr->num_glyphs == 1) { + PangoGlyph glyph = glstr->glyphs[0].glyph; + if (!IS_MISSING_GLYPH(glyph)) { + *aGlyphID = glyph; + } + } + } PangoRectangle ink_rect, log_rect; pango_glyph_string_extents(glstr, analysis.font, &ink_rect, &log_rect); @@ -545,7 +558,7 @@ gfxPangoFont::GetMetrics() mMetrics.maxAdvance = xftFont->max_advance_width; gfxSize isz, lsz; - GetCharSize(' ', isz, lsz); + GetCharSize(' ', isz, lsz, &mSpaceGlyph); mMetrics.spaceWidth = lsz.width; // XXX do some FcCharSetHasChar work here to make sure @@ -621,7 +634,7 @@ gfxPangoFont::GetMetrics() mMetrics.maxAdvance = pango_font_metrics_get_approximate_char_width(pfm) / FLOAT_PANGO_SCALE; // XXX gfxSize isz, lsz; - GetCharSize(' ', isz, lsz); + GetCharSize(' ', isz, lsz, &mSpaceGlyph); mMetrics.spaceWidth = lsz.width; GetCharSize('x', isz, lsz); mMetrics.xHeight = isz.height; @@ -794,15 +807,15 @@ static PRInt32 AppendDirectionalIndicatorUTF8(PRBool aIsRTL, nsACString& aString gfxTextRun * gfxPangoFontGroup::MakeTextRun(const PRUint8 *aString, PRUint32 aLength, - Parameters *aParams) + const Parameters *aParams, PRUint32 aFlags) { - aParams->mFlags |= TEXT_IS_8BIT; - gfxTextRun *run = new gfxTextRun(aParams, aLength); + NS_ASSERTION(aFlags & TEXT_IS_8BIT, "8bit should have been set"); + gfxTextRun *run = new gfxTextRun(aParams, aString, aLength, this, aFlags); if (!run) return nsnull; PRBool isRTL = run->IsRightToLeft(); - if ((aParams->mFlags & TEXT_IS_ASCII) && !isRTL) { + if ((aFlags & TEXT_IS_ASCII) && !isRTL) { // We don't need to send an override character here, the characters must be all // LTR const gchar *utf8Chars = NS_REINTERPRET_CAST(const gchar*, aString); @@ -824,9 +837,9 @@ gfxPangoFontGroup::MakeTextRun(const PRUint8 *aString, PRUint32 aLength, gfxTextRun * gfxPangoFontGroup::MakeTextRun(const PRUnichar *aString, PRUint32 aLength, - Parameters *aParams) + const Parameters *aParams, PRUint32 aFlags) { - gfxTextRun *run = new gfxTextRun(aParams, aLength); + gfxTextRun *run = new gfxTextRun(aParams, aString, aLength, this, aFlags); if (!run) return nsnull; @@ -971,8 +984,6 @@ gfxPangoFont::Measure(gfxTextRun *aTextRun, return GetPangoMetrics(&glyphs, GetPangoFont(), aTextRun->GetAppUnitsPerDevUnit(), clusterCount); } -#define IS_MISSING_GLYPH(g) (((g) & 0x10000000) || (g) == 0x0FFFFFFF) - static cairo_scaled_font_t* CreateScaledFont(cairo_t *aCR, cairo_matrix_t *aCTM, PangoFont *aPangoFont) { diff --git a/mozilla/gfx/thebes/src/gfxTextRunCache.cpp b/mozilla/gfx/thebes/src/gfxTextRunCache.cpp index df8339b0827..6744695b981 100644 --- a/mozilla/gfx/thebes/src/gfxTextRunCache.cpp +++ b/mozilla/gfx/thebes/src/gfxTextRunCache.cpp @@ -133,22 +133,17 @@ gfxTextRunCache::GetOrMakeTextRun(gfxContext *aContext, gfxFontGroup *aFontGroup PRUint32 aAppUnitsPerDevUnit, PRBool aIsRTL, PRBool aEnableSpacing, PRBool *aCallerOwns) { - gfxSkipChars skipChars; // Choose pessimistic flags since we don't want to bother analyzing the string gfxTextRunFactory::Parameters params = { - aContext, nsnull, nsnull, &skipChars, nsnull, 0, aAppUnitsPerDevUnit, - ComputeFlags(aIsRTL, aEnableSpacing) + aContext, nsnull, nsnull, nsnull, 0, aAppUnitsPerDevUnit }; - - if (IsAscii(aString, aLength)) - params.mFlags |= gfxTextRunFactory::TEXT_IS_ASCII; - // else if (Is8Bit(aString, aLength)) - // params.mFlags |= gfxTextRunFactory::TEXT_IS_8BIT; - - if (!(params.mFlags & gfxTextRunFactory::TEXT_IS_ASCII)) { + PRUint32 flags = ComputeFlags(aIsRTL, aEnableSpacing); + if (IsAscii(aString, aLength)) { + flags |= gfxTextRunFactory::TEXT_IS_ASCII; + } else { for (PRUint32 i = 0; i < aLength; ++i) { if (NS_IS_HIGH_SURROGATE(aString[i])) { - params.mFlags |= gfxTextRunFactory::TEXT_HAS_SURROGATES; + flags |= gfxTextRunFactory::TEXT_HAS_SURROGATES; break; } } @@ -176,9 +171,12 @@ gfxTextRunCache::GetOrMakeTextRun(gfxContext *aContext, gfxFontGroup *aFontGroup tr->SetContext(aContext); } } else { - tr = aFontGroup->MakeTextRun(aString, aLength, ¶ms); - entry = new TextRunEntry(tr); key.Realize(); + // Text is persistent since it's in the key, which will live as + // long as this textrun. + tr = aFontGroup->MakeTextRun(key.GetRealString(), aLength, ¶ms, + flags | gfxTextRunFactory::TEXT_IS_PERSISTENT); + entry = new TextRunEntry(tr); mHashTableUTF16.Put(key, entry); } } @@ -188,11 +186,11 @@ gfxTextRunCache::GetOrMakeTextRun(gfxContext *aContext, gfxFontGroup *aFontGroup } else { // Textrun is not in the cache for some reason. *aCallerOwns = PR_TRUE; - tr = aFontGroup->MakeTextRun(aString, aLength, ¶ms); - } - if (tr) { - // We don't want to have to reconstruct the string - tr->RememberText(aString, aLength); + PRUnichar *newStr = new PRUnichar[aLength]; + if (newStr) { + memcpy(newStr, aString, sizeof(PRUnichar)*aLength); + tr = aFontGroup->MakeTextRun(newStr, aLength, ¶ms, flags); + } } return tr; @@ -204,16 +202,13 @@ gfxTextRunCache::GetOrMakeTextRun(gfxContext *aContext, gfxFontGroup *aFontGroup PRUint32 aAppUnitsPerDevUnit, PRBool aIsRTL, PRBool aEnableSpacing, PRBool *aCallerOwns) { - gfxSkipChars skipChars; // Choose pessimistic flags since we don't want to bother analyzing the string gfxTextRunFactory::Parameters params = { - aContext, nsnull, nsnull, &skipChars, nsnull, 0, aAppUnitsPerDevUnit, - ComputeFlags(aIsRTL, aEnableSpacing) + aContext, nsnull, nsnull, nsnull, 0, aAppUnitsPerDevUnit }; + PRUint32 flags = ComputeFlags(aIsRTL, aEnableSpacing) | gfxTextRunFactory::TEXT_IS_8BIT; if (IsAscii(aString, aLength)) - params.mFlags |= gfxTextRunFactory::TEXT_IS_ASCII; - else - params.mFlags |= gfxTextRunFactory::TEXT_IS_8BIT; + flags |= gfxTextRunFactory::TEXT_IS_ASCII; const PRUint8 *str = reinterpret_cast(aString); @@ -239,9 +234,13 @@ gfxTextRunCache::GetOrMakeTextRun(gfxContext *aContext, gfxFontGroup *aFontGroup tr->SetContext(aContext); } } else { - tr = aFontGroup->MakeTextRun(str, aLength, ¶ms); - entry = new TextRunEntry(tr); key.Realize(); + // Text is persistent since it's in the key, which will live as + // long as this textrun. + tr = aFontGroup->MakeTextRun(reinterpret_cast(key.GetRealString()), + aLength, ¶ms, + flags | gfxTextRunFactory::TEXT_IS_PERSISTENT); + entry = new TextRunEntry(tr); mHashTableASCII.Put(key, entry); } } @@ -251,11 +250,11 @@ gfxTextRunCache::GetOrMakeTextRun(gfxContext *aContext, gfxFontGroup *aFontGroup } else { // Textrun is not in the cache for some reason. *aCallerOwns = PR_TRUE; - tr = aFontGroup->MakeTextRun(str, aLength, ¶ms); - } - if (tr) { - // We don't want to have to reconstruct the string - tr->RememberText(str, aLength); + PRUint8 *newStr = new PRUint8[aLength]; + if (newStr) { + memcpy(newStr, str, aLength); + tr = aFontGroup->MakeTextRun(newStr, aLength, ¶ms, flags); + } } return tr; diff --git a/mozilla/gfx/thebes/src/gfxWindowsFonts.cpp b/mozilla/gfx/thebes/src/gfxWindowsFonts.cpp index 1b6eb275592..f624495b40d 100644 --- a/mozilla/gfx/thebes/src/gfxWindowsFonts.cpp +++ b/mozilla/gfx/thebes/src/gfxWindowsFonts.cpp @@ -382,6 +382,16 @@ gfxWindowsFont::ComputeMetrics() GetTextExtentPoint32(dc, " ", 1, &size); mMetrics->spaceWidth = ROUND(size.cx); + mSpaceGlyph = 0; + if (metrics.tmPitchAndFamily & TMPF_TRUETYPE) { + WORD glyph; + DWORD ret = GetGlyphIndicesA(dc, " ", 1, &glyph, + GGI_MARK_NONEXISTING_GLYPHS); + if (ret != GDI_ERROR && glyph != 0xFFFF) { + mSpaceGlyph = glyph; + } + } + SelectObject(dc, oldFont); ReleaseDC((HWND)nsnull, dc); @@ -551,13 +561,13 @@ gfxWindowsFontGroup::Copy(const gfxFontStyle *aStyle) gfxTextRun * gfxWindowsFontGroup::MakeTextRun(const PRUnichar *aString, PRUint32 aLength, - Parameters *aParams) + const Parameters *aParams, PRUint32 aFlags) { // XXX comment out the assertion for now since it fires too much - // NS_ASSERTION(!(aParams->mFlags & TEXT_NEED_BOUNDING_BOX), + // NS_ASSERTION(!(mFlags & TEXT_NEED_BOUNDING_BOX), // "Glyph extents not yet supported"); - gfxTextRun *textRun = new gfxTextRun(aParams, aLength); + gfxTextRun *textRun = new gfxTextRun(aParams, aString, aLength, this, aFlags); if (!textRun) return nsnull; NS_ASSERTION(aParams->mContext, "MakeTextRun called without a gfxContext"); @@ -580,10 +590,11 @@ gfxWindowsFontGroup::MakeTextRun(const PRUnichar *aString, PRUint32 aLength, gfxTextRun * gfxWindowsFontGroup::MakeTextRun(const PRUint8 *aString, PRUint32 aLength, - Parameters *aParams) + const Parameters *aParams, PRUint32 aFlags) { - aParams->mFlags |= TEXT_IS_8BIT; - gfxTextRun *textRun = new gfxTextRun(aParams, aLength); + NS_ASSERTION(aFlags & TEXT_IS_8BIT, "should be marked 8bit"); + + gfxTextRun *textRun = new gfxTextRun(aParams, aString, aLength, this, aFlags); if (!textRun) return nsnull; NS_ASSERTION(aParams->mContext, "MakeTextRun called without a gfxContext"); @@ -597,7 +608,7 @@ gfxWindowsFontGroup::MakeTextRun(const PRUint8 *aString, PRUint32 aLength, /* We can only call GDI "A" functions if this is a true 7bit ASCII string, because they interpret code points from 0x80-0xFF as if they were in the system code page. */ - if (!isComplex && (aParams->mFlags & TEXT_IS_ASCII)) { + if (!isComplex && (aFlags & TEXT_IS_ASCII)) { InitTextRunGDI(aParams->mContext, textRun, reinterpret_cast(aString), aLength); } diff --git a/mozilla/gfx/thebes/test/gfxFontSelectionTest.cpp b/mozilla/gfx/thebes/test/gfxFontSelectionTest.cpp index 81a03b89a57..75545f3b05c 100644 --- a/mozilla/gfx/thebes/test/gfxFontSelectionTest.cpp +++ b/mozilla/gfx/thebes/test/gfxFontSelectionTest.cpp @@ -287,22 +287,22 @@ RunTest (TestEntry *test, gfxContext *ctx) { nsAutoPtr textRun; gfxTextRunFactory::Parameters params = { - ctx, nsnull, nsnull, nsnull, nsnull, 0, 60, - gfxTextRunFactory::TEXT_IS_ASCII + ctx, nsnull, nsnull, nsnull, 0, 60 }; + PRUint32 flags = gfxTextRunFactory::TEXT_IS_PERSISTENT; if (test->isRTL) { - params.mFlags |= gfxTextRunFactory::TEXT_IS_RTL; + flags |= gfxTextRunFactory::TEXT_IS_RTL; } PRUint32 length; if (test->stringType == S_ASCII) { - params.mFlags |= gfxTextRunFactory::TEXT_IS_ASCII; + flags |= gfxTextRunFactory::TEXT_IS_ASCII | gfxTextRunFactory::TEXT_IS_8BIT; length = strlen(test->string); - textRun = fontGroup->MakeTextRun(NS_REINTERPRET_CAST(PRUint8*, test->string), length, ¶ms); + textRun = fontGroup->MakeTextRun(NS_REINTERPRET_CAST(PRUint8*, test->string), length, ¶ms, flags); } else { - params.mFlags |= gfxTextRunFactory::TEXT_HAS_SURROGATES; // just in case + flags |= gfxTextRunFactory::TEXT_HAS_SURROGATES; // just in case NS_ConvertUTF8toUTF16 str(nsDependentCString(test->string)); length = str.Length(); - textRun = fontGroup->MakeTextRun(str.get(), length, ¶ms); + textRun = fontGroup->MakeTextRun(str.get(), length, ¶ms, flags); } gfxFontTestStore::NewStore(); diff --git a/mozilla/gfx/thebes/test/gfxTextRunPerfTest.cpp b/mozilla/gfx/thebes/test/gfxTextRunPerfTest.cpp index 7c973b0d915..100c40df6a3 100644 --- a/mozilla/gfx/thebes/test/gfxTextRunPerfTest.cpp +++ b/mozilla/gfx/thebes/test/gfxTextRunPerfTest.cpp @@ -110,19 +110,20 @@ RunTest (TestEntry *test, gfxContext *ctx) { } } gfxTextRunFactory::Parameters params = { - ctx, nsnull, nsnull, nsnull, nsnull, 0, 60, 0 + ctx, nsnull, nsnull, nsnull, 0, 60 }; + PRUint32 flags = gfxTextRunFactory::TEXT_IS_PERSISTENT; PRUint32 length; if (isASCII) { - params.mFlags |= gfxTextRunFactory::TEXT_IS_ASCII | - gfxTextRunFactory::TEXT_IS_8BIT; + flags |= gfxTextRunFactory::TEXT_IS_ASCII | + gfxTextRunFactory::TEXT_IS_8BIT; length = strlen(test->mString); - textRun = fontGroup->MakeTextRun(NS_REINTERPRET_CAST(const PRUint8*, test->mString), length, ¶ms); + textRun = fontGroup->MakeTextRun(NS_REINTERPRET_CAST(const PRUint8*, test->mString), length, ¶ms, flags); } else { - params.mFlags |= gfxTextRunFactory::TEXT_HAS_SURROGATES; // just in case + flags |= gfxTextRunFactory::TEXT_HAS_SURROGATES; // just in case NS_ConvertUTF8toUTF16 str(nsDependentCString(test->mString)); length = str.Length(); - textRun = fontGroup->MakeTextRun(str.get(), length, ¶ms); + textRun = fontGroup->MakeTextRun(str.get(), length, ¶ms, flags); } // Should we test drawing? diff --git a/mozilla/layout/svg/base/src/nsSVGGlyphFrame.cpp b/mozilla/layout/svg/base/src/nsSVGGlyphFrame.cpp index d0154478e5b..ea8debf6b5d 100644 --- a/mozilla/layout/svg/base/src/nsSVGGlyphFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGGlyphFrame.cpp @@ -1352,14 +1352,14 @@ nsSVGGlyphFrame::GetTextRun(gfxContext *aCtx, const nsString &aText) gfxTextRunFactory::Parameters params = { aCtx, nsnull, nsnull, - nsnull, nsnull, nsnull, - 1, // see note above - 0 }; + nsnull, nsnull, + 1 // see note above + }; if (!mFontGroup) return nsnull; - return mFontGroup->MakeTextRun(aText.get(), aText.Length(), ¶ms); + return mFontGroup->MakeTextRun(aText.get(), aText.Length(), ¶ms, 0); } //----------------------------------------------------------------------