mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1919658 - Add support for text-emphasis-position:auto. r=layout-reviewers,emilio
Differential Revision: https://phabricator.services.mozilla.com/D222855
This commit is contained in:
parent
72630b5ab9
commit
106268f97e
@ -1644,7 +1644,8 @@ void nsLineLayout::AdjustLeadings(nsIFrame* spanFrame, PerSpanData* psd,
|
||||
}
|
||||
if (aStyleText->HasEffectiveTextEmphasis()) {
|
||||
nscoord bsize = GetBSizeOfEmphasisMarks(spanFrame, aInflation);
|
||||
LogicalSide side = aStyleText->TextEmphasisSide(mRootSpan->mWritingMode);
|
||||
LogicalSide side = aStyleText->TextEmphasisSide(
|
||||
mRootSpan->mWritingMode, spanFrame->StyleFont()->mLanguage);
|
||||
if (side == LogicalSide::BStart) {
|
||||
requiredStartLeading += bsize;
|
||||
} else {
|
||||
@ -2272,7 +2273,8 @@ void nsLineLayout::VerticalAlignFrames(PerSpanData* psd) {
|
||||
blockEnd = descent;
|
||||
delta = emphasisHeight;
|
||||
}
|
||||
LogicalSide side = mStyleText->TextEmphasisSide(lineWM);
|
||||
LogicalSide side = mStyleText->TextEmphasisSide(
|
||||
lineWM, spanFrame->StyleFont()->mLanguage);
|
||||
if (side == LogicalSide::BStart) {
|
||||
blockStart -= delta;
|
||||
} else {
|
||||
|
@ -5103,7 +5103,7 @@ nsRect nsTextFrame::UpdateTextEmphasis(WritingMode aWM,
|
||||
info->advance = info->textRun->GetAdvanceWidth();
|
||||
|
||||
// Calculate the baseline offset
|
||||
LogicalSide side = styleText->TextEmphasisSide(aWM);
|
||||
LogicalSide side = styleText->TextEmphasisSide(aWM, StyleFont()->mLanguage);
|
||||
LogicalSize frameSize = GetLogicalSize(aWM);
|
||||
// The overflow rect is inflated in the inline direction by half
|
||||
// advance of the emphasis mark on each side, so that even if a mark
|
||||
|
@ -2818,6 +2818,7 @@ nsStyleText::nsStyleText(const Document& aDocument)
|
||||
StaticPrefs::layout_css_control_characters_visible()
|
||||
? StyleMozControlCharacterVisibility::Visible
|
||||
: StyleMozControlCharacterVisibility::Hidden),
|
||||
mTextEmphasisPosition(StyleTextEmphasisPosition::AUTO),
|
||||
mTextRendering(StyleTextRendering::Auto),
|
||||
mTextEmphasisColor(StyleColor::CurrentColor()),
|
||||
mWebkitTextFillColor(StyleColor::CurrentColor()),
|
||||
@ -2831,11 +2832,6 @@ nsStyleText::nsStyleText(const Document& aDocument)
|
||||
mWebkitTextStrokeWidth(0),
|
||||
mTextEmphasisStyle(StyleTextEmphasisStyle::None()) {
|
||||
MOZ_COUNT_CTOR(nsStyleText);
|
||||
RefPtr<nsAtom> language = aDocument.GetContentLanguageAsAtomForStyle();
|
||||
mTextEmphasisPosition =
|
||||
language && nsStyleUtil::MatchesLanguagePrefix(language, u"zh")
|
||||
? StyleTextEmphasisPosition::UNDER
|
||||
: StyleTextEmphasisPosition::OVER;
|
||||
}
|
||||
|
||||
nsStyleText::nsStyleText(const nsStyleText& aSource)
|
||||
@ -2962,18 +2958,32 @@ nsChangeHint nsStyleText::CalcDifference(const nsStyleText& aNewData) const {
|
||||
return nsChangeHint(0);
|
||||
}
|
||||
|
||||
LogicalSide nsStyleText::TextEmphasisSide(WritingMode aWM) const {
|
||||
bool noLeftBit = !(mTextEmphasisPosition & StyleTextEmphasisPosition::LEFT);
|
||||
DebugOnly<bool> noRightBit =
|
||||
!(mTextEmphasisPosition & StyleTextEmphasisPosition::RIGHT);
|
||||
bool noOverBit = !(mTextEmphasisPosition & StyleTextEmphasisPosition::OVER);
|
||||
DebugOnly<bool> noUnderBit =
|
||||
!(mTextEmphasisPosition & StyleTextEmphasisPosition::UNDER);
|
||||
LogicalSide nsStyleText::TextEmphasisSide(WritingMode aWM,
|
||||
const nsAtom* aLanguage) const {
|
||||
mozilla::Side side;
|
||||
if (mTextEmphasisPosition & StyleTextEmphasisPosition::AUTO) {
|
||||
// 'auto' resolves to 'under right' for Chinese, 'over right' otherwise.
|
||||
if (aWM.IsVertical()) {
|
||||
side = eSideRight;
|
||||
} else {
|
||||
if (nsStyleUtil::MatchesLanguagePrefix(aLanguage, u"zh")) {
|
||||
side = eSideBottom;
|
||||
} else {
|
||||
side = eSideTop;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (aWM.IsVertical()) {
|
||||
side = mTextEmphasisPosition & StyleTextEmphasisPosition::LEFT
|
||||
? eSideLeft
|
||||
: eSideRight;
|
||||
} else {
|
||||
side = mTextEmphasisPosition & StyleTextEmphasisPosition::OVER
|
||||
? eSideTop
|
||||
: eSideBottom;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT((noOverBit != noUnderBit) &&
|
||||
((noLeftBit != noRightBit) || noRightBit));
|
||||
mozilla::Side side = aWM.IsVertical() ? (noLeftBit ? eSideRight : eSideLeft)
|
||||
: (noOverBit ? eSideBottom : eSideTop);
|
||||
LogicalSide result = aWM.LogicalSideForPhysicalSide(side);
|
||||
MOZ_ASSERT(IsBlock(result));
|
||||
return result;
|
||||
|
@ -1015,7 +1015,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText {
|
||||
inline bool WhiteSpaceCanWrap(const nsIFrame* aContextFrame) const;
|
||||
inline bool WordCanWrap(const nsIFrame* aContextFrame) const;
|
||||
|
||||
mozilla::LogicalSide TextEmphasisSide(mozilla::WritingMode aWM) const;
|
||||
mozilla::LogicalSide TextEmphasisSide(mozilla::WritingMode aWM,
|
||||
const nsAtom* aLanguage) const;
|
||||
};
|
||||
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleVisibility {
|
||||
|
@ -177,9 +177,9 @@ ${helpers.predefined_type(
|
||||
${helpers.predefined_type(
|
||||
"text-emphasis-position",
|
||||
"TextEmphasisPosition",
|
||||
"computed::TextEmphasisPosition::OVER",
|
||||
"computed::TextEmphasisPosition::AUTO",
|
||||
engines="gecko",
|
||||
initial_specified_value="specified::TextEmphasisPosition::OVER",
|
||||
initial_specified_value="specified::TextEmphasisPosition::AUTO",
|
||||
animation_type="discrete",
|
||||
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-position",
|
||||
affects="layout",
|
||||
|
@ -692,6 +692,7 @@ impl Parse for TextEmphasisStyle {
|
||||
)]
|
||||
#[repr(C)]
|
||||
#[css(bitflags(
|
||||
single = "auto",
|
||||
mixed = "over,under,left,right",
|
||||
validate_mixed = "Self::validate_and_simplify"
|
||||
))]
|
||||
@ -700,23 +701,27 @@ impl Parse for TextEmphasisStyle {
|
||||
pub struct TextEmphasisPosition(u8);
|
||||
bitflags! {
|
||||
impl TextEmphasisPosition: u8 {
|
||||
/// Draws marks to the right of the text in vertical writing mode.
|
||||
const OVER = 1 << 0;
|
||||
/// Automatically choose mark position based on language.
|
||||
const AUTO = 1 << 0;
|
||||
/// Draw marks over the text in horizontal writing mode.
|
||||
const OVER = 1 << 1;
|
||||
/// Draw marks under the text in horizontal writing mode.
|
||||
const UNDER = 1 << 1;
|
||||
const UNDER = 1 << 2;
|
||||
/// Draw marks to the left of the text in vertical writing mode.
|
||||
const LEFT = 1 << 2;
|
||||
/// Draws marks to the right of the text in vertical writing mode.
|
||||
const RIGHT = 1 << 3;
|
||||
const LEFT = 1 << 3;
|
||||
/// Draw marks to the right of the text in vertical writing mode.
|
||||
const RIGHT = 1 << 4;
|
||||
}
|
||||
}
|
||||
|
||||
impl TextEmphasisPosition {
|
||||
fn validate_and_simplify(&mut self) -> bool {
|
||||
// Require one but not both of 'over' and 'under'.
|
||||
if self.intersects(Self::OVER) == self.intersects(Self::UNDER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If 'left' is present, 'right' must be absent.
|
||||
if self.intersects(Self::LEFT) {
|
||||
return !self.intersects(Self::RIGHT);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user