mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 08:15:31 +00:00
Bug 770780 - Implement rendering support for text-underline-position in nsTextFrame. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D54723 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
3b87f01682
commit
46dd64cc2a
@ -4954,11 +4954,21 @@ static nscoord LazyGetLineBaselineOffset(nsIFrame* aChildFrame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool IsUnderlineRight(nsIFrame* aFrame) {
|
static bool IsUnderlineRight(nsIFrame* aFrame) {
|
||||||
|
// Check for 'left' or 'right' explicitly specified in the property;
|
||||||
|
// if neither is there, we use auto positioning based on lang.
|
||||||
|
const auto position = aFrame->StyleText()->mTextUnderlinePosition;
|
||||||
|
if (position.IsLeft()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (position.IsRight()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// If neither 'left' nor 'right' was specified, check the language.
|
||||||
nsAtom* langAtom = aFrame->StyleFont()->mLanguage;
|
nsAtom* langAtom = aFrame->StyleFont()->mLanguage;
|
||||||
if (!langAtom) {
|
if (!langAtom) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
nsAtomString langStr(langAtom);
|
nsDependentAtomString langStr(langAtom);
|
||||||
return (StringBeginsWith(langStr, NS_LITERAL_STRING("ja")) ||
|
return (StringBeginsWith(langStr, NS_LITERAL_STRING("ja")) ||
|
||||||
StringBeginsWith(langStr, NS_LITERAL_STRING("ko"))) &&
|
StringBeginsWith(langStr, NS_LITERAL_STRING("ko"))) &&
|
||||||
(langStr.Length() == 2 || langStr[2] == '-');
|
(langStr.Length() == 2 || langStr[2] == '-');
|
||||||
@ -5083,17 +5093,20 @@ void nsTextFrame::GetTextDecorations(
|
|||||||
|
|
||||||
if (textDecorations & kUnderline) {
|
if (textDecorations & kUnderline) {
|
||||||
aDecorations.mUnderlines.AppendElement(nsTextFrame::LineDecoration(
|
aDecorations.mUnderlines.AppendElement(nsTextFrame::LineDecoration(
|
||||||
f, baselineOffset, styleText->mTextUnderlineOffset,
|
f, baselineOffset, styleText->mTextUnderlinePosition,
|
||||||
|
styleText->mTextUnderlineOffset,
|
||||||
styleTextReset->mTextDecorationThickness, color, style));
|
styleTextReset->mTextDecorationThickness, color, style));
|
||||||
}
|
}
|
||||||
if (textDecorations & kOverline) {
|
if (textDecorations & kOverline) {
|
||||||
aDecorations.mOverlines.AppendElement(nsTextFrame::LineDecoration(
|
aDecorations.mOverlines.AppendElement(nsTextFrame::LineDecoration(
|
||||||
f, baselineOffset, styleText->mTextUnderlineOffset,
|
f, baselineOffset, styleText->mTextUnderlinePosition,
|
||||||
|
styleText->mTextUnderlineOffset,
|
||||||
styleTextReset->mTextDecorationThickness, color, style));
|
styleTextReset->mTextDecorationThickness, color, style));
|
||||||
}
|
}
|
||||||
if (textDecorations & StyleTextDecorationLine_LINE_THROUGH) {
|
if (textDecorations & StyleTextDecorationLine_LINE_THROUGH) {
|
||||||
aDecorations.mStrikes.AppendElement(nsTextFrame::LineDecoration(
|
aDecorations.mStrikes.AppendElement(nsTextFrame::LineDecoration(
|
||||||
f, baselineOffset, styleText->mTextUnderlineOffset,
|
f, baselineOffset, styleText->mTextUnderlinePosition,
|
||||||
|
styleText->mTextUnderlineOffset,
|
||||||
styleTextReset->mTextDecorationThickness, color, style));
|
styleTextReset->mTextDecorationThickness, color, style));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5356,8 +5369,15 @@ void nsTextFrame::UnionAdditionalOverflow(nsPresContext* aPresContext,
|
|||||||
nscoord underlineOffset, underlineSize;
|
nscoord underlineOffset, underlineSize;
|
||||||
fontMetrics->GetUnderline(underlineOffset, underlineSize);
|
fontMetrics->GetUnderline(underlineOffset, underlineSize);
|
||||||
|
|
||||||
|
// If text-underline-position:under is in effect, override the default
|
||||||
|
// underline position from the font.
|
||||||
|
const auto* styleText = aBlock->StyleText();
|
||||||
|
if (styleText->mTextUnderlinePosition.IsUnder()) {
|
||||||
|
underlineOffset = -fontMetrics->EmDescent();
|
||||||
|
}
|
||||||
|
|
||||||
const StyleTextDecorationLength& textUnderlineOffset =
|
const StyleTextDecorationLength& textUnderlineOffset =
|
||||||
aBlock->Style()->StyleText()->mTextUnderlineOffset;
|
styleText->mTextUnderlineOffset;
|
||||||
|
|
||||||
const StyleTextDecorationLength& textDecorationThickness =
|
const StyleTextDecorationLength& textDecorationThickness =
|
||||||
aBlock->Style()->StyleTextReset()->mTextDecorationThickness;
|
aBlock->Style()->StyleTextReset()->mTextDecorationThickness;
|
||||||
@ -5467,6 +5487,9 @@ void nsTextFrame::UnionAdditionalOverflow(nsPresContext* aPresContext,
|
|||||||
bool swapUnderline = verticalDec && IsUnderlineRight(this);
|
bool swapUnderline = verticalDec && IsUnderlineRight(this);
|
||||||
if (swapUnderline ? lineType == StyleTextDecorationLine_OVERLINE
|
if (swapUnderline ? lineType == StyleTextDecorationLine_OVERLINE
|
||||||
: lineType == StyleTextDecorationLine_UNDERLINE) {
|
: lineType == StyleTextDecorationLine_UNDERLINE) {
|
||||||
|
if (dec.mTextUnderlinePosition.IsUnder()) {
|
||||||
|
params.offset = -metrics.emDescent;
|
||||||
|
}
|
||||||
SetOffsetIfLength(dec.mTextUnderlineOffset, params, metrics,
|
SetOffsetIfLength(dec.mTextUnderlineOffset, params, metrics,
|
||||||
appUnitsPerDevUnit, parentWM.IsSideways(),
|
appUnitsPerDevUnit, parentWM.IsSideways(),
|
||||||
swapUnderline);
|
swapUnderline);
|
||||||
@ -5684,10 +5707,14 @@ void nsTextFrame::DrawSelectionDecorations(
|
|||||||
if (swapUnderline ? aDecoration == StyleTextDecorationLine_OVERLINE
|
if (swapUnderline ? aDecoration == StyleTextDecorationLine_OVERLINE
|
||||||
: aDecoration == StyleTextDecorationLine_UNDERLINE) {
|
: aDecoration == StyleTextDecorationLine_UNDERLINE) {
|
||||||
WritingMode wm = GetWritingMode();
|
WritingMode wm = GetWritingMode();
|
||||||
params.offset = aFontMetrics.underlineOffset;
|
const auto* styleText = StyleText();
|
||||||
SetOffsetIfLength(StyleText()->mTextUnderlineOffset, params,
|
if (styleText->mTextUnderlinePosition.IsUnder()) {
|
||||||
aFontMetrics, appUnitsPerDevPixel, wm.IsSideways(),
|
params.offset = -aFontMetrics.emDescent;
|
||||||
swapUnderline);
|
} else {
|
||||||
|
params.offset = aFontMetrics.underlineOffset;
|
||||||
|
}
|
||||||
|
SetOffsetIfLength(styleText->mTextUnderlineOffset, params, aFontMetrics,
|
||||||
|
appUnitsPerDevPixel, wm.IsSideways(), swapUnderline);
|
||||||
} else {
|
} else {
|
||||||
params.offset = aFontMetrics.maxAscent;
|
params.offset = aFontMetrics.maxAscent;
|
||||||
}
|
}
|
||||||
@ -6295,8 +6322,6 @@ void nsTextFrame::PaintTextSelectionDecorations(
|
|||||||
firstFont->GetMetrics(useVerticalMetrics ? nsFontMetrics::eVertical
|
firstFont->GetMetrics(useVerticalMetrics ? nsFontMetrics::eVertical
|
||||||
: nsFontMetrics::eHorizontal));
|
: nsFontMetrics::eHorizontal));
|
||||||
if (!useVerticalMetrics) {
|
if (!useVerticalMetrics) {
|
||||||
// The potential adjustment from using gfxFontGroup::GetUnderlineOffset
|
|
||||||
// is only valid for horizontal font metrics.
|
|
||||||
decorationMetrics.underlineOffset =
|
decorationMetrics.underlineOffset =
|
||||||
aParams.provider->GetFontGroup()->GetUnderlineOffset();
|
aParams.provider->GetFontGroup()->GetUnderlineOffset();
|
||||||
}
|
}
|
||||||
@ -6968,9 +6993,15 @@ void nsTextFrame::DrawTextRunAndDecorations(
|
|||||||
|
|
||||||
params.color = dec.mColor;
|
params.color = dec.mColor;
|
||||||
params.defaultLineThickness = params.lineSize.height;
|
params.defaultLineThickness = params.lineSize.height;
|
||||||
params.offset = metrics.*lineOffset;
|
|
||||||
params.baselineOffset = dec.mBaselineOffset / app;
|
params.baselineOffset = dec.mBaselineOffset / app;
|
||||||
|
|
||||||
|
if (lineType == StyleTextDecorationLine_UNDERLINE &&
|
||||||
|
dec.mTextUnderlinePosition.IsUnder()) {
|
||||||
|
params.offset = -metrics.emDescent;
|
||||||
|
} else {
|
||||||
|
params.offset = metrics.*lineOffset;
|
||||||
|
}
|
||||||
|
|
||||||
bool swapUnderline = verticalDec && IsUnderlineRight(this);
|
bool swapUnderline = verticalDec && IsUnderlineRight(this);
|
||||||
if (swapUnderline ? lineType == StyleTextDecorationLine_OVERLINE
|
if (swapUnderline ? lineType == StyleTextDecorationLine_OVERLINE
|
||||||
: lineType == StyleTextDecorationLine_UNDERLINE) {
|
: lineType == StyleTextDecorationLine_UNDERLINE) {
|
||||||
@ -7268,7 +7299,12 @@ bool nsTextFrame::CombineSelectionUnderlineRect(nsPresContext* aPresContext,
|
|||||||
|
|
||||||
nsCSSRendering::DecorationRectParams params;
|
nsCSSRendering::DecorationRectParams params;
|
||||||
params.ascent = aPresContext->AppUnitsToGfxUnits(mAscent);
|
params.ascent = aPresContext->AppUnitsToGfxUnits(mAscent);
|
||||||
params.offset = fontGroup->GetUnderlineOffset();
|
|
||||||
|
if (StyleText()->mTextUnderlinePosition.IsUnder()) {
|
||||||
|
params.offset = -metrics.emDescent;
|
||||||
|
} else {
|
||||||
|
params.offset = fontGroup->GetUnderlineOffset();
|
||||||
|
}
|
||||||
|
|
||||||
TextDecorations textDecs;
|
TextDecorations textDecs;
|
||||||
GetTextDecorations(aPresContext, eResolvedColors, textDecs);
|
GetTextDecorations(aPresContext, eResolvedColors, textDecs);
|
||||||
|
@ -869,16 +869,22 @@ class nsTextFrame : public nsFrame {
|
|||||||
nscolor mColor;
|
nscolor mColor;
|
||||||
uint8_t mStyle;
|
uint8_t mStyle;
|
||||||
|
|
||||||
|
// The text-underline-position property; affects the underline offset only
|
||||||
|
// if mTextUnderlineOffset is auto.
|
||||||
|
const mozilla::StyleTextUnderlinePosition mTextUnderlinePosition;
|
||||||
|
|
||||||
LineDecoration(nsIFrame* const aFrame, const nscoord aOff,
|
LineDecoration(nsIFrame* const aFrame, const nscoord aOff,
|
||||||
const mozilla::StyleTextDecorationLength& aUnderline,
|
mozilla::StyleTextUnderlinePosition aUnderlinePosition,
|
||||||
|
const mozilla::StyleTextDecorationLength& aUnderlineOffset,
|
||||||
const mozilla::StyleTextDecorationLength& aDecThickness,
|
const mozilla::StyleTextDecorationLength& aDecThickness,
|
||||||
const nscolor aColor, const uint8_t aStyle)
|
const nscolor aColor, const uint8_t aStyle)
|
||||||
: mFrame(aFrame),
|
: mFrame(aFrame),
|
||||||
mBaselineOffset(aOff),
|
mBaselineOffset(aOff),
|
||||||
mTextUnderlineOffset(aUnderline),
|
mTextUnderlineOffset(aUnderlineOffset),
|
||||||
mTextDecorationThickness(aDecThickness),
|
mTextDecorationThickness(aDecThickness),
|
||||||
mColor(aColor),
|
mColor(aColor),
|
||||||
mStyle(aStyle) {}
|
mStyle(aStyle),
|
||||||
|
mTextUnderlinePosition(aUnderlinePosition) {}
|
||||||
|
|
||||||
LineDecoration(const LineDecoration& aOther)
|
LineDecoration(const LineDecoration& aOther)
|
||||||
: mFrame(aOther.mFrame),
|
: mFrame(aOther.mFrame),
|
||||||
@ -886,12 +892,14 @@ class nsTextFrame : public nsFrame {
|
|||||||
mTextUnderlineOffset(aOther.mTextUnderlineOffset),
|
mTextUnderlineOffset(aOther.mTextUnderlineOffset),
|
||||||
mTextDecorationThickness(aOther.mTextDecorationThickness),
|
mTextDecorationThickness(aOther.mTextDecorationThickness),
|
||||||
mColor(aOther.mColor),
|
mColor(aOther.mColor),
|
||||||
mStyle(aOther.mStyle) {}
|
mStyle(aOther.mStyle),
|
||||||
|
mTextUnderlinePosition(aOther.mTextUnderlinePosition) {}
|
||||||
|
|
||||||
bool operator==(const LineDecoration& aOther) const {
|
bool operator==(const LineDecoration& aOther) const {
|
||||||
return mFrame == aOther.mFrame && mStyle == aOther.mStyle &&
|
return mFrame == aOther.mFrame && mStyle == aOther.mStyle &&
|
||||||
mColor == aOther.mColor &&
|
mColor == aOther.mColor &&
|
||||||
mBaselineOffset == aOther.mBaselineOffset &&
|
mBaselineOffset == aOther.mBaselineOffset &&
|
||||||
|
mTextUnderlinePosition == aOther.mTextUnderlinePosition &&
|
||||||
mTextUnderlineOffset == aOther.mTextUnderlineOffset &&
|
mTextUnderlineOffset == aOther.mTextUnderlineOffset &&
|
||||||
mTextDecorationThickness == aOther.mTextDecorationThickness;
|
mTextDecorationThickness == aOther.mTextDecorationThickness;
|
||||||
}
|
}
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
[text-decoration-underline-position-vertical-ja.html]
|
[text-decoration-underline-position-vertical-ja.html]
|
||||||
|
prefs: [layout.css.text-underline-position.enabled:true]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
bug: https://github.com/web-platform-tests/wpt/issues/20604
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
[text-decoration-underline-position-vertical.html]
|
[text-decoration-underline-position-vertical.html]
|
||||||
expected: FAIL
|
prefs: [layout.css.text-underline-position.enabled:true]
|
||||||
|
Loading…
Reference in New Issue
Block a user