зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
cd53599bad
Коммит
281b20dd55
|
@ -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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче