зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1253840 - patch 2 - When justifying, the full advance of any trimmable end-of-line whitespace needs to be hung into the margin. r=emilio
Depends on D178210 Differential Revision: https://phabricator.services.mozilla.com/D178211
This commit is contained in:
Родитель
d76893ccc8
Коммит
8109de8531
|
@ -928,7 +928,7 @@ uint32_t gfxTextRun::BreakAndMeasureText(
|
|||
gfxFloat aWidth, const PropertyProvider& aProvider,
|
||||
SuppressBreak aSuppressBreak, gfxFont::BoundingBoxType aBoundingBoxType,
|
||||
DrawTarget* aRefDrawTarget, bool aCanWordWrap, bool aCanWhitespaceWrap,
|
||||
gfxFloat* aOutTrimmableWhitespace, Metrics& aOutMetrics,
|
||||
TrimmableWS* aOutTrimmableWhitespace, Metrics& aOutMetrics,
|
||||
bool& aOutUsedHyphenation, uint32_t& aOutLastBreak,
|
||||
gfxBreakPriority& aBreakPriority) {
|
||||
aMaxLength = std::min(aMaxLength, GetLength() - aStart);
|
||||
|
@ -1174,7 +1174,8 @@ uint32_t gfxTextRun::BreakAndMeasureText(
|
|||
aRefDrawTarget, &aProvider);
|
||||
|
||||
if (aOutTrimmableWhitespace) {
|
||||
*aOutTrimmableWhitespace = trimmableAdvance;
|
||||
aOutTrimmableWhitespace->mAdvance = trimmableAdvance;
|
||||
aOutTrimmableWhitespace->mCount = trimmableChars;
|
||||
}
|
||||
|
||||
if (charsFit == aMaxLength) {
|
||||
|
|
|
@ -384,6 +384,13 @@ class gfxTextRun : public gfxShapedText {
|
|||
nsTArray<HyphenType>& aHyphenBuffer,
|
||||
HyphenationState* aWordState);
|
||||
|
||||
// Struct used by BreakAndMeasureText to return the amount of trimmable
|
||||
// trailing whitespace included in the run.
|
||||
struct TrimmableWS {
|
||||
mozilla::gfx::Float mAdvance = 0;
|
||||
uint32_t mCount = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds the longest substring that will fit into the given width.
|
||||
* Uses GetHyphenationBreaks and GetSpacing from aProvider.
|
||||
|
@ -455,7 +462,7 @@ class gfxTextRun : public gfxShapedText {
|
|||
SuppressBreak aSuppressBreak, gfxFont::BoundingBoxType aBoundingBoxType,
|
||||
DrawTarget* aRefDrawTarget, bool aCanWordWrap, bool aCanWhitespaceWrap,
|
||||
// Output parameters:
|
||||
gfxFloat* aOutTrimmableWhitespace, // may be null
|
||||
TrimmableWS* aOutTrimmableWhitespace, // may be null
|
||||
Metrics& aOutMetrics, bool& aOutUsedHyphenation, uint32_t& aOutLastBreak,
|
||||
// In/out:
|
||||
gfxBreakPriority& aBreakPriority);
|
||||
|
|
|
@ -3046,7 +3046,8 @@ void nsLineLayout::ExpandInlineRubyBoxes(PerSpanData* aSpan) {
|
|||
}
|
||||
}
|
||||
|
||||
nscoord nsLineLayout::GetHangFrom(const PerSpanData* aSpan, bool aLineIsRTL) {
|
||||
nscoord nsLineLayout::GetHangFrom(const PerSpanData* aSpan,
|
||||
bool aLineIsRTL) const {
|
||||
const PerFrameData* pfd = aSpan->mLastFrame;
|
||||
nscoord result = 0;
|
||||
while (pfd) {
|
||||
|
@ -3079,6 +3080,36 @@ nscoord nsLineLayout::GetHangFrom(const PerSpanData* aSpan, bool aLineIsRTL) {
|
|||
return result;
|
||||
}
|
||||
|
||||
gfxTextRun::TrimmableWS nsLineLayout::GetTrimFrom(const PerSpanData* aSpan,
|
||||
bool aLineIsRTL) const {
|
||||
const PerFrameData* pfd = aSpan->mLastFrame;
|
||||
while (pfd) {
|
||||
if (const PerSpanData* childSpan = pfd->mSpan) {
|
||||
return GetTrimFrom(childSpan, aLineIsRTL);
|
||||
}
|
||||
if (pfd->mIsTextFrame) {
|
||||
auto* lastText = static_cast<nsTextFrame*>(pfd->mFrame);
|
||||
auto result = lastText->GetTrimmableWS();
|
||||
if (result.mAdvance) {
|
||||
lastText->EnsureTextRun(nsTextFrame::eInflated);
|
||||
auto* textRun = lastText->GetTextRun(nsTextFrame::eInflated);
|
||||
if (textRun && textRun->IsRightToLeft() != aLineIsRTL) {
|
||||
result.mAdvance = -result.mAdvance;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (!pfd->mSkipWhenTrimmingWhitespace) {
|
||||
// If we hit a frame on the end that's not text and not a placeholder or
|
||||
// <br>, then there is no trailing whitespace to trim. Stop the search.
|
||||
return gfxTextRun::TrimmableWS{};
|
||||
}
|
||||
// Scan back for a preceding frame whose whitespace we can trim.
|
||||
pfd = pfd->mPrev;
|
||||
}
|
||||
return gfxTextRun::TrimmableWS{};
|
||||
}
|
||||
|
||||
// Align inline frames within the line according to the CSS text-align
|
||||
// property.
|
||||
void nsLineLayout::TextAlignLine(nsLineBox* aLine, bool aIsLastLine) {
|
||||
|
@ -3106,8 +3137,15 @@ void nsLineLayout::TextAlignLine(nsLineBox* aLine, bool aIsLastLine) {
|
|||
|
||||
// Check if there's trailing whitespace we need to "hang" at line-wrap.
|
||||
nscoord hang = 0;
|
||||
uint32_t trimCount = 0;
|
||||
if (aLine->IsLineWrapped()) {
|
||||
hang = GetHangFrom(mRootSpan, lineWM.IsBidiRTL());
|
||||
if (textAlign == StyleTextAlign::Justify) {
|
||||
auto trim = GetTrimFrom(mRootSpan, lineWM.IsBidiRTL());
|
||||
hang = NSToCoordRound(trim.mAdvance);
|
||||
trimCount = trim.mCount;
|
||||
} else {
|
||||
hang = GetHangFrom(mRootSpan, lineWM.IsBidiRTL());
|
||||
}
|
||||
}
|
||||
|
||||
bool isSVG = LineContainerFrame()->IsInSVGTextSubtree();
|
||||
|
@ -3144,9 +3182,11 @@ void nsLineLayout::TextAlignLine(nsLineBox* aLine, bool aIsLastLine) {
|
|||
switch (textAlign) {
|
||||
case StyleTextAlign::Justify: {
|
||||
int32_t opportunities =
|
||||
psd->mFrame->mJustificationInfo.mInnerOpportunities;
|
||||
psd->mFrame->mJustificationInfo.mInnerOpportunities -
|
||||
(hang ? trimCount : 0);
|
||||
if (opportunities > 0) {
|
||||
int32_t gaps = opportunities * 2 + additionalGaps;
|
||||
remainingISize += std::abs(hang);
|
||||
JustificationApplicationState applyState(gaps, remainingISize);
|
||||
|
||||
// Apply the justification, and make sure to update our linebox
|
||||
|
@ -3154,11 +3194,29 @@ void nsLineLayout::TextAlignLine(nsLineBox* aLine, bool aIsLastLine) {
|
|||
aLine->ExpandBy(ApplyFrameJustification(psd, applyState),
|
||||
ContainerSizeForSpan(psd));
|
||||
|
||||
MOZ_ASSERT(applyState.mGaps.mHandled == applyState.mGaps.mCount,
|
||||
// If the trimmable trailing whitespace that we want to hang had
|
||||
// reverse-inline directionality, adjust line position to account for
|
||||
// it being at the inline-start side.
|
||||
// On top of the original "hang" amount, justification will have
|
||||
// modified its width, so we include that adjustment here.
|
||||
if (hang < 0) {
|
||||
dx = hang - trimCount * remainingISize / opportunities;
|
||||
}
|
||||
|
||||
// Gaps that belong to trimmed whitespace were not included in the
|
||||
// applyState count, so we need to add them here for the assert.
|
||||
DebugOnly<int32_t> trimmedGaps = hang ? trimCount * 2 : 0;
|
||||
MOZ_ASSERT(applyState.mGaps.mHandled ==
|
||||
applyState.mGaps.mCount + trimmedGaps,
|
||||
"Unprocessed justification gaps");
|
||||
NS_ASSERTION(
|
||||
applyState.mWidth.mConsumed == applyState.mWidth.mAvailable,
|
||||
"Unprocessed justification width");
|
||||
// Similarly, account for the adjustment applied to the trimmed
|
||||
// whitespace, which is in addition to the adjustment that applies
|
||||
// within the actual width of the line.
|
||||
DebugOnly<int32_t> trimmedAdjustment =
|
||||
trimCount * remainingISize / opportunities;
|
||||
NS_ASSERTION(applyState.mWidth.mConsumed ==
|
||||
applyState.mWidth.mAvailable + trimmedAdjustment,
|
||||
"Unprocessed justification width");
|
||||
break;
|
||||
}
|
||||
// Fall through to the default case if we could not justify to fill
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define nsLineLayout_h___
|
||||
|
||||
#include "gfxTypes.h"
|
||||
#include "gfxTextRun.h"
|
||||
#include "JustificationUtils.h"
|
||||
#include "mozilla/ArenaAllocator.h"
|
||||
#include "mozilla/WritingModes.h"
|
||||
|
@ -526,7 +527,9 @@ class nsLineLayout {
|
|||
|
||||
// Get the advance of any trailing hangable whitespace. If the whitespace
|
||||
// has directionality opposite to the line, the result is negated.
|
||||
nscoord GetHangFrom(const PerSpanData* aSpan, bool aLineIsRTL);
|
||||
nscoord GetHangFrom(const PerSpanData* aSpan, bool aLineIsRTL) const;
|
||||
gfxTextRun::TrimmableWS GetTrimFrom(const PerSpanData* aSpan,
|
||||
bool aLineIsRTL) const;
|
||||
|
||||
gfxBreakPriority mLastOptionalBreakPriority;
|
||||
int32_t mLastOptionalBreakFrameOffset;
|
||||
|
|
|
@ -198,6 +198,8 @@ NS_DECLARE_FRAME_PROPERTY_RELEASABLE(UninflatedTextRunProperty, gfxTextRun)
|
|||
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(FontSizeInflationProperty, float)
|
||||
|
||||
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(HangableWhitespaceProperty, nscoord)
|
||||
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(TrimmableWhitespaceProperty,
|
||||
gfxTextRun::TrimmableWS)
|
||||
|
||||
struct nsTextFrame::PaintTextSelectionParams : nsTextFrame::PaintTextParams {
|
||||
Point textBaselinePt;
|
||||
|
@ -3888,7 +3890,7 @@ nsTArray<nsTextFrame*>* nsTextFrame::GetContinuations() {
|
|||
if (!mNextContinuation) {
|
||||
return nullptr;
|
||||
}
|
||||
if (mHasContinuationsProperty) {
|
||||
if (mPropertyFlags & PropertyFlags::Continuations) {
|
||||
return GetProperty(ContinuationsProperty());
|
||||
}
|
||||
size_t count = 0;
|
||||
|
@ -3906,7 +3908,7 @@ nsTArray<nsTextFrame*>* nsTextFrame::GetContinuations() {
|
|||
continuations = nullptr;
|
||||
}
|
||||
AddProperty(ContinuationsProperty(), continuations);
|
||||
mHasContinuationsProperty = true;
|
||||
mPropertyFlags |= PropertyFlags::Continuations;
|
||||
return continuations;
|
||||
}
|
||||
|
||||
|
@ -8155,20 +8157,53 @@ void nsTextFrame::SetFontSizeInflation(float aInflation) {
|
|||
void nsTextFrame::SetHangableISize(nscoord aISize) {
|
||||
MOZ_ASSERT(aISize >= 0, "unexpected negative hangable advance");
|
||||
if (aISize <= 0) {
|
||||
if (mHasHangableWS) {
|
||||
RemoveProperty(HangableWhitespaceProperty());
|
||||
}
|
||||
mHasHangableWS = false;
|
||||
ClearHangableISize();
|
||||
return;
|
||||
}
|
||||
SetProperty(HangableWhitespaceProperty(), aISize);
|
||||
mHasHangableWS = true;
|
||||
mPropertyFlags |= PropertyFlags::HangableWS;
|
||||
}
|
||||
|
||||
nscoord nsTextFrame::GetHangableISize() const {
|
||||
MOZ_ASSERT(mHasHangableWS == HasProperty(HangableWhitespaceProperty()),
|
||||
MOZ_ASSERT(!!(mPropertyFlags & PropertyFlags::HangableWS) ==
|
||||
HasProperty(HangableWhitespaceProperty()),
|
||||
"flag/property mismatch!");
|
||||
return mHasHangableWS ? GetProperty(HangableWhitespaceProperty()) : 0;
|
||||
return (mPropertyFlags & PropertyFlags::HangableWS)
|
||||
? GetProperty(HangableWhitespaceProperty())
|
||||
: 0;
|
||||
}
|
||||
|
||||
void nsTextFrame::ClearHangableISize() {
|
||||
if (mPropertyFlags & PropertyFlags::HangableWS) {
|
||||
RemoveProperty(HangableWhitespaceProperty());
|
||||
mPropertyFlags &= ~PropertyFlags::HangableWS;
|
||||
}
|
||||
}
|
||||
|
||||
void nsTextFrame::SetTrimmableWS(gfxTextRun::TrimmableWS aTrimmableWS) {
|
||||
MOZ_ASSERT(aTrimmableWS.mAdvance >= 0, "negative trimmable size");
|
||||
if (aTrimmableWS.mAdvance <= 0) {
|
||||
ClearTrimmableWS();
|
||||
return;
|
||||
}
|
||||
SetProperty(TrimmableWhitespaceProperty(), aTrimmableWS);
|
||||
mPropertyFlags |= PropertyFlags::TrimmableWS;
|
||||
}
|
||||
|
||||
gfxTextRun::TrimmableWS nsTextFrame::GetTrimmableWS() const {
|
||||
MOZ_ASSERT(!!(mPropertyFlags & PropertyFlags::TrimmableWS) ==
|
||||
HasProperty(TrimmableWhitespaceProperty()),
|
||||
"flag/property mismatch!");
|
||||
return (mPropertyFlags & PropertyFlags::TrimmableWS)
|
||||
? GetProperty(TrimmableWhitespaceProperty())
|
||||
: gfxTextRun::TrimmableWS{};
|
||||
}
|
||||
|
||||
void nsTextFrame::ClearTrimmableWS() {
|
||||
if (mPropertyFlags & PropertyFlags::TrimmableWS) {
|
||||
RemoveProperty(TrimmableWhitespaceProperty());
|
||||
mPropertyFlags &= ~PropertyFlags::TrimmableWS;
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
|
@ -9167,7 +9202,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
|||
gfxTextRun::Metrics textMetrics;
|
||||
uint32_t transformedLastBreak = 0;
|
||||
bool usedHyphenation = false;
|
||||
gfxFloat trimmableWidth = 0;
|
||||
gfxTextRun::TrimmableWS trimmableWS;
|
||||
gfxFloat availWidth = aAvailableWidth;
|
||||
if (Style()->IsTextCombined()) {
|
||||
// If text-combine-upright is 'all', we would compress whatever long
|
||||
|
@ -9192,8 +9227,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
|||
availWidth, provider, suppressBreak, boundingBoxType, aDrawTarget,
|
||||
textStyle->WordCanWrap(this), isBreakSpaces,
|
||||
// The following are output parameters:
|
||||
canTrimTrailingWhitespace || whitespaceCanHang ? &trimmableWidth
|
||||
: nullptr,
|
||||
canTrimTrailingWhitespace || whitespaceCanHang ? &trimmableWS : nullptr,
|
||||
textMetrics, usedHyphenation, transformedLastBreak,
|
||||
// In/out
|
||||
breakPriority);
|
||||
|
@ -9254,7 +9288,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
|||
}
|
||||
|
||||
bool brokeText = forceBreak >= 0 || transformedCharsFit < transformedLength;
|
||||
if (trimmableWidth > 0.0) {
|
||||
if (trimmableWS.mAdvance > 0.0) {
|
||||
if (canTrimTrailingWhitespace) {
|
||||
// Optimization: if we we can be sure this frame will be at end of line,
|
||||
// then trim the whitespace now.
|
||||
|
@ -9262,32 +9296,41 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
|||
// We're definitely going to break so our trailing whitespace should
|
||||
// definitely be trimmed. Record that we've already done it.
|
||||
AddStateBits(TEXT_TRIMMED_TRAILING_WHITESPACE);
|
||||
textMetrics.mAdvanceWidth -= trimmableWidth;
|
||||
trimmableWidth = 0.0;
|
||||
textMetrics.mAdvanceWidth -= trimmableWS.mAdvance;
|
||||
trimmableWS.mAdvance = 0.0;
|
||||
}
|
||||
SetHangableISize(0);
|
||||
ClearHangableISize();
|
||||
ClearTrimmableWS();
|
||||
} else if (whitespaceCanHang) {
|
||||
// Figure out how much whitespace will hang if at end-of-line.
|
||||
gfxFloat hang =
|
||||
std::min(std::max(0.0, textMetrics.mAdvanceWidth - availWidth),
|
||||
trimmableWidth);
|
||||
SetHangableISize(NSToCoordRound(trimmableWidth - hang));
|
||||
gfxFloat(trimmableWS.mAdvance));
|
||||
SetHangableISize(NSToCoordRound(trimmableWS.mAdvance - hang));
|
||||
// nsLineLayout only needs the TrimmableWS property if justifying, so
|
||||
// check whether this is relevant.
|
||||
if (textStyle->mTextAlign == StyleTextAlign::Justify ||
|
||||
textStyle->mTextAlignLast == StyleTextAlignLast::Justify) {
|
||||
SetTrimmableWS(trimmableWS);
|
||||
}
|
||||
textMetrics.mAdvanceWidth -= hang;
|
||||
trimmableWidth = 0.0;
|
||||
trimmableWS.mAdvance = 0.0;
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("How did trimmableWidth get set?!");
|
||||
SetHangableISize(0);
|
||||
trimmableWidth = 0.0;
|
||||
MOZ_ASSERT_UNREACHABLE("How did trimmableWS get set?!");
|
||||
ClearHangableISize();
|
||||
ClearTrimmableWS();
|
||||
trimmableWS.mAdvance = 0.0;
|
||||
}
|
||||
} else {
|
||||
// Remove any stale frame property.
|
||||
SetHangableISize(0);
|
||||
// Remove any stale frame properties.
|
||||
ClearHangableISize();
|
||||
ClearTrimmableWS();
|
||||
}
|
||||
|
||||
if (!brokeText && lastBreak >= 0) {
|
||||
// Since everything fit and no break was forced,
|
||||
// record the last break opportunity
|
||||
NS_ASSERTION(textMetrics.mAdvanceWidth - trimmableWidth <= availWidth,
|
||||
NS_ASSERTION(textMetrics.mAdvanceWidth - trimmableWS.mAdvance <= availWidth,
|
||||
"If the text doesn't fit, and we have a break opportunity, "
|
||||
"why didn't MeasureText use it?");
|
||||
MOZ_ASSERT(lastBreak >= offset, "Strange break position");
|
||||
|
@ -9415,7 +9458,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
|||
// at most one space so there's no way for trimmable width from a previous
|
||||
// frame to accumulate with trimmable width from this frame.)
|
||||
if (transformedCharsFit > 0) {
|
||||
aLineLayout.SetTrimmableISize(NSToCoordFloor(trimmableWidth));
|
||||
aLineLayout.SetTrimmableISize(NSToCoordFloor(trimmableWS.mAdvance));
|
||||
AddStateBits(TEXT_HAS_NONCOLLAPSED_CHARACTERS);
|
||||
}
|
||||
bool breakAfter = forceBreakAfter;
|
||||
|
@ -9443,7 +9486,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
|||
// trailing whitespace. So we need to subtract trimmableWidth here
|
||||
// because if we did break at this point, that much width would be
|
||||
// trimmed.
|
||||
if (textMetrics.mAdvanceWidth - trimmableWidth > availWidth) {
|
||||
if (textMetrics.mAdvanceWidth - trimmableWS.mAdvance > availWidth) {
|
||||
breakAfter = true;
|
||||
} else {
|
||||
aLineLayout.NotifyOptionalBreakPosition(this, length, true,
|
||||
|
|
|
@ -773,6 +773,11 @@ class nsTextFrame : public nsIFrame {
|
|||
|
||||
void SetHangableISize(nscoord aISize);
|
||||
nscoord GetHangableISize() const;
|
||||
void ClearHangableISize();
|
||||
|
||||
void SetTrimmableWS(gfxTextRun::TrimmableWS aTrimmableWS);
|
||||
gfxTextRun::TrimmableWS GetTrimmableWS() const;
|
||||
void ClearTrimmableWS();
|
||||
|
||||
protected:
|
||||
virtual ~nsTextFrame();
|
||||
|
@ -808,13 +813,20 @@ class nsTextFrame : public nsIFrame {
|
|||
};
|
||||
mutable SelectionState mIsSelected;
|
||||
|
||||
// Whether a cached continuations array is present.
|
||||
bool mHasContinuationsProperty = false;
|
||||
// Flags used to track whether certain properties are present.
|
||||
// (Public to keep MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS happy.)
|
||||
public:
|
||||
enum class PropertyFlags : uint8_t {
|
||||
// Whether a cached continuations array is present.
|
||||
Continuations = 1 << 0,
|
||||
// Whether a HangableWhitespace property is present.
|
||||
HangableWS = 1 << 1,
|
||||
// Whether a TrimmableWhitespace property is present.
|
||||
TrimmableWS = 2 << 1,
|
||||
};
|
||||
|
||||
// Whether a HangableWhitespace property is present. This could have been a
|
||||
// frame state bit, but they are currently full. Because we have a uint8_t
|
||||
// and a bool just above, there's a hole here that we can use.
|
||||
bool mHasHangableWS = false;
|
||||
protected:
|
||||
PropertyFlags mPropertyFlags = PropertyFlags(0);
|
||||
|
||||
/**
|
||||
* Return true if the frame is part of a Selection.
|
||||
|
@ -1000,13 +1012,7 @@ class nsTextFrame : public nsIFrame {
|
|||
|
||||
// Clear any cached continuations array; this should be called whenever the
|
||||
// chain is modified.
|
||||
void ClearCachedContinuations() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (mHasContinuationsProperty) {
|
||||
RemoveProperty(ContinuationsProperty());
|
||||
mHasContinuationsProperty = false;
|
||||
}
|
||||
}
|
||||
inline void ClearCachedContinuations();
|
||||
|
||||
/**
|
||||
* UpdateIteratorFromOffset() updates the iterator from a given offset.
|
||||
|
@ -1022,5 +1028,14 @@ class nsTextFrame : public nsIFrame {
|
|||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsTextFrame::TrimmedOffsetFlags)
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsTextFrame::PropertyFlags)
|
||||
|
||||
inline void nsTextFrame::ClearCachedContinuations() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (mPropertyFlags & PropertyFlags::Continuations) {
|
||||
RemoveProperty(ContinuationsProperty());
|
||||
mPropertyFlags &= ~PropertyFlags::Continuations;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче