Chromium Code Reviews| Index: Source/core/rendering/style/RenderStyle.cpp |
| diff --git a/Source/core/rendering/style/RenderStyle.cpp b/Source/core/rendering/style/RenderStyle.cpp |
| index dfeb3bed61f5b2ce8ec111e0e8193140b5c768cd..4d5b9103b04bd38bd768524e813771eef50650f1 100644 |
| --- a/Source/core/rendering/style/RenderStyle.cpp |
| +++ b/Source/core/rendering/style/RenderStyle.cpp |
| @@ -28,6 +28,7 @@ |
| #include "core/css/resolver/StyleResolver.h" |
| #include "core/rendering/RenderTheme.h" |
| #include "core/rendering/TextAutosizer.h" |
| +#include "core/rendering/style/AppliedTextDecoration.h" |
| #include "core/rendering/style/ContentData.h" |
| #include "core/rendering/style/CursorList.h" |
| #include "core/rendering/style/QuotesData.h" |
| @@ -688,7 +689,7 @@ unsigned RenderStyle::computeChangedContextSensitiveProperties(const RenderStyle |
| if (!diff.needsRepaint()) { |
| if (inherited->color != other.inherited->color |
| - || inherited_flags._text_decorations != other.inherited_flags._text_decorations |
| + || inherited_flags.m_textUnderline != other.inherited_flags.m_textUnderline |
| || visual->textDecoration != other.visual->textDecoration) { |
| changedContextSensitiveProperties |= ContextSensitivePropertyTextOrColor; |
| } else if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) { |
| @@ -699,7 +700,8 @@ unsigned RenderStyle::computeChangedContextSensitiveProperties(const RenderStyle |
| if (rareInheritedData->textFillColor() != other.rareInheritedData->textFillColor() |
| || rareInheritedData->textStrokeColor() != other.rareInheritedData->textStrokeColor() |
| || rareInheritedData->textEmphasisColor() != other.rareInheritedData->textEmphasisColor() |
| - || rareInheritedData->textEmphasisFill != other.rareInheritedData->textEmphasisFill) |
| + || rareInheritedData->textEmphasisFill != other.rareInheritedData->textEmphasisFill |
| + || rareInheritedData->appliedTextDecorations != other.rareInheritedData->appliedTextDecorations) |
| changedContextSensitiveProperties |= ContextSensitivePropertyTextOrColor; |
| } |
| } |
| @@ -1204,6 +1206,31 @@ float RenderStyle::computedFontSize() const { return fontDescription().computedS |
| int RenderStyle::fontSize() const { return fontDescription().computedPixelSize(); } |
| FontWeight RenderStyle::fontWeight() const { return fontDescription().weight(); } |
| +TextDecoration RenderStyle::textDecorationsInEffect() const |
| +{ |
| + int decorations = 0; |
| + |
| + const Vector<AppliedTextDecoration>& applied = appliedTextDecorations(); |
| + |
| + for (size_t i = 0; i < applied.size(); ++i) |
| + decorations |= applied[i].line(); |
| + |
| + return static_cast<TextDecoration>(decorations); |
| +} |
| + |
| +const Vector<AppliedTextDecoration>& RenderStyle::appliedTextDecorations() const |
| +{ |
| + DEFINE_STATIC_LOCAL(Vector<AppliedTextDecoration>, empty, ()); |
| + DEFINE_STATIC_LOCAL(Vector<AppliedTextDecoration>, underline, (1, AppliedTextDecoration(TextDecorationUnderline))); |
|
Julien - ping for review
2014/05/05 17:45:08
I would prefer the vectors to be defined inside th
andersr
2014/05/06 13:15:29
Done.
|
| + |
| + if (!inherited_flags.m_textUnderline && !rareInheritedData->appliedTextDecorations) |
|
Julien - ping for review
2014/05/05 17:45:08
This line makes me think that when inherited_flags
andersr
2014/05/06 13:15:29
Do you mean that it does not read well, or that it
|
| + return empty; |
| + if (inherited_flags.m_textUnderline && !rareInheritedData->appliedTextDecorations) |
|
Julien - ping for review
2014/05/05 17:45:08
Wouldn't rareInheritedData->appliedTextDecorations
andersr
2014/05/06 13:15:29
That's true. Fixed.
|
| + return underline; |
| + |
| + return rareInheritedData->appliedTextDecorations->vector(); |
| +} |
| + |
| float RenderStyle::wordSpacing() const { return fontDescription().wordSpacing(); } |
| float RenderStyle::letterSpacing() const { return fontDescription().letterSpacing(); } |
| @@ -1299,6 +1326,72 @@ void RenderStyle::setFontWeight(FontWeight weight) |
| font().update(currentFontSelector); |
| } |
| +void RenderStyle::setTextDecorationsInEffect(TextDecoration decorations) |
| +{ |
| + clearAppliedTextDecorations(); |
| + |
| + if (decorations & TextDecorationUnderline) |
| + addAppliedTextDecoration(AppliedTextDecoration(TextDecorationUnderline)); |
| + if (decorations & TextDecorationOverline) |
| + addAppliedTextDecoration(AppliedTextDecoration(TextDecorationOverline)); |
| + if (decorations & TextDecorationLineThrough) |
| + addAppliedTextDecoration(AppliedTextDecoration(TextDecorationLineThrough)); |
| +} |
| + |
| +void RenderStyle::addAppliedTextDecoration(const AppliedTextDecoration& decoration) |
| +{ |
| + bool isSimpleUnderline = decoration.isSimple() && decoration.line() == TextDecorationUnderline; |
|
Julien - ping for review
2014/05/05 17:45:08
It's weird that we check for this simple case repe
andersr
2014/05/06 13:15:29
I don't know ... is that really weird?
Currently,
|
| + |
| + if (!rareInheritedData->appliedTextDecorations && isSimpleUnderline) { |
| + // To save memory, we don't use AppliedTextDecoration objects in the |
| + // common case of a single solid underline with the current color. Instead, |
| + // we set a bit to indicate that a solid underline must be drawn with the |
| + // current color. |
| + inherited_flags.m_textUnderline = true; |
| + return; |
| + } |
| + |
| + RefPtr<AppliedTextDecorationList>& list = rareInheritedData.access()->appliedTextDecorations; |
| + |
| + if (!list) |
| + list = AppliedTextDecorationList::create(); |
| + else if (!list->hasOneRef()) |
| + list = list->copy(); |
|
Julien - ping for review
2014/05/05 17:45:08
It's probably me but I have a hard time understand
andersr
2014/05/06 13:15:29
A) The same reason we copy DataRef objects? When t
|
| + |
| + if (inherited_flags.m_textUnderline) { |
| + inherited_flags.m_textUnderline = false; |
| + list->append(AppliedTextDecoration(TextDecorationUnderline, TextDecorationStyleSolid, StyleColor::currentColor())); |
| + } |
| + |
| + list->append(decoration); |
| +} |
| + |
| +void RenderStyle::applyTextDecorations() |
| +{ |
| + if (textDecoration() == TextDecorationNone) |
| + return; |
| + |
| + TextDecorationStyle style = textDecorationStyle(); |
| + StyleColor styleColor = visitedDependentDecorationStyleColor(); |
| + |
| + int decorations = textDecoration(); |
| + |
| + if (decorations & TextDecorationUnderline) |
| + addAppliedTextDecoration(AppliedTextDecoration(TextDecorationUnderline, style, styleColor)); |
| + if (decorations & TextDecorationOverline) |
| + addAppliedTextDecoration(AppliedTextDecoration(TextDecorationOverline, style, styleColor)); |
| + if (decorations & TextDecorationLineThrough) |
| + addAppliedTextDecoration(AppliedTextDecoration(TextDecorationLineThrough, style, styleColor)); |
| +} |
| + |
| +void RenderStyle::clearAppliedTextDecorations() |
| +{ |
| + inherited_flags.m_textUnderline = false; |
| + |
| + if (rareInheritedData->appliedTextDecorations) |
| + rareInheritedData.access()->appliedTextDecorations = nullptr; |
| +} |
| + |
| void RenderStyle::getShadowExtent(const ShadowList* shadowList, LayoutUnit &top, LayoutUnit &right, LayoutUnit &bottom, LayoutUnit &left) const |
| { |
| top = 0; |
| @@ -1376,10 +1469,29 @@ void RenderStyle::getShadowVerticalExtent(const ShadowList* shadowList, LayoutUn |
| } |
| } |
| -StyleColor RenderStyle::visitedDependentDecorationColor() const |
| +StyleColor RenderStyle::visitedDependentDecorationStyleColor() const |
| +{ |
| + bool visitedLink = insideLink() == InsideVisitedLink; |
| + |
| + StyleColor styleColor = visitedLink ? visitedLinkTextDecorationColor() : textDecorationColor(); |
| + |
| + if (!styleColor.isCurrentColor()) |
| + return styleColor; |
| + |
| + if (textStrokeWidth()) { |
| + // Prefer stroke color if possible but not if it's fully transparent. |
| + StyleColor textStrokeStyleColor = visitedLink ? visitedLinkTextStrokeColor() : textStrokeColor(); |
| + if (!textStrokeStyleColor.isCurrentColor() && textStrokeStyleColor.color().alpha()) |
| + return textStrokeStyleColor; |
| + } |
| + |
| + return visitedLink ? visitedLinkTextFillColor() : textFillColor(); |
| +} |
| + |
| +Color RenderStyle::visitedDependentDecorationColor() const |
| { |
| - // Text decoration color fallback is handled in RenderObject::decorationColor. |
| - return insideLink() == InsideVisitedLink ? visitedLinkTextDecorationColor() : textDecorationColor(); |
| + bool visitedLink = insideLink() == InsideVisitedLink; |
| + return visitedDependentDecorationStyleColor().resolve(visitedLink ? visitedLinkColor() : color()); |
| } |
| Color RenderStyle::colorIncludingFallback(int colorProperty, bool visitedLink) const |