Bug 384836. Avoid using a stale gfxContext, by not holding onto one in nsTransformedTextRun, passing in a gfxContext when required instead. r=pavlov,smontagu

This commit is contained in:
roc+@cs.cmu.edu 2007-06-25 21:25:00 -07:00
Родитель cd53599bad
Коммит 281b20dd55
5 изменённых файлов: 50 добавлений и 32 удалений

Просмотреть файл

@ -589,7 +589,8 @@ public:
* breaks are the same as the old * breaks are the same as the old
*/ */
virtual PRBool SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength, virtual PRBool SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength,
PRPackedBool *aBreakBefore); PRPackedBool *aBreakBefore,
gfxContext *aRefContext);
/** /**
* Layout provides PropertyProvider objects. These allow detection of * Layout provides PropertyProvider objects. These allow detection of
@ -719,7 +720,8 @@ public:
*/ */
virtual PRBool SetLineBreaks(PRUint32 aStart, PRUint32 aLength, virtual PRBool SetLineBreaks(PRUint32 aStart, PRUint32 aLength,
PRBool aLineBreakBefore, PRBool aLineBreakAfter, PRBool aLineBreakBefore, PRBool aLineBreakAfter,
gfxFloat *aAdvanceWidthDelta); gfxFloat *aAdvanceWidthDelta,
gfxContext *aRefContext);
/** /**
* Finds the longest substring that will fit into the given width. * Finds the longest substring that will fit into the given width.

Просмотреть файл

@ -686,7 +686,8 @@ gfxTextRun::Clone(const gfxTextRunFactory::Parameters *aParams, const void *aTex
PRBool PRBool
gfxTextRun::SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength, gfxTextRun::SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength,
PRPackedBool *aBreakBefore) PRPackedBool *aBreakBefore,
gfxContext *aRefContext)
{ {
NS_ASSERTION(aStart + aLength <= mCharacterCount, "Overflow"); NS_ASSERTION(aStart + aLength <= mCharacterCount, "Overflow");
@ -1416,7 +1417,8 @@ gfxTextRun::GetAdvanceWidth(PRUint32 aStart, PRUint32 aLength,
PRBool PRBool
gfxTextRun::SetLineBreaks(PRUint32 aStart, PRUint32 aLength, gfxTextRun::SetLineBreaks(PRUint32 aStart, PRUint32 aLength,
PRBool aLineBreakBefore, PRBool aLineBreakAfter, PRBool aLineBreakBefore, PRBool aLineBreakAfter,
gfxFloat *aAdvanceWidthDelta) gfxFloat *aAdvanceWidthDelta,
gfxContext *aRefContext)
{ {
// Do nothing because our shaping does not currently take linebreaks into // Do nothing because our shaping does not currently take linebreaks into
// account. There is no change in advance width. // account. There is no change in advance width.

Просмотреть файл

@ -910,20 +910,22 @@ public:
class BreakSink : public nsILineBreakSink { class BreakSink : public nsILineBreakSink {
public: public:
BreakSink(gfxTextRun* aTextRun, PRUint32 aOffsetIntoTextRun, BreakSink(gfxTextRun* aTextRun, gfxContext* aContext, PRUint32 aOffsetIntoTextRun,
PRBool aExistingTextRun) : PRBool aExistingTextRun) :
mTextRun(aTextRun), mOffsetIntoTextRun(aOffsetIntoTextRun), mTextRun(aTextRun), mContext(aContext),
mChangedBreaks(PR_FALSE), mExistingTextRun(aExistingTextRun) {} mOffsetIntoTextRun(aOffsetIntoTextRun),
mChangedBreaks(PR_FALSE), mExistingTextRun(aExistingTextRun) {}
virtual void SetBreaks(PRUint32 aOffset, PRUint32 aLength, virtual void SetBreaks(PRUint32 aOffset, PRUint32 aLength,
PRPackedBool* aBreakBefore) { PRPackedBool* aBreakBefore) {
if (mTextRun->SetPotentialLineBreaks(aOffset + mOffsetIntoTextRun, aLength, if (mTextRun->SetPotentialLineBreaks(aOffset + mOffsetIntoTextRun, aLength,
aBreakBefore)) { aBreakBefore, mContext)) {
mChangedBreaks = PR_TRUE; mChangedBreaks = PR_TRUE;
} }
} }
gfxTextRun* mTextRun; gfxTextRun* mTextRun;
gfxContext* mContext;
PRUint32 mOffsetIntoTextRun; PRUint32 mOffsetIntoTextRun;
PRPackedBool mChangedBreaks; PRPackedBool mChangedBreaks;
PRPackedBool mExistingTextRun; PRPackedBool mExistingTextRun;
@ -1806,7 +1808,7 @@ HasCompressedLeadingWhitespace(nsTextFrame* aFrame, PRInt32 aContentEndOffset,
} }
void void
BuildTextRunsScanner::SetupBreakSinksForTextRun(gfxTextRun* aTextRun, BuildTextRunsScanner::SetupBreakSinksForTextRun(gfxTextRun* aTextRun,
PRBool aIsExistingTextRun, PRBool aIsExistingTextRun,
PRBool aSuppressSink) PRBool aSuppressSink)
{ {
@ -1821,7 +1823,8 @@ BuildTextRunsScanner::SetupBreakSinksForTextRun(gfxTextRun* aTextRun,
for (i = 0; i < mMappedFlows.Length(); ++i) { for (i = 0; i < mMappedFlows.Length(); ++i) {
MappedFlow* mappedFlow = &mMappedFlows[i]; MappedFlow* mappedFlow = &mMappedFlows[i];
nsAutoPtr<BreakSink>* breakSink = mBreakSinks.AppendElement( nsAutoPtr<BreakSink>* breakSink = mBreakSinks.AppendElement(
new BreakSink(aTextRun, mappedFlow->mTransformedTextOffset, aIsExistingTextRun)); new BreakSink(aTextRun, mContext,
mappedFlow->mTransformedTextOffset, aIsExistingTextRun));
if (!breakSink || !*breakSink) if (!breakSink || !*breakSink)
return; return;
PRUint32 offset = mappedFlow->mTransformedTextOffset; 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; gfxFloat advanceDelta;
mTextRun->SetLineBreaks(trimmedStart, trimmedEnd - trimmedStart, mTextRun->SetLineBreaks(trimmedStart, trimmedEnd - trimmedStart,
(GetStateBits() & TEXT_START_OF_LINE) != 0, PR_TRUE, (GetStateBits() & TEXT_START_OF_LINE) != 0, PR_TRUE,
&advanceDelta); &advanceDelta, ctx);
// aDeltaWidth is *subtracted* from our width. // aDeltaWidth is *subtracted* from our width.
// If advanceDelta is positive then setting the line break made us longer, // If advanceDelta is positive then setting the line break made us longer,

Просмотреть файл

@ -61,8 +61,7 @@ public:
const PRUint32 aFlags, nsStyleContext** aStyles, const PRUint32 aFlags, nsStyleContext** aStyles,
PRBool aOwnsFactory) PRBool aOwnsFactory)
: gfxTextRun(aParams, aString, aLength, aFontGroup, aFlags), : gfxTextRun(aParams, aString, aLength, aFontGroup, aFlags),
mFactory(aFactory), mRefContext(aParams->mContext), mFactory(aFactory), mOwnsFactory(aOwnsFactory)
mOwnsFactory(aOwnsFactory)
{ {
PRUint32 i; PRUint32 i;
for (i = 0; i < aLength; ++i) { for (i = 0; i < aLength; ++i) {
@ -80,18 +79,20 @@ public:
} }
virtual PRBool SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength, virtual PRBool SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength,
PRPackedBool* aBreakBefore) PRPackedBool* aBreakBefore,
gfxContext* aRefContext)
{ {
PRBool changed = gfxTextRun::SetPotentialLineBreaks(aStart, aLength, aBreakBefore); PRBool changed = gfxTextRun::SetPotentialLineBreaks(aStart, aLength,
mFactory->RebuildTextRun(this); aBreakBefore, aRefContext);
mFactory->RebuildTextRun(this, aRefContext);
return changed; return changed;
} }
virtual PRBool SetLineBreaks(PRUint32 aStart, PRUint32 aLength, virtual PRBool SetLineBreaks(PRUint32 aStart, PRUint32 aLength,
PRBool aLineBreakBefore, PRBool aLineBreakAfter, PRBool aLineBreakBefore, PRBool aLineBreakAfter,
gfxFloat* aAdvanceWidthDelta); gfxFloat* aAdvanceWidthDelta,
gfxContext* aRefContext);
nsTransformingTextRunFactory *mFactory; nsTransformingTextRunFactory *mFactory;
nsRefPtr<gfxContext> mRefContext;
nsTArray<PRUint32> mLineBreaks; nsTArray<PRUint32> mLineBreaks;
nsTArray<nsRefPtr<nsStyleContext> > mStyles; nsTArray<nsRefPtr<nsStyleContext> > mStyles;
PRPackedBool mOwnsFactory; PRPackedBool mOwnsFactory;
@ -100,7 +101,8 @@ public:
PRBool PRBool
nsTransformedTextRun::SetLineBreaks(PRUint32 aStart, PRUint32 aLength, nsTransformedTextRun::SetLineBreaks(PRUint32 aStart, PRUint32 aLength,
PRBool aLineBreakBefore, PRBool aLineBreakAfter, PRBool aLineBreakBefore, PRBool aLineBreakAfter,
gfxFloat* aAdvanceWidthDelta) gfxFloat* aAdvanceWidthDelta,
gfxContext* aRefContext)
{ {
nsTArray<PRUint32> newBreaks; nsTArray<PRUint32> newBreaks;
PRUint32 i; PRUint32 i;
@ -141,7 +143,7 @@ nsTransformedTextRun::SetLineBreaks(PRUint32 aStart, PRUint32 aLength,
mLineBreaks.SwapElements(newBreaks); mLineBreaks.SwapElements(newBreaks);
gfxFloat currentAdvance = GetAdvanceWidth(aStart, aLength, nsnull); gfxFloat currentAdvance = GetAdvanceWidth(aStart, aLength, nsnull);
mFactory->RebuildTextRun(this); mFactory->RebuildTextRun(this, aRefContext);
if (aAdvanceWidthDelta) { if (aAdvanceWidthDelta) {
*aAdvanceWidthDelta = GetAdvanceWidth(aStart, aLength, nsnull) - currentAdvance; *aAdvanceWidthDelta = GetAdvanceWidth(aStart, aLength, nsnull) - currentAdvance;
} }
@ -160,7 +162,7 @@ nsTransformingTextRunFactory::MakeTextRun(const PRUnichar* aString, PRUint32 aLe
if (!textRun) if (!textRun)
return nsnull; return nsnull;
RebuildTextRun(textRun); RebuildTextRun(textRun, aParams->mContext);
return textRun; return textRun;
} }
@ -310,10 +312,11 @@ MergeCharactersInTextRun(gfxTextRun* aDest, gfxTextRun* aSrc,
} }
static gfxTextRunFactory::Parameters static gfxTextRunFactory::Parameters
GetParametersForInner(nsTransformedTextRun* aTextRun, PRUint32* aFlags) GetParametersForInner(nsTransformedTextRun* aTextRun, PRUint32* aFlags,
gfxContext* aRefContext)
{ {
gfxTextRunFactory::Parameters params = gfxTextRunFactory::Parameters params =
{ aTextRun->mRefContext, nsnull, nsnull, { aRefContext, nsnull, nsnull,
nsnull, nsnull, PRUint32(aTextRun->GetAppUnitsPerDevUnit()) nsnull, nsnull, PRUint32(aTextRun->GetAppUnitsPerDevUnit())
}; };
*aFlags = aTextRun->GetFlags() & ~gfxFontGroup::TEXT_IS_PERSISTENT; *aFlags = aTextRun->GetFlags() & ~gfxFontGroup::TEXT_IS_PERSISTENT;
@ -321,7 +324,8 @@ GetParametersForInner(nsTransformedTextRun* aTextRun, PRUint32* aFlags)
} }
void void
nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun) nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
gfxContext* aRefContext)
{ {
nsICaseConversion* converter = nsTextTransformer::GetCaseConv(); nsICaseConversion* converter = nsTextTransformer::GetCaseConv();
if (!converter) if (!converter)
@ -335,7 +339,8 @@ nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun)
return; return;
PRUint32 flags; PRUint32 flags;
gfxTextRunFactory::Parameters innerParams = GetParametersForInner(aTextRun, &flags); gfxTextRunFactory::Parameters innerParams =
GetParametersForInner(aTextRun, &flags, aRefContext);
// The text outlives the child and inner textruns // The text outlives the child and inner textruns
flags |= gfxFontGroup::TEXT_IS_PERSISTENT; flags |= gfxFontGroup::TEXT_IS_PERSISTENT;
@ -404,7 +409,8 @@ nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun)
// (and also child will be shaped appropriately) // (and also child will be shaped appropriately)
NS_ASSERTION(canBreakBeforeArray.Length() == i - runStart, NS_ASSERTION(canBreakBeforeArray.Length() == i - runStart,
"lost some break-before values?"); "lost some break-before values?");
child->SetPotentialLineBreaks(0, canBreakBeforeArray.Length(), canBreakBeforeArray.Elements()); child->SetPotentialLineBreaks(0, canBreakBeforeArray.Length(),
canBreakBeforeArray.Elements(), aRefContext);
AppendTextRun(aTextRun, child, runStart); AppendTextRun(aTextRun, child, runStart);
runStart = i; runStart = i;
@ -427,7 +433,8 @@ nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun)
} }
void void
nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun) nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
gfxContext* aRefContext)
{ {
nsICaseConversion* converter = nsTextTransformer::GetCaseConv(); nsICaseConversion* converter = nsTextTransformer::GetCaseConv();
if (!converter) if (!converter)
@ -507,7 +514,8 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun)
"lost track of line breaks somehow"); "lost track of line breaks somehow");
PRUint32 flags; PRUint32 flags;
gfxTextRunFactory::Parameters innerParams = GetParametersForInner(aTextRun, &flags); gfxTextRunFactory::Parameters innerParams =
GetParametersForInner(aTextRun, &flags, aRefContext);
gfxFontGroup* fontGroup = aTextRun->GetFontGroup(); gfxFontGroup* fontGroup = aTextRun->GetFontGroup();
nsAutoPtr<gfxTextRun> child; nsAutoPtr<gfxTextRun> child;
@ -531,7 +539,8 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun)
// (and also child will be shaped appropriately) // (and also child will be shaped appropriately)
NS_ASSERTION(convertedString.Length() == canBreakBeforeArray.Length(), NS_ASSERTION(convertedString.Length() == canBreakBeforeArray.Length(),
"Dropped characters or break-before values somewhere!"); "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 // Now merge multiple characters into one multi-glyph character as required
MergeCharactersInTextRun(aTextRun, child, charsToMergeArray.Elements()); MergeCharactersInTextRun(aTextRun, child, charsToMergeArray.Elements());
} }

Просмотреть файл

@ -57,7 +57,7 @@ public:
gfxFontGroup* aFontGroup, PRUint32 aFlags, gfxFontGroup* aFontGroup, PRUint32 aFlags,
nsStyleContext** aStyles, PRBool aOwnsFactory = PR_TRUE); 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 { class nsFontVariantTextRunFactory : public nsTransformingTextRunFactory {
public: public:
virtual void RebuildTextRun(nsTransformedTextRun* aTextRun); virtual void RebuildTextRun(nsTransformedTextRun* aTextRun, gfxContext* aRefContext);
}; };
/** /**
@ -87,7 +87,7 @@ public:
: mInnerTransformingTextRunFactory(aInnerTransformingTextRunFactory), : mInnerTransformingTextRunFactory(aInnerTransformingTextRunFactory),
mAllUppercase(aAllUppercase) {} mAllUppercase(aAllUppercase) {}
virtual void RebuildTextRun(nsTransformedTextRun* aTextRun); virtual void RebuildTextRun(nsTransformedTextRun* aTextRun, gfxContext* aRefContext);
protected: protected:
nsAutoPtr<nsTransformingTextRunFactory> mInnerTransformingTextRunFactory; nsAutoPtr<nsTransformingTextRunFactory> mInnerTransformingTextRunFactory;