mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-25 19:25:43 +00:00
Bug 1509167 - Cache an nsFontMetrics reference in nsTextFrame so that we don't have to re-create it on every DrawText call. r=jwatt
This commit is contained in:
parent
33bcfcbc16
commit
803d5550bd
@ -2040,6 +2040,22 @@ GetFontGroupForFrame(const nsIFrame* aFrame, float aFontSizeInflation,
|
||||
return fontGroup;
|
||||
}
|
||||
|
||||
static gfxFontGroup*
|
||||
GetInflatedFontGroupForFrame(nsTextFrame* aFrame)
|
||||
{
|
||||
gfxTextRun* textRun = aFrame->GetTextRun(nsTextFrame::eInflated);
|
||||
if (textRun) {
|
||||
return textRun->GetFontGroup();
|
||||
}
|
||||
if (!aFrame->InflatedFontMetrics()) {
|
||||
float inflation = nsLayoutUtils::FontSizeInflationFor(aFrame);
|
||||
RefPtr<nsFontMetrics> metrics =
|
||||
nsLayoutUtils::GetFontMetricsForFrame(aFrame, inflation);
|
||||
aFrame->SetInflatedFontMetrics(metrics);
|
||||
}
|
||||
return aFrame->InflatedFontMetrics()->GetThebesFontGroup();
|
||||
}
|
||||
|
||||
static already_AddRefed<DrawTarget>
|
||||
CreateReferenceDrawTarget(const nsTextFrame* aTextFrame)
|
||||
{
|
||||
@ -2284,13 +2300,15 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
|
||||
// Now build the textrun
|
||||
nsTextFrame* firstFrame = mMappedFlows[0].mStartFrame;
|
||||
float fontInflation;
|
||||
gfxFontGroup* fontGroup;
|
||||
if (mWhichTextRun == nsTextFrame::eNotInflated) {
|
||||
fontInflation = 1.0f;
|
||||
fontGroup = GetFontGroupForFrame(firstFrame, fontInflation);
|
||||
} else {
|
||||
fontInflation = nsLayoutUtils::FontSizeInflationFor(firstFrame);
|
||||
fontGroup = GetInflatedFontGroupForFrame(firstFrame);
|
||||
}
|
||||
|
||||
gfxFontGroup* fontGroup = GetFontGroupForFrame(firstFrame, fontInflation);
|
||||
if (!fontGroup) {
|
||||
DestroyUserData(userDataToDestroy);
|
||||
return nullptr;
|
||||
@ -3126,8 +3144,10 @@ public:
|
||||
* *must* be called before this!!!
|
||||
*/
|
||||
PropertyProvider(nsTextFrame* aFrame, const gfxSkipCharsIterator& aStart,
|
||||
nsTextFrame::TextRunType aWhichTextRun)
|
||||
nsTextFrame::TextRunType aWhichTextRun,
|
||||
nsFontMetrics* aFontMetrics)
|
||||
: mTextRun(aFrame->GetTextRun(aWhichTextRun)), mFontGroup(nullptr),
|
||||
mFontMetrics(aFontMetrics),
|
||||
mTextStyle(aFrame->StyleText()),
|
||||
mFrag(aFrame->GetContent()->GetText()),
|
||||
mLineContainer(nullptr),
|
||||
@ -3189,7 +3209,7 @@ public:
|
||||
|
||||
gfxFontGroup* GetFontGroup() const {
|
||||
if (!mFontGroup) {
|
||||
InitFontGroupAndFontMetrics();
|
||||
mFontGroup = GetFontMetrics()->GetThebesFontGroup();
|
||||
}
|
||||
return mFontGroup;
|
||||
}
|
||||
@ -3216,10 +3236,21 @@ protected:
|
||||
void SetupJustificationSpacing(bool aPostReflow);
|
||||
|
||||
void InitFontGroupAndFontMetrics() const {
|
||||
float inflation = (mWhichTextRun == nsTextFrame::eInflated)
|
||||
? mFrame->GetFontSizeInflation() : 1.0f;
|
||||
mFontGroup = GetFontGroupForFrame(mFrame, inflation,
|
||||
getter_AddRefs(mFontMetrics));
|
||||
if (!mFontMetrics) {
|
||||
if (mWhichTextRun == nsTextFrame::eInflated) {
|
||||
if (!mFrame->InflatedFontMetrics()) {
|
||||
float inflation = mFrame->GetFontSizeInflation();
|
||||
mFontMetrics =
|
||||
nsLayoutUtils::GetFontMetricsForFrame(mFrame, inflation);
|
||||
mFrame->SetInflatedFontMetrics(mFontMetrics);
|
||||
} else {
|
||||
mFontMetrics = mFrame->InflatedFontMetrics();
|
||||
}
|
||||
} else {
|
||||
mFontMetrics = nsLayoutUtils::GetFontMetricsForFrame(mFrame, 1.0f);
|
||||
}
|
||||
}
|
||||
mFontGroup = mFontMetrics->GetThebesFontGroup();
|
||||
}
|
||||
|
||||
const RefPtr<gfxTextRun> mTextRun;
|
||||
@ -4760,6 +4791,7 @@ nsTextFrame::RemoveTextRun(gfxTextRun* aTextRun)
|
||||
{
|
||||
if (aTextRun == mTextRun) {
|
||||
mTextRun = nullptr;
|
||||
mFontMetrics = nullptr;
|
||||
return true;
|
||||
}
|
||||
if ((GetStateBits() & TEXT_HAS_FONT_INFLATION) &&
|
||||
@ -4779,6 +4811,10 @@ nsTextFrame::ClearTextRun(nsTextFrame* aStartContinuation,
|
||||
return;
|
||||
}
|
||||
|
||||
if (aWhichTextRun == nsTextFrame::eInflated) {
|
||||
mFontMetrics = nullptr;
|
||||
}
|
||||
|
||||
DebugOnly<bool> checkmTextrun = textRun == mTextRun;
|
||||
UnhookTextRunFromFrames(textRun, aStartContinuation);
|
||||
MOZ_ASSERT(checkmTextrun ? !mTextRun
|
||||
@ -5538,7 +5574,7 @@ NS_DECLARE_FRAME_PROPERTY_DELETABLE(EmphasisMarkProperty, EmphasisMarkInfo)
|
||||
|
||||
static already_AddRefed<gfxTextRun>
|
||||
GenerateTextRunForEmphasisMarks(nsTextFrame* aFrame,
|
||||
nsFontMetrics* aFontMetrics,
|
||||
gfxFontGroup* aFontGroup,
|
||||
ComputedStyle* aComputedStyle,
|
||||
const nsStyleText* aStyleText)
|
||||
{
|
||||
@ -5550,7 +5586,7 @@ GenerateTextRunForEmphasisMarks(nsTextFrame* aFrame,
|
||||
// The emphasis marks should always be rendered upright per spec.
|
||||
flags = gfx::ShapedTextFlags::TEXT_ORIENT_VERTICAL_UPRIGHT;
|
||||
}
|
||||
return aFontMetrics->GetThebesFontGroup()->
|
||||
return aFontGroup->
|
||||
MakeTextRun<char16_t>(emphasisString.get(), emphasisString.Length(),
|
||||
dt, appUnitsPerDevUnit, flags,
|
||||
nsTextFrameUtils::Flags(), nullptr);
|
||||
@ -5590,7 +5626,8 @@ nsTextFrame::UpdateTextEmphasis(WritingMode aWM, PropertyProvider& aProvider)
|
||||
GetFontSizeInflation());
|
||||
EmphasisMarkInfo* info = new EmphasisMarkInfo;
|
||||
info->textRun =
|
||||
GenerateTextRunForEmphasisMarks(this, fm, computedStyle, styleText);
|
||||
GenerateTextRunForEmphasisMarks(this, fm->GetThebesFontGroup(),
|
||||
computedStyle, styleText);
|
||||
info->advance = info->textRun->GetAdvanceWidth();
|
||||
|
||||
// Calculate the baseline offset
|
||||
@ -6725,7 +6762,7 @@ nsTextFrame::GetCaretColorAt(int32_t aOffset)
|
||||
|
||||
nscolor result = nsFrame::GetCaretColorAt(aOffset);
|
||||
gfxSkipCharsIterator iter = EnsureTextRun(nsTextFrame::eInflated);
|
||||
PropertyProvider provider(this, iter, nsTextFrame::eInflated);
|
||||
PropertyProvider provider(this, iter, nsTextFrame::eInflated, mFontMetrics);
|
||||
int32_t contentOffset = provider.GetStart().GetOriginalOffset();
|
||||
int32_t contentLength = provider.GetOriginalLength();
|
||||
MOZ_ASSERT(aOffset >= contentOffset &&
|
||||
@ -6796,7 +6833,7 @@ nsTextFrame::MeasureCharClippedText(nscoord aVisIStartEdge,
|
||||
if (!mTextRun)
|
||||
return false;
|
||||
|
||||
PropertyProvider provider(this, iter, nsTextFrame::eInflated);
|
||||
PropertyProvider provider(this, iter, nsTextFrame::eInflated, mFontMetrics);
|
||||
// Trim trailing whitespace
|
||||
provider.InitializeForDisplay(true);
|
||||
|
||||
@ -6982,7 +7019,7 @@ nsTextFrame::PaintText(const PaintTextParams& aParams,
|
||||
if (!mTextRun)
|
||||
return;
|
||||
|
||||
PropertyProvider provider(this, iter, nsTextFrame::eInflated);
|
||||
PropertyProvider provider(this, iter, nsTextFrame::eInflated, mFontMetrics);
|
||||
if (aItem.mIsFrameSelected.isNothing()) {
|
||||
aItem.mIsFrameSelected.emplace(IsSelected());
|
||||
}
|
||||
@ -7501,7 +7538,7 @@ nsTextFrame::GetCharacterOffsetAtFramePointInternal(const nsPoint& aPoint,
|
||||
if (!mTextRun)
|
||||
return offsets;
|
||||
|
||||
PropertyProvider provider(this, iter, nsTextFrame::eInflated);
|
||||
PropertyProvider provider(this, iter, nsTextFrame::eInflated, mFontMetrics);
|
||||
// Trim leading but not trailing whitespace if possible
|
||||
provider.InitializeForDisplay(false);
|
||||
gfxFloat width = mTextRun->IsVertical()
|
||||
@ -7593,9 +7630,7 @@ nsTextFrame::CombineSelectionUnderlineRect(nsPresContext* aPresContext,
|
||||
|
||||
nsRect givenRect = aRect;
|
||||
|
||||
RefPtr<nsFontMetrics> fm =
|
||||
nsLayoutUtils::GetFontMetricsForFrame(this, GetFontSizeInflation());
|
||||
gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
|
||||
gfxFontGroup* fontGroup = GetInflatedFontGroupForFrame(this);
|
||||
gfxFont* firstFont = fontGroup->GetFirstValidFont();
|
||||
WritingMode wm = GetWritingMode();
|
||||
bool verticalRun = wm.IsVertical();
|
||||
@ -7795,7 +7830,7 @@ nsTextFrame::GetPointFromOffset(int32_t inOffset,
|
||||
if (!mTextRun)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PropertyProvider properties(this, iter, nsTextFrame::eInflated);
|
||||
PropertyProvider properties(this, iter, nsTextFrame::eInflated, mFontMetrics);
|
||||
// Don't trim trailing whitespace, we want the caret to appear in the right
|
||||
// place if it's positioned there
|
||||
properties.InitializeForDisplay(false);
|
||||
@ -7826,7 +7861,7 @@ nsTextFrame::GetCharacterRectsInRange(int32_t aInOffset,
|
||||
}
|
||||
|
||||
gfxSkipCharsIterator iter = EnsureTextRun(nsTextFrame::eInflated);
|
||||
PropertyProvider properties(this, iter, nsTextFrame::eInflated);
|
||||
PropertyProvider properties(this, iter, nsTextFrame::eInflated, mFontMetrics);
|
||||
// Don't trim trailing whitespace, we want the caret to appear in the right
|
||||
// place if it's positioned there
|
||||
properties.InitializeForDisplay(false);
|
||||
@ -8724,6 +8759,7 @@ nsTextFrame::AddInlineMinISize(gfxContext *aRenderingContext,
|
||||
// FIXME: Ideally, if we already have a text run, we'd move it to be
|
||||
// the uninflated text run.
|
||||
ClearTextRun(nullptr, nsTextFrame::eInflated);
|
||||
mFontMetrics = nullptr;
|
||||
}
|
||||
|
||||
nsTextFrame* f;
|
||||
@ -8876,6 +8912,7 @@ nsTextFrame::AddInlinePrefISize(gfxContext *aRenderingContext,
|
||||
// FIXME: Ideally, if we already have a text run, we'd move it to be
|
||||
// the uninflated text run.
|
||||
ClearTextRun(nullptr, nsTextFrame::eInflated);
|
||||
mFontMetrics = nullptr;
|
||||
}
|
||||
|
||||
nsTextFrame* f;
|
||||
@ -8944,7 +8981,7 @@ nsTextFrame::ComputeTightBounds(DrawTarget* aDrawTarget) const
|
||||
return nsRect(0, 0, 0, 0);
|
||||
|
||||
PropertyProvider provider(const_cast<nsTextFrame*>(this), iter,
|
||||
nsTextFrame::eInflated);
|
||||
nsTextFrame::eInflated, mFontMetrics);
|
||||
// Trim trailing whitespace
|
||||
provider.InitializeForDisplay(true);
|
||||
|
||||
@ -8978,7 +9015,7 @@ nsTextFrame::GetPrefWidthTightBounds(gfxContext* aContext,
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PropertyProvider provider(const_cast<nsTextFrame*>(this), iter,
|
||||
nsTextFrame::eInflated);
|
||||
nsTextFrame::eInflated, mFontMetrics);
|
||||
provider.InitializeForMeasure();
|
||||
|
||||
gfxTextRun::Metrics metrics =
|
||||
@ -9456,6 +9493,7 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
||||
// FIXME: Ideally, if we already have a text run, we'd move it to be
|
||||
// the uninflated text run.
|
||||
ClearTextRun(nullptr, nsTextFrame::eInflated);
|
||||
mFontMetrics = nullptr;
|
||||
}
|
||||
|
||||
gfxSkipCharsIterator iter =
|
||||
@ -9971,7 +10009,7 @@ nsTextFrame::RecomputeOverflow(nsIFrame* aBlockFrame)
|
||||
if (!mTextRun)
|
||||
return result;
|
||||
|
||||
PropertyProvider provider(this, iter, nsTextFrame::eInflated);
|
||||
PropertyProvider provider(this, iter, nsTextFrame::eInflated, mFontMetrics);
|
||||
// Don't trim trailing space, in case we need to paint it as selected.
|
||||
provider.InitializeForDisplay(false);
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "gfxSkipChars.h"
|
||||
#include "gfxTextRun.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "JustificationUtils.h"
|
||||
#include "RubyUtils.h"
|
||||
|
||||
@ -670,9 +671,17 @@ public:
|
||||
*/
|
||||
void NotifyNativeAnonymousTextnodeChange(uint32_t aOldLength);
|
||||
|
||||
void SetInflatedFontMetrics(nsFontMetrics* aMetrics) {
|
||||
mFontMetrics = aMetrics;
|
||||
}
|
||||
nsFontMetrics* InflatedFontMetrics() const {
|
||||
return mFontMetrics;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~nsTextFrame();
|
||||
|
||||
RefPtr<nsFontMetrics> mFontMetrics;
|
||||
RefPtr<gfxTextRun> mTextRun;
|
||||
nsTextFrame* mNextContinuation;
|
||||
// The key invariant here is that mContentOffset never decreases along
|
||||
|
Loading…
Reference in New Issue
Block a user