From 281b20dd55e81187a452e786c62c381db9c3ff59 Mon Sep 17 00:00:00 2001 From: "roc+@cs.cmu.edu" Date: Mon, 25 Jun 2007 21:25:00 -0700 Subject: [PATCH] Bug 384836. Avoid using a stale gfxContext, by not holding onto one in nsTransformedTextRun, passing in a gfxContext when required instead. r=pavlov,smontagu --- gfx/thebes/public/gfxFont.h | 6 ++- gfx/thebes/src/gfxFont.cpp | 6 ++- layout/generic/nsTextFrameThebes.cpp | 19 +++++---- layout/generic/nsTextRunTransformations.cpp | 45 ++++++++++++--------- layout/generic/nsTextRunTransformations.h | 6 +-- 5 files changed, 50 insertions(+), 32 deletions(-) diff --git a/gfx/thebes/public/gfxFont.h b/gfx/thebes/public/gfxFont.h index 0a73e5c3ca5..769e07b7550 100644 --- a/gfx/thebes/public/gfxFont.h +++ b/gfx/thebes/public/gfxFont.h @@ -589,7 +589,8 @@ public: * breaks are the same as the old */ virtual PRBool SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength, - PRPackedBool *aBreakBefore); + PRPackedBool *aBreakBefore, + gfxContext *aRefContext); /** * Layout provides PropertyProvider objects. These allow detection of @@ -719,7 +720,8 @@ public: */ virtual PRBool SetLineBreaks(PRUint32 aStart, PRUint32 aLength, PRBool aLineBreakBefore, PRBool aLineBreakAfter, - gfxFloat *aAdvanceWidthDelta); + gfxFloat *aAdvanceWidthDelta, + gfxContext *aRefContext); /** * Finds the longest substring that will fit into the given width. diff --git a/gfx/thebes/src/gfxFont.cpp b/gfx/thebes/src/gfxFont.cpp index 03d902275d4..9d284ba9f2f 100644 --- a/gfx/thebes/src/gfxFont.cpp +++ b/gfx/thebes/src/gfxFont.cpp @@ -686,7 +686,8 @@ gfxTextRun::Clone(const gfxTextRunFactory::Parameters *aParams, const void *aTex PRBool gfxTextRun::SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength, - PRPackedBool *aBreakBefore) + PRPackedBool *aBreakBefore, + gfxContext *aRefContext) { NS_ASSERTION(aStart + aLength <= mCharacterCount, "Overflow"); @@ -1416,7 +1417,8 @@ gfxTextRun::GetAdvanceWidth(PRUint32 aStart, PRUint32 aLength, PRBool gfxTextRun::SetLineBreaks(PRUint32 aStart, PRUint32 aLength, PRBool aLineBreakBefore, PRBool aLineBreakAfter, - gfxFloat *aAdvanceWidthDelta) + gfxFloat *aAdvanceWidthDelta, + gfxContext *aRefContext) { // Do nothing because our shaping does not currently take linebreaks into // account. There is no change in advance width. diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp index 5daea2b3cad..53e10456bd0 100644 --- a/layout/generic/nsTextFrameThebes.cpp +++ b/layout/generic/nsTextFrameThebes.cpp @@ -910,20 +910,22 @@ public: class BreakSink : public nsILineBreakSink { public: - BreakSink(gfxTextRun* aTextRun, PRUint32 aOffsetIntoTextRun, + BreakSink(gfxTextRun* aTextRun, gfxContext* aContext, PRUint32 aOffsetIntoTextRun, PRBool aExistingTextRun) : - mTextRun(aTextRun), mOffsetIntoTextRun(aOffsetIntoTextRun), - mChangedBreaks(PR_FALSE), mExistingTextRun(aExistingTextRun) {} + mTextRun(aTextRun), mContext(aContext), + mOffsetIntoTextRun(aOffsetIntoTextRun), + mChangedBreaks(PR_FALSE), mExistingTextRun(aExistingTextRun) {} virtual void SetBreaks(PRUint32 aOffset, PRUint32 aLength, PRPackedBool* aBreakBefore) { if (mTextRun->SetPotentialLineBreaks(aOffset + mOffsetIntoTextRun, aLength, - aBreakBefore)) { + aBreakBefore, mContext)) { mChangedBreaks = PR_TRUE; } } gfxTextRun* mTextRun; + gfxContext* mContext; PRUint32 mOffsetIntoTextRun; PRPackedBool mChangedBreaks; PRPackedBool mExistingTextRun; @@ -1806,7 +1808,7 @@ HasCompressedLeadingWhitespace(nsTextFrame* aFrame, PRInt32 aContentEndOffset, } void -BuildTextRunsScanner::SetupBreakSinksForTextRun(gfxTextRun* aTextRun, +BuildTextRunsScanner::SetupBreakSinksForTextRun(gfxTextRun* aTextRun, PRBool aIsExistingTextRun, PRBool aSuppressSink) { @@ -1821,7 +1823,8 @@ BuildTextRunsScanner::SetupBreakSinksForTextRun(gfxTextRun* aTextRun, for (i = 0; i < mMappedFlows.Length(); ++i) { MappedFlow* mappedFlow = &mMappedFlows[i]; nsAutoPtr* breakSink = mBreakSinks.AppendElement( - new BreakSink(aTextRun, mappedFlow->mTransformedTextOffset, aIsExistingTextRun)); + new BreakSink(aTextRun, mContext, + mappedFlow->mTransformedTextOffset, aIsExistingTextRun)); if (!breakSink || !*breakSink) return; PRUint32 offset = mappedFlow->mTransformedTextOffset; @@ -5566,10 +5569,12 @@ nsTextFrame::TrimTrailingWhiteSpace(nsPresContext* aPresContext, } } + gfxContext* ctx = NS_STATIC_CAST(gfxContext*, + aRC.GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT)); gfxFloat advanceDelta; mTextRun->SetLineBreaks(trimmedStart, trimmedEnd - trimmedStart, (GetStateBits() & TEXT_START_OF_LINE) != 0, PR_TRUE, - &advanceDelta); + &advanceDelta, ctx); // aDeltaWidth is *subtracted* from our width. // If advanceDelta is positive then setting the line break made us longer, diff --git a/layout/generic/nsTextRunTransformations.cpp b/layout/generic/nsTextRunTransformations.cpp index a3eb176607c..cb13b6d6b51 100644 --- a/layout/generic/nsTextRunTransformations.cpp +++ b/layout/generic/nsTextRunTransformations.cpp @@ -61,8 +61,7 @@ public: const PRUint32 aFlags, nsStyleContext** aStyles, PRBool aOwnsFactory) : gfxTextRun(aParams, aString, aLength, aFontGroup, aFlags), - mFactory(aFactory), mRefContext(aParams->mContext), - mOwnsFactory(aOwnsFactory) + mFactory(aFactory), mOwnsFactory(aOwnsFactory) { PRUint32 i; for (i = 0; i < aLength; ++i) { @@ -80,18 +79,20 @@ public: } virtual PRBool SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength, - PRPackedBool* aBreakBefore) + PRPackedBool* aBreakBefore, + gfxContext* aRefContext) { - PRBool changed = gfxTextRun::SetPotentialLineBreaks(aStart, aLength, aBreakBefore); - mFactory->RebuildTextRun(this); + PRBool changed = gfxTextRun::SetPotentialLineBreaks(aStart, aLength, + aBreakBefore, aRefContext); + mFactory->RebuildTextRun(this, aRefContext); return changed; } virtual PRBool SetLineBreaks(PRUint32 aStart, PRUint32 aLength, PRBool aLineBreakBefore, PRBool aLineBreakAfter, - gfxFloat* aAdvanceWidthDelta); + gfxFloat* aAdvanceWidthDelta, + gfxContext* aRefContext); nsTransformingTextRunFactory *mFactory; - nsRefPtr mRefContext; nsTArray mLineBreaks; nsTArray > mStyles; PRPackedBool mOwnsFactory; @@ -100,7 +101,8 @@ public: PRBool nsTransformedTextRun::SetLineBreaks(PRUint32 aStart, PRUint32 aLength, PRBool aLineBreakBefore, PRBool aLineBreakAfter, - gfxFloat* aAdvanceWidthDelta) + gfxFloat* aAdvanceWidthDelta, + gfxContext* aRefContext) { nsTArray newBreaks; PRUint32 i; @@ -141,7 +143,7 @@ nsTransformedTextRun::SetLineBreaks(PRUint32 aStart, PRUint32 aLength, mLineBreaks.SwapElements(newBreaks); gfxFloat currentAdvance = GetAdvanceWidth(aStart, aLength, nsnull); - mFactory->RebuildTextRun(this); + mFactory->RebuildTextRun(this, aRefContext); if (aAdvanceWidthDelta) { *aAdvanceWidthDelta = GetAdvanceWidth(aStart, aLength, nsnull) - currentAdvance; } @@ -160,7 +162,7 @@ nsTransformingTextRunFactory::MakeTextRun(const PRUnichar* aString, PRUint32 aLe if (!textRun) return nsnull; - RebuildTextRun(textRun); + RebuildTextRun(textRun, aParams->mContext); return textRun; } @@ -310,10 +312,11 @@ MergeCharactersInTextRun(gfxTextRun* aDest, gfxTextRun* aSrc, } static gfxTextRunFactory::Parameters -GetParametersForInner(nsTransformedTextRun* aTextRun, PRUint32* aFlags) +GetParametersForInner(nsTransformedTextRun* aTextRun, PRUint32* aFlags, + gfxContext* aRefContext) { gfxTextRunFactory::Parameters params = - { aTextRun->mRefContext, nsnull, nsnull, + { aRefContext, nsnull, nsnull, nsnull, nsnull, PRUint32(aTextRun->GetAppUnitsPerDevUnit()) }; *aFlags = aTextRun->GetFlags() & ~gfxFontGroup::TEXT_IS_PERSISTENT; @@ -321,7 +324,8 @@ GetParametersForInner(nsTransformedTextRun* aTextRun, PRUint32* aFlags) } void -nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun) +nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun, + gfxContext* aRefContext) { nsICaseConversion* converter = nsTextTransformer::GetCaseConv(); if (!converter) @@ -335,7 +339,8 @@ nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun) return; PRUint32 flags; - gfxTextRunFactory::Parameters innerParams = GetParametersForInner(aTextRun, &flags); + gfxTextRunFactory::Parameters innerParams = + GetParametersForInner(aTextRun, &flags, aRefContext); // The text outlives the child and inner textruns flags |= gfxFontGroup::TEXT_IS_PERSISTENT; @@ -404,7 +409,8 @@ nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun) // (and also child will be shaped appropriately) NS_ASSERTION(canBreakBeforeArray.Length() == i - runStart, "lost some break-before values?"); - child->SetPotentialLineBreaks(0, canBreakBeforeArray.Length(), canBreakBeforeArray.Elements()); + child->SetPotentialLineBreaks(0, canBreakBeforeArray.Length(), + canBreakBeforeArray.Elements(), aRefContext); AppendTextRun(aTextRun, child, runStart); runStart = i; @@ -427,7 +433,8 @@ nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun) } void -nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun) +nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun, + gfxContext* aRefContext) { nsICaseConversion* converter = nsTextTransformer::GetCaseConv(); if (!converter) @@ -507,7 +514,8 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun) "lost track of line breaks somehow"); PRUint32 flags; - gfxTextRunFactory::Parameters innerParams = GetParametersForInner(aTextRun, &flags); + gfxTextRunFactory::Parameters innerParams = + GetParametersForInner(aTextRun, &flags, aRefContext); gfxFontGroup* fontGroup = aTextRun->GetFontGroup(); nsAutoPtr child; @@ -531,7 +539,8 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun) // (and also child will be shaped appropriately) NS_ASSERTION(convertedString.Length() == canBreakBeforeArray.Length(), "Dropped characters or break-before values somewhere!"); - child->SetPotentialLineBreaks(0, canBreakBeforeArray.Length(), canBreakBeforeArray.Elements()); + child->SetPotentialLineBreaks(0, canBreakBeforeArray.Length(), + canBreakBeforeArray.Elements(), aRefContext); // Now merge multiple characters into one multi-glyph character as required MergeCharactersInTextRun(aTextRun, child, charsToMergeArray.Elements()); } diff --git a/layout/generic/nsTextRunTransformations.h b/layout/generic/nsTextRunTransformations.h index 2c259fda21e..938af971679 100644 --- a/layout/generic/nsTextRunTransformations.h +++ b/layout/generic/nsTextRunTransformations.h @@ -57,7 +57,7 @@ public: gfxFontGroup* aFontGroup, PRUint32 aFlags, nsStyleContext** aStyles, PRBool aOwnsFactory = PR_TRUE); - virtual void RebuildTextRun(nsTransformedTextRun* aTextRun) = 0; + virtual void RebuildTextRun(nsTransformedTextRun* aTextRun, gfxContext* aRefContext) = 0; }; /** @@ -66,7 +66,7 @@ public: */ class nsFontVariantTextRunFactory : public nsTransformingTextRunFactory { public: - virtual void RebuildTextRun(nsTransformedTextRun* aTextRun); + virtual void RebuildTextRun(nsTransformedTextRun* aTextRun, gfxContext* aRefContext); }; /** @@ -87,7 +87,7 @@ public: : mInnerTransformingTextRunFactory(aInnerTransformingTextRunFactory), mAllUppercase(aAllUppercase) {} - virtual void RebuildTextRun(nsTransformedTextRun* aTextRun); + virtual void RebuildTextRun(nsTransformedTextRun* aTextRun, gfxContext* aRefContext); protected: nsAutoPtr mInnerTransformingTextRunFactory;