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