Bug 1725555 - patch 2 - Enable the primary nsTextFrame to provide, and cache, an array of all the continuations in the chain. r=emilio
This allows us to binary-search the continuations from nsRange::CollectClientRectsAndText, instead of linear-searching the linked list for every range we need to look up. Depends on D122998 Differential Revision: https://phabricator.services.mozilla.com/D122999
This commit is contained in:
@@ -4384,6 +4384,35 @@ void nsTextFrame::DestroyFrom(nsIFrame* aDestructRoot,
|
||||
nsIFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
|
||||
}
|
||||
|
||||
nsTArray<nsTextFrame*>* nsTextFrame::GetContinuations() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// Only for use on the primary frame, which has no prev-continuation.
|
||||
MOZ_ASSERT(!GetPrevContinuation());
|
||||
if (!mNextContinuation) {
|
||||
return nullptr;
|
||||
}
|
||||
if (mHasContinuationsProperty) {
|
||||
return GetProperty(ContinuationsProperty());
|
||||
}
|
||||
size_t count = 0;
|
||||
for (nsIFrame* f = this; f; f = f->GetNextContinuation()) {
|
||||
++count;
|
||||
}
|
||||
auto* continuations = new nsTArray<nsTextFrame*>;
|
||||
if (continuations->SetCapacity(count, fallible)) {
|
||||
for (nsTextFrame* f = this; f;
|
||||
f = static_cast<nsTextFrame*>(f->GetNextContinuation())) {
|
||||
continuations->AppendElement(f);
|
||||
}
|
||||
} else {
|
||||
delete continuations;
|
||||
continuations = nullptr;
|
||||
}
|
||||
AddProperty(ContinuationsProperty(), continuations);
|
||||
mHasContinuationsProperty = true;
|
||||
return continuations;
|
||||
}
|
||||
|
||||
class nsContinuingTextFrame final : public nsTextFrame {
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS(nsContinuingTextFrame)
|
||||
@@ -4410,10 +4439,16 @@ class nsContinuingTextFrame final : public nsTextFrame {
|
||||
nsTextFrame* prevFirst = mFirstContinuation;
|
||||
if (mPrevContinuation) {
|
||||
mFirstContinuation = mPrevContinuation->FirstContinuation();
|
||||
if (mFirstContinuation) {
|
||||
mFirstContinuation->ClearCachedContinuations();
|
||||
}
|
||||
} else {
|
||||
mFirstContinuation = nullptr;
|
||||
}
|
||||
if (mFirstContinuation != prevFirst) {
|
||||
if (prevFirst) {
|
||||
prevFirst->ClearCachedContinuations();
|
||||
}
|
||||
auto* f = static_cast<nsContinuingTextFrame*>(mNextContinuation);
|
||||
while (f) {
|
||||
f->mFirstContinuation = mFirstContinuation;
|
||||
@@ -4438,10 +4473,16 @@ class nsContinuingTextFrame final : public nsTextFrame {
|
||||
nsTextFrame* prevFirst = mFirstContinuation;
|
||||
if (mPrevContinuation) {
|
||||
mFirstContinuation = mPrevContinuation->FirstContinuation();
|
||||
if (mFirstContinuation) {
|
||||
mFirstContinuation->ClearCachedContinuations();
|
||||
}
|
||||
} else {
|
||||
mFirstContinuation = nullptr;
|
||||
}
|
||||
if (mFirstContinuation != prevFirst) {
|
||||
if (prevFirst) {
|
||||
prevFirst->ClearCachedContinuations();
|
||||
}
|
||||
auto* f = static_cast<nsContinuingTextFrame*>(mNextContinuation);
|
||||
while (f) {
|
||||
f->mFirstContinuation = mFirstContinuation;
|
||||
@@ -4457,6 +4498,8 @@ class nsContinuingTextFrame final : public nsTextFrame {
|
||||
return mFirstContinuation;
|
||||
};
|
||||
|
||||
nsTArray<nsTextFrame*>* GetContinuations() final { return nullptr; }
|
||||
|
||||
void AddInlineMinISize(gfxContext* aRenderingContext,
|
||||
InlineMinISizeData* aData) final;
|
||||
void AddInlinePrefISize(gfxContext* aRenderingContext,
|
||||
@@ -9121,6 +9164,12 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
||||
RemoveStateBits(TEXT_REFLOW_FLAGS | TEXT_WHITESPACE_FLAGS);
|
||||
mReflowRequestedForCharDataChange = false;
|
||||
RemoveProperty(WebRenderTextBounds());
|
||||
|
||||
// Discard cached continuations array that will be invalidated by the reflow.
|
||||
if (nsTextFrame* first = FirstContinuation()) {
|
||||
first->ClearCachedContinuations();
|
||||
}
|
||||
|
||||
// Temporarily map all possible content while we construct our new textrun.
|
||||
// so that when doing reflow our styles prevail over any part of the
|
||||
// textrun we look at. Note that next-in-flows may be mapping the same
|
||||
|
||||
Reference in New Issue
Block a user