summaryrefslogtreecommitdiffstats
path: root/layout/generic/nsTextFrame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'layout/generic/nsTextFrame.cpp')
-rw-r--r--layout/generic/nsTextFrame.cpp66
1 files changed, 57 insertions, 9 deletions
diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp
index 9afefc5c28..0ad527e842 100644
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -1929,8 +1929,8 @@ bool BuildTextRunsScanner::ContinueTextRunAcrossFrames(nsTextFrame* aFrame1,
// Map inline-end and inline-start to physical sides for checking presence
// of non-zero margin/border/padding.
- Side side1 = wm.PhysicalSide(eLogicalSideIEnd);
- Side side2 = wm.PhysicalSide(eLogicalSideIStart);
+ Side side1 = wm.PhysicalSide(LogicalSide::IEnd);
+ Side side2 = wm.PhysicalSide(LogicalSide::IStart);
// If the frames have an embedding level that is opposite to the writing
// mode, we need to swap which sides we're checking.
if (aFrame1->GetEmbeddingLevel().IsRTL() == wm.IsBidiLTR()) {
@@ -3611,6 +3611,20 @@ void nsTextFrame::PropertyProvider::GetSpacing(Range aRange,
!(mTextRun->GetFlags2() & nsTextFrameUtils::Flags::HasTab));
}
+static bool CanAddSpacingBefore(const gfxTextRun* aTextRun, uint32_t aOffset,
+ bool aNewlineIsSignificant) {
+ const auto* g = aTextRun->GetCharacterGlyphs();
+ MOZ_ASSERT(aOffset < aTextRun->GetLength());
+ if (aNewlineIsSignificant && g[aOffset].CharIsNewline()) {
+ return false;
+ }
+ if (!aOffset) {
+ return true;
+ }
+ return g[aOffset].IsClusterStart() && g[aOffset].IsLigatureGroupStart() &&
+ !g[aOffset - 1].CharIsFormattingControl() && !g[aOffset].CharIsTab();
+}
+
static bool CanAddSpacingAfter(const gfxTextRun* aTextRun, uint32_t aOffset,
bool aNewlineIsSignificant) {
const auto* g = aTextRun->GetCharacterGlyphs();
@@ -3683,14 +3697,45 @@ void nsTextFrame::PropertyProvider::GetSpacingInternal(Range aRange,
nsSkipCharsRunIterator run(
start, nsSkipCharsRunIterator::LENGTH_UNSKIPPED_ONLY, aRange.Length());
bool newlineIsSignificant = mTextStyle->NewlineIsSignificant(mFrame);
+ // Which letter-spacing model are we using?
+ // 0 - Gecko legacy model, spacing added to trailing side of letter
+ // 1 - WebKit/Blink-compatible, spacing added to right-hand side
+ // 2 - Symmetrical spacing, half added to each side
+ gfxFloat before, after;
+ switch (StaticPrefs::layout_css_letter_spacing_model()) {
+ default: // use Gecko legacy behavior if pref value is unknown
+ case 0:
+ before = 0.0;
+ after = mLetterSpacing;
+ break;
+ case 1:
+ if (mTextRun->IsRightToLeft()) {
+ before = mLetterSpacing;
+ after = 0.0;
+ } else {
+ before = 0.0;
+ after = mLetterSpacing;
+ }
+ break;
+ case 2:
+ before = mLetterSpacing / 2.0;
+ after = mLetterSpacing - before;
+ break;
+ }
while (run.NextRun()) {
uint32_t runOffsetInSubstring = run.GetSkippedOffset() - aRange.start;
gfxSkipCharsIterator iter = run.GetPos();
for (int32_t i = 0; i < run.GetRunLength(); ++i) {
- if (CanAddSpacingAfter(mTextRun, run.GetSkippedOffset() + i,
+ if (before != 0.0 &&
+ CanAddSpacingBefore(mTextRun, run.GetSkippedOffset() + i,
+ newlineIsSignificant)) {
+ aSpacing[runOffsetInSubstring + i].mBefore += before;
+ }
+ if (after != 0.0 &&
+ CanAddSpacingAfter(mTextRun, run.GetSkippedOffset() + i,
newlineIsSignificant)) {
// End of a cluster, not in a ligature: put letter-spacing after it
- aSpacing[runOffsetInSubstring + i].mAfter += mLetterSpacing;
+ aSpacing[runOffsetInSubstring + i].mAfter += after;
}
if (IsCSSWordSpacingSpace(mFrag, i + run.GetOriginalOffset(), mFrame,
mTextStyle)) {
@@ -5050,25 +5095,25 @@ nsRect nsTextFrame::UpdateTextEmphasis(WritingMode aWM,
: do_AddRef(aProvider.GetFontMetrics());
// When the writing mode is vertical-lr the line is inverted, and thus
// the ascent and descent are swapped.
- nscoord absOffset = (side == eLogicalSideBStart) != aWM.IsLineInverted()
+ nscoord absOffset = (side == LogicalSide::BStart) != aWM.IsLineInverted()
? baseFontMetrics->MaxAscent() + fm->MaxDescent()
: baseFontMetrics->MaxDescent() + fm->MaxAscent();
RubyBlockLeadings leadings;
if (nsRubyFrame* ruby = FindFurthestInlineRubyAncestor(this)) {
leadings = ruby->GetBlockLeadings();
}
- if (side == eLogicalSideBStart) {
+ if (side == LogicalSide::BStart) {
info->baselineOffset = -absOffset - leadings.mStart;
overflowRect.BStart(aWM) = -overflowRect.BSize(aWM) - leadings.mStart;
} else {
- MOZ_ASSERT(side == eLogicalSideBEnd);
+ MOZ_ASSERT(side == LogicalSide::BEnd);
info->baselineOffset = absOffset + leadings.mEnd;
overflowRect.BStart(aWM) = frameSize.BSize(aWM) + leadings.mEnd;
}
// If text combined, fix the gap between the text frame and its parent.
if (isTextCombined) {
nscoord gap = (baseFontMetrics->MaxHeight() - frameSize.BSize(aWM)) / 2;
- overflowRect.BStart(aWM) += gap * (side == eLogicalSideBStart ? -1 : 1);
+ overflowRect.BStart(aWM) += gap * (side == LogicalSide::BStart ? -1 : 1);
}
SetProperty(EmphasisMarkProperty(), info);
@@ -5676,6 +5721,10 @@ bool nsTextFrame::GetSelectionTextColors(SelectionType aSelectionType,
aHighlightName, aBackground);
return hasForeground || hasBackground;
}
+ case SelectionType::eTargetText: {
+ aTextPaintStyle.GetTargetTextColors(aForeground, aBackground);
+ return true;
+ }
case SelectionType::eURLSecondary:
aTextPaintStyle.GetURLSecondaryColor(aForeground);
*aBackground = NS_RGBA(0, 0, 0, 0);
@@ -9216,7 +9265,6 @@ void nsTextFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
nsReflowStatus& aStatus) {
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsTextFrame");
- DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
InvalidateSelectionState();