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