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