Bug 1067755 - Store relevant style data rather than style context pointers on transformed text runs. r=jdaggett

This commit is contained in:
Cameron McCormack 2015-02-10 21:30:25 +11:00
parent c2ace4c6a3
commit 67365c392b
4 changed files with 78 additions and 49 deletions

View File

@ -9,7 +9,6 @@
#include "mozilla/BinarySearch.h"
#include "nsStyleConsts.h"
#include "nsStyleContext.h"
#include "nsTextFrameUtils.h"
#include "nsFontMetrics.h"
#include "nsDeviceContext.h"
@ -538,7 +537,7 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
nsAutoString convertedString;
nsAutoTArray<bool,50> charsToMergeArray;
nsAutoTArray<bool,50> deletedCharsArray;
nsAutoTArray<nsStyleContext*,50> styleArray;
nsAutoTArray<nsRefPtr<nsTransformedCharStyle>,50> styleArray;
nsAutoTArray<uint8_t,50> canBreakBeforeArray;
bool mergeNeeded = false;
@ -547,10 +546,10 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
uint32_t length = aTextRun->GetLength();
const char16_t* str = aTextRun->mString.BeginReading();
nsRefPtr<nsStyleContext>* styles = aTextRun->mStyles.Elements();
const nsTArray<nsRefPtr<nsTransformedCharStyle>>& styles = aTextRun->mStyles;
nsFont font;
if (length) {
font = styles[0]->StyleFont()->mFont;
font = styles[0]->mFont;
if (mSSTYScriptLevel || (mFlags & MATH_FONT_FEATURE_DTLS)) {
bool foundSSTY = false;
@ -565,7 +564,7 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
}
if (mSSTYScriptLevel && !foundSSTY) {
uint8_t sstyLevel = 0;
float scriptScaling = pow(styles[0]->StyleFont()->mScriptSizeMultiplier,
float scriptScaling = pow(styles[0]->mScriptSizeMultiplier,
mSSTYScriptLevel);
static_assert(NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER < 1,
"Shouldn't it make things smaller?");
@ -626,8 +625,7 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
for (uint32_t i = 0; i < length; ++i) {
int extraChars = 0;
nsStyleContext* styleContext = styles[i];
mathVar = styleContext->StyleFont()->mMathVariant;
mathVar = styles[i]->mMathVariant;
if (singleCharMI && mathVar == NS_MATHML_MATHVARIANT_NONE) {
// If the user has explicitly set a non-default value for fontstyle or
@ -688,7 +686,7 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
deletedCharsArray.AppendElement(false);
charsToMergeArray.AppendElement(false);
styleArray.AppendElement(styleContext);
styleArray.AppendElement(styles[i]);
canBreakBeforeArray.AppendElement(aTextRun->CanBreakLineBefore(i));
if (IS_IN_BMP(ch2)) {
@ -707,7 +705,7 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
while (extraChars-- > 0) {
mergeNeeded = true;
charsToMergeArray.AppendElement(true);
styleArray.AppendElement(styleContext);
styleArray.AppendElement(styles[i]);
canBreakBeforeArray.AppendElement(false);
}
}
@ -742,12 +740,11 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
// Get the correct gfxFontGroup that corresponds to the earlier font changes.
if (length) {
font.size = NSToCoordRound(font.size * mFontInflation);
nsPresContext* pc = styles[0]->PresContext();
nsPresContext* pc = styles[0]->mPresContext;
nsRefPtr<nsFontMetrics> metrics;
const nsStyleFont* styleFont = styles[0]->StyleFont();
pc->DeviceContext()->GetMetricsFor(font,
styleFont->mLanguage,
styleFont->mExplicitLanguage,
styles[0]->mLanguage,
styles[0]->mExplicitLanguage,
gfxFont::eHorizontal,
pc->GetUserFontSet(),
pc->GetTextPerfMetrics(),
@ -766,7 +763,7 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
if (mInnerTransformingTextRunFactory) {
transformedChild = mInnerTransformingTextRunFactory->MakeTextRun(
convertedString.BeginReading(), convertedString.Length(),
&innerParams, newFontGroup, flags, styleArray.Elements(), false);
&innerParams, newFontGroup, flags, Move(styleArray), false);
child = transformedChild.get();
} else {
cachedChild = newFontGroup->MakeTextRun(

View File

@ -2125,21 +2125,26 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
new MathMLTextRunFactory(transformingFactory.forget(), mathFlags,
sstyScriptLevel, fontInflation);
}
nsTArray<nsStyleContext*> styles;
nsTArray<nsRefPtr<nsTransformedCharStyle>> styles;
if (transformingFactory) {
iter.SetOriginalOffset(0);
for (uint32_t i = 0; i < mMappedFlows.Length(); ++i) {
MappedFlow* mappedFlow = &mMappedFlows[i];
nsTextFrame* f;
nsStyleContext* sc = nullptr;
nsRefPtr<nsTransformedCharStyle> charStyle;
for (f = mappedFlow->mStartFrame; f != mappedFlow->mEndFrame;
f = static_cast<nsTextFrame*>(f->GetNextContinuation())) {
uint32_t offset = iter.GetSkippedOffset();
iter.AdvanceOriginal(f->GetContentLength());
uint32_t end = iter.GetSkippedOffset();
nsStyleContext* sc = f->StyleContext();
if (sc != f->StyleContext()) {
sc = f->StyleContext();
charStyle = new nsTransformedCharStyle(sc);
}
uint32_t j;
for (j = offset; j < end; ++j) {
styles.AppendElement(sc);
styles.AppendElement(charStyle);
}
}
}
@ -2160,7 +2165,7 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
if (transformingFactory) {
textRun = transformingFactory->MakeTextRun(text, transformedLength,
&params, fontGroup, textFlags,
styles.Elements(), true);
Move(styles), true);
if (textRun) {
// ownership of the factory has passed to the textrun
transformingFactory.forget();
@ -2175,7 +2180,7 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
if (transformingFactory) {
textRun = transformingFactory->MakeTextRun(text, transformedLength,
&params, fontGroup, textFlags,
styles.Elements(), true);
Move(styles), true);
if (textRun) {
// ownership of the factory has passed to the textrun
transformingFactory.forget();

View File

@ -9,7 +9,6 @@
#include "nsGkAtoms.h"
#include "nsStyleConsts.h"
#include "nsStyleContext.h"
#include "nsUnicharUtils.h"
#include "nsUnicodeProperties.h"
#include "nsSpecialCasingData.h"
@ -36,7 +35,8 @@ nsTransformedTextRun::Create(const gfxTextRunFactory::Parameters* aParams,
nsTransformingTextRunFactory* aFactory,
gfxFontGroup* aFontGroup,
const char16_t* aString, uint32_t aLength,
const uint32_t aFlags, nsStyleContext** aStyles,
const uint32_t aFlags,
nsTArray<nsRefPtr<nsTransformedCharStyle>>&& aStyles,
bool aOwnsFactory)
{
NS_ASSERTION(!(aFlags & gfxTextRunFactory::TEXT_IS_8BIT),
@ -49,7 +49,8 @@ nsTransformedTextRun::Create(const gfxTextRunFactory::Parameters* aParams,
return new (storage) nsTransformedTextRun(aParams, aFactory, aFontGroup,
aString, aLength,
aFlags, aStyles, aOwnsFactory);
aFlags, Move(aStyles),
aOwnsFactory);
}
void
@ -101,24 +102,27 @@ nsTransformedTextRun*
nsTransformingTextRunFactory::MakeTextRun(const char16_t* aString, uint32_t aLength,
const gfxTextRunFactory::Parameters* aParams,
gfxFontGroup* aFontGroup, uint32_t aFlags,
nsStyleContext** aStyles, bool aOwnsFactory)
nsTArray<nsRefPtr<nsTransformedCharStyle>>&& aStyles,
bool aOwnsFactory)
{
return nsTransformedTextRun::Create(aParams, this, aFontGroup,
aString, aLength, aFlags, aStyles, aOwnsFactory);
aString, aLength, aFlags, Move(aStyles),
aOwnsFactory);
}
nsTransformedTextRun*
nsTransformingTextRunFactory::MakeTextRun(const uint8_t* aString, uint32_t aLength,
const gfxTextRunFactory::Parameters* aParams,
gfxFontGroup* aFontGroup, uint32_t aFlags,
nsStyleContext** aStyles, bool aOwnsFactory)
nsTArray<nsRefPtr<nsTransformedCharStyle>>&& aStyles,
bool aOwnsFactory)
{
// We'll only have a Unicode code path to minimize the amount of code needed
// for these rarely used features
NS_ConvertASCIItoUTF16 unicodeString(reinterpret_cast<const char*>(aString), aLength);
return MakeTextRun(unicodeString.get(), aLength, aParams, aFontGroup,
aFlags & ~(gfxFontGroup::TEXT_IS_PERSISTENT | gfxFontGroup::TEXT_IS_8BIT),
aStyles, aOwnsFactory);
Move(aStyles), aOwnsFactory);
}
void
@ -277,7 +281,7 @@ nsCaseTransformTextRunFactory::TransformString(
nsTArray<bool>& aDeletedCharsArray,
nsTransformedTextRun* aTextRun,
nsTArray<uint8_t>* aCanBreakBeforeArray,
nsTArray<nsStyleContext*>* aStyleArray)
nsTArray<nsRefPtr<nsTransformedCharStyle>>* aStyleArray)
{
NS_PRECONDITION(!aTextRun || (aCanBreakBeforeArray && aStyleArray),
"either none or all three optional parameters required");
@ -305,15 +309,14 @@ nsCaseTransformTextRunFactory::TransformString(
for (uint32_t i = 0; i < length; ++i) {
uint32_t ch = str[i];
nsStyleContext* styleContext;
nsRefPtr<nsTransformedCharStyle> charStyle;
if (aTextRun) {
styleContext = aTextRun->mStyles[i];
charStyle = aTextRun->mStyles[i];
style = aAllUppercase ? NS_STYLE_TEXT_TRANSFORM_UPPERCASE :
styleContext->StyleText()->mTextTransform;
charStyle->mTextTransform;
const nsStyleFont* styleFont = styleContext->StyleFont();
nsIAtom* newLang = styleFont->mExplicitLanguage
? styleFont->mLanguage : nullptr;
nsIAtom* newLang = charStyle->mExplicitLanguage
? charStyle->mLanguage : nullptr;
if (lang != newLang) {
lang = newLang;
languageSpecificCasing = GetCasingFor(lang);
@ -564,7 +567,7 @@ nsCaseTransformTextRunFactory::TransformString(
aDeletedCharsArray.AppendElement(false);
aCharsToMergeArray.AppendElement(false);
if (aTextRun) {
aStyleArray->AppendElement(styleContext);
aStyleArray->AppendElement(charStyle);
aCanBreakBeforeArray->AppendElement(inhibitBreakBefore ? false :
aTextRun->CanBreakLineBefore(i));
}
@ -584,7 +587,7 @@ nsCaseTransformTextRunFactory::TransformString(
mergeNeeded = true;
aCharsToMergeArray.AppendElement(true);
if (aTextRun) {
aStyleArray->AppendElement(styleContext);
aStyleArray->AppendElement(charStyle);
aCanBreakBeforeArray->AppendElement(false);
}
}
@ -602,7 +605,7 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
nsAutoTArray<bool,50> charsToMergeArray;
nsAutoTArray<bool,50> deletedCharsArray;
nsAutoTArray<uint8_t,50> canBreakBeforeArray;
nsAutoTArray<nsStyleContext*,50> styleArray;
nsAutoTArray<nsRefPtr<nsTransformedCharStyle>,50> styleArray;
bool mergeNeeded = TransformString(aTextRun->mString,
convertedString,
@ -626,7 +629,7 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
if (mInnerTransformingTextRunFactory) {
transformedChild = mInnerTransformingTextRunFactory->MakeTextRun(
convertedString.BeginReading(), convertedString.Length(),
&innerParams, fontGroup, flags, styleArray.Elements(), false);
&innerParams, fontGroup, flags, Move(styleArray), false);
child = transformedChild.get();
} else {
cachedChild = fontGroup->MakeTextRun(

View File

@ -13,6 +13,32 @@
class nsTransformedTextRun;
struct nsTransformedCharStyle MOZ_FINAL {
NS_INLINE_DECL_REFCOUNTING(nsTransformedCharStyle)
explicit nsTransformedCharStyle(nsStyleContext* aContext)
: mFont(aContext->StyleFont()->mFont)
, mLanguage(aContext->StyleFont()->mLanguage)
, mPresContext(aContext->PresContext())
, mScriptSizeMultiplier(aContext->StyleFont()->mScriptSizeMultiplier)
, mTextTransform(aContext->StyleText()->mTextTransform)
, mMathVariant(aContext->StyleFont()->mMathVariant)
, mExplicitLanguage(aContext->StyleFont()->mExplicitLanguage) {}
nsFont mFont;
nsCOMPtr<nsIAtom> mLanguage;
nsRefPtr<nsPresContext> mPresContext;
float mScriptSizeMultiplier;
uint8_t mTextTransform;
uint8_t mMathVariant;
bool mExplicitLanguage;
private:
~nsTransformedCharStyle() {}
nsTransformedCharStyle(const nsTransformedCharStyle& aOther) = delete;
nsTransformedCharStyle& operator=(const nsTransformedCharStyle& aOther) = delete;
};
class nsTransformingTextRunFactory {
public:
virtual ~nsTransformingTextRunFactory() {}
@ -21,12 +47,12 @@ public:
nsTransformedTextRun* MakeTextRun(const uint8_t* aString, uint32_t aLength,
const gfxFontGroup::Parameters* aParams,
gfxFontGroup* aFontGroup, uint32_t aFlags,
nsStyleContext** aStyles,
nsTArray<nsRefPtr<nsTransformedCharStyle>>&& aStyles,
bool aOwnsFactory);
nsTransformedTextRun* MakeTextRun(const char16_t* aString, uint32_t aLength,
const gfxFontGroup::Parameters* aParams,
gfxFontGroup* aFontGroup, uint32_t aFlags,
nsStyleContext** aStyles,
nsTArray<nsRefPtr<nsTransformedCharStyle>>&& aStyles,
bool aOwnsFactory);
virtual void RebuildTextRun(nsTransformedTextRun* aTextRun,
@ -74,7 +100,7 @@ public:
nsTArray<bool>& aDeletedCharsArray,
nsTransformedTextRun* aTextRun = nullptr,
nsTArray<uint8_t>* aCanBreakBeforeArray = nullptr,
nsTArray<nsStyleContext*>* aStyleArray = nullptr);
nsTArray<nsRefPtr<nsTransformedCharStyle>>* aStyleArray = nullptr);
protected:
nsAutoPtr<nsTransformingTextRunFactory> mInnerTransformingTextRunFactory;
@ -87,11 +113,13 @@ protected:
*/
class nsTransformedTextRun MOZ_FINAL : public gfxTextRun {
public:
static nsTransformedTextRun *Create(const gfxTextRunFactory::Parameters* aParams,
nsTransformingTextRunFactory* aFactory,
gfxFontGroup* aFontGroup,
const char16_t* aString, uint32_t aLength,
const uint32_t aFlags, nsStyleContext** aStyles,
const uint32_t aFlags,
nsTArray<nsRefPtr<nsTransformedCharStyle>>&& aStyles,
bool aOwnsFactory);
~nsTransformedTextRun() {
@ -125,7 +153,7 @@ public:
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) MOZ_MUST_OVERRIDE;
nsTransformingTextRunFactory *mFactory;
nsTArray<nsRefPtr<nsStyleContext> > mStyles;
nsTArray<nsRefPtr<nsTransformedCharStyle>> mStyles;
nsTArray<bool> mCapitalize;
nsString mString;
bool mOwnsFactory;
@ -136,18 +164,14 @@ private:
nsTransformingTextRunFactory* aFactory,
gfxFontGroup* aFontGroup,
const char16_t* aString, uint32_t aLength,
const uint32_t aFlags, nsStyleContext** aStyles,
const uint32_t aFlags,
nsTArray<nsRefPtr<nsTransformedCharStyle>>&& aStyles,
bool aOwnsFactory)
: gfxTextRun(aParams, aLength, aFontGroup, aFlags),
mFactory(aFactory), mString(aString, aLength),
mFactory(aFactory), mStyles(aStyles), mString(aString, aLength),
mOwnsFactory(aOwnsFactory), mNeedsRebuild(true)
{
mCharacterGlyphs = reinterpret_cast<CompressedGlyph*>(this + 1);
uint32_t i;
for (i = 0; i < aLength; ++i) {
mStyles.AppendElement(aStyles[i]);
}
}
};