Index: Source/core/rendering/style/RenderStyle.cpp |
diff --git a/Source/core/rendering/style/RenderStyle.cpp b/Source/core/rendering/style/RenderStyle.cpp |
index a4cb88432c2c76f68e13a4f1be202f7770eaf843..7739040ec894288af70c784accd619a476a645b8 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/AppliedTextDecorationList.h" |
#include "core/rendering/style/ContentData.h" |
#include "core/rendering/style/CursorList.h" |
#include "core/rendering/style/QuotesData.h" |
@@ -657,14 +658,15 @@ StyleDifference RenderStyle::repaintOnlyDiff(const RenderStyle* other, unsigned& |
} |
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 |
|| rareNonInheritedData->m_textDecorationStyle != other->rareNonInheritedData->m_textDecorationStyle |
|| rareNonInheritedData->m_textDecorationColor != other->rareNonInheritedData->m_textDecorationColor |
|| 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) |
return StyleDifferenceRepaintIfTextOrColorChange; |
// Cursors are not checked, since they will be set appropriately in response to mouse events, |
@@ -1186,6 +1188,22 @@ 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; |
+ |
+ if (appliedTextUnderline()) |
+ decorations |= TextDecorationUnderline; |
+ |
+ const AppliedTextDecorationList* applied = appliedTextDecorations(); |
+ |
+ if (applied) |
+ for (size_t i = 0; i < applied->size(); ++i) |
+ decorations |= applied->at(i).line(); |
esprehn
2014/03/31 17:41:24
This needs braces, we also prefer early return.
i
|
+ |
+ return static_cast<TextDecoration>(decorations); |
+} |
+ |
float RenderStyle::wordSpacing() const { return fontDescription().wordSpacing(); } |
float RenderStyle::letterSpacing() const { return fontDescription().letterSpacing(); } |
@@ -1281,6 +1299,79 @@ void RenderStyle::setFontWeight(FontWeight weight) |
font().update(currentFontSelector); |
} |
+void RenderStyle::setTextDecorationsInEffect(TextDecoration decorations) |
+{ |
+ clearAppliedTextDecorations(); |
+ |
+ if (decorations & TextDecorationUnderline) |
+ addAppliedTextDecoration(TextDecorationUnderline); |
+ if (decorations & TextDecorationOverline) |
+ addAppliedTextDecoration(TextDecorationOverline); |
+ if (decorations & TextDecorationLineThrough) |
+ addAppliedTextDecoration(TextDecorationLineThrough); |
+} |
+ |
+void RenderStyle::addAppliedTextDecoration(TextDecoration decoration) |
+{ |
+ if (!appliedTextDecorations() && decoration == TextDecorationUnderline) { |
+ // 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 an underline must be drawn during painting. |
+ inherited_flags.m_textUnderline = true; |
+ return; |
+ } |
+ |
+ addAppliedTextDecoration(AppliedTextDecoration(decoration, TextDecorationStyleSolid, color())); |
+} |
+ |
+void RenderStyle::addAppliedTextDecoration(const AppliedTextDecoration& decoration) |
+{ |
+ RefPtr<AppliedTextDecorationList>& list = rareInheritedData.access()->appliedTextDecorations; |
+ |
+ if (!list) |
+ list = AppliedTextDecorationList::create(); |
+ else if (!list->hasOneRef()) |
+ list = list->copy(); |
+ |
+ list->append(decoration); |
+} |
+ |
+void RenderStyle::applyTextDecoration(TextDecoration decoration, TextDecorationStyle style, const StyleColor& styleColor) |
+{ |
+ const bool isSimple = style == TextDecorationStyleSolid && styleColor.isCurrentColor(); |
esprehn
2014/03/31 17:41:24
remove const
|
+ |
+ if (isSimple) |
+ addAppliedTextDecoration(decoration); |
+ else |
+ addAppliedTextDecoration(AppliedTextDecoration(decoration, style, styleColor.resolve(color()))); |
+} |
+ |
+void RenderStyle::applyTextDecorations() |
+{ |
+ if (textDecoration() == TextDecorationNone) |
+ return; |
+ |
+ TextDecorationStyle style = textDecorationStyle(); |
+ StyleColor styleColor = visitedDependentDecorationStyleColor(); |
+ |
+ const int decorations = textDecoration(); |
esprehn
2014/03/31 17:41:24
no const
|
+ |
+ if (decorations & TextDecorationUnderline) |
+ applyTextDecoration(TextDecorationUnderline, style, styleColor); |
+ if (decorations & TextDecorationOverline) |
+ applyTextDecoration(TextDecorationOverline, style, styleColor); |
+ if (decorations & TextDecorationLineThrough) |
+ applyTextDecoration(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; |
@@ -1358,10 +1449,29 @@ void RenderStyle::getShadowVerticalExtent(const ShadowList* shadowList, LayoutUn |
} |
} |
-StyleColor RenderStyle::visitedDependentDecorationColor() const |
+StyleColor RenderStyle::visitedDependentDecorationStyleColor() const |
+{ |
+ const bool visitedLink = insideLink() == InsideVisitedLink; |
esprehn
2014/03/31 17:41:24
ditto
|
+ |
+ StyleColor styleColor = visitedLink ? visitedLinkTextDecorationColor() : textDecorationColor(); |
+ |
+ if (!styleColor.isCurrentColor()) |
+ return styleColor; |
+ |
+ if (textStrokeWidth() > 0) { |
esprehn
2014/03/31 17:41:24
Remove > 0, can this be negative?
|
+ // 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(); |
+ const bool visitedLink = insideLink() == InsideVisitedLink; |
+ return visitedDependentDecorationStyleColor().resolve(visitedLink ? visitedLinkColor() : color()); |
} |
Color RenderStyle::colorIncludingFallback(int colorProperty, bool visitedLink) const |