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