e73f92971224da79c20cca75767befdeca34facc
[WebKit-https.git] / Source / WebCore / rendering / style / RenderStyle.cpp
1 /*
2  * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
3  * Copyright (C) 2004-2015 Apple Inc. All rights reserved.
4  * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #include "config.h"
24 #include "RenderStyle.h"
25
26 #include "ContentData.h"
27 #include "CursorList.h"
28 #include "CSSPropertyNames.h"
29 #include "FloatRoundedRect.h"
30 #include "FontCascade.h"
31 #include "FontSelector.h"
32 #include "InlineTextBoxStyle.h"
33 #include "Pagination.h"
34 #include "QuotesData.h"
35 #include "RenderObject.h"
36 #include "ScaleTransformOperation.h"
37 #include "ShadowData.h"
38 #include "StyleImage.h"
39 #include "StyleInheritedData.h"
40 #include "StyleResolver.h"
41 #include "StyleScrollSnapPoints.h"
42 #include <wtf/MathExtras.h>
43 #include <wtf/StdLibExtras.h>
44 #include <algorithm>
45
46 #if ENABLE(IOS_TEXT_AUTOSIZING)
47 #include <wtf/text/StringHash.h>
48 #endif
49
50 #if ENABLE(TEXT_AUTOSIZING)
51 #include "TextAutosizer.h"
52 #endif
53
54 #if ENABLE(TOUCH_EVENTS)
55 #include "RenderTheme.h"
56 #endif
57
58 namespace WebCore {
59
60 struct SameSizeAsBorderValue {
61     float m_width;
62     RGBA32 m_color;
63     int m_restBits;
64 };
65
66 COMPILE_ASSERT(sizeof(BorderValue) == sizeof(SameSizeAsBorderValue), BorderValue_should_not_grow);
67
68 struct SameSizeAsRenderStyle : public RefCounted<SameSizeAsRenderStyle> {
69     void* dataRefs[7];
70     void* ownPtrs[1];
71     void* dataRefSvgStyle;
72     struct InheritedFlags {
73         unsigned m_bitfields[2];
74     } inherited_flags;
75
76     struct NonInheritedFlags {
77         uint64_t m_flags;
78     } noninherited_flags;
79 };
80
81 COMPILE_ASSERT(sizeof(RenderStyle) == sizeof(SameSizeAsRenderStyle), RenderStyle_should_stay_small);
82
83 inline RenderStyle& defaultStyle()
84 {
85     static RenderStyle& style = RenderStyle::createDefaultStyle().leakRef();
86     return style;
87 }
88
89 Ref<RenderStyle> RenderStyle::create()
90 {
91     return adoptRef(*new RenderStyle(defaultStyle()));
92 }
93
94 Ref<RenderStyle> RenderStyle::createDefaultStyle()
95 {
96     return adoptRef(*new RenderStyle(true));
97 }
98
99 Ref<RenderStyle> RenderStyle::createAnonymousStyleWithDisplay(const RenderStyle* parentStyle, EDisplay display)
100 {
101     auto newStyle = RenderStyle::create();
102     newStyle.get().inheritFrom(parentStyle);
103     newStyle.get().inheritUnicodeBidiFrom(parentStyle);
104     newStyle.get().setDisplay(display);
105     return newStyle;
106 }
107
108 Ref<RenderStyle> RenderStyle::clone(const RenderStyle* other)
109 {
110     return adoptRef(*new RenderStyle(*other));
111 }
112
113 Ref<RenderStyle> RenderStyle::createStyleInheritingFromPseudoStyle(const RenderStyle& pseudoStyle)
114 {
115     ASSERT(pseudoStyle.styleType() == BEFORE || pseudoStyle.styleType() == AFTER);
116
117     auto style = RenderStyle::create();
118     style.get().inheritFrom(&pseudoStyle);
119     return style;
120 }
121
122 ALWAYS_INLINE RenderStyle::RenderStyle(bool)
123     : m_box(StyleBoxData::create())
124     , visual(StyleVisualData::create())
125     , m_background(StyleBackgroundData::create())
126     , surround(StyleSurroundData::create())
127     , rareNonInheritedData(StyleRareNonInheritedData::create())
128     , rareInheritedData(StyleRareInheritedData::create())
129     , inherited(StyleInheritedData::create())
130     , m_svgStyle(SVGRenderStyle::create())
131 {
132     inherited_flags._empty_cells = initialEmptyCells();
133     inherited_flags._caption_side = initialCaptionSide();
134     inherited_flags._list_style_type = initialListStyleType();
135     inherited_flags._list_style_position = initialListStylePosition();
136     inherited_flags._visibility = initialVisibility();
137     inherited_flags._text_align = initialTextAlign();
138     inherited_flags._text_transform = initialTextTransform();
139     inherited_flags._text_decorations = initialTextDecoration();
140     inherited_flags._cursor_style = initialCursor();
141 #if ENABLE(CURSOR_VISIBILITY)
142     inherited_flags.m_cursorVisibility = initialCursorVisibility();
143 #endif
144     inherited_flags._direction = initialDirection();
145     inherited_flags._white_space = initialWhiteSpace();
146     inherited_flags._border_collapse = initialBorderCollapse();
147     inherited_flags.m_rtlOrdering = initialRTLOrdering();
148     inherited_flags._box_direction = initialBoxDirection();
149     inherited_flags.m_printColorAdjust = initialPrintColorAdjust();
150     inherited_flags._pointerEvents = initialPointerEvents();
151     inherited_flags._insideLink = NotInsideLink;
152     inherited_flags._insideDefaultButton = false;
153     inherited_flags.m_writingMode = initialWritingMode();
154
155     static_assert((sizeof(InheritedFlags) <= 8), "InheritedFlags does not grow");
156     static_assert((sizeof(NonInheritedFlags) <= 8), "NonInheritedFlags does not grow");
157 }
158
159 ALWAYS_INLINE RenderStyle::RenderStyle(const RenderStyle& o)
160     : RefCounted<RenderStyle>()
161     , m_box(o.m_box)
162     , visual(o.visual)
163     , m_background(o.m_background)
164     , surround(o.surround)
165     , rareNonInheritedData(o.rareNonInheritedData)
166     , rareInheritedData(o.rareInheritedData)
167     , inherited(o.inherited)
168     , m_svgStyle(o.m_svgStyle)
169     , inherited_flags(o.inherited_flags)
170     , noninherited_flags(o.noninherited_flags)
171 {
172 }
173
174 ItemPosition RenderStyle::resolveAlignment(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForRenderer)
175 {
176     // The auto keyword computes to the parent's align-items computed value, or to "stretch", if not set or "auto".
177     if (childStyle.alignSelfPosition() == ItemPositionAuto)
178         return (parentStyle.alignItemsPosition() == ItemPositionAuto) ? resolvedAutoPositionForRenderer : parentStyle.alignItemsPosition();
179     return childStyle.alignSelfPosition();
180 }
181
182 ItemPosition RenderStyle::resolveJustification(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForLayoutObject)
183 {
184     if (childStyle.justifySelfPosition() == ItemPositionAuto)
185         return (parentStyle.justifyItemsPosition() == ItemPositionAuto) ? resolvedAutoPositionForLayoutObject : parentStyle.justifyItemsPosition();
186     return childStyle.justifySelfPosition();
187 }
188
189 void RenderStyle::inheritFrom(const RenderStyle* inheritParent, IsAtShadowBoundary isAtShadowBoundary)
190 {
191     if (isAtShadowBoundary == AtShadowBoundary) {
192         // Even if surrounding content is user-editable, shadow DOM should act as a single unit, and not necessarily be editable
193         EUserModify currentUserModify = userModify();
194         rareInheritedData = inheritParent->rareInheritedData;
195         setUserModify(currentUserModify);
196     } else
197         rareInheritedData = inheritParent->rareInheritedData;
198     inherited = inheritParent->inherited;
199     inherited_flags = inheritParent->inherited_flags;
200
201     if (m_svgStyle != inheritParent->m_svgStyle)
202         m_svgStyle.access()->inheritFrom(inheritParent->m_svgStyle.get());
203 }
204
205 void RenderStyle::copyNonInheritedFrom(const RenderStyle* other)
206 {
207     m_box = other->m_box;
208     visual = other->visual;
209     m_background = other->m_background;
210     surround = other->surround;
211     rareNonInheritedData = other->rareNonInheritedData;
212     noninherited_flags.copyNonInheritedFrom(other->noninherited_flags);
213
214     if (m_svgStyle != other->m_svgStyle)
215         m_svgStyle.access()->copyNonInheritedFrom(other->m_svgStyle.get());
216
217     ASSERT(zoom() == initialZoom());
218 }
219
220 bool RenderStyle::operator==(const RenderStyle& o) const
221 {
222     // compare everything except the pseudoStyle pointer
223     return inherited_flags == o.inherited_flags
224         && noninherited_flags == o.noninherited_flags
225         && m_box == o.m_box
226         && visual == o.visual
227         && m_background == o.m_background
228         && surround == o.surround
229         && rareNonInheritedData == o.rareNonInheritedData
230         && rareInheritedData == o.rareInheritedData
231         && inherited == o.inherited
232         && m_svgStyle == o.m_svgStyle
233             ;
234 }
235
236 bool RenderStyle::isStyleAvailable() const
237 {
238     return this != StyleResolver::styleNotYetAvailable();
239 }
240
241 bool RenderStyle::hasUniquePseudoStyle() const
242 {
243     if (!m_cachedPseudoStyles || styleType() != NOPSEUDO)
244         return false;
245
246     for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) {
247         RenderStyle* pseudoStyle = m_cachedPseudoStyles->at(i).get();
248         if (pseudoStyle->unique())
249             return true;
250     }
251
252     return false;
253 }
254
255 RenderStyle* RenderStyle::getCachedPseudoStyle(PseudoId pid) const
256 {
257     if (!m_cachedPseudoStyles || !m_cachedPseudoStyles->size())
258         return 0;
259
260     if (styleType() != NOPSEUDO) 
261         return 0;
262
263     for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) {
264         RenderStyle* pseudoStyle = m_cachedPseudoStyles->at(i).get();
265         if (pseudoStyle->styleType() == pid)
266             return pseudoStyle;
267     }
268
269     return 0;
270 }
271
272 RenderStyle* RenderStyle::addCachedPseudoStyle(PassRefPtr<RenderStyle> pseudo)
273 {
274     if (!pseudo)
275         return 0;
276
277     ASSERT(pseudo->styleType() > NOPSEUDO);
278
279     RenderStyle* result = pseudo.get();
280
281     if (!m_cachedPseudoStyles)
282         m_cachedPseudoStyles = std::make_unique<PseudoStyleCache>();
283
284     m_cachedPseudoStyles->append(pseudo);
285
286     return result;
287 }
288
289 void RenderStyle::removeCachedPseudoStyle(PseudoId pid)
290 {
291     if (!m_cachedPseudoStyles)
292         return;
293     for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) {
294         RenderStyle* pseudoStyle = m_cachedPseudoStyles->at(i).get();
295         if (pseudoStyle->styleType() == pid) {
296             m_cachedPseudoStyles->remove(i);
297             return;
298         }
299     }
300 }
301
302 bool RenderStyle::inheritedNotEqual(const RenderStyle* other) const
303 {
304     return inherited_flags != other->inherited_flags
305            || inherited != other->inherited
306            || m_svgStyle->inheritedNotEqual(other->m_svgStyle.get())
307            || rareInheritedData != other->rareInheritedData;
308 }
309
310 #if ENABLE(IOS_TEXT_AUTOSIZING)
311 inline unsigned computeFontHash(const FontCascade& font)
312 {
313     unsigned hashCodes[2] = {
314         CaseFoldingHash::hash(font.fontDescription().firstFamily().impl()),
315         static_cast<unsigned>(font.fontDescription().specifiedSize())
316     };
317     return StringHasher::computeHash(reinterpret_cast<UChar*>(hashCodes), 2 * sizeof(unsigned) / sizeof(UChar));
318 }
319
320 uint32_t RenderStyle::hashForTextAutosizing() const
321 {
322     // FIXME: Not a very smart hash. Could be improved upon. See <https://bugs.webkit.org/show_bug.cgi?id=121131>.
323     uint32_t hash = 0;
324     
325     hash ^= rareNonInheritedData->m_appearance;
326     hash ^= rareNonInheritedData->marginBeforeCollapse;
327     hash ^= rareNonInheritedData->marginAfterCollapse;
328     hash ^= rareNonInheritedData->lineClamp.value();
329     hash ^= rareInheritedData->overflowWrap;
330     hash ^= rareInheritedData->nbspMode;
331     hash ^= rareInheritedData->lineBreak;
332     hash ^= WTF::FloatHash<float>::hash(inherited->specifiedLineHeight.value());
333     hash ^= computeFontHash(inherited->fontCascade);
334     hash ^= inherited->horizontal_border_spacing;
335     hash ^= inherited->vertical_border_spacing;
336     hash ^= inherited_flags._box_direction;
337     hash ^= inherited_flags.m_rtlOrdering;
338     hash ^= noninherited_flags.position();
339     hash ^= noninherited_flags.floating();
340     hash ^= rareNonInheritedData->textOverflow;
341     hash ^= rareInheritedData->textSecurity;
342     return hash;
343 }
344
345 bool RenderStyle::equalForTextAutosizing(const RenderStyle* other) const
346 {
347     return rareNonInheritedData->m_appearance == other->rareNonInheritedData->m_appearance
348         && rareNonInheritedData->marginBeforeCollapse == other->rareNonInheritedData->marginBeforeCollapse
349         && rareNonInheritedData->marginAfterCollapse == other->rareNonInheritedData->marginAfterCollapse
350         && rareNonInheritedData->lineClamp == other->rareNonInheritedData->lineClamp
351         && rareInheritedData->textSizeAdjust == other->rareInheritedData->textSizeAdjust
352         && rareInheritedData->overflowWrap == other->rareInheritedData->overflowWrap
353         && rareInheritedData->nbspMode == other->rareInheritedData->nbspMode
354         && rareInheritedData->lineBreak == other->rareInheritedData->lineBreak
355         && rareInheritedData->textSecurity == other->rareInheritedData->textSecurity
356         && inherited->specifiedLineHeight == other->inherited->specifiedLineHeight
357         && inherited->fontCascade.equalForTextAutoSizing(other->inherited->fontCascade)
358         && inherited->horizontal_border_spacing == other->inherited->horizontal_border_spacing
359         && inherited->vertical_border_spacing == other->inherited->vertical_border_spacing
360         && inherited_flags._box_direction == other->inherited_flags._box_direction
361         && inherited_flags.m_rtlOrdering == other->inherited_flags.m_rtlOrdering
362         && noninherited_flags.position() == other->noninherited_flags.position()
363         && noninherited_flags.floating() == other->noninherited_flags.floating()
364         && rareNonInheritedData->textOverflow == other->rareNonInheritedData->textOverflow;
365 }
366 #endif // ENABLE(IOS_TEXT_AUTOSIZING)
367
368 bool RenderStyle::inheritedDataShared(const RenderStyle* other) const
369 {
370     // This is a fast check that only looks if the data structures are shared.
371     return inherited_flags == other->inherited_flags
372         && inherited.get() == other->inherited.get()
373         && m_svgStyle.get() == other->m_svgStyle.get()
374         && rareInheritedData.get() == other->rareInheritedData.get();
375 }
376
377 static bool positionChangeIsMovementOnly(const LengthBox& a, const LengthBox& b, const Length& width)
378 {
379     // If any unit types are different, then we can't guarantee
380     // that this was just a movement.
381     if (a.left().type() != b.left().type()
382         || a.right().type() != b.right().type()
383         || a.top().type() != b.top().type()
384         || a.bottom().type() != b.bottom().type())
385         return false;
386
387     // Only one unit can be non-auto in the horizontal direction and
388     // in the vertical direction.  Otherwise the adjustment of values
389     // is changing the size of the box.
390     if (!a.left().isIntrinsicOrAuto() && !a.right().isIntrinsicOrAuto())
391         return false;
392     if (!a.top().isIntrinsicOrAuto() && !a.bottom().isIntrinsicOrAuto())
393         return false;
394     // If our width is auto and left or right is specified then this 
395     // is not just a movement - we need to resize to our container.
396     if ((!a.left().isIntrinsicOrAuto() || !a.right().isIntrinsicOrAuto()) && width.isIntrinsicOrAuto())
397         return false;
398
399     // One of the units is fixed or percent in both directions and stayed
400     // that way in the new style.  Therefore all we are doing is moving.
401     return true;
402 }
403
404 inline bool RenderStyle::changeAffectsVisualOverflow(const RenderStyle& other) const
405 {
406     if (rareNonInheritedData.get() != other.rareNonInheritedData.get()
407         && !rareNonInheritedData->shadowDataEquivalent(*other.rareNonInheritedData.get()))
408         return true;
409
410     if (rareInheritedData.get() != other.rareInheritedData.get()
411         && !rareInheritedData->shadowDataEquivalent(*other.rareInheritedData.get()))
412         return true;
413
414     if (inherited_flags._text_decorations != other.inherited_flags._text_decorations
415         || visual->textDecoration != other.visual->textDecoration
416         || rareNonInheritedData->m_textDecorationStyle != other.rareNonInheritedData->m_textDecorationStyle) {
417         // Underlines are always drawn outside of their textbox bounds when text-underline-position: under;
418         // is specified. We can take an early out here.
419         if (textUnderlinePosition() == TextUnderlinePositionUnder
420             || other.textUnderlinePosition() == TextUnderlinePositionUnder)
421             return true;
422         return visualOverflowForDecorations(*this, nullptr) != visualOverflowForDecorations(other, nullptr);
423     }
424
425     return false;
426 }
427
428 bool RenderStyle::changeRequiresLayout(const RenderStyle& other, unsigned& changedContextSensitiveProperties) const
429 {
430     if (m_box->width() != other.m_box->width()
431         || m_box->minWidth() != other.m_box->minWidth()
432         || m_box->maxWidth() != other.m_box->maxWidth()
433         || m_box->height() != other.m_box->height()
434         || m_box->minHeight() != other.m_box->minHeight()
435         || m_box->maxHeight() != other.m_box->maxHeight())
436         return true;
437
438     if (m_box->verticalAlign() != other.m_box->verticalAlign() || noninherited_flags.verticalAlign() != other.noninherited_flags.verticalAlign())
439         return true;
440
441     if (m_box->boxSizing() != other.m_box->boxSizing())
442         return true;
443
444     if (surround->margin != other.surround->margin)
445         return true;
446
447     if (surround->padding != other.surround->padding)
448         return true;
449
450     // FIXME: We should add an optimized form of layout that just recomputes visual overflow.
451     if (changeAffectsVisualOverflow(other))
452         return true;
453
454     if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
455         if (rareNonInheritedData->m_appearance != other.rareNonInheritedData->m_appearance
456             || rareNonInheritedData->marginBeforeCollapse != other.rareNonInheritedData->marginBeforeCollapse
457             || rareNonInheritedData->marginAfterCollapse != other.rareNonInheritedData->marginAfterCollapse
458             || rareNonInheritedData->lineClamp != other.rareNonInheritedData->lineClamp
459             || rareNonInheritedData->m_initialLetter != other.rareNonInheritedData->m_initialLetter
460             || rareNonInheritedData->textOverflow != other.rareNonInheritedData->textOverflow)
461             return true;
462
463         if (rareNonInheritedData->m_regionFragment != other.rareNonInheritedData->m_regionFragment)
464             return true;
465
466 #if ENABLE(CSS_SHAPES)
467         if (rareNonInheritedData->m_shapeMargin != other.rareNonInheritedData->m_shapeMargin)
468             return true;
469 #endif
470
471         if (rareNonInheritedData->m_deprecatedFlexibleBox.get() != other.rareNonInheritedData->m_deprecatedFlexibleBox.get()
472             && *rareNonInheritedData->m_deprecatedFlexibleBox.get() != *other.rareNonInheritedData->m_deprecatedFlexibleBox.get())
473             return true;
474
475         if (rareNonInheritedData->m_flexibleBox.get() != other.rareNonInheritedData->m_flexibleBox.get()
476             && *rareNonInheritedData->m_flexibleBox.get() != *other.rareNonInheritedData->m_flexibleBox.get())
477             return true;
478         if (rareNonInheritedData->m_order != other.rareNonInheritedData->m_order
479             || rareNonInheritedData->m_alignContent != other.rareNonInheritedData->m_alignContent
480             || rareNonInheritedData->m_alignItems != other.rareNonInheritedData->m_alignItems
481             || rareNonInheritedData->m_alignSelf != other.rareNonInheritedData->m_alignSelf
482             || rareNonInheritedData->m_justifyContent != other.rareNonInheritedData->m_justifyContent)
483             return true;
484
485         if (!rareNonInheritedData->reflectionDataEquivalent(*other.rareNonInheritedData.get()))
486             return true;
487
488         if (rareNonInheritedData->m_multiCol.get() != other.rareNonInheritedData->m_multiCol.get()
489             && *rareNonInheritedData->m_multiCol.get() != *other.rareNonInheritedData->m_multiCol.get())
490             return true;
491
492         if (rareNonInheritedData->m_transform != other.rareNonInheritedData->m_transform) {
493             if (rareNonInheritedData->m_transform->hasTransform() != other.rareNonInheritedData->m_transform->hasTransform())
494                 return true;
495             if (*rareNonInheritedData->m_transform != *other.rareNonInheritedData->m_transform) {
496                 changedContextSensitiveProperties |= ContextSensitivePropertyTransform;
497                 // Don't return; keep looking for another change
498             }
499         }
500
501 #if ENABLE(CSS_GRID_LAYOUT)
502         if (rareNonInheritedData->m_grid.get() != other.rareNonInheritedData->m_grid.get()
503             || rareNonInheritedData->m_gridItem.get() != other.rareNonInheritedData->m_gridItem.get())
504             return true;
505 #endif
506
507 #if ENABLE(DASHBOARD_SUPPORT)
508         // If regions change, trigger a relayout to re-calc regions.
509         if (rareNonInheritedData->m_dashboardRegions != other.rareNonInheritedData->m_dashboardRegions)
510             return true;
511 #endif
512     }
513
514     if (rareInheritedData.get() != other.rareInheritedData.get()) {
515         if (rareInheritedData->indent != other.rareInheritedData->indent
516 #if ENABLE(CSS3_TEXT)
517             || rareInheritedData->m_textAlignLast != other.rareInheritedData->m_textAlignLast
518             || rareInheritedData->m_textJustify != other.rareInheritedData->m_textJustify
519             || rareInheritedData->m_textIndentLine != other.rareInheritedData->m_textIndentLine
520 #endif
521             || rareInheritedData->m_effectiveZoom != other.rareInheritedData->m_effectiveZoom
522 #if ENABLE(IOS_TEXT_AUTOSIZING)
523             || rareInheritedData->textSizeAdjust != other.rareInheritedData->textSizeAdjust
524 #endif
525             || rareInheritedData->wordBreak != other.rareInheritedData->wordBreak
526             || rareInheritedData->overflowWrap != other.rareInheritedData->overflowWrap
527             || rareInheritedData->nbspMode != other.rareInheritedData->nbspMode
528             || rareInheritedData->lineBreak != other.rareInheritedData->lineBreak
529             || rareInheritedData->textSecurity != other.rareInheritedData->textSecurity
530             || rareInheritedData->hyphens != other.rareInheritedData->hyphens
531             || rareInheritedData->hyphenationLimitBefore != other.rareInheritedData->hyphenationLimitBefore
532             || rareInheritedData->hyphenationLimitAfter != other.rareInheritedData->hyphenationLimitAfter
533             || rareInheritedData->hyphenationString != other.rareInheritedData->hyphenationString
534             || rareInheritedData->locale != other.rareInheritedData->locale
535             || rareInheritedData->m_rubyPosition != other.rareInheritedData->m_rubyPosition
536             || rareInheritedData->textEmphasisMark != other.rareInheritedData->textEmphasisMark
537             || rareInheritedData->textEmphasisPosition != other.rareInheritedData->textEmphasisPosition
538             || rareInheritedData->textEmphasisCustomMark != other.rareInheritedData->textEmphasisCustomMark
539             || rareInheritedData->m_textOrientation != other.rareInheritedData->m_textOrientation
540             || rareInheritedData->m_tabSize != other.rareInheritedData->m_tabSize
541             || rareInheritedData->m_lineBoxContain != other.rareInheritedData->m_lineBoxContain
542             || rareInheritedData->m_lineGrid != other.rareInheritedData->m_lineGrid
543 #if ENABLE(CSS_IMAGE_ORIENTATION)
544             || rareInheritedData->m_imageOrientation != other.rareInheritedData->m_imageOrientation
545 #endif
546 #if ENABLE(CSS_IMAGE_RESOLUTION)
547             || rareInheritedData->m_imageResolutionSource != other.rareInheritedData->m_imageResolutionSource
548             || rareInheritedData->m_imageResolutionSnap != other.rareInheritedData->m_imageResolutionSnap
549             || rareInheritedData->m_imageResolution != other.rareInheritedData->m_imageResolution
550 #endif
551             || rareInheritedData->m_lineSnap != other.rareInheritedData->m_lineSnap
552             || rareInheritedData->m_lineAlign != other.rareInheritedData->m_lineAlign
553 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
554             || rareInheritedData->useTouchOverflowScrolling != other.rareInheritedData->useTouchOverflowScrolling
555 #endif
556             || rareInheritedData->listStyleImage != other.rareInheritedData->listStyleImage)
557             return true;
558
559         if (textStrokeWidth() != other.textStrokeWidth())
560             return true;
561     }
562
563 #if ENABLE(TEXT_AUTOSIZING)
564     if (visual->m_textAutosizingMultiplier != other.visual->m_textAutosizingMultiplier)
565         return true;
566 #endif
567
568     if (inherited->line_height != other.inherited->line_height
569 #if ENABLE(IOS_TEXT_AUTOSIZING)
570         || inherited->specifiedLineHeight != other.inherited->specifiedLineHeight
571 #endif
572         || inherited->fontCascade != other.inherited->fontCascade
573         || inherited->horizontal_border_spacing != other.inherited->horizontal_border_spacing
574         || inherited->vertical_border_spacing != other.inherited->vertical_border_spacing
575         || inherited_flags._box_direction != other.inherited_flags._box_direction
576         || inherited_flags.m_rtlOrdering != other.inherited_flags.m_rtlOrdering
577         || noninherited_flags.position() != other.noninherited_flags.position()
578         || noninherited_flags.floating() != other.noninherited_flags.floating()
579         || noninherited_flags.originalDisplay() != other.noninherited_flags.originalDisplay())
580         return true;
581
582
583     if ((noninherited_flags.effectiveDisplay()) >= TABLE) {
584         if (inherited_flags._border_collapse != other.inherited_flags._border_collapse
585             || inherited_flags._empty_cells != other.inherited_flags._empty_cells
586             || inherited_flags._caption_side != other.inherited_flags._caption_side
587             || noninherited_flags.tableLayout() != other.noninherited_flags.tableLayout())
588             return true;
589
590         // In the collapsing border model, 'hidden' suppresses other borders, while 'none'
591         // does not, so these style differences can be width differences.
592         if (inherited_flags._border_collapse
593             && ((borderTopStyle() == BHIDDEN && other.borderTopStyle() == BNONE)
594                 || (borderTopStyle() == BNONE && other.borderTopStyle() == BHIDDEN)
595                 || (borderBottomStyle() == BHIDDEN && other.borderBottomStyle() == BNONE)
596                 || (borderBottomStyle() == BNONE && other.borderBottomStyle() == BHIDDEN)
597                 || (borderLeftStyle() == BHIDDEN && other.borderLeftStyle() == BNONE)
598                 || (borderLeftStyle() == BNONE && other.borderLeftStyle() == BHIDDEN)
599                 || (borderRightStyle() == BHIDDEN && other.borderRightStyle() == BNONE)
600                 || (borderRightStyle() == BNONE && other.borderRightStyle() == BHIDDEN)))
601             return true;
602     }
603
604     if (noninherited_flags.effectiveDisplay() == LIST_ITEM) {
605         if (inherited_flags._list_style_type != other.inherited_flags._list_style_type
606             || inherited_flags._list_style_position != other.inherited_flags._list_style_position)
607             return true;
608     }
609
610     if (inherited_flags._text_align != other.inherited_flags._text_align
611         || inherited_flags._text_transform != other.inherited_flags._text_transform
612         || inherited_flags._direction != other.inherited_flags._direction
613         || inherited_flags._white_space != other.inherited_flags._white_space
614         || noninherited_flags.clear() != other.noninherited_flags.clear()
615         || noninherited_flags.unicodeBidi() != other.noninherited_flags.unicodeBidi())
616         return true;
617
618     // Check block flow direction.
619     if (inherited_flags.m_writingMode != other.inherited_flags.m_writingMode)
620         return true;
621
622     // Check text combine mode.
623     if (rareNonInheritedData->m_textCombine != other.rareNonInheritedData->m_textCombine)
624         return true;
625
626     // Overflow returns a layout hint.
627     if (noninherited_flags.overflowX() != other.noninherited_flags.overflowX()
628         || noninherited_flags.overflowY() != other.noninherited_flags.overflowY())
629         return true;
630
631     // If our border widths change, then we need to layout.  Other changes to borders
632     // only necessitate a repaint.
633     if (borderLeftWidth() != other.borderLeftWidth()
634         || borderTopWidth() != other.borderTopWidth()
635         || borderBottomWidth() != other.borderBottomWidth()
636         || borderRightWidth() != other.borderRightWidth())
637         return true;
638
639     // If the counter directives change, trigger a relayout to re-calculate counter values and rebuild the counter node tree.
640     const CounterDirectiveMap* mapA = rareNonInheritedData->m_counterDirectives.get();
641     const CounterDirectiveMap* mapB = other.rareNonInheritedData->m_counterDirectives.get();
642     if (!(mapA == mapB || (mapA && mapB && *mapA == *mapB)))
643         return true;
644
645     if ((visibility() == COLLAPSE) != (other.visibility() == COLLAPSE))
646         return true;
647
648     if (rareNonInheritedData->hasOpacity() != other.rareNonInheritedData->hasOpacity()) {
649         // FIXME: We would like to use SimplifiedLayout here, but we can't quite do that yet.
650         // We need to make sure SimplifiedLayout can operate correctly on RenderInlines (we will need
651         // to add a selfNeedsSimplifiedLayout bit in order to not get confused and taint every line).
652         // In addition we need to solve the floating object issue when layers come and go. Right now
653         // a full layout is necessary to keep floating object lists sane.
654         return true;
655     }
656
657     if (rareNonInheritedData->hasFilters() != other.rareNonInheritedData->hasFilters())
658         return true;
659
660 #if ENABLE(FILTERS_LEVEL_2)
661     if (rareNonInheritedData->hasBackdropFilters() != other.rareNonInheritedData->hasBackdropFilters())
662         return true;
663 #endif
664
665     const QuotesData* quotesDataA = rareInheritedData->quotes.get();
666     const QuotesData* quotesDataB = other.rareInheritedData->quotes.get();
667     if (!(quotesDataA == quotesDataB || (quotesDataA && quotesDataB && *quotesDataA == *quotesDataB)))
668         return true;
669
670     if (position() != StaticPosition) {
671         if (surround->offset != other.surround->offset) {
672             // FIXME: We would like to use SimplifiedLayout for relative positioning, but we can't quite do that yet.
673             // We need to make sure SimplifiedLayout can operate correctly on RenderInlines (we will need
674             // to add a selfNeedsSimplifiedLayout bit in order to not get confused and taint every line).
675             if (position() != AbsolutePosition)
676                 return true;
677
678             // Optimize for the case where a positioned layer is moving but not changing size.
679             if (!positionChangeIsMovementOnly(surround->offset, other.surround->offset, m_box->width()))
680                 return true;
681         }
682     }
683     
684     return false;
685 }
686
687 bool RenderStyle::changeRequiresPositionedLayoutOnly(const RenderStyle& other, unsigned&) const
688 {
689     if (position() == StaticPosition)
690         return false;
691
692     if (surround->offset != other.surround->offset) {
693         // Optimize for the case where a positioned layer is moving but not changing size.
694         if (position() == AbsolutePosition && positionChangeIsMovementOnly(surround->offset, other.surround->offset, m_box->width()))
695             return true;
696     }
697     
698     return false;
699 }
700
701 bool RenderStyle::changeRequiresLayerRepaint(const RenderStyle& other, unsigned& changedContextSensitiveProperties) const
702 {
703     // StyleResolver has ensured that zIndex is non-auto only if it's applicable.
704     if (m_box->zIndex() != other.m_box->zIndex() || m_box->hasAutoZIndex() != other.m_box->hasAutoZIndex())
705         return true;
706
707     if (position() != StaticPosition) {
708         if (visual->clip != other.visual->clip || visual->hasClip != other.visual->hasClip) {
709             changedContextSensitiveProperties |= ContextSensitivePropertyClipRect;
710             return true;
711         }
712     }
713
714 #if ENABLE(CSS_COMPOSITING)
715     if (rareNonInheritedData->m_effectiveBlendMode != other.rareNonInheritedData->m_effectiveBlendMode)
716         return true;
717 #endif
718
719     if (rareNonInheritedData->opacity != other.rareNonInheritedData->opacity) {
720         changedContextSensitiveProperties |= ContextSensitivePropertyOpacity;
721         // Don't return; keep looking for another change.
722     }
723
724     if (rareNonInheritedData->m_filter.get() != other.rareNonInheritedData->m_filter.get()
725         && *rareNonInheritedData->m_filter.get() != *other.rareNonInheritedData->m_filter.get()) {
726         changedContextSensitiveProperties |= ContextSensitivePropertyFilter;
727         // Don't return; keep looking for another change.
728     }
729
730     if (rareNonInheritedData->m_mask != other.rareNonInheritedData->m_mask
731         || rareNonInheritedData->m_maskBoxImage != other.rareNonInheritedData->m_maskBoxImage)
732         return true;
733
734     return false;
735 }
736
737 bool RenderStyle::changeRequiresRepaint(const RenderStyle& other, unsigned& changedContextSensitiveProperties) const
738 {
739     if (inherited_flags._visibility != other.inherited_flags._visibility
740         || inherited_flags.m_printColorAdjust != other.inherited_flags.m_printColorAdjust
741         || inherited_flags._insideLink != other.inherited_flags._insideLink
742         || inherited_flags._insideDefaultButton != other.inherited_flags._insideDefaultButton
743         || surround->border != other.surround->border
744         || !m_background->isEquivalentForPainting(*other.m_background)
745         || rareInheritedData->userModify != other.rareInheritedData->userModify
746         || rareInheritedData->userSelect != other.rareInheritedData->userSelect
747         || rareNonInheritedData->userDrag != other.rareNonInheritedData->userDrag
748         || rareNonInheritedData->m_borderFit != other.rareNonInheritedData->m_borderFit
749         || rareNonInheritedData->m_objectFit != other.rareNonInheritedData->m_objectFit
750         || rareInheritedData->m_imageRendering != other.rareInheritedData->m_imageRendering)
751         return true;
752
753 #if ENABLE(CSS_SHAPES)
754     if (rareNonInheritedData->m_shapeOutside != other.rareNonInheritedData->m_shapeOutside)
755         return true;
756 #endif
757
758     // FIXME: this should probably be moved to changeRequiresLayerRepaint().
759     if (rareNonInheritedData->m_clipPath != other.rareNonInheritedData->m_clipPath) {
760         changedContextSensitiveProperties |= ContextSensitivePropertyClipPath;
761         // Don't return; keep looking for another change.
762     }
763
764     return false;
765 }
766
767 bool RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline(const RenderStyle& other, unsigned&) const
768 {
769     if (inherited->color != other.inherited->color
770         || inherited_flags._text_decorations != other.inherited_flags._text_decorations
771         || visual->textDecoration != other.visual->textDecoration
772         || rareNonInheritedData->m_textDecorationStyle != other.rareNonInheritedData->m_textDecorationStyle
773         || rareNonInheritedData->m_textDecorationColor != other.rareNonInheritedData->m_textDecorationColor
774         || rareInheritedData->m_textDecorationSkip != other.rareInheritedData->m_textDecorationSkip
775         || rareInheritedData->textFillColor != other.rareInheritedData->textFillColor
776         || rareInheritedData->textStrokeColor != other.rareInheritedData->textStrokeColor
777         || rareInheritedData->textEmphasisColor != other.rareInheritedData->textEmphasisColor
778         || rareInheritedData->textEmphasisFill != other.rareInheritedData->textEmphasisFill)
779         return true;
780
781     return false;
782 }
783
784 bool RenderStyle::changeRequiresRecompositeLayer(const RenderStyle& other, unsigned&) const
785 {
786     if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
787         if (rareNonInheritedData->m_transformStyle3D != other.rareNonInheritedData->m_transformStyle3D
788             || rareNonInheritedData->m_backfaceVisibility != other.rareNonInheritedData->m_backfaceVisibility
789             || rareNonInheritedData->m_perspective != other.rareNonInheritedData->m_perspective
790             || rareNonInheritedData->m_perspectiveOriginX != other.rareNonInheritedData->m_perspectiveOriginX
791             || rareNonInheritedData->m_perspectiveOriginY != other.rareNonInheritedData->m_perspectiveOriginY)
792             return true;
793     }
794
795     return false;
796 }
797
798 StyleDifference RenderStyle::diff(const RenderStyle& other, unsigned& changedContextSensitiveProperties) const
799 {
800     changedContextSensitiveProperties = ContextSensitivePropertyNone;
801
802     StyleDifference svgChange = StyleDifferenceEqual;
803     if (m_svgStyle != other.m_svgStyle) {
804         svgChange = m_svgStyle->diff(other.m_svgStyle.get());
805         if (svgChange == StyleDifferenceLayout)
806             return svgChange;
807     }
808
809     if (changeRequiresLayout(other, changedContextSensitiveProperties))
810         return StyleDifferenceLayout;
811
812     // SVGRenderStyle::diff() might have returned StyleDifferenceRepaint, eg. if fill changes.
813     // If eg. the font-size changed at the same time, we're not allowed to return StyleDifferenceRepaint,
814     // but have to return StyleDifferenceLayout, that's why  this if branch comes after all branches
815     // that are relevant for SVG and might return StyleDifferenceLayout.
816     if (svgChange != StyleDifferenceEqual)
817         return svgChange;
818
819     if (changeRequiresPositionedLayoutOnly(other, changedContextSensitiveProperties))
820         return StyleDifferenceLayoutPositionedMovementOnly;
821
822     if (changeRequiresLayerRepaint(other, changedContextSensitiveProperties))
823         return StyleDifferenceRepaintLayer;
824
825     if (changeRequiresRepaint(other, changedContextSensitiveProperties))
826         return StyleDifferenceRepaint;
827
828     if (changeRequiresRecompositeLayer(other, changedContextSensitiveProperties))
829         return StyleDifferenceRecompositeLayer;
830
831     if (changeRequiresRepaintIfTextOrBorderOrOutline(other, changedContextSensitiveProperties))
832         return StyleDifferenceRepaintIfTextOrBorderOrOutline;
833
834     // Cursors are not checked, since they will be set appropriately in response to mouse events,
835     // so they don't need to cause any repaint or layout.
836
837     // Animations don't need to be checked either.  We always set the new style on the RenderObject, so we will get a chance to fire off
838     // the resulting transition properly.
839     return StyleDifferenceEqual;
840 }
841
842 bool RenderStyle::diffRequiresLayerRepaint(const RenderStyle& style, bool isComposited) const
843 {
844     unsigned changedContextSensitiveProperties = 0;
845
846     if (changeRequiresRepaint(style, changedContextSensitiveProperties))
847         return true;
848
849     if (isComposited && changeRequiresLayerRepaint(style, changedContextSensitiveProperties))
850         return changedContextSensitiveProperties & ContextSensitivePropertyClipRect;
851
852     return false;
853 }
854     
855 void RenderStyle::setMaskImage(const Vector<RefPtr<MaskImageOperation>>& ops)
856 {
857     FillLayer* curLayer = &rareNonInheritedData.access()->m_mask;
858     while (curLayer) {
859         curLayer->setMaskImage(nullptr);
860         curLayer = curLayer->next();
861     }
862
863     curLayer = &rareNonInheritedData.access()->m_mask;
864     FillLayer* prevLayer = nullptr;
865     for (auto& maskImage : ops) {
866         if (!curLayer) {
867             prevLayer->setNext(std::make_unique<FillLayer>(MaskFillLayer));
868             curLayer = prevLayer->next();
869         }
870
871         curLayer->setMaskImage(maskImage);
872         prevLayer = curLayer;
873         curLayer = curLayer->next();
874     }
875 }
876
877 void RenderStyle::setClip(Length top, Length right, Length bottom, Length left)
878 {
879     StyleVisualData* data = visual.access();
880     data->clip.m_top = top;
881     data->clip.m_right = right;
882     data->clip.m_bottom = bottom;
883     data->clip.m_left = left;
884 }
885
886 void RenderStyle::addCursor(PassRefPtr<StyleImage> image, const IntPoint& hotSpot)
887 {
888     if (!rareInheritedData.access()->cursorData)
889         rareInheritedData.access()->cursorData = CursorList::create();
890     rareInheritedData.access()->cursorData->append(CursorData(image, hotSpot));
891 }
892
893 void RenderStyle::setCursorList(PassRefPtr<CursorList> other)
894 {
895     rareInheritedData.access()->cursorData = other;
896 }
897
898 void RenderStyle::setQuotes(PassRefPtr<QuotesData> q)
899 {
900     if (rareInheritedData->quotes == q || (rareInheritedData->quotes && q && *rareInheritedData->quotes == *q))
901         return;
902
903     rareInheritedData.access()->quotes = q;
904 }
905
906 void RenderStyle::clearCursorList()
907 {
908     if (rareInheritedData->cursorData)
909         rareInheritedData.access()->cursorData = 0;
910 }
911
912 void RenderStyle::clearContent()
913 {
914     if (rareNonInheritedData->m_content)
915         rareNonInheritedData.access()->m_content = nullptr;
916 }
917
918 void RenderStyle::appendContent(std::unique_ptr<ContentData> contentData)
919 {
920     auto& content = rareNonInheritedData.access()->m_content;
921     ContentData* lastContent = content.get();
922     while (lastContent && lastContent->next())
923         lastContent = lastContent->next();
924
925     if (lastContent)
926         lastContent->setNext(WTF::move(contentData));
927     else
928         content = WTF::move(contentData);
929 }
930
931 void RenderStyle::setContent(PassRefPtr<StyleImage> image, bool add)
932 {
933     if (!image)
934         return;
935         
936     if (add) {
937         appendContent(std::make_unique<ImageContentData>(image));
938         return;
939     }
940
941     rareNonInheritedData.access()->m_content = std::make_unique<ImageContentData>(image);
942     if (!rareNonInheritedData.access()->m_altText.isNull())
943         rareNonInheritedData.access()->m_content->setAltText(rareNonInheritedData.access()->m_altText);
944 }
945
946 void RenderStyle::setContent(const String& string, bool add)
947 {
948     auto& content = rareNonInheritedData.access()->m_content;
949     if (add) {
950         ContentData* lastContent = content.get();
951         while (lastContent && lastContent->next())
952             lastContent = lastContent->next();
953
954         if (lastContent) {
955             // We attempt to merge with the last ContentData if possible.
956             if (is<TextContentData>(*lastContent)) {
957                 TextContentData& textContent = downcast<TextContentData>(*lastContent);
958                 textContent.setText(textContent.text() + string);
959             } else
960                 lastContent->setNext(std::make_unique<TextContentData>(string));
961
962             if (!rareNonInheritedData.access()->m_altText.isNull())
963                 lastContent->setAltText(rareNonInheritedData.access()->m_altText);
964             return;
965         }
966     }
967
968     content = std::make_unique<TextContentData>(string);
969     if (!rareNonInheritedData.access()->m_altText.isNull())
970         content->setAltText(rareNonInheritedData.access()->m_altText);
971 }
972
973 void RenderStyle::setContent(std::unique_ptr<CounterContent> counter, bool add)
974 {
975     if (!counter)
976         return;
977
978     if (add) {
979         appendContent(std::make_unique<CounterContentData>(WTF::move(counter)));
980         return;
981     }
982
983     rareNonInheritedData.access()->m_content = std::make_unique<CounterContentData>(WTF::move(counter));
984 }
985
986 void RenderStyle::setContent(QuoteType quote, bool add)
987 {
988     if (add) {
989         appendContent(std::make_unique<QuoteContentData>(quote));
990         return;
991     }
992
993     rareNonInheritedData.access()->m_content = std::make_unique<QuoteContentData>(quote);
994 }
995
996 void RenderStyle::setContentAltText(const String& string)
997 {
998     rareNonInheritedData.access()->m_altText = string;
999     
1000     if (rareNonInheritedData.access()->m_content)
1001         rareNonInheritedData.access()->m_content->setAltText(string);
1002 }
1003
1004 const String& RenderStyle::contentAltText() const
1005 {
1006     return rareNonInheritedData->m_altText;
1007 }
1008
1009 // FIXME: use affectedByTransformOrigin().
1010 static inline bool requireTransformOrigin(const Vector<RefPtr<TransformOperation>>& transformOperations, RenderStyle::ApplyTransformOrigin applyOrigin)
1011 {
1012     // transform-origin brackets the transform with translate operations.
1013     // Optimize for the case where the only transform is a translation, since the transform-origin is irrelevant
1014     // in that case.
1015     if (applyOrigin != RenderStyle::IncludeTransformOrigin)
1016         return false;
1017
1018     for (auto& operation : transformOperations) {
1019         TransformOperation::OperationType type = operation->type();
1020         if (type != TransformOperation::TRANSLATE_X
1021             && type != TransformOperation::TRANSLATE_Y
1022             && type != TransformOperation::TRANSLATE 
1023             && type != TransformOperation::TRANSLATE_Z
1024             && type != TransformOperation::TRANSLATE_3D)
1025             return true;
1026     }
1027
1028     return false;
1029 }
1030
1031 void RenderStyle::applyTransform(TransformationMatrix& transform, const FloatRect& boundingBox, ApplyTransformOrigin applyOrigin) const
1032 {
1033     auto& operations = rareNonInheritedData->m_transform->m_operations.operations();
1034     bool applyTransformOrigin = requireTransformOrigin(operations, applyOrigin);
1035
1036     float offsetX = transformOriginX().isPercentNotCalculated() ? boundingBox.x() : 0;
1037     float offsetY = transformOriginY().isPercentNotCalculated() ? boundingBox.y() : 0;
1038
1039     if (applyTransformOrigin) {
1040         transform.translate3d(floatValueForLength(transformOriginX(), boundingBox.width()) + offsetX,
1041                               floatValueForLength(transformOriginY(), boundingBox.height()) + offsetY,
1042                               transformOriginZ());
1043     }
1044
1045     for (auto& operation : operations)
1046         operation->apply(transform, boundingBox.size());
1047
1048     if (applyTransformOrigin) {
1049         transform.translate3d(-floatValueForLength(transformOriginX(), boundingBox.width()) - offsetX,
1050                               -floatValueForLength(transformOriginY(), boundingBox.height()) - offsetY,
1051                               -transformOriginZ());
1052     }
1053 }
1054
1055 void RenderStyle::setPageScaleTransform(float scale)
1056 {
1057     if (scale == 1)
1058         return;
1059     TransformOperations transform;
1060     transform.operations().append(ScaleTransformOperation::create(scale, scale, ScaleTransformOperation::SCALE));
1061     setTransform(transform);
1062     setTransformOriginX(Length(0, Fixed));
1063     setTransformOriginY(Length(0, Fixed));
1064 }
1065
1066 void RenderStyle::setTextShadow(std::unique_ptr<ShadowData> shadowData, bool add)
1067 {
1068     ASSERT(!shadowData || (!shadowData->spread() && shadowData->style() == Normal));
1069
1070     StyleRareInheritedData* rareData = rareInheritedData.access();
1071     if (!add) {
1072         rareData->textShadow = WTF::move(shadowData);
1073         return;
1074     }
1075
1076     shadowData->setNext(WTF::move(rareData->textShadow));
1077     rareData->textShadow = WTF::move(shadowData);
1078 }
1079
1080 void RenderStyle::setBoxShadow(std::unique_ptr<ShadowData> shadowData, bool add)
1081 {
1082     StyleRareNonInheritedData* rareData = rareNonInheritedData.access();
1083     if (!add) {
1084         rareData->m_boxShadow = WTF::move(shadowData);
1085         return;
1086     }
1087
1088     shadowData->setNext(WTF::move(rareData->m_boxShadow));
1089     rareData->m_boxShadow = WTF::move(shadowData);
1090 }
1091
1092 static RoundedRect::Radii calcRadiiFor(const BorderData& border, const LayoutSize& size)
1093 {
1094     return RoundedRect::Radii(
1095         LayoutSize(valueForLength(border.topLeft().width(), size.width()),
1096             valueForLength(border.topLeft().height(), size.height())),
1097         LayoutSize(valueForLength(border.topRight().width(), size.width()),
1098             valueForLength(border.topRight().height(), size.height())),
1099         LayoutSize(valueForLength(border.bottomLeft().width(), size.width()),
1100             valueForLength(border.bottomLeft().height(), size.height())),
1101         LayoutSize(valueForLength(border.bottomRight().width(), size.width()),
1102             valueForLength(border.bottomRight().height(), size.height())));
1103 }
1104
1105 StyleImage* RenderStyle::listStyleImage() const { return rareInheritedData->listStyleImage.get(); }
1106 void RenderStyle::setListStyleImage(PassRefPtr<StyleImage> v)
1107 {
1108     if (rareInheritedData->listStyleImage != v)
1109         rareInheritedData.access()->listStyleImage = v;
1110 }
1111
1112 Color RenderStyle::color() const { return inherited->color; }
1113 Color RenderStyle::visitedLinkColor() const { return inherited->visitedLinkColor; }
1114 void RenderStyle::setColor(const Color& v) { SET_VAR(inherited, color, v); }
1115 void RenderStyle::setVisitedLinkColor(const Color& v) { SET_VAR(inherited, visitedLinkColor, v); }
1116
1117 short RenderStyle::horizontalBorderSpacing() const { return inherited->horizontal_border_spacing; }
1118 short RenderStyle::verticalBorderSpacing() const { return inherited->vertical_border_spacing; }
1119 void RenderStyle::setHorizontalBorderSpacing(short v) { SET_VAR(inherited, horizontal_border_spacing, v); }
1120 void RenderStyle::setVerticalBorderSpacing(short v) { SET_VAR(inherited, vertical_border_spacing, v); }
1121
1122 RoundedRect RenderStyle::getRoundedBorderFor(const LayoutRect& borderRect, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
1123 {
1124     RoundedRect roundedRect(borderRect);
1125     if (hasBorderRadius()) {
1126         RoundedRect::Radii radii = calcRadiiFor(surround->border, borderRect.size());
1127         radii.scale(calcBorderRadiiConstraintScaleFor(borderRect, radii));
1128         roundedRect.includeLogicalEdges(radii, isHorizontalWritingMode(), includeLogicalLeftEdge, includeLogicalRightEdge);
1129     }
1130     return roundedRect;
1131 }
1132
1133 RoundedRect RenderStyle::getRoundedInnerBorderFor(const LayoutRect& borderRect, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
1134 {
1135     bool horizontal = isHorizontalWritingMode();
1136
1137     LayoutUnit leftWidth = (!horizontal || includeLogicalLeftEdge) ? borderLeftWidth() : 0;
1138     LayoutUnit rightWidth = (!horizontal || includeLogicalRightEdge) ? borderRightWidth() : 0;
1139     LayoutUnit topWidth = (horizontal || includeLogicalLeftEdge) ? borderTopWidth() : 0;
1140     LayoutUnit bottomWidth = (horizontal || includeLogicalRightEdge) ? borderBottomWidth() : 0;
1141
1142     return getRoundedInnerBorderFor(borderRect, topWidth, bottomWidth, leftWidth, rightWidth, includeLogicalLeftEdge, includeLogicalRightEdge);
1143 }
1144
1145 RoundedRect RenderStyle::getRoundedInnerBorderFor(const LayoutRect& borderRect, LayoutUnit topWidth, LayoutUnit bottomWidth,
1146     LayoutUnit leftWidth, LayoutUnit rightWidth, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
1147 {
1148     LayoutRect innerRect(borderRect.x() + leftWidth, 
1149                borderRect.y() + topWidth, 
1150                borderRect.width() - leftWidth - rightWidth, 
1151                borderRect.height() - topWidth - bottomWidth);
1152
1153     RoundedRect roundedRect(innerRect);
1154
1155     if (hasBorderRadius()) {
1156         RoundedRect::Radii radii = getRoundedBorderFor(borderRect).radii();
1157         radii.shrink(topWidth, bottomWidth, leftWidth, rightWidth);
1158         roundedRect.includeLogicalEdges(radii, isHorizontalWritingMode(), includeLogicalLeftEdge, includeLogicalRightEdge);
1159     }
1160     return roundedRect;
1161 }
1162
1163 static bool allLayersAreFixed(const FillLayer* layer)
1164 {
1165     bool allFixed = true;
1166     
1167     for (const FillLayer* currLayer = layer; currLayer; currLayer = currLayer->next())
1168         allFixed &= (currLayer->image() && currLayer->attachment() == FixedBackgroundAttachment);
1169
1170     return layer && allFixed;
1171 }
1172
1173 bool RenderStyle::hasEntirelyFixedBackground() const
1174 {
1175     return allLayersAreFixed(backgroundLayers());
1176 }
1177
1178 const CounterDirectiveMap* RenderStyle::counterDirectives() const
1179 {
1180     return rareNonInheritedData->m_counterDirectives.get();
1181 }
1182
1183 CounterDirectiveMap& RenderStyle::accessCounterDirectives()
1184 {
1185     auto& map = rareNonInheritedData.access()->m_counterDirectives;
1186     if (!map)
1187         map = std::make_unique<CounterDirectiveMap>();
1188     return *map;
1189 }
1190
1191 const CounterDirectives RenderStyle::getCounterDirectives(const AtomicString& identifier) const
1192 {
1193     if (const CounterDirectiveMap* directives = counterDirectives())
1194         return directives->get(identifier);
1195     return CounterDirectives();
1196 }
1197
1198 const AtomicString& RenderStyle::hyphenString() const
1199 {
1200     ASSERT(hyphens() != HyphensNone);
1201
1202     const AtomicString& hyphenationString = rareInheritedData.get()->hyphenationString;
1203     if (!hyphenationString.isNull())
1204         return hyphenationString;
1205
1206     // FIXME: This should depend on locale.
1207     DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, hyphenMinusString, (&hyphenMinus, 1));
1208     DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, hyphenString, (&hyphen, 1));
1209     return fontCascade().primaryFont().glyphForCharacter(hyphen) ? hyphenString : hyphenMinusString;
1210 }
1211
1212 const AtomicString& RenderStyle::textEmphasisMarkString() const
1213 {
1214     switch (textEmphasisMark()) {
1215     case TextEmphasisMarkNone:
1216         return nullAtom;
1217     case TextEmphasisMarkCustom:
1218         return textEmphasisCustomMark();
1219     case TextEmphasisMarkDot: {
1220         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, filledDotString, (&bullet, 1));
1221         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, openDotString, (&whiteBullet, 1));
1222         return textEmphasisFill() == TextEmphasisFillFilled ? filledDotString : openDotString;
1223     }
1224     case TextEmphasisMarkCircle: {
1225         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, filledCircleString, (&blackCircle, 1));
1226         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, openCircleString, (&whiteCircle, 1));
1227         return textEmphasisFill() == TextEmphasisFillFilled ? filledCircleString : openCircleString;
1228     }
1229     case TextEmphasisMarkDoubleCircle: {
1230         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, filledDoubleCircleString, (&fisheye, 1));
1231         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, openDoubleCircleString, (&bullseye, 1));
1232         return textEmphasisFill() == TextEmphasisFillFilled ? filledDoubleCircleString : openDoubleCircleString;
1233     }
1234     case TextEmphasisMarkTriangle: {
1235         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, filledTriangleString, (&blackUpPointingTriangle, 1));
1236         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, openTriangleString, (&whiteUpPointingTriangle, 1));
1237         return textEmphasisFill() == TextEmphasisFillFilled ? filledTriangleString : openTriangleString;
1238     }
1239     case TextEmphasisMarkSesame: {
1240         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, filledSesameString, (&sesameDot, 1));
1241         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, openSesameString, (&whiteSesameDot, 1));
1242         return textEmphasisFill() == TextEmphasisFillFilled ? filledSesameString : openSesameString;
1243     }
1244     case TextEmphasisMarkAuto:
1245         ASSERT_NOT_REACHED();
1246         return nullAtom;
1247     }
1248
1249     ASSERT_NOT_REACHED();
1250     return nullAtom;
1251 }
1252
1253 #if ENABLE(DASHBOARD_SUPPORT)
1254 const Vector<StyleDashboardRegion>& RenderStyle::initialDashboardRegions()
1255 {
1256     DEPRECATED_DEFINE_STATIC_LOCAL(Vector<StyleDashboardRegion>, emptyList, ());
1257     return emptyList;
1258 }
1259
1260 const Vector<StyleDashboardRegion>& RenderStyle::noneDashboardRegions()
1261 {
1262     DEPRECATED_DEFINE_STATIC_LOCAL(Vector<StyleDashboardRegion>, noneList, ());
1263     static bool noneListInitialized = false;
1264
1265     if (!noneListInitialized) {
1266         StyleDashboardRegion region;
1267         region.label = "";
1268         region.offset.m_top  = Length();
1269         region.offset.m_right = Length();
1270         region.offset.m_bottom = Length();
1271         region.offset.m_left = Length();
1272         region.type = StyleDashboardRegion::None;
1273         noneList.append(region);
1274         noneListInitialized = true;
1275     }
1276     return noneList;
1277 }
1278 #endif
1279
1280 void RenderStyle::adjustAnimations()
1281 {
1282     AnimationList* animationList = rareNonInheritedData->m_animations.get();
1283     if (!animationList)
1284         return;
1285
1286     // Get rid of empty animations and anything beyond them
1287     for (size_t i = 0; i < animationList->size(); ++i) {
1288         if (animationList->animation(i).isEmpty()) {
1289             animationList->resize(i);
1290             break;
1291         }
1292     }
1293
1294     if (animationList->isEmpty()) {
1295         clearAnimations();
1296         return;
1297     }
1298
1299     // Repeat patterns into layers that don't have some properties set.
1300     animationList->fillUnsetProperties();
1301 }
1302
1303 void RenderStyle::adjustTransitions()
1304 {
1305     AnimationList* transitionList = rareNonInheritedData->m_transitions.get();
1306     if (!transitionList)
1307         return;
1308
1309     // Get rid of empty transitions and anything beyond them
1310     for (size_t i = 0; i < transitionList->size(); ++i) {
1311         if (transitionList->animation(i).isEmpty()) {
1312             transitionList->resize(i);
1313             break;
1314         }
1315     }
1316
1317     if (transitionList->isEmpty()) {
1318         clearTransitions();
1319         return;
1320     }
1321
1322     // Repeat patterns into layers that don't have some properties set.
1323     transitionList->fillUnsetProperties();
1324
1325     // Make sure there are no duplicate properties. This is an O(n^2) algorithm
1326     // but the lists tend to be very short, so it is probably ok
1327     for (size_t i = 0; i < transitionList->size(); ++i) {
1328         for (size_t j = i+1; j < transitionList->size(); ++j) {
1329             if (transitionList->animation(i).property() == transitionList->animation(j).property()) {
1330                 // toss i
1331                 transitionList->remove(i);
1332                 j = i;
1333             }
1334         }
1335     }
1336 }
1337
1338 AnimationList& RenderStyle::ensureAnimations()
1339 {
1340     if (!rareNonInheritedData.access()->m_animations)
1341         rareNonInheritedData.access()->m_animations = std::make_unique<AnimationList>();
1342     return *rareNonInheritedData->m_animations;
1343 }
1344
1345 AnimationList& RenderStyle::ensureTransitions()
1346 {
1347     if (!rareNonInheritedData.access()->m_transitions)
1348         rareNonInheritedData.access()->m_transitions = std::make_unique<AnimationList>();
1349     return *rareNonInheritedData->m_transitions;
1350 }
1351
1352 const Animation* RenderStyle::transitionForProperty(CSSPropertyID property) const
1353 {
1354     if (transitions()) {
1355         for (size_t i = 0; i < transitions()->size(); ++i) {
1356             const Animation& p = transitions()->animation(i);
1357             if (p.animationMode() == Animation::AnimateAll || p.property() == property) {
1358                 return &p;
1359             }
1360         }
1361     }
1362     return 0;
1363 }
1364
1365 const FontCascade& RenderStyle::fontCascade() const { return inherited->fontCascade; }
1366 const FontMetrics& RenderStyle::fontMetrics() const { return inherited->fontCascade.fontMetrics(); }
1367 const FontDescription& RenderStyle::fontDescription() const { return inherited->fontCascade.fontDescription(); }
1368 float RenderStyle::specifiedFontSize() const { return fontDescription().specifiedSize(); }
1369 float RenderStyle::computedFontSize() const { return fontDescription().computedSize(); }
1370 int RenderStyle::fontSize() const { return inherited->fontCascade.pixelSize(); }
1371
1372 const Length& RenderStyle::wordSpacing() const { return rareInheritedData->wordSpacing; }
1373 float RenderStyle::letterSpacing() const { return inherited->fontCascade.letterSpacing(); }
1374
1375 bool RenderStyle::setFontDescription(const FontDescription& v)
1376 {
1377     if (inherited->fontCascade.fontDescription() != v) {
1378         inherited.access()->fontCascade = FontCascade(v, inherited->fontCascade.letterSpacing(), inherited->fontCascade.wordSpacing());
1379         return true;
1380     }
1381     return false;
1382 }
1383
1384 #if ENABLE(IOS_TEXT_AUTOSIZING)
1385 const Length& RenderStyle::specifiedLineHeight() const { return inherited->specifiedLineHeight; }
1386 void RenderStyle::setSpecifiedLineHeight(Length v) { SET_VAR(inherited, specifiedLineHeight, v); }
1387 #else
1388 const Length& RenderStyle::specifiedLineHeight() const { return inherited->line_height; }
1389 #endif
1390
1391 Length RenderStyle::lineHeight() const
1392 {
1393     const Length& lh = inherited->line_height;
1394 #if ENABLE(TEXT_AUTOSIZING)
1395     // Unlike fontDescription().computedSize() and hence fontSize(), this is
1396     // recalculated on demand as we only store the specified line height.
1397     // FIXME: Should consider scaling the fixed part of any calc expressions
1398     // too, though this involves messily poking into CalcExpressionLength.
1399     float multiplier = textAutosizingMultiplier();
1400     if (multiplier > 1 && lh.isFixed())
1401         return Length(TextAutosizer::computeAutosizedFontSize(lh.value(), multiplier), Fixed);
1402 #endif
1403     return lh;
1404 }
1405 void RenderStyle::setLineHeight(Length specifiedLineHeight) { SET_VAR(inherited, line_height, specifiedLineHeight); }
1406
1407 int RenderStyle::computedLineHeight() const
1408 {
1409     const Length& lh = lineHeight();
1410
1411     // Negative value means the line height is not set. Use the font's built-in spacing.
1412     if (lh.isNegative())
1413         return fontMetrics().lineSpacing();
1414
1415     if (lh.isPercent())
1416         return minimumValueForLength(lh, fontSize());
1417
1418     return clampTo<int>(lh.value());
1419 }
1420
1421 void RenderStyle::setWordSpacing(Length value)
1422 {
1423     float fontWordSpacing;
1424     switch (value.type()) {
1425     case Auto:
1426         fontWordSpacing = 0;
1427         break;
1428     case Percent:
1429         fontWordSpacing = value.percent() * fontCascade().spaceWidth() / 100;
1430         break;
1431     case Fixed:
1432         fontWordSpacing = value.value();
1433         break;
1434     case Calculated:
1435         fontWordSpacing = value.nonNanCalculatedValue(maxValueForCssLength);
1436         break;
1437     default:
1438         ASSERT_NOT_REACHED();
1439         fontWordSpacing = 0;
1440         break;
1441     }
1442     inherited.access()->fontCascade.setWordSpacing(fontWordSpacing);
1443     rareInheritedData.access()->wordSpacing = WTF::move(value);
1444 }
1445
1446 void RenderStyle::setLetterSpacing(float v) { inherited.access()->fontCascade.setLetterSpacing(v); }
1447
1448 void RenderStyle::setFontSize(float size)
1449 {
1450     // size must be specifiedSize if Text Autosizing is enabled, but computedSize if text
1451     // zoom is enabled (if neither is enabled it's irrelevant as they're probably the same).
1452
1453     ASSERT(std::isfinite(size));
1454     if (!std::isfinite(size) || size < 0)
1455         size = 0;
1456     else
1457         size = std::min(maximumAllowedFontSize, size);
1458
1459     FontSelector* currentFontSelector = fontCascade().fontSelector();
1460     FontDescription desc(fontDescription());
1461     desc.setSpecifiedSize(size);
1462     desc.setComputedSize(size);
1463
1464 #if ENABLE(TEXT_AUTOSIZING)
1465     float multiplier = textAutosizingMultiplier();
1466     if (multiplier > 1) {
1467         float autosizedFontSize = TextAutosizer::computeAutosizedFontSize(size, multiplier);
1468         desc.setComputedSize(min(maximumAllowedFontSize, autosizedFontSize));
1469     }
1470 #endif
1471
1472     setFontDescription(desc);
1473     fontCascade().update(currentFontSelector);
1474 }
1475
1476 void RenderStyle::getShadowExtent(const ShadowData* shadow, LayoutUnit &top, LayoutUnit &right, LayoutUnit &bottom, LayoutUnit &left) const
1477 {
1478     top = 0;
1479     right = 0;
1480     bottom = 0;
1481     left = 0;
1482
1483     for ( ; shadow; shadow = shadow->next()) {
1484         if (shadow->style() == Inset)
1485             continue;
1486
1487         int extentAndSpread = shadow->paintingExtent() + shadow->spread();
1488         top = std::min<LayoutUnit>(top, shadow->y() - extentAndSpread);
1489         right = std::max<LayoutUnit>(right, shadow->x() + extentAndSpread);
1490         bottom = std::max<LayoutUnit>(bottom, shadow->y() + extentAndSpread);
1491         left = std::min<LayoutUnit>(left, shadow->x() - extentAndSpread);
1492     }
1493 }
1494
1495 LayoutBoxExtent RenderStyle::getShadowInsetExtent(const ShadowData* shadow) const
1496 {
1497     LayoutUnit top = 0;
1498     LayoutUnit right = 0;
1499     LayoutUnit bottom = 0;
1500     LayoutUnit left = 0;
1501
1502     for ( ; shadow; shadow = shadow->next()) {
1503         if (shadow->style() == Normal)
1504             continue;
1505
1506         int extentAndSpread = shadow->paintingExtent() + shadow->spread();
1507         top = std::max<LayoutUnit>(top, shadow->y() + extentAndSpread);
1508         right = std::min<LayoutUnit>(right, shadow->x() - extentAndSpread);
1509         bottom = std::min<LayoutUnit>(bottom, shadow->y() - extentAndSpread);
1510         left = std::max<LayoutUnit>(left, shadow->x() + extentAndSpread);
1511     }
1512
1513     return LayoutBoxExtent(top, right, bottom, left);
1514 }
1515
1516 void RenderStyle::getShadowHorizontalExtent(const ShadowData* shadow, LayoutUnit &left, LayoutUnit &right) const
1517 {
1518     left = 0;
1519     right = 0;
1520
1521     for ( ; shadow; shadow = shadow->next()) {
1522         if (shadow->style() == Inset)
1523             continue;
1524
1525         int extentAndSpread = shadow->paintingExtent() + shadow->spread();
1526         left = std::min<LayoutUnit>(left, shadow->x() - extentAndSpread);
1527         right = std::max<LayoutUnit>(right, shadow->x() + extentAndSpread);
1528     }
1529 }
1530
1531 void RenderStyle::getShadowVerticalExtent(const ShadowData* shadow, LayoutUnit &top, LayoutUnit &bottom) const
1532 {
1533     top = 0;
1534     bottom = 0;
1535
1536     for ( ; shadow; shadow = shadow->next()) {
1537         if (shadow->style() == Inset)
1538             continue;
1539
1540         int extentAndSpread = shadow->paintingExtent() + shadow->spread();
1541         top = std::min<LayoutUnit>(top, shadow->y() - extentAndSpread);
1542         bottom = std::max<LayoutUnit>(bottom, shadow->y() + extentAndSpread);
1543     }
1544 }
1545
1546 Color RenderStyle::colorIncludingFallback(int colorProperty, bool visitedLink) const
1547 {
1548     Color result;
1549     EBorderStyle borderStyle = BNONE;
1550     switch (colorProperty) {
1551     case CSSPropertyBackgroundColor:
1552         return visitedLink ? visitedLinkBackgroundColor() : backgroundColor(); // Background color doesn't fall back.
1553     case CSSPropertyBorderLeftColor:
1554         result = visitedLink ? visitedLinkBorderLeftColor() : borderLeftColor();
1555         borderStyle = borderLeftStyle();
1556         break;
1557     case CSSPropertyBorderRightColor:
1558         result = visitedLink ? visitedLinkBorderRightColor() : borderRightColor();
1559         borderStyle = borderRightStyle();
1560         break;
1561     case CSSPropertyBorderTopColor:
1562         result = visitedLink ? visitedLinkBorderTopColor() : borderTopColor();
1563         borderStyle = borderTopStyle();
1564         break;
1565     case CSSPropertyBorderBottomColor:
1566         result = visitedLink ? visitedLinkBorderBottomColor() : borderBottomColor();
1567         borderStyle = borderBottomStyle();
1568         break;
1569     case CSSPropertyColor:
1570         result = visitedLink ? visitedLinkColor() : color();
1571         break;
1572     case CSSPropertyOutlineColor:
1573         result = visitedLink ? visitedLinkOutlineColor() : outlineColor();
1574         break;
1575     case CSSPropertyColumnRuleColor:
1576         result = visitedLink ? visitedLinkColumnRuleColor() : columnRuleColor();
1577         break;
1578     case CSSPropertyWebkitTextDecorationColor:
1579         // Text decoration color fallback is handled in RenderObject::decorationColor.
1580         return visitedLink ? visitedLinkTextDecorationColor() : textDecorationColor();
1581     case CSSPropertyWebkitTextEmphasisColor:
1582         result = visitedLink ? visitedLinkTextEmphasisColor() : textEmphasisColor();
1583         break;
1584     case CSSPropertyWebkitTextFillColor:
1585         result = visitedLink ? visitedLinkTextFillColor() : textFillColor();
1586         break;
1587     case CSSPropertyWebkitTextStrokeColor:
1588         result = visitedLink ? visitedLinkTextStrokeColor() : textStrokeColor();
1589         break;
1590     default:
1591         ASSERT_NOT_REACHED();
1592         break;
1593     }
1594
1595     if (!result.isValid()) {
1596         if (!visitedLink && (borderStyle == INSET || borderStyle == OUTSET || borderStyle == RIDGE || borderStyle == GROOVE))
1597             result.setRGB(238, 238, 238);
1598         else
1599             result = visitedLink ? visitedLinkColor() : color();
1600     }
1601     return result;
1602 }
1603
1604 Color RenderStyle::visitedDependentColor(int colorProperty) const
1605 {
1606     Color unvisitedColor = colorIncludingFallback(colorProperty, false);
1607     if (insideLink() != InsideVisitedLink)
1608         return unvisitedColor;
1609
1610     Color visitedColor = colorIncludingFallback(colorProperty, true);
1611
1612     // Text decoration color validity is preserved (checked in RenderObject::decorationColor).
1613     if (colorProperty == CSSPropertyWebkitTextDecorationColor)
1614         return visitedColor;
1615
1616     // FIXME: Technically someone could explicitly specify the color transparent, but for now we'll just
1617     // assume that if the background color is transparent that it wasn't set. Note that it's weird that
1618     // we're returning unvisited info for a visited link, but given our restriction that the alpha values
1619     // have to match, it makes more sense to return the unvisited background color if specified than it
1620     // does to return black. This behavior matches what Firefox 4 does as well.
1621     if (colorProperty == CSSPropertyBackgroundColor && visitedColor == Color::transparent)
1622         return unvisitedColor;
1623
1624     // Take the alpha from the unvisited color, but get the RGB values from the visited color.
1625     return Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), unvisitedColor.alpha());
1626 }
1627
1628 const BorderValue& RenderStyle::borderBefore() const
1629 {
1630     switch (writingMode()) {
1631     case TopToBottomWritingMode:
1632         return borderTop();
1633     case BottomToTopWritingMode:
1634         return borderBottom();
1635     case LeftToRightWritingMode:
1636         return borderLeft();
1637     case RightToLeftWritingMode:
1638         return borderRight();
1639     }
1640     ASSERT_NOT_REACHED();
1641     return borderTop();
1642 }
1643
1644 const BorderValue& RenderStyle::borderAfter() const
1645 {
1646     switch (writingMode()) {
1647     case TopToBottomWritingMode:
1648         return borderBottom();
1649     case BottomToTopWritingMode:
1650         return borderTop();
1651     case LeftToRightWritingMode:
1652         return borderRight();
1653     case RightToLeftWritingMode:
1654         return borderLeft();
1655     }
1656     ASSERT_NOT_REACHED();
1657     return borderBottom();
1658 }
1659
1660 const BorderValue& RenderStyle::borderStart() const
1661 {
1662     if (isHorizontalWritingMode())
1663         return isLeftToRightDirection() ? borderLeft() : borderRight();
1664     return isLeftToRightDirection() ? borderTop() : borderBottom();
1665 }
1666
1667 const BorderValue& RenderStyle::borderEnd() const
1668 {
1669     if (isHorizontalWritingMode())
1670         return isLeftToRightDirection() ? borderRight() : borderLeft();
1671     return isLeftToRightDirection() ? borderBottom() : borderTop();
1672 }
1673
1674 float RenderStyle::borderBeforeWidth() const
1675 {
1676     switch (writingMode()) {
1677     case TopToBottomWritingMode:
1678         return borderTopWidth();
1679     case BottomToTopWritingMode:
1680         return borderBottomWidth();
1681     case LeftToRightWritingMode:
1682         return borderLeftWidth();
1683     case RightToLeftWritingMode:
1684         return borderRightWidth();
1685     }
1686     ASSERT_NOT_REACHED();
1687     return borderTopWidth();
1688 }
1689
1690 float RenderStyle::borderAfterWidth() const
1691 {
1692     switch (writingMode()) {
1693     case TopToBottomWritingMode:
1694         return borderBottomWidth();
1695     case BottomToTopWritingMode:
1696         return borderTopWidth();
1697     case LeftToRightWritingMode:
1698         return borderRightWidth();
1699     case RightToLeftWritingMode:
1700         return borderLeftWidth();
1701     }
1702     ASSERT_NOT_REACHED();
1703     return borderBottomWidth();
1704 }
1705
1706 float RenderStyle::borderStartWidth() const
1707 {
1708     if (isHorizontalWritingMode())
1709         return isLeftToRightDirection() ? borderLeftWidth() : borderRightWidth();
1710     return isLeftToRightDirection() ? borderTopWidth() : borderBottomWidth();
1711 }
1712
1713 float RenderStyle::borderEndWidth() const
1714 {
1715     if (isHorizontalWritingMode())
1716         return isLeftToRightDirection() ? borderRightWidth() : borderLeftWidth();
1717     return isLeftToRightDirection() ? borderBottomWidth() : borderTopWidth();
1718 }
1719
1720 void RenderStyle::setMarginStart(Length margin)
1721 {
1722     if (isHorizontalWritingMode()) {
1723         if (isLeftToRightDirection())
1724             setMarginLeft(margin);
1725         else
1726             setMarginRight(margin);
1727     } else {
1728         if (isLeftToRightDirection())
1729             setMarginTop(margin);
1730         else
1731             setMarginBottom(margin);
1732     }
1733 }
1734
1735 void RenderStyle::setMarginEnd(Length margin)
1736 {
1737     if (isHorizontalWritingMode()) {
1738         if (isLeftToRightDirection())
1739             setMarginRight(margin);
1740         else
1741             setMarginLeft(margin);
1742     } else {
1743         if (isLeftToRightDirection())
1744             setMarginBottom(margin);
1745         else
1746             setMarginTop(margin);
1747     }
1748 }
1749
1750 TextEmphasisMark RenderStyle::textEmphasisMark() const
1751 {
1752     TextEmphasisMark mark = static_cast<TextEmphasisMark>(rareInheritedData->textEmphasisMark);
1753     if (mark != TextEmphasisMarkAuto)
1754         return mark;
1755
1756     if (isHorizontalWritingMode())
1757         return TextEmphasisMarkDot;
1758
1759     return TextEmphasisMarkSesame;
1760 }
1761
1762 #if ENABLE(TOUCH_EVENTS)
1763 Color RenderStyle::initialTapHighlightColor()
1764 {
1765     return RenderTheme::tapHighlightColor();
1766 }
1767 #endif
1768
1769 LayoutBoxExtent RenderStyle::imageOutsets(const NinePieceImage& image) const
1770 {
1771     return LayoutBoxExtent(NinePieceImage::computeOutset(image.outset().top(), borderTopWidth()),
1772                            NinePieceImage::computeOutset(image.outset().right(), borderRightWidth()),
1773                            NinePieceImage::computeOutset(image.outset().bottom(), borderBottomWidth()),
1774                            NinePieceImage::computeOutset(image.outset().left(), borderLeftWidth()));
1775 }
1776
1777 void RenderStyle::getFontAndGlyphOrientation(FontOrientation& fontOrientation, NonCJKGlyphOrientation& glyphOrientation)
1778 {
1779     if (isHorizontalWritingMode()) {
1780         fontOrientation = Horizontal;
1781         glyphOrientation = NonCJKGlyphOrientationVerticalRight;
1782         return;
1783     }
1784
1785     switch (textOrientation()) {
1786     case TextOrientationVerticalRight:
1787         fontOrientation = Vertical;
1788         glyphOrientation = NonCJKGlyphOrientationVerticalRight;
1789         return;
1790     case TextOrientationUpright:
1791         fontOrientation = Vertical;
1792         glyphOrientation = NonCJKGlyphOrientationUpright;
1793         return;
1794     case TextOrientationSideways:
1795         if (writingMode() == LeftToRightWritingMode) {
1796             // FIXME: This should map to sideways-left, which is not supported yet.
1797             fontOrientation = Vertical;
1798             glyphOrientation = NonCJKGlyphOrientationVerticalRight;
1799             return;
1800         }
1801         fontOrientation = Horizontal;
1802         glyphOrientation = NonCJKGlyphOrientationVerticalRight;
1803         return;
1804     case TextOrientationSidewaysRight:
1805         fontOrientation = Horizontal;
1806         glyphOrientation = NonCJKGlyphOrientationVerticalRight;
1807         return;
1808     default:
1809         ASSERT_NOT_REACHED();
1810         fontOrientation = Horizontal;
1811         glyphOrientation = NonCJKGlyphOrientationVerticalRight;
1812         return;
1813     }
1814 }
1815
1816 void RenderStyle::setBorderImageSource(PassRefPtr<StyleImage> image)
1817 {
1818     if (surround->border.m_image.image() == image.get())
1819         return;
1820     surround.access()->border.m_image.setImage(image);
1821 }
1822
1823 void RenderStyle::setBorderImageSlices(LengthBox slices)
1824 {
1825     if (surround->border.m_image.imageSlices() == slices)
1826         return;
1827     surround.access()->border.m_image.setImageSlices(slices);
1828 }
1829
1830 void RenderStyle::setBorderImageWidth(LengthBox slices)
1831 {
1832     if (surround->border.m_image.borderSlices() == slices)
1833         return;
1834     surround.access()->border.m_image.setBorderSlices(slices);
1835 }
1836
1837 void RenderStyle::setBorderImageOutset(LengthBox outset)
1838 {
1839     if (surround->border.m_image.outset() == outset)
1840         return;
1841     surround.access()->border.m_image.setOutset(outset);
1842 }
1843
1844 void RenderStyle::setColumnStylesFromPaginationMode(const Pagination::Mode& paginationMode)
1845 {
1846     if (paginationMode == Pagination::Unpaginated)
1847         return;
1848     
1849     setColumnFill(ColumnFillAuto);
1850     
1851     switch (paginationMode) {
1852     case Pagination::LeftToRightPaginated:
1853         setColumnAxis(HorizontalColumnAxis);
1854         if (isHorizontalWritingMode())
1855             setColumnProgression(isLeftToRightDirection() ? NormalColumnProgression : ReverseColumnProgression);
1856         else
1857             setColumnProgression(isFlippedBlocksWritingMode() ? ReverseColumnProgression : NormalColumnProgression);
1858         break;
1859     case Pagination::RightToLeftPaginated:
1860         setColumnAxis(HorizontalColumnAxis);
1861         if (isHorizontalWritingMode())
1862             setColumnProgression(isLeftToRightDirection() ? ReverseColumnProgression : NormalColumnProgression);
1863         else
1864             setColumnProgression(isFlippedBlocksWritingMode() ? NormalColumnProgression : ReverseColumnProgression);
1865         break;
1866     case Pagination::TopToBottomPaginated:
1867         setColumnAxis(VerticalColumnAxis);
1868         if (isHorizontalWritingMode())
1869             setColumnProgression(isFlippedBlocksWritingMode() ? ReverseColumnProgression : NormalColumnProgression);
1870         else
1871             setColumnProgression(isLeftToRightDirection() ? NormalColumnProgression : ReverseColumnProgression);
1872         break;
1873     case Pagination::BottomToTopPaginated:
1874         setColumnAxis(VerticalColumnAxis);
1875         if (isHorizontalWritingMode())
1876             setColumnProgression(isFlippedBlocksWritingMode() ? NormalColumnProgression : ReverseColumnProgression);
1877         else
1878             setColumnProgression(isLeftToRightDirection() ? ReverseColumnProgression : NormalColumnProgression);
1879         break;
1880     case Pagination::Unpaginated:
1881         ASSERT_NOT_REACHED();
1882         break;
1883     }
1884 }
1885
1886 #if ENABLE(CSS_SCROLL_SNAP)
1887 LengthSize RenderStyle::initialScrollSnapDestination()
1888 {
1889     return defaultScrollSnapDestination();
1890 }
1891
1892 Vector<LengthSize> RenderStyle::initialScrollSnapCoordinates()
1893 {
1894     return Vector<LengthSize>();
1895 }
1896
1897 const ScrollSnapPoints* RenderStyle::scrollSnapPointsX() const
1898 {
1899     return rareNonInheritedData->m_scrollSnapPoints->xPoints.get();
1900 }
1901
1902 const ScrollSnapPoints* RenderStyle::scrollSnapPointsY() const
1903 {
1904     return rareNonInheritedData->m_scrollSnapPoints->yPoints.get();
1905 }
1906
1907 const LengthSize& RenderStyle::scrollSnapDestination() const
1908 {
1909     return rareNonInheritedData->m_scrollSnapPoints->destination;
1910 }
1911
1912 const Vector<LengthSize>& RenderStyle::scrollSnapCoordinates() const
1913 {
1914     return rareNonInheritedData->m_scrollSnapPoints->coordinates;
1915 }
1916
1917 void RenderStyle::setScrollSnapPointsX(std::unique_ptr<ScrollSnapPoints> points)
1918 {
1919     if (rareNonInheritedData->m_scrollSnapPoints->xPoints.get() == points.get())
1920         return;
1921     rareNonInheritedData.access()->m_scrollSnapPoints.access()->xPoints = WTF::move(points);
1922 }
1923
1924 void RenderStyle::setScrollSnapPointsY(std::unique_ptr<ScrollSnapPoints> points)
1925 {
1926     if (rareNonInheritedData->m_scrollSnapPoints->yPoints.get() == points.get())
1927         return;
1928     rareNonInheritedData.access()->m_scrollSnapPoints.access()->yPoints = WTF::move(points);
1929 }
1930
1931 void RenderStyle::setScrollSnapDestination(LengthSize destination)
1932 {
1933     if (rareNonInheritedData->m_scrollSnapPoints->destination == destination)
1934         return;
1935     rareNonInheritedData.access()->m_scrollSnapPoints.access()->destination = WTF::move(destination);
1936 }
1937
1938 void RenderStyle::setScrollSnapCoordinates(Vector<LengthSize> coordinates)
1939 {
1940     if (rareNonInheritedData->m_scrollSnapPoints->coordinates == coordinates)
1941         return;
1942     rareNonInheritedData.access()->m_scrollSnapPoints.access()->coordinates = WTF::move(coordinates);
1943 }
1944
1945 #endif
1946
1947 } // namespace WebCore