mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 1535165 - Use cbindgen for text-decoration-line. r=dholbert,boris
Differential Revision: https://phabricator.services.mozilla.com/D23412 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
9928a5bda4
commit
e66fb8488c
@ -606,9 +606,9 @@ TextAttrsMgr::TextDecorValue::TextDecorValue(nsIFrame* aFrame) {
|
||||
const nsStyleTextReset* textReset = aFrame->StyleTextReset();
|
||||
mStyle = textReset->mTextDecorationStyle;
|
||||
mColor = textReset->mTextDecorationColor.CalcColor(aFrame);
|
||||
mLine = textReset->mTextDecorationLine &
|
||||
(NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE |
|
||||
NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH);
|
||||
mLine =
|
||||
textReset->mTextDecorationLine & (StyleTextDecorationLine_UNDERLINE |
|
||||
StyleTextDecorationLine_LINE_THROUGH);
|
||||
}
|
||||
|
||||
TextAttrsMgr::TextDecorTextAttr::TextDecorTextAttr(nsIFrame* aRootFrame,
|
||||
|
@ -358,7 +358,7 @@ class TextAttrsMgr {
|
||||
public:
|
||||
TextDecorValue()
|
||||
: mColor{0},
|
||||
mLine{NS_STYLE_TEXT_DECORATION_LINE_NONE},
|
||||
mLine{StyleTextDecorationLine_NONE},
|
||||
mStyle{NS_STYLE_TEXT_DECORATION_STYLE_NONE} {}
|
||||
explicit TextDecorValue(nsIFrame* aFrame);
|
||||
|
||||
@ -367,10 +367,10 @@ class TextAttrsMgr {
|
||||
|
||||
bool IsDefined() const { return IsUnderline() || IsLineThrough(); }
|
||||
bool IsUnderline() const {
|
||||
return mLine & NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
|
||||
return bool(mLine & mozilla::StyleTextDecorationLine_UNDERLINE);
|
||||
}
|
||||
bool IsLineThrough() const {
|
||||
return mLine & NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
|
||||
return bool(mLine & mozilla::StyleTextDecorationLine_LINE_THROUGH);
|
||||
}
|
||||
|
||||
bool operator==(const TextDecorValue& aValue) {
|
||||
@ -381,7 +381,7 @@ class TextAttrsMgr {
|
||||
|
||||
private:
|
||||
nscolor mColor;
|
||||
uint8_t mLine;
|
||||
mozilla::StyleTextDecorationLine mLine;
|
||||
uint8_t mStyle;
|
||||
};
|
||||
|
||||
|
@ -73,7 +73,7 @@ void HTMLFontElement::MapAttributesIntoRule(
|
||||
}
|
||||
if (aDecls.Document()->GetCompatibilityMode() == eCompatibility_NavQuirks) {
|
||||
// Make <a><font color="red">text</font></a> give the text a red underline
|
||||
// in quirks mode. The NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL flag only
|
||||
// in quirks mode. The StyleTextDecorationLine_COLOR_OVERRIDE flag only
|
||||
// affects quirks mode rendering.
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::color);
|
||||
nscolor color;
|
||||
|
@ -5279,10 +5279,11 @@ void nsTextFrame::GetTextDecorations(
|
||||
}
|
||||
|
||||
const nsStyleTextReset* const styleText = context->StyleTextReset();
|
||||
const uint8_t textDecorations = styleText->mTextDecorationLine;
|
||||
const StyleTextDecorationLine textDecorations =
|
||||
styleText->mTextDecorationLine;
|
||||
|
||||
if (!useOverride &&
|
||||
(NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL & textDecorations)) {
|
||||
(StyleTextDecorationLine_COLOR_OVERRIDE & textDecorations)) {
|
||||
// This handles the <a href="blah.html"><font color="green">La
|
||||
// la la</font></a> case. The link underline should be green.
|
||||
useOverride = true;
|
||||
@ -5347,12 +5348,12 @@ void nsTextFrame::GetTextDecorations(
|
||||
}
|
||||
|
||||
bool swapUnderlineAndOverline = vertical && IsUnderlineRight(f);
|
||||
const uint8_t kUnderline = swapUnderlineAndOverline
|
||||
? NS_STYLE_TEXT_DECORATION_LINE_OVERLINE
|
||||
: NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
|
||||
const uint8_t kOverline = swapUnderlineAndOverline
|
||||
? NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE
|
||||
: NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
|
||||
const auto kUnderline = swapUnderlineAndOverline
|
||||
? StyleTextDecorationLine_OVERLINE
|
||||
: StyleTextDecorationLine_UNDERLINE;
|
||||
const auto kOverline = swapUnderlineAndOverline
|
||||
? StyleTextDecorationLine_UNDERLINE
|
||||
: StyleTextDecorationLine_OVERLINE;
|
||||
|
||||
if (textDecorations & kUnderline) {
|
||||
aDecorations.mUnderlines.AppendElement(
|
||||
@ -5362,7 +5363,7 @@ void nsTextFrame::GetTextDecorations(
|
||||
aDecorations.mOverlines.AppendElement(
|
||||
nsTextFrame::LineDecoration(f, baselineOffset, color, style));
|
||||
}
|
||||
if (textDecorations & NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH) {
|
||||
if (textDecorations & StyleTextDecorationLine_LINE_THROUGH) {
|
||||
aDecorations.mStrikes.AppendElement(
|
||||
nsTextFrame::LineDecoration(f, baselineOffset, color, style));
|
||||
}
|
||||
@ -5551,11 +5552,11 @@ void nsTextFrame::UnionAdditionalOverflow(nsPresContext* aPresContext,
|
||||
params.sidewaysLeft = mTextRun->IsSidewaysLeft();
|
||||
|
||||
params.offset = underlineOffset / appUnitsPerDevUnit;
|
||||
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
|
||||
params.decoration = StyleTextDecorationLine_UNDERLINE;
|
||||
nsRect underlineRect =
|
||||
nsCSSRendering::GetTextDecorationRect(aPresContext, params);
|
||||
params.offset = maxAscent / appUnitsPerDevUnit;
|
||||
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
|
||||
params.decoration = StyleTextDecorationLine_OVERLINE;
|
||||
nsRect overlineRect =
|
||||
nsCSSRendering::GetTextDecorationRect(aPresContext, params);
|
||||
|
||||
@ -5638,17 +5639,17 @@ void nsTextFrame::UnionAdditionalOverflow(nsPresContext* aPresContext,
|
||||
|
||||
// Below we loop through all text decorations and compute the rectangle
|
||||
// containing all of them, in this frame's coordinate space
|
||||
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
|
||||
params.decoration = StyleTextDecorationLine_UNDERLINE;
|
||||
for (const LineDecoration& dec : textDecs.mUnderlines) {
|
||||
accumulateDecorationRect(dec, &Metrics::underlineSize,
|
||||
&Metrics::underlineOffset);
|
||||
}
|
||||
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
|
||||
params.decoration = StyleTextDecorationLine_OVERLINE;
|
||||
for (const LineDecoration& dec : textDecs.mOverlines) {
|
||||
accumulateDecorationRect(dec, &Metrics::underlineSize,
|
||||
&Metrics::maxAscent);
|
||||
}
|
||||
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
|
||||
params.decoration = StyleTextDecorationLine_LINE_THROUGH;
|
||||
for (const LineDecoration& dec : textDecs.mStrikes) {
|
||||
accumulateDecorationRect(dec, &Metrics::strikeoutSize,
|
||||
&Metrics::strikeoutOffset);
|
||||
@ -5789,14 +5790,14 @@ void nsTextFrame::DrawSelectionDecorations(
|
||||
const TextRangeStyle& aRangeStyle, const Point& aPt,
|
||||
gfxFloat aICoordInFrame, gfxFloat aWidth, gfxFloat aAscent,
|
||||
const gfxFont::Metrics& aFontMetrics, DrawPathCallbacks* aCallbacks,
|
||||
bool aVertical, uint8_t aDecoration) {
|
||||
bool aVertical, StyleTextDecorationLine aDecoration) {
|
||||
PaintDecorationLineParams params;
|
||||
params.context = aContext;
|
||||
params.dirtyRect = aDirtyRect;
|
||||
params.pt = aPt;
|
||||
params.lineSize.width = aWidth;
|
||||
params.ascent = aAscent;
|
||||
params.offset = aDecoration == NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE
|
||||
params.offset = aDecoration == StyleTextDecorationLine_UNDERLINE
|
||||
? aFontMetrics.underlineOffset
|
||||
: aFontMetrics.maxAscent;
|
||||
params.decoration = aDecoration;
|
||||
@ -5894,7 +5895,7 @@ void nsTextFrame::DrawSelectionDecorations(
|
||||
params.style = NS_STYLE_TEXT_DECORATION_STYLE_SOLID;
|
||||
params.lineSize.height = metrics.strikeoutSize;
|
||||
params.offset = metrics.strikeoutOffset + 0.5;
|
||||
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
|
||||
params.decoration = StyleTextDecorationLine_LINE_THROUGH;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -6413,9 +6414,8 @@ void nsTextFrame::PaintTextSelectionDecorations(
|
||||
gfxFont* firstFont = aParams.provider->GetFontGroup()->GetFirstValidFont();
|
||||
bool verticalRun = mTextRun->IsVertical();
|
||||
bool rightUnderline = verticalRun && IsUnderlineRight(this);
|
||||
const uint8_t kDecoration = rightUnderline
|
||||
? NS_STYLE_TEXT_DECORATION_LINE_OVERLINE
|
||||
: NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
|
||||
const auto kDecoration = rightUnderline ? StyleTextDecorationLine_OVERLINE
|
||||
: StyleTextDecorationLine_UNDERLINE;
|
||||
bool useVerticalMetrics = verticalRun && mTextRun->UseCenterBaseline();
|
||||
gfxFont::Metrics decorationMetrics(firstFont->GetMetrics(
|
||||
useVerticalMetrics ? gfxFont::eVertical : gfxFont::eHorizontal));
|
||||
@ -7126,14 +7126,14 @@ void nsTextFrame::DrawTextRunAndDecorations(
|
||||
}
|
||||
|
||||
// Underlines
|
||||
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
|
||||
params.decoration = StyleTextDecorationLine_UNDERLINE;
|
||||
for (const LineDecoration& dec : Reversed(aDecorations.mUnderlines)) {
|
||||
paintDecorationLine(dec, &Metrics::underlineSize,
|
||||
&Metrics::underlineOffset);
|
||||
}
|
||||
|
||||
// Overlines
|
||||
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
|
||||
params.decoration = StyleTextDecorationLine_OVERLINE;
|
||||
for (const LineDecoration& dec : Reversed(aDecorations.mOverlines)) {
|
||||
paintDecorationLine(dec, &Metrics::underlineSize, &Metrics::maxAscent);
|
||||
}
|
||||
@ -7166,7 +7166,7 @@ void nsTextFrame::DrawTextRunAndDecorations(
|
||||
}
|
||||
|
||||
// Line-throughs
|
||||
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
|
||||
params.decoration = StyleTextDecorationLine_LINE_THROUGH;
|
||||
for (const LineDecoration& dec : Reversed(aDecorations.mStrikes)) {
|
||||
paintDecorationLine(dec, &Metrics::strikeoutSize,
|
||||
&Metrics::strikeoutOffset);
|
||||
|
@ -760,7 +760,7 @@ class nsTextFrame : public nsFrame {
|
||||
const TextRangeStyle& aRangeStyle, const Point& aPt,
|
||||
gfxFloat aICoordInFrame, gfxFloat aWidth, gfxFloat aAscent,
|
||||
const gfxFont::Metrics& aFontMetrics, DrawPathCallbacks* aCallbacks,
|
||||
bool aVertical, uint8_t aDecoration);
|
||||
bool aVertical, mozilla::StyleTextDecorationLine aDecoration);
|
||||
|
||||
struct PaintDecorationLineParams;
|
||||
void PaintDecorationLine(const PaintDecorationLineParams& aParams);
|
||||
|
@ -3682,10 +3682,10 @@ void nsCSSRendering::PaintDecorationLine(
|
||||
return;
|
||||
}
|
||||
|
||||
if (aParams.decoration != NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE &&
|
||||
aParams.decoration != NS_STYLE_TEXT_DECORATION_LINE_OVERLINE &&
|
||||
aParams.decoration != NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH) {
|
||||
NS_ERROR("Invalid decoration value!");
|
||||
if (aParams.decoration != StyleTextDecorationLine_UNDERLINE &&
|
||||
aParams.decoration != StyleTextDecorationLine_OVERLINE &&
|
||||
aParams.decoration != StyleTextDecorationLine_LINE_THROUGH) {
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid text decoration value");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3961,10 +3961,10 @@ Rect nsCSSRendering::DecorationLineToPath(
|
||||
return path;
|
||||
}
|
||||
|
||||
if (aParams.decoration != NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE &&
|
||||
aParams.decoration != NS_STYLE_TEXT_DECORATION_LINE_OVERLINE &&
|
||||
aParams.decoration != NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH) {
|
||||
NS_ERROR("Invalid decoration value!");
|
||||
if (aParams.decoration != StyleTextDecorationLine_UNDERLINE &&
|
||||
aParams.decoration != StyleTextDecorationLine_OVERLINE &&
|
||||
aParams.decoration != StyleTextDecorationLine_LINE_THROUGH) {
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid text decoration value");
|
||||
return path;
|
||||
}
|
||||
|
||||
@ -4109,42 +4109,34 @@ gfxRect nsCSSRendering::GetTextDecorationRectInternal(
|
||||
// upwards. We'll swap them to be physical coords at the end.
|
||||
gfxFloat offset = 0.0;
|
||||
|
||||
switch (aParams.decoration) {
|
||||
case NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE:
|
||||
offset = aParams.offset;
|
||||
if (canLiftUnderline) {
|
||||
if (descentLimit < -offset + r.Height()) {
|
||||
// If we can ignore the offset and the decoration line is overflowing,
|
||||
// we should align the bottom edge of the decoration line rect if it's
|
||||
// possible. Otherwise, we should lift up the top edge of the rect as
|
||||
// far as possible.
|
||||
gfxFloat offsetBottomAligned = -descentLimit + r.Height();
|
||||
gfxFloat offsetTopAligned = 0.0;
|
||||
offset = std::min(offsetBottomAligned, offsetTopAligned);
|
||||
}
|
||||
if (aParams.decoration == StyleTextDecorationLine_UNDERLINE) {
|
||||
offset = aParams.offset;
|
||||
if (canLiftUnderline) {
|
||||
if (descentLimit < -offset + r.Height()) {
|
||||
// If we can ignore the offset and the decoration line is overflowing,
|
||||
// we should align the bottom edge of the decoration line rect if it's
|
||||
// possible. Otherwise, we should lift up the top edge of the rect as
|
||||
// far as possible.
|
||||
gfxFloat offsetBottomAligned = -descentLimit + r.Height();
|
||||
gfxFloat offsetTopAligned = 0.0;
|
||||
offset = std::min(offsetBottomAligned, offsetTopAligned);
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_STYLE_TEXT_DECORATION_LINE_OVERLINE:
|
||||
// For overline, we adjust the offset by lineThickness (the thickness of
|
||||
// a single decoration line) because empirically it looks better to draw
|
||||
// the overline just inside rather than outside the font's ascent, which
|
||||
// is what nsTextFrame passes as aParams.offset (as fonts don't provide
|
||||
// an explicit overline-offset).
|
||||
offset = aParams.offset - lineThickness + r.Height();
|
||||
break;
|
||||
|
||||
case NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH: {
|
||||
// To maintain a consistent mid-point for line-through decorations,
|
||||
// we adjust the offset by half of the decoration rect's height.
|
||||
gfxFloat extra = floor(r.Height() / 2.0 + 0.5);
|
||||
extra = std::max(extra, lineThickness);
|
||||
offset = aParams.offset - lineThickness + extra;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NS_ERROR("Invalid decoration value!");
|
||||
} else if (aParams.decoration == StyleTextDecorationLine_OVERLINE) {
|
||||
// For overline, we adjust the offset by lineThickness (the thickness of
|
||||
// a single decoration line) because empirically it looks better to draw
|
||||
// the overline just inside rather than outside the font's ascent, which
|
||||
// is what nsTextFrame passes as aParams.offset (as fonts don't provide
|
||||
// an explicit overline-offset).
|
||||
offset = aParams.offset - lineThickness + r.Height();
|
||||
} else if (aParams.decoration == StyleTextDecorationLine_LINE_THROUGH) {
|
||||
// To maintain a consistent mid-point for line-through decorations,
|
||||
// we adjust the offset by half of the decoration rect's height.
|
||||
gfxFloat extra = floor(r.Height() / 2.0 + 0.5);
|
||||
extra = std::max(extra, lineThickness);
|
||||
offset = aParams.offset - lineThickness + extra;
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid text decoration value");
|
||||
}
|
||||
|
||||
// Convert line-relative coordinate system (x = line-right, y = line-up)
|
||||
|
@ -572,10 +572,9 @@ struct nsCSSRendering {
|
||||
// strikeout line and overline too.
|
||||
Float descentLimit = -1.0f;
|
||||
// Which line will be painted. The value can be
|
||||
// NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE or
|
||||
// NS_STYLE_TEXT_DECORATION_LINE_OVERLINE or
|
||||
// NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH.
|
||||
uint8_t decoration = NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
|
||||
// UNDERLINE or OVERLINE or LINE_THROUGH.
|
||||
mozilla::StyleTextDecorationLine decoration =
|
||||
mozilla::StyleTextDecorationLine_UNDERLINE;
|
||||
// The style of the decoration line such as
|
||||
// NS_STYLE_TEXT_DECORATION_STYLE_*.
|
||||
uint8_t style = NS_STYLE_TEXT_DECORATION_STYLE_NONE;
|
||||
|
@ -449,6 +449,7 @@ cbindgen-types = [
|
||||
{ gecko = "StyleGenericLineHeight", servo = "values::generics::text::LineHeight" },
|
||||
{ gecko = "StyleContain", servo = "values::computed::Contain" },
|
||||
{ gecko = "StyleRestyleHint", servo = "invalidation::element::restyle_hints::RestyleHint" },
|
||||
{ gecko = "StyleTextDecorationLine", servo = "values::computed::TextDecorationLine" },
|
||||
]
|
||||
|
||||
mapped-generic-types = [
|
||||
|
@ -114,7 +114,6 @@ LONGHANDS_NOT_SERIALIZED_WITH_SERVO = [
|
||||
"scroll-snap-points-x",
|
||||
"scroll-snap-points-y",
|
||||
"stroke",
|
||||
"text-decoration-line",
|
||||
"text-emphasis-position",
|
||||
"text-emphasis-style",
|
||||
"text-overflow",
|
||||
|
@ -359,14 +359,6 @@ const KTableEntry nsCSSProps::kTextAlignKTable[] = {
|
||||
{eCSSKeyword_end, NS_STYLE_TEXT_ALIGN_END},
|
||||
{eCSSKeyword_UNKNOWN, -1}};
|
||||
|
||||
const KTableEntry nsCSSProps::kTextDecorationLineKTable[] = {
|
||||
{eCSSKeyword_none, NS_STYLE_TEXT_DECORATION_LINE_NONE},
|
||||
{eCSSKeyword_underline, NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE},
|
||||
{eCSSKeyword_overline, NS_STYLE_TEXT_DECORATION_LINE_OVERLINE},
|
||||
{eCSSKeyword_line_through, NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH},
|
||||
{eCSSKeyword_blink, NS_STYLE_TEXT_DECORATION_LINE_BLINK},
|
||||
{eCSSKeyword_UNKNOWN, -1}};
|
||||
|
||||
const KTableEntry nsCSSProps::kTextDecorationStyleKTable[] = {
|
||||
{eCSSKeyword__moz_none, NS_STYLE_TEXT_DECORATION_STYLE_NONE},
|
||||
{eCSSKeyword_solid, NS_STYLE_TEXT_DECORATION_STYLE_SOLID},
|
||||
|
@ -306,7 +306,6 @@ class nsCSSProps {
|
||||
static const KTableEntry kGridTrackBreadthKTable[];
|
||||
static const KTableEntry kLineHeightKTable[];
|
||||
static const KTableEntry kTextAlignKTable[];
|
||||
static const KTableEntry kTextDecorationLineKTable[];
|
||||
static const KTableEntry kTextDecorationStyleKTable[];
|
||||
static const KTableEntry kTextEmphasisStyleShapeKTable[];
|
||||
static const KTableEntry kTextOverflowKTable[];
|
||||
|
@ -1990,13 +1990,22 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextDecoration() {
|
||||
textReset->mTextDecorationStyle == NS_STYLE_TEXT_DECORATION_STYLE_SOLID;
|
||||
StyleComplexColor color = textReset->mTextDecorationColor;
|
||||
|
||||
RefPtr<nsROCSSPrimitiveValue> textDecorationLine = new nsROCSSPrimitiveValue;
|
||||
|
||||
{
|
||||
nsAutoString decorationLine;
|
||||
Servo_GetPropertyValue(mComputedStyle, eCSSProperty_text_decoration_line,
|
||||
&decorationLine);
|
||||
textDecorationLine->SetString(decorationLine);
|
||||
}
|
||||
|
||||
if (isInitialStyle && color.IsCurrentColor()) {
|
||||
return DoGetTextDecorationLine();
|
||||
return textDecorationLine.forget();
|
||||
}
|
||||
|
||||
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
|
||||
|
||||
valueList->AppendCSSValue(DoGetTextDecorationLine());
|
||||
valueList->AppendCSSValue(textDecorationLine.forget());
|
||||
if (!isInitialStyle) {
|
||||
valueList->AppendCSSValue(DoGetTextDecorationStyle());
|
||||
}
|
||||
@ -2013,28 +2022,6 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextDecorationColor() {
|
||||
return val.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextDecorationLine() {
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
|
||||
int32_t intValue = StyleTextReset()->mTextDecorationLine;
|
||||
|
||||
if (NS_STYLE_TEXT_DECORATION_LINE_NONE == intValue) {
|
||||
val->SetIdent(eCSSKeyword_none);
|
||||
} else {
|
||||
nsAutoString decorationLineString;
|
||||
// Clear the OVERRIDE_ALL bits -- we don't want these to appear in
|
||||
// the computed style.
|
||||
intValue &= ~NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL;
|
||||
nsStyleUtil::AppendBitmaskCSSValue(
|
||||
nsCSSProps::kTextDecorationLineKTable, intValue,
|
||||
NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE,
|
||||
NS_STYLE_TEXT_DECORATION_LINE_BLINK, decorationLineString);
|
||||
val->SetString(decorationLineString);
|
||||
}
|
||||
|
||||
return val.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextDecorationStyle() {
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
|
||||
|
@ -307,7 +307,6 @@ class nsComputedDOMStyle final : public nsDOMCSSDeclaration,
|
||||
already_AddRefed<CSSValue> DoGetLineHeight();
|
||||
already_AddRefed<CSSValue> DoGetTextDecoration();
|
||||
already_AddRefed<CSSValue> DoGetTextDecorationColor();
|
||||
already_AddRefed<CSSValue> DoGetTextDecorationLine();
|
||||
already_AddRefed<CSSValue> DoGetTextDecorationStyle();
|
||||
already_AddRefed<CSSValue> DoGetTextEmphasisPosition();
|
||||
already_AddRefed<CSSValue> DoGetTextEmphasisStyle();
|
||||
|
@ -562,20 +562,6 @@ enum class StyleGridTrackBreadth : uint8_t {
|
||||
// Note: make sure that the largest NS_STYLE_TEXT_ALIGN_* value is smaller than
|
||||
// the smallest NS_STYLE_VERTICAL_ALIGN_* value below!
|
||||
|
||||
// See nsStyleText, nsStyleFont
|
||||
#define NS_STYLE_TEXT_DECORATION_LINE_NONE 0
|
||||
#define NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE 0x01
|
||||
#define NS_STYLE_TEXT_DECORATION_LINE_OVERLINE 0x02
|
||||
#define NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH 0x04
|
||||
#define NS_STYLE_TEXT_DECORATION_LINE_BLINK 0x08
|
||||
// OVERRIDE_ALL does not occur in stylesheets; it only comes from HTML
|
||||
// attribute mapping (and thus appears in computed data)
|
||||
#define NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL 0x10
|
||||
#define NS_STYLE_TEXT_DECORATION_LINE_LINES_MASK \
|
||||
(NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE | \
|
||||
NS_STYLE_TEXT_DECORATION_LINE_OVERLINE | \
|
||||
NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH)
|
||||
|
||||
// See nsStyleText
|
||||
#define NS_STYLE_TEXT_DECORATION_STYLE_NONE \
|
||||
0 // not in CSS spec, mapped to -moz-none
|
||||
|
@ -3618,7 +3618,7 @@ nsChangeHint nsStyleContent::CalcDifference(
|
||||
|
||||
nsStyleTextReset::nsStyleTextReset(const Document& aDocument)
|
||||
: mTextOverflow(),
|
||||
mTextDecorationLine(NS_STYLE_TEXT_DECORATION_LINE_NONE),
|
||||
mTextDecorationLine(StyleTextDecorationLine_NONE),
|
||||
mTextDecorationStyle(NS_STYLE_TEXT_DECORATION_STYLE_SOLID),
|
||||
mUnicodeBidi(NS_STYLE_UNICODE_BIDI_NORMAL),
|
||||
mInitialLetterSink(0),
|
||||
|
@ -1425,15 +1425,16 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTextReset {
|
||||
// Note the difference between this and
|
||||
// ComputedStyle::HasTextDecorationLines.
|
||||
bool HasTextDecorationLines() const {
|
||||
return mTextDecorationLine != NS_STYLE_TEXT_DECORATION_LINE_NONE &&
|
||||
mTextDecorationLine != NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL;
|
||||
return mTextDecorationLine != mozilla::StyleTextDecorationLine_NONE &&
|
||||
mTextDecorationLine !=
|
||||
mozilla::StyleTextDecorationLine_COLOR_OVERRIDE;
|
||||
}
|
||||
|
||||
nsChangeHint CalcDifference(const nsStyleTextReset& aNewData) const;
|
||||
|
||||
nsStyleTextOverflow mTextOverflow; // enum, string
|
||||
|
||||
uint8_t mTextDecorationLine; // NS_STYLE_TEXT_DECORATION_LINE_*
|
||||
mozilla::StyleTextDecorationLine mTextDecorationLine;
|
||||
uint8_t mTextDecorationStyle; // NS_STYLE_TEXT_DECORATION_STYLE_*
|
||||
uint8_t mUnicodeBidi; // NS_STYLE_UNICODE_BIDI_*
|
||||
nscoord mInitialLetterSink; // 0 means normal
|
||||
|
@ -371,9 +371,11 @@ void nsTextBoxFrame::DrawText(gfxContext& aRenderingContext,
|
||||
uint8_t strikeStyle = 0;
|
||||
|
||||
// Begin with no decorations
|
||||
uint8_t decorations = NS_STYLE_TEXT_DECORATION_LINE_NONE;
|
||||
// A mask of all possible decorations.
|
||||
uint8_t decorMask = NS_STYLE_TEXT_DECORATION_LINE_LINES_MASK;
|
||||
auto decorations = StyleTextDecorationLine_NONE;
|
||||
// A mask of all possible line decorations.
|
||||
auto decorMask = StyleTextDecorationLine_UNDERLINE |
|
||||
StyleTextDecorationLine_OVERLINE |
|
||||
StyleTextDecorationLine_LINE_THROUGH;
|
||||
|
||||
WritingMode wm = GetWritingMode();
|
||||
bool vertical = wm.IsVertical();
|
||||
@ -396,29 +398,30 @@ void nsTextBoxFrame::DrawText(gfxContext& aRenderingContext,
|
||||
}
|
||||
uint8_t style = styleText->mTextDecorationStyle;
|
||||
|
||||
if (NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE & decorMask &
|
||||
if (StyleTextDecorationLine_UNDERLINE & decorMask &
|
||||
styleText->mTextDecorationLine) {
|
||||
underColor = color;
|
||||
underStyle = style;
|
||||
decorMask &= ~NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
|
||||
decorations |= NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
|
||||
// TODO(emilio): Could add `operator~` or `remove()` to cbindgen.
|
||||
decorMask.bits &= ~StyleTextDecorationLine_UNDERLINE.bits;
|
||||
decorations |= StyleTextDecorationLine_UNDERLINE;
|
||||
}
|
||||
if (NS_STYLE_TEXT_DECORATION_LINE_OVERLINE & decorMask &
|
||||
if (StyleTextDecorationLine_OVERLINE & decorMask &
|
||||
styleText->mTextDecorationLine) {
|
||||
overColor = color;
|
||||
overStyle = style;
|
||||
decorMask &= ~NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
|
||||
decorations |= NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
|
||||
decorMask.bits &= ~StyleTextDecorationLine_OVERLINE.bits;
|
||||
decorations |= StyleTextDecorationLine_OVERLINE;
|
||||
}
|
||||
if (NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH & decorMask &
|
||||
if (StyleTextDecorationLine_LINE_THROUGH & decorMask &
|
||||
styleText->mTextDecorationLine) {
|
||||
strikeColor = color;
|
||||
strikeStyle = style;
|
||||
decorMask &= ~NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
|
||||
decorations |= NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
|
||||
decorMask.bits &= ~StyleTextDecorationLine_LINE_THROUGH.bits;
|
||||
decorations |= StyleTextDecorationLine_LINE_THROUGH;
|
||||
}
|
||||
}
|
||||
} while (0 != decorMask && (f = nsLayoutUtils::GetParentOrPlaceholderFor(f)));
|
||||
} while (decorMask && (f = nsLayoutUtils::GetParentOrPlaceholderFor(f)));
|
||||
|
||||
RefPtr<nsFontMetrics> fontMet =
|
||||
nsLayoutUtils::GetFontMetricsForFrame(this, 1.0f);
|
||||
@ -458,23 +461,23 @@ void nsTextBoxFrame::DrawText(gfxContext& aRenderingContext,
|
||||
// (We don't apply this rule to the access-key underline because we only
|
||||
// find out where that is as a side effect of drawing the text, in the
|
||||
// general case -- see below.)
|
||||
if (decorations & (NS_STYLE_TEXT_DECORATION_LINE_OVERLINE |
|
||||
NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE)) {
|
||||
if (decorations &
|
||||
(StyleTextDecorationLine_OVERLINE | StyleTextDecorationLine_UNDERLINE)) {
|
||||
fontMet->GetUnderline(offset, size);
|
||||
params.lineSize.height = presContext->AppUnitsToGfxUnits(size);
|
||||
if ((decorations & NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE) &&
|
||||
if ((decorations & StyleTextDecorationLine_UNDERLINE) &&
|
||||
underStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
|
||||
params.color = underColor;
|
||||
params.offset = presContext->AppUnitsToGfxUnits(offset);
|
||||
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
|
||||
params.decoration = StyleTextDecorationLine_UNDERLINE;
|
||||
params.style = underStyle;
|
||||
nsCSSRendering::PaintDecorationLine(this, *drawTarget, params);
|
||||
}
|
||||
if ((decorations & NS_STYLE_TEXT_DECORATION_LINE_OVERLINE) &&
|
||||
if ((decorations & StyleTextDecorationLine_OVERLINE) &&
|
||||
overStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
|
||||
params.color = overColor;
|
||||
params.offset = params.ascent;
|
||||
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
|
||||
params.decoration = StyleTextDecorationLine_OVERLINE;
|
||||
params.style = overStyle;
|
||||
nsCSSRendering::PaintDecorationLine(this, *drawTarget, params);
|
||||
}
|
||||
@ -544,13 +547,13 @@ void nsTextBoxFrame::DrawText(gfxContext& aRenderingContext,
|
||||
|
||||
// Strikeout is drawn on top of the text, per
|
||||
// http://www.w3.org/TR/CSS21/zindex.html point 7.2.1.4.1.1.
|
||||
if ((decorations & NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH) &&
|
||||
if ((decorations & StyleTextDecorationLine_LINE_THROUGH) &&
|
||||
strikeStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
|
||||
fontMet->GetStrikeout(offset, size);
|
||||
params.color = strikeColor;
|
||||
params.lineSize.height = presContext->AppUnitsToGfxUnits(size);
|
||||
params.offset = presContext->AppUnitsToGfxUnits(offset);
|
||||
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
|
||||
params.decoration = StyleTextDecorationLine_LINE_THROUGH;
|
||||
params.style = strikeStyle;
|
||||
nsCSSRendering::PaintDecorationLine(this, *drawTarget, params);
|
||||
}
|
||||
|
@ -3446,26 +3446,27 @@ ImgDrawResult nsTreeBodyFrame::PaintText(
|
||||
ColorPattern color(ToDeviceColor(textContext->StyleColor()->mColor));
|
||||
|
||||
// Draw decorations.
|
||||
uint8_t decorations = textContext->StyleTextReset()->mTextDecorationLine;
|
||||
StyleTextDecorationLine decorations =
|
||||
textContext->StyleTextReset()->mTextDecorationLine;
|
||||
|
||||
nscoord offset;
|
||||
nscoord size;
|
||||
if (decorations & (NS_STYLE_TEXT_DECORATION_LINE_OVERLINE |
|
||||
NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE)) {
|
||||
if (decorations &
|
||||
(StyleTextDecorationLine_OVERLINE | StyleTextDecorationLine_UNDERLINE)) {
|
||||
fontMet->GetUnderline(offset, size);
|
||||
if (decorations & NS_STYLE_TEXT_DECORATION_LINE_OVERLINE) {
|
||||
if (decorations & StyleTextDecorationLine_OVERLINE) {
|
||||
nsRect r(textRect.x, textRect.y, textRect.width, size);
|
||||
Rect devPxRect = NSRectToSnappedRect(r, appUnitsPerDevPixel, *drawTarget);
|
||||
drawTarget->FillRect(devPxRect, color);
|
||||
}
|
||||
if (decorations & NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE) {
|
||||
if (decorations & StyleTextDecorationLine_UNDERLINE) {
|
||||
nsRect r(textRect.x, textRect.y + baseline - offset, textRect.width,
|
||||
size);
|
||||
Rect devPxRect = NSRectToSnappedRect(r, appUnitsPerDevPixel, *drawTarget);
|
||||
drawTarget->FillRect(devPxRect, color);
|
||||
}
|
||||
}
|
||||
if (decorations & NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH) {
|
||||
if (decorations & StyleTextDecorationLine_LINE_THROUGH) {
|
||||
fontMet->GetStrikeout(offset, size);
|
||||
nsRect r(textRect.x, textRect.y + baseline - offset, textRect.width, size);
|
||||
Rect devPxRect = NSRectToSnappedRect(r, appUnitsPerDevPixel, *drawTarget);
|
||||
|
@ -105,6 +105,7 @@ include = [
|
||||
"WordBreak",
|
||||
"Contain",
|
||||
"RestyleHint",
|
||||
"TextDecorationLine",
|
||||
]
|
||||
item_types = ["enums", "structs", "typedefs"]
|
||||
|
||||
|
@ -3996,9 +3996,7 @@ fn static_assert() {
|
||||
</%self:impl_trait>
|
||||
|
||||
<%self:impl_trait style_struct_name="Text"
|
||||
skip_longhands="text-decoration-line text-overflow initial-letter">
|
||||
|
||||
${impl_simple_type_with_conversion("text_decoration_line")}
|
||||
skip_longhands="text-overflow initial-letter">
|
||||
|
||||
fn clear_overflow_sides_if_string(&mut self) {
|
||||
use crate::gecko_bindings::structs::nsStyleTextOverflowSide;
|
||||
@ -4112,21 +4110,6 @@ fn static_assert() {
|
||||
InitialLetter::Specified(self.gecko.mInitialLetterSize, Some(self.gecko.mInitialLetterSink))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn has_underline(&self) -> bool {
|
||||
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE as u8)) != 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn has_overline(&self) -> bool {
|
||||
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_OVERLINE as u8)) != 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn has_line_through(&self) -> bool {
|
||||
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH as u8)) != 0
|
||||
}
|
||||
</%self:impl_trait>
|
||||
|
||||
// Set SVGPathData to StyleShapeSource.
|
||||
|
@ -5,16 +5,7 @@
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
<% from data import Method %>
|
||||
|
||||
<% data.new_style_struct(
|
||||
"Text",
|
||||
inherited=False,
|
||||
gecko_name="TextReset",
|
||||
additional_methods=[
|
||||
Method("has_underline", "bool"),
|
||||
Method("has_overline", "bool"),
|
||||
Method("has_line_through", "bool"),
|
||||
]
|
||||
) %>
|
||||
<% data.new_style_struct("Text", inherited=False, gecko_name="TextReset") %>
|
||||
|
||||
${helpers.predefined_type(
|
||||
"text-overflow",
|
||||
|
@ -2638,24 +2638,6 @@ pub mod style_structs {
|
||||
use crate::Zero;
|
||||
!self.outline_width.is_zero()
|
||||
}
|
||||
% elif style_struct.name == "Text":
|
||||
/// Whether the text decoration has an underline.
|
||||
#[inline]
|
||||
pub fn has_underline(&self) -> bool {
|
||||
self.text_decoration_line.contains(longhands::text_decoration_line::SpecifiedValue::UNDERLINE)
|
||||
}
|
||||
|
||||
/// Whether the text decoration has an overline.
|
||||
#[inline]
|
||||
pub fn has_overline(&self) -> bool {
|
||||
self.text_decoration_line.contains(longhands::text_decoration_line::SpecifiedValue::OVERLINE)
|
||||
}
|
||||
|
||||
/// Whether the text decoration has a line through.
|
||||
#[inline]
|
||||
pub fn has_line_through(&self) -> bool {
|
||||
self.text_decoration_line.contains(longhands::text_decoration_line::SpecifiedValue::LINE_THROUGH)
|
||||
}
|
||||
% elif style_struct.name == "Box":
|
||||
/// Sets the display property, but without touching original_display,
|
||||
/// except when the adjustment comes from root or item display fixups.
|
||||
|
@ -19,7 +19,7 @@ use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ToCss};
|
||||
|
||||
pub use crate::values::specified::TextAlignKeyword as TextAlign;
|
||||
pub use crate::values::specified::TextEmphasisPosition;
|
||||
pub use crate::values::specified::{TextEmphasisPosition, TextDecorationLine};
|
||||
pub use crate::values::specified::{OverflowWrap, WordBreak};
|
||||
|
||||
/// A computed value for the `initial-letter` property.
|
||||
@ -182,11 +182,11 @@ impl TextDecorationsInEffect {
|
||||
.clone(),
|
||||
};
|
||||
|
||||
let text_style = style.get_text();
|
||||
let line = style.get_text().clone_text_decoration_line();
|
||||
|
||||
result.underline |= text_style.has_underline();
|
||||
result.overline |= text_style.has_overline();
|
||||
result.line_through |= text_style.has_line_through();
|
||||
result.underline |= line.contains(TextDecorationLine::UNDERLINE);
|
||||
result.overline |= line.contains(TextDecorationLine::OVERLINE);
|
||||
result.line_through |= line.contains(TextDecorationLine::LINE_THROUGH);
|
||||
|
||||
result
|
||||
}
|
||||
|
@ -22,8 +22,7 @@ use cssparser::{Parser, Token};
|
||||
use selectors::parser::SelectorParseErrorKind;
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::values::SequenceWriter;
|
||||
use style_traits::{CssWriter, KeywordsCollectFn, ParseError};
|
||||
use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss};
|
||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
/// A specified type for the `initial-letter` property.
|
||||
@ -255,119 +254,115 @@ impl ToComputedValue for TextOverflow {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_text_decoration_line {
|
||||
{
|
||||
$(
|
||||
$(#[$($meta:tt)+])*
|
||||
$ident:ident / $css:expr => $value:expr,
|
||||
)+
|
||||
} => {
|
||||
bitflags! {
|
||||
#[derive(MallocSizeOf, ToComputedValue)]
|
||||
/// Specified keyword values for the text-decoration-line property.
|
||||
pub struct TextDecorationLine: u8 {
|
||||
/// No text decoration line is specified
|
||||
const NONE = 0;
|
||||
$(
|
||||
$(#[$($meta)+])*
|
||||
const $ident = $value;
|
||||
)+
|
||||
#[cfg(feature = "gecko")]
|
||||
/// Only set by presentation attributes
|
||||
///
|
||||
/// Setting this will mean that text-decorations use the color
|
||||
/// specified by `color` in quirks mode.
|
||||
///
|
||||
/// For example, this gives <a href=foo><font color="red">text</font></a>
|
||||
/// a red text decoration
|
||||
const COLOR_OVERRIDE = 0x10;
|
||||
bitflags! {
|
||||
#[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue)]
|
||||
#[value_info(other_values = "none,underline,overline,line-through,blink")]
|
||||
#[repr(C)]
|
||||
/// Specified keyword values for the text-decoration-line property.
|
||||
pub struct TextDecorationLine: u8 {
|
||||
/// No text decoration line is specified.
|
||||
const NONE = 0;
|
||||
/// underline
|
||||
const UNDERLINE = 1 << 0;
|
||||
/// overline
|
||||
const OVERLINE = 1 << 1;
|
||||
/// line-through
|
||||
const LINE_THROUGH = 1 << 2;
|
||||
/// blink
|
||||
const BLINK = 1 << 3;
|
||||
/// Only set by presentation attributes
|
||||
///
|
||||
/// Setting this will mean that text-decorations use the color
|
||||
/// specified by `color` in quirks mode.
|
||||
///
|
||||
/// For example, this gives <a href=foo><font color="red">text</font></a>
|
||||
/// a red text decoration
|
||||
#[cfg(feature = "gecko")]
|
||||
const COLOR_OVERRIDE = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Parse for TextDecorationLine {
|
||||
/// none | [ underline || overline || line-through || blink ]
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let mut result = TextDecorationLine::empty();
|
||||
|
||||
// NOTE(emilio): this loop has this weird structure because we run this
|
||||
// code to parse the text-decoration shorthand as well, so we need to
|
||||
// ensure we don't return an error if we don't consume the whole thing
|
||||
// because we find an invalid identifier or other kind of token.
|
||||
loop {
|
||||
let flag: Result<_, ParseError<'i>> = input.try(|input| {
|
||||
let flag = try_match_ident_ignore_ascii_case! { input,
|
||||
"none" if result.is_empty() => TextDecorationLine::NONE,
|
||||
"underline" => TextDecorationLine::UNDERLINE,
|
||||
"overline" => TextDecorationLine::OVERLINE,
|
||||
"line-through" => TextDecorationLine::LINE_THROUGH,
|
||||
"blink" => TextDecorationLine::BLINK,
|
||||
};
|
||||
|
||||
Ok(flag)
|
||||
});
|
||||
|
||||
let flag = match flag {
|
||||
Ok(flag) => flag,
|
||||
Err(..) => break,
|
||||
};
|
||||
|
||||
if flag.is_empty() {
|
||||
return Ok(TextDecorationLine::NONE);
|
||||
}
|
||||
|
||||
if result.contains(flag) {
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
|
||||
result.insert(flag)
|
||||
}
|
||||
|
||||
impl Parse for TextDecorationLine {
|
||||
/// none | [ underline || overline || line-through || blink ]
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<TextDecorationLine, ParseError<'i>> {
|
||||
let mut result = TextDecorationLine::NONE;
|
||||
if input
|
||||
.try(|input| input.expect_ident_matching("none"))
|
||||
.is_ok()
|
||||
{
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
loop {
|
||||
let result = input.try(|input| {
|
||||
let ident = input.expect_ident().map_err(|_| ())?;
|
||||
match_ignore_ascii_case! { ident,
|
||||
$(
|
||||
$css => {
|
||||
if result.contains(TextDecorationLine::$ident) {
|
||||
Err(())
|
||||
} else {
|
||||
result.insert(TextDecorationLine::$ident);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
)+
|
||||
_ => Err(()),
|
||||
}
|
||||
});
|
||||
if result.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if !result.is_empty() {
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for TextDecorationLine {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
if self.is_empty() {
|
||||
return dest.write_str("none");
|
||||
}
|
||||
|
||||
let mut writer = SequenceWriter::new(dest, " ");
|
||||
$(
|
||||
if self.contains(TextDecorationLine::$ident) {
|
||||
writer.raw_item($css)?;
|
||||
}
|
||||
)+
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl SpecifiedValueInfo for TextDecorationLine {
|
||||
fn collect_completion_keywords(f: KeywordsCollectFn) {
|
||||
f(&["none", $($css,)+]);
|
||||
}
|
||||
if !result.is_empty() {
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_text_decoration_line! {
|
||||
/// Underline
|
||||
UNDERLINE / "underline" => 1 << 0,
|
||||
/// Overline
|
||||
OVERLINE / "overline" => 1 << 1,
|
||||
/// Line through
|
||||
LINE_THROUGH / "line-through" => 1 << 2,
|
||||
/// Blink
|
||||
BLINK / "blink" => 1 << 3,
|
||||
}
|
||||
impl ToCss for TextDecorationLine {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
if self.is_empty() {
|
||||
return dest.write_str("none");
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl_bitflags_conversions!(TextDecorationLine);
|
||||
let mut writer = SequenceWriter::new(dest, " ");
|
||||
let mut any = false;
|
||||
|
||||
macro_rules! maybe_write {
|
||||
($ident:ident => $str:expr) => {
|
||||
if self.contains(TextDecorationLine::$ident) {
|
||||
any = true;
|
||||
writer.raw_item($str)?;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
maybe_write!(UNDERLINE => "underline");
|
||||
maybe_write!(OVERLINE => "overline");
|
||||
maybe_write!(LINE_THROUGH => "line-through");
|
||||
maybe_write!(BLINK => "blink");
|
||||
|
||||
debug_assert!(any || *self == TextDecorationLine::COLOR_OVERRIDE);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl TextDecorationLine {
|
||||
#[inline]
|
||||
|
@ -4742,8 +4742,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetTextDecorationColorOverride(
|
||||
use style::properties::PropertyDeclaration;
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
|
||||
let mut decoration = TextDecorationLine::none();
|
||||
decoration |= TextDecorationLine::COLOR_OVERRIDE;
|
||||
let decoration = TextDecorationLine::COLOR_OVERRIDE;
|
||||
let decl = PropertyDeclaration::TextDecorationLine(decoration);
|
||||
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
||||
decls.push(decl, Importance::Normal);
|
||||
|
Loading…
Reference in New Issue
Block a user