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.
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.
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.
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.
24 #include "RenderStyle.h"
26 #include "ContentData.h"
27 #include "CursorList.h"
28 #include "CSSPropertyNames.h"
30 #include "FontSelector.h"
31 #include "Pagination.h"
32 #include "QuotesData.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"
42 #include <wtf/MathExtras.h>
43 #include <wtf/StdLibExtras.h>
46 #if ENABLE(IOS_TEXT_AUTOSIZING)
47 #include <wtf/text/StringHash.h>
50 #if ENABLE(TEXT_AUTOSIZING)
51 #include "TextAutosizer.h"
56 struct SameSizeAsBorderValue {
61 COMPILE_ASSERT(sizeof(BorderValue) == sizeof(SameSizeAsBorderValue), BorderValue_should_not_grow);
63 struct SameSizeAsRenderStyle : public RefCounted<SameSizeAsRenderStyle> {
67 void* dataRefSvgStyle;
69 struct InheritedFlags {
70 unsigned m_bitfields[2];
73 struct NonInheritedFlags {
74 unsigned m_bitfields[2];
78 COMPILE_ASSERT(sizeof(RenderStyle) == sizeof(SameSizeAsRenderStyle), RenderStyle_should_stay_small);
80 inline RenderStyle& defaultStyle()
82 static RenderStyle& style = RenderStyle::createDefaultStyle().leakRef();
86 PassRef<RenderStyle> RenderStyle::create()
88 return adoptRef(*new RenderStyle());
91 PassRef<RenderStyle> RenderStyle::createDefaultStyle()
93 return adoptRef(*new RenderStyle(true));
96 PassRef<RenderStyle> RenderStyle::createAnonymousStyleWithDisplay(const RenderStyle* parentStyle, EDisplay display)
98 auto newStyle = RenderStyle::create();
99 newStyle.get().inheritFrom(parentStyle);
100 newStyle.get().inheritUnicodeBidiFrom(parentStyle);
101 newStyle.get().setDisplay(display);
105 PassRef<RenderStyle> RenderStyle::clone(const RenderStyle* other)
107 return adoptRef(*new RenderStyle(*other));
110 ALWAYS_INLINE RenderStyle::RenderStyle()
111 : m_box(defaultStyle().m_box)
112 , visual(defaultStyle().visual)
113 , m_background(defaultStyle().m_background)
114 , surround(defaultStyle().surround)
115 , rareNonInheritedData(defaultStyle().rareNonInheritedData)
116 , rareInheritedData(defaultStyle().rareInheritedData)
117 , inherited(defaultStyle().inherited)
119 , m_svgStyle(defaultStyle().m_svgStyle)
122 setBitDefaults(); // Would it be faster to copy this from the default style?
123 COMPILE_ASSERT((sizeof(InheritedFlags) <= 8), InheritedFlags_does_not_grow);
124 COMPILE_ASSERT((sizeof(NonInheritedFlags) <= 8), NonInheritedFlags_does_not_grow);
127 ALWAYS_INLINE RenderStyle::RenderStyle(bool)
128 : m_box(StyleBoxData::create())
129 , visual(StyleVisualData::create())
130 , m_background(StyleBackgroundData::create())
131 , surround(StyleSurroundData::create())
132 , rareNonInheritedData(StyleRareNonInheritedData::create())
133 , rareInheritedData(StyleRareInheritedData::create())
134 , inherited(StyleInheritedData::create())
136 , m_svgStyle(SVGRenderStyle::create())
142 ALWAYS_INLINE RenderStyle::RenderStyle(const RenderStyle& o)
143 : RefCounted<RenderStyle>()
146 , m_background(o.m_background)
147 , surround(o.surround)
148 , rareNonInheritedData(o.rareNonInheritedData)
149 , rareInheritedData(o.rareInheritedData)
150 , inherited(o.inherited)
152 , m_svgStyle(o.m_svgStyle)
154 , inherited_flags(o.inherited_flags)
155 , noninherited_flags(o.noninherited_flags)
159 void RenderStyle::inheritFrom(const RenderStyle* inheritParent, IsAtShadowBoundary isAtShadowBoundary)
161 if (isAtShadowBoundary == AtShadowBoundary) {
162 // Even if surrounding content is user-editable, shadow DOM should act as a single unit, and not necessarily be editable
163 EUserModify currentUserModify = userModify();
164 rareInheritedData = inheritParent->rareInheritedData;
165 setUserModify(currentUserModify);
167 rareInheritedData = inheritParent->rareInheritedData;
168 inherited = inheritParent->inherited;
169 inherited_flags = inheritParent->inherited_flags;
171 if (m_svgStyle != inheritParent->m_svgStyle)
172 m_svgStyle.access()->inheritFrom(inheritParent->m_svgStyle.get());
176 void RenderStyle::copyNonInheritedFrom(const RenderStyle* other)
178 m_box = other->m_box;
179 visual = other->visual;
180 m_background = other->m_background;
181 surround = other->surround;
182 rareNonInheritedData = other->rareNonInheritedData;
183 // The flags are copied one-by-one because noninherited_flags contains a bunch of stuff other than real style data.
184 noninherited_flags._effectiveDisplay = other->noninherited_flags._effectiveDisplay;
185 noninherited_flags._originalDisplay = other->noninherited_flags._originalDisplay;
186 noninherited_flags._overflowX = other->noninherited_flags._overflowX;
187 noninherited_flags._overflowY = other->noninherited_flags._overflowY;
188 noninherited_flags._vertical_align = other->noninherited_flags._vertical_align;
189 noninherited_flags._clear = other->noninherited_flags._clear;
190 noninherited_flags._position = other->noninherited_flags._position;
191 noninherited_flags._floating = other->noninherited_flags._floating;
192 noninherited_flags._table_layout = other->noninherited_flags._table_layout;
193 noninherited_flags._unicodeBidi = other->noninherited_flags._unicodeBidi;
194 noninherited_flags._page_break_before = other->noninherited_flags._page_break_before;
195 noninherited_flags._page_break_after = other->noninherited_flags._page_break_after;
196 noninherited_flags._page_break_inside = other->noninherited_flags._page_break_inside;
197 noninherited_flags.explicitInheritance = other->noninherited_flags.explicitInheritance;
199 if (m_svgStyle != other->m_svgStyle)
200 m_svgStyle.access()->copyNonInheritedFrom(other->m_svgStyle.get());
202 ASSERT(zoom() == initialZoom());
205 bool RenderStyle::operator==(const RenderStyle& o) const
207 // compare everything except the pseudoStyle pointer
208 return inherited_flags == o.inherited_flags
209 && noninherited_flags == o.noninherited_flags
211 && visual == o.visual
212 && m_background == o.m_background
213 && surround == o.surround
214 && rareNonInheritedData == o.rareNonInheritedData
215 && rareInheritedData == o.rareInheritedData
216 && inherited == o.inherited
218 && m_svgStyle == o.m_svgStyle
223 bool RenderStyle::isStyleAvailable() const
225 return this != StyleResolver::styleNotYetAvailable();
228 bool RenderStyle::hasUniquePseudoStyle() const
230 if (!m_cachedPseudoStyles || styleType() != NOPSEUDO)
233 for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) {
234 RenderStyle* pseudoStyle = m_cachedPseudoStyles->at(i).get();
235 if (pseudoStyle->unique())
242 RenderStyle* RenderStyle::getCachedPseudoStyle(PseudoId pid) const
244 if (!m_cachedPseudoStyles || !m_cachedPseudoStyles->size())
247 if (styleType() != NOPSEUDO)
250 for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) {
251 RenderStyle* pseudoStyle = m_cachedPseudoStyles->at(i).get();
252 if (pseudoStyle->styleType() == pid)
259 RenderStyle* RenderStyle::addCachedPseudoStyle(PassRefPtr<RenderStyle> pseudo)
264 ASSERT(pseudo->styleType() > NOPSEUDO);
266 RenderStyle* result = pseudo.get();
268 if (!m_cachedPseudoStyles)
269 m_cachedPseudoStyles = adoptPtr(new PseudoStyleCache);
271 m_cachedPseudoStyles->append(pseudo);
276 void RenderStyle::removeCachedPseudoStyle(PseudoId pid)
278 if (!m_cachedPseudoStyles)
280 for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) {
281 RenderStyle* pseudoStyle = m_cachedPseudoStyles->at(i).get();
282 if (pseudoStyle->styleType() == pid) {
283 m_cachedPseudoStyles->remove(i);
289 bool RenderStyle::inheritedNotEqual(const RenderStyle* other) const
291 return inherited_flags != other->inherited_flags
292 || inherited != other->inherited
294 || m_svgStyle->inheritedNotEqual(other->m_svgStyle.get())
296 || rareInheritedData != other->rareInheritedData;
299 #if ENABLE(IOS_TEXT_AUTOSIZING)
300 inline unsigned computeFontHash(const Font& font)
302 unsigned hashCodes[2] = {
303 CaseFoldingHash::hash(font.fontDescription().firstFamily().impl()),
304 static_cast<unsigned>(font.fontDescription().specifiedSize())
306 return StringHasher::computeHash(reinterpret_cast<UChar*>(hashCodes), 2 * sizeof(unsigned) / sizeof(UChar));
309 uint32_t RenderStyle::hashForTextAutosizing() const
311 // FIXME: Not a very smart hash. Could be improved upon. See <https://bugs.webkit.org/show_bug.cgi?id=121131>.
314 hash ^= rareNonInheritedData->m_appearance;
315 hash ^= rareNonInheritedData->marginBeforeCollapse;
316 hash ^= rareNonInheritedData->marginAfterCollapse;
317 hash ^= rareNonInheritedData->lineClamp.value();
318 hash ^= rareInheritedData->overflowWrap;
319 hash ^= rareInheritedData->nbspMode;
320 hash ^= rareInheritedData->lineBreak;
321 hash ^= WTF::FloatHash<float>::hash(inherited->specifiedLineHeight.value());
322 hash ^= computeFontHash(inherited->font);
323 hash ^= inherited->horizontal_border_spacing;
324 hash ^= inherited->vertical_border_spacing;
325 hash ^= inherited_flags._box_direction;
326 hash ^= inherited_flags.m_rtlOrdering;
327 hash ^= noninherited_flags._position;
328 hash ^= noninherited_flags._floating;
329 hash ^= rareNonInheritedData->textOverflow;
330 hash ^= rareInheritedData->textSecurity;
334 bool RenderStyle::equalForTextAutosizing(const RenderStyle* other) const
336 return rareNonInheritedData->m_appearance == other->rareNonInheritedData->m_appearance
337 && rareNonInheritedData->marginBeforeCollapse == other->rareNonInheritedData->marginBeforeCollapse
338 && rareNonInheritedData->marginAfterCollapse == other->rareNonInheritedData->marginAfterCollapse
339 && rareNonInheritedData->lineClamp == other->rareNonInheritedData->lineClamp
340 && rareInheritedData->textSizeAdjust == other->rareInheritedData->textSizeAdjust
341 && rareInheritedData->overflowWrap == other->rareInheritedData->overflowWrap
342 && rareInheritedData->nbspMode == other->rareInheritedData->nbspMode
343 && rareInheritedData->lineBreak == other->rareInheritedData->lineBreak
344 && rareInheritedData->textSecurity == other->rareInheritedData->textSecurity
345 && inherited->specifiedLineHeight == other->inherited->specifiedLineHeight
346 && inherited->font.equalForTextAutoSizing(other->inherited->font)
347 && inherited->horizontal_border_spacing == other->inherited->horizontal_border_spacing
348 && inherited->vertical_border_spacing == other->inherited->vertical_border_spacing
349 && inherited_flags._box_direction == other->inherited_flags._box_direction
350 && inherited_flags.m_rtlOrdering == other->inherited_flags.m_rtlOrdering
351 && noninherited_flags._position == other->noninherited_flags._position
352 && noninherited_flags._floating == other->noninherited_flags._floating
353 && rareNonInheritedData->textOverflow == other->rareNonInheritedData->textOverflow;
355 #endif // ENABLE(IOS_TEXT_AUTOSIZING)
357 bool RenderStyle::inheritedDataShared(const RenderStyle* other) const
359 // This is a fast check that only looks if the data structures are shared.
360 return inherited_flags == other->inherited_flags
361 && inherited.get() == other->inherited.get()
363 && m_svgStyle.get() == other->m_svgStyle.get()
365 && rareInheritedData.get() == other->rareInheritedData.get();
368 static bool positionChangeIsMovementOnly(const LengthBox& a, const LengthBox& b, const Length& width)
370 // If any unit types are different, then we can't guarantee
371 // that this was just a movement.
372 if (a.left().type() != b.left().type()
373 || a.right().type() != b.right().type()
374 || a.top().type() != b.top().type()
375 || a.bottom().type() != b.bottom().type())
378 // Only one unit can be non-auto in the horizontal direction and
379 // in the vertical direction. Otherwise the adjustment of values
380 // is changing the size of the box.
381 if (!a.left().isIntrinsicOrAuto() && !a.right().isIntrinsicOrAuto())
383 if (!a.top().isIntrinsicOrAuto() && !a.bottom().isIntrinsicOrAuto())
385 // If our width is auto and left or right is specified then this
386 // is not just a movement - we need to resize to our container.
387 if ((!a.left().isIntrinsicOrAuto() || !a.right().isIntrinsicOrAuto()) && width.isIntrinsicOrAuto())
390 // One of the units is fixed or percent in both directions and stayed
391 // that way in the new style. Therefore all we are doing is moving.
395 bool RenderStyle::changeRequiresLayout(const RenderStyle* other, unsigned& changedContextSensitiveProperties) const
397 if (m_box->width() != other->m_box->width()
398 || m_box->minWidth() != other->m_box->minWidth()
399 || m_box->maxWidth() != other->m_box->maxWidth()
400 || m_box->height() != other->m_box->height()
401 || m_box->minHeight() != other->m_box->minHeight()
402 || m_box->maxHeight() != other->m_box->maxHeight())
405 if (m_box->verticalAlign() != other->m_box->verticalAlign() || noninherited_flags._vertical_align != other->noninherited_flags._vertical_align)
408 if (m_box->boxSizing() != other->m_box->boxSizing())
411 if (surround->margin != other->surround->margin)
414 if (surround->padding != other->surround->padding)
417 if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) {
418 if (rareNonInheritedData->m_appearance != other->rareNonInheritedData->m_appearance
419 || rareNonInheritedData->marginBeforeCollapse != other->rareNonInheritedData->marginBeforeCollapse
420 || rareNonInheritedData->marginAfterCollapse != other->rareNonInheritedData->marginAfterCollapse
421 || rareNonInheritedData->lineClamp != other->rareNonInheritedData->lineClamp
422 || rareNonInheritedData->textOverflow != other->rareNonInheritedData->textOverflow)
425 if (rareNonInheritedData->m_regionFragment != other->rareNonInheritedData->m_regionFragment)
428 if (rareNonInheritedData->m_wrapFlow != other->rareNonInheritedData->m_wrapFlow
429 || rareNonInheritedData->m_wrapThrough != other->rareNonInheritedData->m_wrapThrough)
432 #if ENABLE(CSS_SHAPES)
433 if (rareNonInheritedData->m_shapeMargin != other->rareNonInheritedData->m_shapeMargin
434 || rareNonInheritedData->m_shapePadding != other->rareNonInheritedData->m_shapePadding)
438 if (rareNonInheritedData->m_deprecatedFlexibleBox.get() != other->rareNonInheritedData->m_deprecatedFlexibleBox.get()
439 && *rareNonInheritedData->m_deprecatedFlexibleBox.get() != *other->rareNonInheritedData->m_deprecatedFlexibleBox.get())
442 if (rareNonInheritedData->m_flexibleBox.get() != other->rareNonInheritedData->m_flexibleBox.get()
443 && *rareNonInheritedData->m_flexibleBox.get() != *other->rareNonInheritedData->m_flexibleBox.get())
445 if (rareNonInheritedData->m_order != other->rareNonInheritedData->m_order
446 || rareNonInheritedData->m_alignContent != other->rareNonInheritedData->m_alignContent
447 || rareNonInheritedData->m_alignItems != other->rareNonInheritedData->m_alignItems
448 || rareNonInheritedData->m_alignSelf != other->rareNonInheritedData->m_alignSelf
449 || rareNonInheritedData->m_justifyContent != other->rareNonInheritedData->m_justifyContent)
452 // FIXME: We should add an optimized form of layout that just recomputes visual overflow.
453 if (!rareNonInheritedData->shadowDataEquivalent(*other->rareNonInheritedData.get()))
456 if (!rareNonInheritedData->reflectionDataEquivalent(*other->rareNonInheritedData.get()))
459 if (rareNonInheritedData->m_multiCol.get() != other->rareNonInheritedData->m_multiCol.get()
460 && *rareNonInheritedData->m_multiCol.get() != *other->rareNonInheritedData->m_multiCol.get())
463 if (rareNonInheritedData->m_transform.get() != other->rareNonInheritedData->m_transform.get()
464 && *rareNonInheritedData->m_transform.get() != *other->rareNonInheritedData->m_transform.get()) {
465 #if USE(ACCELERATED_COMPOSITING)
466 changedContextSensitiveProperties |= ContextSensitivePropertyTransform;
467 // Don't return; keep looking for another change
469 UNUSED_PARAM(changedContextSensitiveProperties);
474 if (rareNonInheritedData->m_grid.get() != other->rareNonInheritedData->m_grid.get()
475 || rareNonInheritedData->m_gridItem.get() != other->rareNonInheritedData->m_gridItem.get())
478 #if !USE(ACCELERATED_COMPOSITING)
479 if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) {
480 if (rareNonInheritedData->m_transformStyle3D != other->rareNonInheritedData->m_transformStyle3D
481 || rareNonInheritedData->m_backfaceVisibility != other->rareNonInheritedData->m_backfaceVisibility
482 || rareNonInheritedData->m_perspective != other->rareNonInheritedData->m_perspective
483 || rareNonInheritedData->m_perspectiveOriginX != other->rareNonInheritedData->m_perspectiveOriginX
484 || rareNonInheritedData->m_perspectiveOriginY != other->rareNonInheritedData->m_perspectiveOriginY)
489 #if ENABLE(DASHBOARD_SUPPORT)
490 // If regions change, trigger a relayout to re-calc regions.
491 if (rareNonInheritedData->m_dashboardRegions != other->rareNonInheritedData->m_dashboardRegions)
495 #if ENABLE(CSS_SHAPES)
496 if (rareNonInheritedData->m_shapeInside != other->rareNonInheritedData->m_shapeInside)
501 if (rareInheritedData.get() != other->rareInheritedData.get()) {
502 if (rareInheritedData->highlight != other->rareInheritedData->highlight
503 || rareInheritedData->indent != other->rareInheritedData->indent
504 #if ENABLE(CSS3_TEXT)
505 || rareInheritedData->m_textAlignLast != other->rareInheritedData->m_textAlignLast
506 || rareInheritedData->m_textIndentLine != other->rareInheritedData->m_textIndentLine
508 || rareInheritedData->m_effectiveZoom != other->rareInheritedData->m_effectiveZoom
509 #if ENABLE(IOS_TEXT_AUTOSIZING)
510 || rareInheritedData->textSizeAdjust != other->rareInheritedData->textSizeAdjust
512 || rareInheritedData->wordBreak != other->rareInheritedData->wordBreak
513 || rareInheritedData->overflowWrap != other->rareInheritedData->overflowWrap
514 || rareInheritedData->nbspMode != other->rareInheritedData->nbspMode
515 || rareInheritedData->lineBreak != other->rareInheritedData->lineBreak
516 || rareInheritedData->textSecurity != other->rareInheritedData->textSecurity
517 || rareInheritedData->hyphens != other->rareInheritedData->hyphens
518 || rareInheritedData->hyphenationLimitBefore != other->rareInheritedData->hyphenationLimitBefore
519 || rareInheritedData->hyphenationLimitAfter != other->rareInheritedData->hyphenationLimitAfter
520 || rareInheritedData->hyphenationString != other->rareInheritedData->hyphenationString
521 || rareInheritedData->locale != other->rareInheritedData->locale
522 || rareInheritedData->m_rubyPosition != other->rareInheritedData->m_rubyPosition
523 || rareInheritedData->textEmphasisMark != other->rareInheritedData->textEmphasisMark
524 || rareInheritedData->textEmphasisPosition != other->rareInheritedData->textEmphasisPosition
525 || rareInheritedData->textEmphasisCustomMark != other->rareInheritedData->textEmphasisCustomMark
526 || rareInheritedData->m_textOrientation != other->rareInheritedData->m_textOrientation
527 || rareInheritedData->m_tabSize != other->rareInheritedData->m_tabSize
528 || rareInheritedData->m_lineBoxContain != other->rareInheritedData->m_lineBoxContain
529 || rareInheritedData->m_lineGrid != other->rareInheritedData->m_lineGrid
530 #if ENABLE(CSS_IMAGE_ORIENTATION)
531 || rareInheritedData->m_imageOrientation != other->rareInheritedData->m_imageOrientation
533 #if ENABLE(CSS_IMAGE_RESOLUTION)
534 || rareInheritedData->m_imageResolutionSource != other->rareInheritedData->m_imageResolutionSource
535 || rareInheritedData->m_imageResolutionSnap != other->rareInheritedData->m_imageResolutionSnap
536 || rareInheritedData->m_imageResolution != other->rareInheritedData->m_imageResolution
538 || rareInheritedData->m_lineSnap != other->rareInheritedData->m_lineSnap
539 || rareInheritedData->m_lineAlign != other->rareInheritedData->m_lineAlign
540 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
541 || rareInheritedData->useTouchOverflowScrolling != other->rareInheritedData->useTouchOverflowScrolling
543 || rareInheritedData->listStyleImage != other->rareInheritedData->listStyleImage)
546 if (!rareInheritedData->shadowDataEquivalent(*other->rareInheritedData.get()))
549 if (textStrokeWidth() != other->textStrokeWidth())
553 #if ENABLE(TEXT_AUTOSIZING)
554 if (visual->m_textAutosizingMultiplier != other->visual->m_textAutosizingMultiplier)
558 if (inherited->line_height != other->inherited->line_height
559 #if ENABLE(IOS_TEXT_AUTOSIZING)
560 || inherited->specifiedLineHeight != other->inherited->specifiedLineHeight
562 || inherited->font != other->inherited->font
563 || inherited->horizontal_border_spacing != other->inherited->horizontal_border_spacing
564 || inherited->vertical_border_spacing != other->inherited->vertical_border_spacing
565 || inherited_flags._box_direction != other->inherited_flags._box_direction
566 || inherited_flags.m_rtlOrdering != other->inherited_flags.m_rtlOrdering
567 || noninherited_flags._position != other->noninherited_flags._position
568 || noninherited_flags._floating != other->noninherited_flags._floating
569 || noninherited_flags._originalDisplay != other->noninherited_flags._originalDisplay)
573 if (((int)noninherited_flags._effectiveDisplay) >= TABLE) {
574 if (inherited_flags._border_collapse != other->inherited_flags._border_collapse
575 || inherited_flags._empty_cells != other->inherited_flags._empty_cells
576 || inherited_flags._caption_side != other->inherited_flags._caption_side
577 || noninherited_flags._table_layout != other->noninherited_flags._table_layout)
580 // In the collapsing border model, 'hidden' suppresses other borders, while 'none'
581 // does not, so these style differences can be width differences.
582 if (inherited_flags._border_collapse
583 && ((borderTopStyle() == BHIDDEN && other->borderTopStyle() == BNONE)
584 || (borderTopStyle() == BNONE && other->borderTopStyle() == BHIDDEN)
585 || (borderBottomStyle() == BHIDDEN && other->borderBottomStyle() == BNONE)
586 || (borderBottomStyle() == BNONE && other->borderBottomStyle() == BHIDDEN)
587 || (borderLeftStyle() == BHIDDEN && other->borderLeftStyle() == BNONE)
588 || (borderLeftStyle() == BNONE && other->borderLeftStyle() == BHIDDEN)
589 || (borderRightStyle() == BHIDDEN && other->borderRightStyle() == BNONE)
590 || (borderRightStyle() == BNONE && other->borderRightStyle() == BHIDDEN)))
594 if (noninherited_flags._effectiveDisplay == LIST_ITEM) {
595 if (inherited_flags._list_style_type != other->inherited_flags._list_style_type
596 || inherited_flags._list_style_position != other->inherited_flags._list_style_position)
600 if (inherited_flags._text_align != other->inherited_flags._text_align
601 || inherited_flags._text_transform != other->inherited_flags._text_transform
602 || inherited_flags._direction != other->inherited_flags._direction
603 || inherited_flags._white_space != other->inherited_flags._white_space
604 || noninherited_flags._clear != other->noninherited_flags._clear
605 || noninherited_flags._unicodeBidi != other->noninherited_flags._unicodeBidi)
608 // Check block flow direction.
609 if (inherited_flags.m_writingMode != other->inherited_flags.m_writingMode)
612 // Check text combine mode.
613 if (rareNonInheritedData->m_textCombine != other->rareNonInheritedData->m_textCombine)
616 // Overflow returns a layout hint.
617 if (noninherited_flags._overflowX != other->noninherited_flags._overflowX
618 || noninherited_flags._overflowY != other->noninherited_flags._overflowY)
621 // If our border widths change, then we need to layout. Other changes to borders
622 // only necessitate a repaint.
623 if (borderLeftWidth() != other->borderLeftWidth()
624 || borderTopWidth() != other->borderTopWidth()
625 || borderBottomWidth() != other->borderBottomWidth()
626 || borderRightWidth() != other->borderRightWidth())
629 // If the counter directives change, trigger a relayout to re-calculate counter values and rebuild the counter node tree.
630 const CounterDirectiveMap* mapA = rareNonInheritedData->m_counterDirectives.get();
631 const CounterDirectiveMap* mapB = other->rareNonInheritedData->m_counterDirectives.get();
632 if (!(mapA == mapB || (mapA && mapB && *mapA == *mapB)))
635 if ((visibility() == COLLAPSE) != (other->visibility() == COLLAPSE))
638 if (rareNonInheritedData->hasOpacity() != other->rareNonInheritedData->hasOpacity()) {
639 // FIXME: We would like to use SimplifiedLayout here, but we can't quite do that yet.
640 // We need to make sure SimplifiedLayout can operate correctly on RenderInlines (we will need
641 // to add a selfNeedsSimplifiedLayout bit in order to not get confused and taint every line).
642 // In addition we need to solve the floating object issue when layers come and go. Right now
643 // a full layout is necessary to keep floating object lists sane.
647 #if ENABLE(CSS_FILTERS)
648 if (rareNonInheritedData->hasFilters() != other->rareNonInheritedData->hasFilters())
652 const QuotesData* quotesDataA = rareInheritedData->quotes.get();
653 const QuotesData* quotesDataB = other->rareInheritedData->quotes.get();
654 if (!(quotesDataA == quotesDataB || (quotesDataA && quotesDataB && *quotesDataA == *quotesDataB)))
657 if (position() != StaticPosition) {
658 if (surround->offset != other->surround->offset) {
659 // FIXME: We would like to use SimplifiedLayout for relative positioning, but we can't quite do that yet.
660 // We need to make sure SimplifiedLayout can operate correctly on RenderInlines (we will need
661 // to add a selfNeedsSimplifiedLayout bit in order to not get confused and taint every line).
662 if (position() != AbsolutePosition)
665 // Optimize for the case where a positioned layer is moving but not changing size.
666 if (!positionChangeIsMovementOnly(surround->offset, other->surround->offset, m_box->width()))
674 bool RenderStyle::changeRequiresPositionedLayoutOnly(const RenderStyle* other, unsigned&) const
676 if (position() == StaticPosition)
679 if (surround->offset != other->surround->offset) {
680 // Optimize for the case where a positioned layer is moving but not changing size.
681 if (position() == AbsolutePosition && positionChangeIsMovementOnly(surround->offset, other->surround->offset, m_box->width()))
688 bool RenderStyle::changeRequiresLayerRepaint(const RenderStyle* other, unsigned& changedContextSensitiveProperties) const
690 if (position() != StaticPosition) {
691 if (m_box->zIndex() != other->m_box->zIndex()
692 || m_box->hasAutoZIndex() != other->m_box->hasAutoZIndex()
693 || visual->clip != other->visual->clip
694 || visual->hasClip != other->visual->hasClip)
698 #if ENABLE(CSS_COMPOSITING)
699 if (rareNonInheritedData->m_effectiveBlendMode != other->rareNonInheritedData->m_effectiveBlendMode)
703 if (rareNonInheritedData->opacity != other->rareNonInheritedData->opacity) {
704 #if USE(ACCELERATED_COMPOSITING)
705 changedContextSensitiveProperties |= ContextSensitivePropertyOpacity;
706 // Don't return; keep looking for another change.
708 UNUSED_PARAM(changedContextSensitiveProperties);
713 #if ENABLE(CSS_FILTERS)
714 if (rareNonInheritedData->m_filter.get() != other->rareNonInheritedData->m_filter.get()
715 && *rareNonInheritedData->m_filter.get() != *other->rareNonInheritedData->m_filter.get()) {
716 #if USE(ACCELERATED_COMPOSITING)
717 changedContextSensitiveProperties |= ContextSensitivePropertyFilter;
718 // Don't return; keep looking for another change.
725 if (rareNonInheritedData->m_mask != other->rareNonInheritedData->m_mask
726 || rareNonInheritedData->m_maskBoxImage != other->rareNonInheritedData->m_maskBoxImage)
732 bool RenderStyle::changeRequiresRepaint(const RenderStyle* other, unsigned&) const
734 if (inherited_flags._visibility != other->inherited_flags._visibility
735 || inherited_flags.m_printColorAdjust != other->inherited_flags.m_printColorAdjust
736 || inherited_flags._insideLink != other->inherited_flags._insideLink
737 || surround->border != other->surround->border
738 || !m_background->isEquivalentForPainting(*other->m_background)
739 || rareInheritedData->userModify != other->rareInheritedData->userModify
740 || rareInheritedData->userSelect != other->rareInheritedData->userSelect
741 || rareNonInheritedData->userDrag != other->rareNonInheritedData->userDrag
742 || rareNonInheritedData->m_borderFit != other->rareNonInheritedData->m_borderFit
743 || rareNonInheritedData->m_objectFit != other->rareNonInheritedData->m_objectFit
744 || rareInheritedData->m_imageRendering != other->rareInheritedData->m_imageRendering)
747 #if ENABLE(CSS_SHAPES)
748 // FIXME: The current spec is being reworked to remove dependencies between exclusions and affected
749 // content. There's a proposal to use floats instead. In that case, wrap-shape should actually relayout
750 // the parent container. For sure, I will have to revisit this code, but for now I've added this in order
751 // to avoid having diff() == StyleDifferenceEqual where wrap-shapes actually differ.
752 // Tracking bug: https://bugs.webkit.org/show_bug.cgi?id=62991
753 if (rareNonInheritedData->m_shapeOutside != other->rareNonInheritedData->m_shapeOutside)
757 if (rareNonInheritedData->m_clipPath != other->rareNonInheritedData->m_clipPath)
763 bool RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline(const RenderStyle* other, unsigned&) const
765 if (inherited->color != other->inherited->color
766 || inherited_flags._text_decorations != other->inherited_flags._text_decorations
767 || visual->textDecoration != other->visual->textDecoration
768 || rareNonInheritedData->m_textDecorationStyle != other->rareNonInheritedData->m_textDecorationStyle
769 || rareNonInheritedData->m_textDecorationColor != other->rareNonInheritedData->m_textDecorationColor
770 || rareInheritedData->m_textDecorationSkip != other->rareInheritedData->m_textDecorationSkip
771 || rareInheritedData->textFillColor != other->rareInheritedData->textFillColor
772 || rareInheritedData->textStrokeColor != other->rareInheritedData->textStrokeColor
773 || rareInheritedData->textEmphasisColor != other->rareInheritedData->textEmphasisColor
774 || rareInheritedData->textEmphasisFill != other->rareInheritedData->textEmphasisFill)
780 bool RenderStyle::changeRequiresRecompositeLayer(const RenderStyle* other, unsigned&) const
782 #if USE(ACCELERATED_COMPOSITING)
783 if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) {
784 if (rareNonInheritedData->m_transformStyle3D != other->rareNonInheritedData->m_transformStyle3D
785 || rareNonInheritedData->m_backfaceVisibility != other->rareNonInheritedData->m_backfaceVisibility
786 || rareNonInheritedData->m_perspective != other->rareNonInheritedData->m_perspective
787 || rareNonInheritedData->m_perspectiveOriginX != other->rareNonInheritedData->m_perspectiveOriginX
788 || rareNonInheritedData->m_perspectiveOriginY != other->rareNonInheritedData->m_perspectiveOriginY)
797 StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedContextSensitiveProperties) const
799 changedContextSensitiveProperties = ContextSensitivePropertyNone;
802 StyleDifference svgChange = StyleDifferenceEqual;
803 if (m_svgStyle != other->m_svgStyle) {
804 svgChange = m_svgStyle->diff(other->m_svgStyle.get());
805 if (svgChange == StyleDifferenceLayout)
810 if (changeRequiresLayout(other, changedContextSensitiveProperties))
811 return StyleDifferenceLayout;
814 // SVGRenderStyle::diff() might have returned StyleDifferenceRepaint, eg. if fill changes.
815 // If eg. the font-size changed at the same time, we're not allowed to return StyleDifferenceRepaint,
816 // but have to return StyleDifferenceLayout, that's why this if branch comes after all branches
817 // that are relevant for SVG and might return StyleDifferenceLayout.
818 if (svgChange != StyleDifferenceEqual)
822 if (changeRequiresPositionedLayoutOnly(other, changedContextSensitiveProperties))
823 return StyleDifferenceLayoutPositionedMovementOnly;
825 if (changeRequiresLayerRepaint(other, changedContextSensitiveProperties))
826 return StyleDifferenceRepaintLayer;
828 if (changeRequiresRepaint(other, changedContextSensitiveProperties))
829 return StyleDifferenceRepaint;
831 #if USE(ACCELERATED_COMPOSITING)
832 if (changeRequiresRecompositeLayer(other, changedContextSensitiveProperties))
833 return StyleDifferenceRecompositeLayer;
836 if (changeRequiresRepaintIfTextOrBorderOrOutline(other, changedContextSensitiveProperties))
837 return StyleDifferenceRepaintIfTextOrBorderOrOutline;
839 // Cursors are not checked, since they will be set appropriately in response to mouse events,
840 // so they don't need to cause any repaint or layout.
842 // 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
843 // the resulting transition properly.
844 return StyleDifferenceEqual;
847 bool RenderStyle::diffRequiresRepaint(const RenderStyle* style) const
849 unsigned changedContextSensitiveProperties = 0;
850 return changeRequiresRepaint(style, changedContextSensitiveProperties);
853 void RenderStyle::setClip(Length top, Length right, Length bottom, Length left)
855 StyleVisualData* data = visual.access();
856 data->clip.m_top = top;
857 data->clip.m_right = right;
858 data->clip.m_bottom = bottom;
859 data->clip.m_left = left;
862 void RenderStyle::addCursor(PassRefPtr<StyleImage> image, const IntPoint& hotSpot)
864 if (!rareInheritedData.access()->cursorData)
865 rareInheritedData.access()->cursorData = CursorList::create();
866 rareInheritedData.access()->cursorData->append(CursorData(image, hotSpot));
869 void RenderStyle::setCursorList(PassRefPtr<CursorList> other)
871 rareInheritedData.access()->cursorData = other;
874 void RenderStyle::setQuotes(PassRefPtr<QuotesData> q)
876 if (rareInheritedData->quotes == q || (rareInheritedData->quotes && q && *rareInheritedData->quotes == *q))
879 rareInheritedData.access()->quotes = q;
882 void RenderStyle::clearCursorList()
884 if (rareInheritedData->cursorData)
885 rareInheritedData.access()->cursorData = 0;
888 void RenderStyle::clearContent()
890 if (rareNonInheritedData->m_content)
891 rareNonInheritedData.access()->m_content = nullptr;
894 void RenderStyle::appendContent(std::unique_ptr<ContentData> contentData)
896 auto& content = rareNonInheritedData.access()->m_content;
897 ContentData* lastContent = content.get();
898 while (lastContent && lastContent->next())
899 lastContent = lastContent->next();
902 lastContent->setNext(std::move(contentData));
904 content = std::move(contentData);
907 void RenderStyle::setContent(PassRefPtr<StyleImage> image, bool add)
913 appendContent(std::make_unique<ImageContentData>(image));
917 rareNonInheritedData.access()->m_content = std::make_unique<ImageContentData>(image);
918 if (!rareNonInheritedData.access()->m_altText.isNull())
919 rareNonInheritedData.access()->m_content->setAltText(rareNonInheritedData.access()->m_altText);
922 void RenderStyle::setContent(const String& string, bool add)
924 auto& content = rareNonInheritedData.access()->m_content;
926 ContentData* lastContent = content.get();
927 while (lastContent && lastContent->next())
928 lastContent = lastContent->next();
931 // We attempt to merge with the last ContentData if possible.
932 if (lastContent->isText()) {
933 TextContentData* textContent = static_cast<TextContentData*>(lastContent);
934 textContent->setText(textContent->text() + string);
936 lastContent->setNext(std::make_unique<TextContentData>(string));
938 if (!rareNonInheritedData.access()->m_altText.isNull())
939 lastContent->setAltText(rareNonInheritedData.access()->m_altText);
944 content = std::make_unique<TextContentData>(string);
945 if (!rareNonInheritedData.access()->m_altText.isNull())
946 content->setAltText(rareNonInheritedData.access()->m_altText);
949 void RenderStyle::setContent(std::unique_ptr<CounterContent> counter, bool add)
955 appendContent(std::make_unique<CounterContentData>(std::move(counter)));
959 rareNonInheritedData.access()->m_content = std::make_unique<CounterContentData>(std::move(counter));
962 void RenderStyle::setContent(QuoteType quote, bool add)
965 appendContent(std::make_unique<QuoteContentData>(quote));
969 rareNonInheritedData.access()->m_content = std::make_unique<QuoteContentData>(quote);
972 void RenderStyle::setContentAltText(const String& string)
974 rareNonInheritedData.access()->m_altText = string;
976 if (rareNonInheritedData.access()->m_content)
977 rareNonInheritedData.access()->m_content->setAltText(string);
980 const String& RenderStyle::contentAltText() const
982 return rareNonInheritedData->m_altText;
985 inline bool requireTransformOrigin(const Vector<RefPtr<TransformOperation>>& transformOperations, RenderStyle::ApplyTransformOrigin applyOrigin)
987 // transform-origin brackets the transform with translate operations.
988 // Optimize for the case where the only transform is a translation, since the transform-origin is irrelevant
990 if (applyOrigin != RenderStyle::IncludeTransformOrigin)
993 unsigned size = transformOperations.size();
994 for (unsigned i = 0; i < size; ++i) {
995 TransformOperation::OperationType type = transformOperations[i]->type();
996 if (type != TransformOperation::TRANSLATE_X
997 && type != TransformOperation::TRANSLATE_Y
998 && type != TransformOperation::TRANSLATE
999 && type != TransformOperation::TRANSLATE_Z
1000 && type != TransformOperation::TRANSLATE_3D)
1007 void RenderStyle::applyTransform(TransformationMatrix& transform, const LayoutSize& borderBoxSize, ApplyTransformOrigin applyOrigin) const
1009 // FIXME: when subpixel layout is supported (bug 71143) the body of this function could be replaced by
1010 // applyTransform(transform, FloatRect(FloatPoint(), borderBoxSize), applyOrigin);
1012 const Vector<RefPtr<TransformOperation>>& transformOperations = rareNonInheritedData->m_transform->m_operations.operations();
1013 bool applyTransformOrigin = requireTransformOrigin(transformOperations, applyOrigin);
1015 if (applyTransformOrigin)
1016 transform.translate3d(floatValueForLength(transformOriginX(), borderBoxSize.width()), floatValueForLength(transformOriginY(), borderBoxSize.height()), transformOriginZ());
1018 unsigned size = transformOperations.size();
1019 for (unsigned i = 0; i < size; ++i)
1020 transformOperations[i]->apply(transform, borderBoxSize);
1022 if (applyTransformOrigin)
1023 transform.translate3d(-floatValueForLength(transformOriginX(), borderBoxSize.width()), -floatValueForLength(transformOriginY(), borderBoxSize.height()), -transformOriginZ());
1026 void RenderStyle::applyTransform(TransformationMatrix& transform, const FloatRect& boundingBox, ApplyTransformOrigin applyOrigin) const
1028 const Vector<RefPtr<TransformOperation>>& transformOperations = rareNonInheritedData->m_transform->m_operations.operations();
1029 bool applyTransformOrigin = requireTransformOrigin(transformOperations, applyOrigin);
1031 float offsetX = transformOriginX().type() == Percent ? boundingBox.x() : 0;
1032 float offsetY = transformOriginY().type() == Percent ? boundingBox.y() : 0;
1034 if (applyTransformOrigin) {
1035 transform.translate3d(floatValueForLength(transformOriginX(), boundingBox.width()) + offsetX,
1036 floatValueForLength(transformOriginY(), boundingBox.height()) + offsetY,
1037 transformOriginZ());
1040 unsigned size = transformOperations.size();
1041 for (unsigned i = 0; i < size; ++i)
1042 transformOperations[i]->apply(transform, boundingBox.size());
1044 if (applyTransformOrigin) {
1045 transform.translate3d(-floatValueForLength(transformOriginX(), boundingBox.width()) - offsetX,
1046 -floatValueForLength(transformOriginY(), boundingBox.height()) - offsetY,
1047 -transformOriginZ());
1051 void RenderStyle::setPageScaleTransform(float scale)
1055 TransformOperations transform;
1056 transform.operations().append(ScaleTransformOperation::create(scale, scale, ScaleTransformOperation::SCALE));
1057 setTransform(transform);
1058 setTransformOriginX(Length(0, Fixed));
1059 setTransformOriginY(Length(0, Fixed));
1062 void RenderStyle::setTextShadow(PassOwnPtr<ShadowData> shadowData, bool add)
1064 ASSERT(!shadowData || (!shadowData->spread() && shadowData->style() == Normal));
1066 StyleRareInheritedData* rareData = rareInheritedData.access();
1068 rareData->textShadow = shadowData;
1072 shadowData->setNext(rareData->textShadow.release());
1073 rareData->textShadow = shadowData;
1076 void RenderStyle::setBoxShadow(PassOwnPtr<ShadowData> shadowData, bool add)
1078 StyleRareNonInheritedData* rareData = rareNonInheritedData.access();
1080 rareData->m_boxShadow = shadowData;
1084 shadowData->setNext(rareData->m_boxShadow.release());
1085 rareData->m_boxShadow = shadowData;
1088 static RoundedRect::Radii calcRadiiFor(const BorderData& border, IntSize size, RenderView* renderView)
1090 return RoundedRect::Radii(
1091 IntSize(valueForLength(border.topLeft().width(), size.width(), renderView),
1092 valueForLength(border.topLeft().height(), size.height(), renderView)),
1093 IntSize(valueForLength(border.topRight().width(), size.width(), renderView),
1094 valueForLength(border.topRight().height(), size.height(), renderView)),
1095 IntSize(valueForLength(border.bottomLeft().width(), size.width(), renderView),
1096 valueForLength(border.bottomLeft().height(), size.height(), renderView)),
1097 IntSize(valueForLength(border.bottomRight().width(), size.width(), renderView),
1098 valueForLength(border.bottomRight().height(), size.height(), renderView)));
1101 static float calcConstraintScaleFor(const IntRect& rect, const RoundedRect::Radii& radii)
1103 // Constrain corner radii using CSS3 rules:
1104 // http://www.w3.org/TR/css3-background/#the-border-radius
1110 radiiSum = static_cast<unsigned>(radii.topLeft().width()) + static_cast<unsigned>(radii.topRight().width()); // Casts to avoid integer overflow.
1111 if (radiiSum > static_cast<unsigned>(rect.width()))
1112 factor = std::min(static_cast<float>(rect.width()) / radiiSum, factor);
1115 radiiSum = static_cast<unsigned>(radii.bottomLeft().width()) + static_cast<unsigned>(radii.bottomRight().width());
1116 if (radiiSum > static_cast<unsigned>(rect.width()))
1117 factor = std::min(static_cast<float>(rect.width()) / radiiSum, factor);
1120 radiiSum = static_cast<unsigned>(radii.topLeft().height()) + static_cast<unsigned>(radii.bottomLeft().height());
1121 if (radiiSum > static_cast<unsigned>(rect.height()))
1122 factor = std::min(static_cast<float>(rect.height()) / radiiSum, factor);
1125 radiiSum = static_cast<unsigned>(radii.topRight().height()) + static_cast<unsigned>(radii.bottomRight().height());
1126 if (radiiSum > static_cast<unsigned>(rect.height()))
1127 factor = std::min(static_cast<float>(rect.height()) / radiiSum, factor);
1129 ASSERT(factor <= 1);
1133 StyleImage* RenderStyle::listStyleImage() const { return rareInheritedData->listStyleImage.get(); }
1134 void RenderStyle::setListStyleImage(PassRefPtr<StyleImage> v)
1136 if (rareInheritedData->listStyleImage != v)
1137 rareInheritedData.access()->listStyleImage = v;
1140 Color RenderStyle::color() const { return inherited->color; }
1141 Color RenderStyle::visitedLinkColor() const { return inherited->visitedLinkColor; }
1142 void RenderStyle::setColor(const Color& v) { SET_VAR(inherited, color, v); }
1143 void RenderStyle::setVisitedLinkColor(const Color& v) { SET_VAR(inherited, visitedLinkColor, v); }
1145 short RenderStyle::horizontalBorderSpacing() const { return inherited->horizontal_border_spacing; }
1146 short RenderStyle::verticalBorderSpacing() const { return inherited->vertical_border_spacing; }
1147 void RenderStyle::setHorizontalBorderSpacing(short v) { SET_VAR(inherited, horizontal_border_spacing, v); }
1148 void RenderStyle::setVerticalBorderSpacing(short v) { SET_VAR(inherited, vertical_border_spacing, v); }
1150 RoundedRect RenderStyle::getRoundedBorderFor(const LayoutRect& borderRect, RenderView* renderView, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
1152 IntRect snappedBorderRect(pixelSnappedIntRect(borderRect));
1153 RoundedRect roundedRect(snappedBorderRect);
1154 if (hasBorderRadius()) {
1155 RoundedRect::Radii radii = calcRadiiFor(surround->border, snappedBorderRect.size(), renderView);
1156 radii.scale(calcConstraintScaleFor(snappedBorderRect, radii));
1157 roundedRect.includeLogicalEdges(radii, isHorizontalWritingMode(), includeLogicalLeftEdge, includeLogicalRightEdge);
1162 RoundedRect RenderStyle::getRoundedInnerBorderFor(const LayoutRect& borderRect, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
1164 bool horizontal = isHorizontalWritingMode();
1166 int leftWidth = (!horizontal || includeLogicalLeftEdge) ? borderLeftWidth() : 0;
1167 int rightWidth = (!horizontal || includeLogicalRightEdge) ? borderRightWidth() : 0;
1168 int topWidth = (horizontal || includeLogicalLeftEdge) ? borderTopWidth() : 0;
1169 int bottomWidth = (horizontal || includeLogicalRightEdge) ? borderBottomWidth() : 0;
1171 return getRoundedInnerBorderFor(borderRect, topWidth, bottomWidth, leftWidth, rightWidth, includeLogicalLeftEdge, includeLogicalRightEdge);
1174 RoundedRect RenderStyle::getRoundedInnerBorderFor(const LayoutRect& borderRect,
1175 int topWidth, int bottomWidth, int leftWidth, int rightWidth, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
1177 LayoutRect innerRect(borderRect.x() + leftWidth,
1178 borderRect.y() + topWidth,
1179 borderRect.width() - leftWidth - rightWidth,
1180 borderRect.height() - topWidth - bottomWidth);
1182 RoundedRect roundedRect(pixelSnappedIntRect(innerRect));
1184 if (hasBorderRadius()) {
1185 RoundedRect::Radii radii = getRoundedBorderFor(borderRect).radii();
1186 radii.shrink(topWidth, bottomWidth, leftWidth, rightWidth);
1187 roundedRect.includeLogicalEdges(radii, isHorizontalWritingMode(), includeLogicalLeftEdge, includeLogicalRightEdge);
1192 static bool allLayersAreFixed(const FillLayer* layer)
1194 bool allFixed = true;
1196 for (const FillLayer* currLayer = layer; currLayer; currLayer = currLayer->next())
1197 allFixed &= (currLayer->image() && currLayer->attachment() == FixedBackgroundAttachment);
1199 return layer && allFixed;
1202 bool RenderStyle::hasEntirelyFixedBackground() const
1204 return allLayersAreFixed(backgroundLayers());
1207 const CounterDirectiveMap* RenderStyle::counterDirectives() const
1209 return rareNonInheritedData->m_counterDirectives.get();
1212 CounterDirectiveMap& RenderStyle::accessCounterDirectives()
1214 OwnPtr<CounterDirectiveMap>& map = rareNonInheritedData.access()->m_counterDirectives;
1216 map = adoptPtr(new CounterDirectiveMap);
1220 const CounterDirectives RenderStyle::getCounterDirectives(const AtomicString& identifier) const
1222 if (const CounterDirectiveMap* directives = counterDirectives())
1223 return directives->get(identifier);
1224 return CounterDirectives();
1227 const AtomicString& RenderStyle::hyphenString() const
1229 ASSERT(hyphens() != HyphensNone);
1231 const AtomicString& hyphenationString = rareInheritedData.get()->hyphenationString;
1232 if (!hyphenationString.isNull())
1233 return hyphenationString;
1235 // FIXME: This should depend on locale.
1236 DEFINE_STATIC_LOCAL(AtomicString, hyphenMinusString, (&hyphenMinus, 1));
1237 DEFINE_STATIC_LOCAL(AtomicString, hyphenString, (&hyphen, 1));
1238 return font().primaryFontHasGlyphForCharacter(hyphen) ? hyphenString : hyphenMinusString;
1241 const AtomicString& RenderStyle::textEmphasisMarkString() const
1243 switch (textEmphasisMark()) {
1244 case TextEmphasisMarkNone:
1246 case TextEmphasisMarkCustom:
1247 return textEmphasisCustomMark();
1248 case TextEmphasisMarkDot: {
1249 DEFINE_STATIC_LOCAL(AtomicString, filledDotString, (&bullet, 1));
1250 DEFINE_STATIC_LOCAL(AtomicString, openDotString, (&whiteBullet, 1));
1251 return textEmphasisFill() == TextEmphasisFillFilled ? filledDotString : openDotString;
1253 case TextEmphasisMarkCircle: {
1254 DEFINE_STATIC_LOCAL(AtomicString, filledCircleString, (&blackCircle, 1));
1255 DEFINE_STATIC_LOCAL(AtomicString, openCircleString, (&whiteCircle, 1));
1256 return textEmphasisFill() == TextEmphasisFillFilled ? filledCircleString : openCircleString;
1258 case TextEmphasisMarkDoubleCircle: {
1259 DEFINE_STATIC_LOCAL(AtomicString, filledDoubleCircleString, (&fisheye, 1));
1260 DEFINE_STATIC_LOCAL(AtomicString, openDoubleCircleString, (&bullseye, 1));
1261 return textEmphasisFill() == TextEmphasisFillFilled ? filledDoubleCircleString : openDoubleCircleString;
1263 case TextEmphasisMarkTriangle: {
1264 DEFINE_STATIC_LOCAL(AtomicString, filledTriangleString, (&blackUpPointingTriangle, 1));
1265 DEFINE_STATIC_LOCAL(AtomicString, openTriangleString, (&whiteUpPointingTriangle, 1));
1266 return textEmphasisFill() == TextEmphasisFillFilled ? filledTriangleString : openTriangleString;
1268 case TextEmphasisMarkSesame: {
1269 DEFINE_STATIC_LOCAL(AtomicString, filledSesameString, (&sesameDot, 1));
1270 DEFINE_STATIC_LOCAL(AtomicString, openSesameString, (&whiteSesameDot, 1));
1271 return textEmphasisFill() == TextEmphasisFillFilled ? filledSesameString : openSesameString;
1273 case TextEmphasisMarkAuto:
1274 ASSERT_NOT_REACHED();
1278 ASSERT_NOT_REACHED();
1282 #if ENABLE(DASHBOARD_SUPPORT)
1283 const Vector<StyleDashboardRegion>& RenderStyle::initialDashboardRegions()
1285 DEFINE_STATIC_LOCAL(Vector<StyleDashboardRegion>, emptyList, ());
1289 const Vector<StyleDashboardRegion>& RenderStyle::noneDashboardRegions()
1291 DEFINE_STATIC_LOCAL(Vector<StyleDashboardRegion>, noneList, ());
1292 static bool noneListInitialized = false;
1294 if (!noneListInitialized) {
1295 StyleDashboardRegion region;
1297 region.offset.m_top = Length();
1298 region.offset.m_right = Length();
1299 region.offset.m_bottom = Length();
1300 region.offset.m_left = Length();
1301 region.type = StyleDashboardRegion::None;
1302 noneList.append(region);
1303 noneListInitialized = true;
1309 void RenderStyle::adjustAnimations()
1311 AnimationList* animationList = rareNonInheritedData->m_animations.get();
1315 // Get rid of empty animations and anything beyond them
1316 for (size_t i = 0; i < animationList->size(); ++i) {
1317 if (animationList->animation(i).isEmpty()) {
1318 animationList->resize(i);
1323 if (animationList->isEmpty()) {
1328 // Repeat patterns into layers that don't have some properties set.
1329 animationList->fillUnsetProperties();
1332 void RenderStyle::adjustTransitions()
1334 AnimationList* transitionList = rareNonInheritedData->m_transitions.get();
1335 if (!transitionList)
1338 // Get rid of empty transitions and anything beyond them
1339 for (size_t i = 0; i < transitionList->size(); ++i) {
1340 if (transitionList->animation(i).isEmpty()) {
1341 transitionList->resize(i);
1346 if (transitionList->isEmpty()) {
1351 // Repeat patterns into layers that don't have some properties set.
1352 transitionList->fillUnsetProperties();
1354 // Make sure there are no duplicate properties. This is an O(n^2) algorithm
1355 // but the lists tend to be very short, so it is probably ok
1356 for (size_t i = 0; i < transitionList->size(); ++i) {
1357 for (size_t j = i+1; j < transitionList->size(); ++j) {
1358 if (transitionList->animation(i).property() == transitionList->animation(j).property()) {
1360 transitionList->remove(i);
1367 AnimationList* RenderStyle::accessAnimations()
1369 if (!rareNonInheritedData.access()->m_animations)
1370 rareNonInheritedData.access()->m_animations = adoptPtr(new AnimationList());
1371 return rareNonInheritedData->m_animations.get();
1374 AnimationList* RenderStyle::accessTransitions()
1376 if (!rareNonInheritedData.access()->m_transitions)
1377 rareNonInheritedData.access()->m_transitions = adoptPtr(new AnimationList());
1378 return rareNonInheritedData->m_transitions.get();
1381 const Animation* RenderStyle::transitionForProperty(CSSPropertyID property) const
1383 if (transitions()) {
1384 for (size_t i = 0; i < transitions()->size(); ++i) {
1385 const Animation& p = transitions()->animation(i);
1386 if (p.animationMode() == Animation::AnimateAll || p.property() == property) {
1394 const Font& RenderStyle::font() const { return inherited->font; }
1395 const FontMetrics& RenderStyle::fontMetrics() const { return inherited->font.fontMetrics(); }
1396 const FontDescription& RenderStyle::fontDescription() const { return inherited->font.fontDescription(); }
1397 float RenderStyle::specifiedFontSize() const { return fontDescription().specifiedSize(); }
1398 float RenderStyle::computedFontSize() const { return fontDescription().computedSize(); }
1399 int RenderStyle::fontSize() const { return inherited->font.pixelSize(); }
1401 const Length& RenderStyle::wordSpacing() const { return rareInheritedData->wordSpacing; }
1402 float RenderStyle::letterSpacing() const { return inherited->font.letterSpacing(); }
1404 bool RenderStyle::setFontDescription(const FontDescription& v)
1406 if (inherited->font.fontDescription() != v) {
1407 inherited.access()->font = Font(v, inherited->font.letterSpacing(), inherited->font.wordSpacing());
1413 #if ENABLE(IOS_TEXT_AUTOSIZING)
1414 const Length& RenderStyle::specifiedLineHeight() const { return inherited->specifiedLineHeight; }
1415 void RenderStyle::setSpecifiedLineHeight(Length v) { SET_VAR(inherited, specifiedLineHeight, v); }
1417 const Length& RenderStyle::specifiedLineHeight() const { return inherited->line_height; }
1420 Length RenderStyle::lineHeight() const
1422 const Length& lh = inherited->line_height;
1423 #if ENABLE(TEXT_AUTOSIZING)
1424 // Unlike fontDescription().computedSize() and hence fontSize(), this is
1425 // recalculated on demand as we only store the specified line height.
1426 // FIXME: Should consider scaling the fixed part of any calc expressions
1427 // too, though this involves messily poking into CalcExpressionLength.
1428 float multiplier = textAutosizingMultiplier();
1429 if (multiplier > 1 && lh.isFixed())
1430 return Length(TextAutosizer::computeAutosizedFontSize(lh.value(), multiplier), Fixed);
1434 void RenderStyle::setLineHeight(Length specifiedLineHeight) { SET_VAR(inherited, line_height, specifiedLineHeight); }
1436 int RenderStyle::computedLineHeight(RenderView* renderView) const
1438 const Length& lh = lineHeight();
1440 // Negative value means the line height is not set. Use the font's built-in spacing.
1441 if (lh.isNegative())
1442 return fontMetrics().lineSpacing();
1445 return minimumValueForLength(lh, fontSize());
1447 if (lh.isViewportPercentage())
1448 return valueForLength(lh, 0, renderView);
1453 void RenderStyle::setWordSpacing(Length v)
1455 float fontWordSpacing;
1458 fontWordSpacing = 0;
1460 fontWordSpacing = v.getFloatValue() * font().spaceWidth() / 100;
1463 fontWordSpacing = v.getFloatValue();
1466 ASSERT_NOT_REACHED();
1467 fontWordSpacing = 0;
1470 inherited.access()->font.setWordSpacing(fontWordSpacing);
1471 rareInheritedData.access()->wordSpacing = std::move(v);
1474 void RenderStyle::setLetterSpacing(float v) { inherited.access()->font.setLetterSpacing(v); }
1476 void RenderStyle::setFontSize(float size)
1478 // size must be specifiedSize if Text Autosizing is enabled, but computedSize if text
1479 // zoom is enabled (if neither is enabled it's irrelevant as they're probably the same).
1481 ASSERT(std::isfinite(size));
1482 if (!std::isfinite(size) || size < 0)
1485 size = std::min(maximumAllowedFontSize, size);
1487 FontSelector* currentFontSelector = font().fontSelector();
1488 FontDescription desc(fontDescription());
1489 desc.setSpecifiedSize(size);
1490 desc.setComputedSize(size);
1492 #if ENABLE(TEXT_AUTOSIZING)
1493 float multiplier = textAutosizingMultiplier();
1494 if (multiplier > 1) {
1495 float autosizedFontSize = TextAutosizer::computeAutosizedFontSize(size, multiplier);
1496 desc.setComputedSize(min(maximumAllowedFontSize, autosizedFontSize));
1500 setFontDescription(desc);
1501 font().update(currentFontSelector);
1504 void RenderStyle::getShadowExtent(const ShadowData* shadow, LayoutUnit &top, LayoutUnit &right, LayoutUnit &bottom, LayoutUnit &left) const
1511 for ( ; shadow; shadow = shadow->next()) {
1512 if (shadow->style() == Inset)
1515 int extentAndSpread = shadow->paintingExtent() + shadow->spread();
1516 top = std::min<LayoutUnit>(top, shadow->y() - extentAndSpread);
1517 right = std::max<LayoutUnit>(right, shadow->x() + extentAndSpread);
1518 bottom = std::max<LayoutUnit>(bottom, shadow->y() + extentAndSpread);
1519 left = std::min<LayoutUnit>(left, shadow->x() - extentAndSpread);
1523 LayoutBoxExtent RenderStyle::getShadowInsetExtent(const ShadowData* shadow) const
1526 LayoutUnit right = 0;
1527 LayoutUnit bottom = 0;
1528 LayoutUnit left = 0;
1530 for ( ; shadow; shadow = shadow->next()) {
1531 if (shadow->style() == Normal)
1534 int extentAndSpread = shadow->paintingExtent() + shadow->spread();
1535 top = std::max<LayoutUnit>(top, shadow->y() + extentAndSpread);
1536 right = std::min<LayoutUnit>(right, shadow->x() - extentAndSpread);
1537 bottom = std::min<LayoutUnit>(bottom, shadow->y() - extentAndSpread);
1538 left = std::max<LayoutUnit>(left, shadow->x() + extentAndSpread);
1541 return LayoutBoxExtent(top, right, bottom, left);
1544 void RenderStyle::getShadowHorizontalExtent(const ShadowData* shadow, LayoutUnit &left, LayoutUnit &right) const
1549 for ( ; shadow; shadow = shadow->next()) {
1550 if (shadow->style() == Inset)
1553 int extentAndSpread = shadow->paintingExtent() + shadow->spread();
1554 left = std::min<LayoutUnit>(left, shadow->x() - extentAndSpread);
1555 right = std::max<LayoutUnit>(right, shadow->x() + extentAndSpread);
1559 void RenderStyle::getShadowVerticalExtent(const ShadowData* shadow, LayoutUnit &top, LayoutUnit &bottom) const
1564 for ( ; shadow; shadow = shadow->next()) {
1565 if (shadow->style() == Inset)
1568 int extentAndSpread = shadow->paintingExtent() + shadow->spread();
1569 top = std::min<LayoutUnit>(top, shadow->y() - extentAndSpread);
1570 bottom = std::max<LayoutUnit>(bottom, shadow->y() + extentAndSpread);
1574 Color RenderStyle::colorIncludingFallback(int colorProperty, bool visitedLink) const
1577 EBorderStyle borderStyle = BNONE;
1578 switch (colorProperty) {
1579 case CSSPropertyBackgroundColor:
1580 return visitedLink ? visitedLinkBackgroundColor() : backgroundColor(); // Background color doesn't fall back.
1581 case CSSPropertyBorderLeftColor:
1582 result = visitedLink ? visitedLinkBorderLeftColor() : borderLeftColor();
1583 borderStyle = borderLeftStyle();
1585 case CSSPropertyBorderRightColor:
1586 result = visitedLink ? visitedLinkBorderRightColor() : borderRightColor();
1587 borderStyle = borderRightStyle();
1589 case CSSPropertyBorderTopColor:
1590 result = visitedLink ? visitedLinkBorderTopColor() : borderTopColor();
1591 borderStyle = borderTopStyle();
1593 case CSSPropertyBorderBottomColor:
1594 result = visitedLink ? visitedLinkBorderBottomColor() : borderBottomColor();
1595 borderStyle = borderBottomStyle();
1597 case CSSPropertyColor:
1598 result = visitedLink ? visitedLinkColor() : color();
1600 case CSSPropertyOutlineColor:
1601 result = visitedLink ? visitedLinkOutlineColor() : outlineColor();
1603 case CSSPropertyWebkitColumnRuleColor:
1604 result = visitedLink ? visitedLinkColumnRuleColor() : columnRuleColor();
1606 case CSSPropertyWebkitTextDecorationColor:
1607 // Text decoration color fallback is handled in RenderObject::decorationColor.
1608 return visitedLink ? visitedLinkTextDecorationColor() : textDecorationColor();
1609 case CSSPropertyWebkitTextEmphasisColor:
1610 result = visitedLink ? visitedLinkTextEmphasisColor() : textEmphasisColor();
1612 case CSSPropertyWebkitTextFillColor:
1613 result = visitedLink ? visitedLinkTextFillColor() : textFillColor();
1615 case CSSPropertyWebkitTextStrokeColor:
1616 result = visitedLink ? visitedLinkTextStrokeColor() : textStrokeColor();
1619 ASSERT_NOT_REACHED();
1623 if (!result.isValid()) {
1624 if (!visitedLink && (borderStyle == INSET || borderStyle == OUTSET || borderStyle == RIDGE || borderStyle == GROOVE))
1625 result.setRGB(238, 238, 238);
1627 result = visitedLink ? visitedLinkColor() : color();
1632 Color RenderStyle::visitedDependentColor(int colorProperty) const
1634 Color unvisitedColor = colorIncludingFallback(colorProperty, false);
1635 if (insideLink() != InsideVisitedLink)
1636 return unvisitedColor;
1638 Color visitedColor = colorIncludingFallback(colorProperty, true);
1640 // Text decoration color validity is preserved (checked in RenderObject::decorationColor).
1641 if (colorProperty == CSSPropertyWebkitTextDecorationColor)
1642 return visitedColor;
1644 // FIXME: Technically someone could explicitly specify the color transparent, but for now we'll just
1645 // assume that if the background color is transparent that it wasn't set. Note that it's weird that
1646 // we're returning unvisited info for a visited link, but given our restriction that the alpha values
1647 // have to match, it makes more sense to return the unvisited background color if specified than it
1648 // does to return black. This behavior matches what Firefox 4 does as well.
1649 if (colorProperty == CSSPropertyBackgroundColor && visitedColor == Color::transparent)
1650 return unvisitedColor;
1652 // Take the alpha from the unvisited color, but get the RGB values from the visited color.
1653 return Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), unvisitedColor.alpha());
1656 const BorderValue& RenderStyle::borderBefore() const
1658 switch (writingMode()) {
1659 case TopToBottomWritingMode:
1661 case BottomToTopWritingMode:
1662 return borderBottom();
1663 case LeftToRightWritingMode:
1664 return borderLeft();
1665 case RightToLeftWritingMode:
1666 return borderRight();
1668 ASSERT_NOT_REACHED();
1672 const BorderValue& RenderStyle::borderAfter() const
1674 switch (writingMode()) {
1675 case TopToBottomWritingMode:
1676 return borderBottom();
1677 case BottomToTopWritingMode:
1679 case LeftToRightWritingMode:
1680 return borderRight();
1681 case RightToLeftWritingMode:
1682 return borderLeft();
1684 ASSERT_NOT_REACHED();
1685 return borderBottom();
1688 const BorderValue& RenderStyle::borderStart() const
1690 if (isHorizontalWritingMode())
1691 return isLeftToRightDirection() ? borderLeft() : borderRight();
1692 return isLeftToRightDirection() ? borderTop() : borderBottom();
1695 const BorderValue& RenderStyle::borderEnd() const
1697 if (isHorizontalWritingMode())
1698 return isLeftToRightDirection() ? borderRight() : borderLeft();
1699 return isLeftToRightDirection() ? borderBottom() : borderTop();
1702 unsigned short RenderStyle::borderBeforeWidth() const
1704 switch (writingMode()) {
1705 case TopToBottomWritingMode:
1706 return borderTopWidth();
1707 case BottomToTopWritingMode:
1708 return borderBottomWidth();
1709 case LeftToRightWritingMode:
1710 return borderLeftWidth();
1711 case RightToLeftWritingMode:
1712 return borderRightWidth();
1714 ASSERT_NOT_REACHED();
1715 return borderTopWidth();
1718 unsigned short RenderStyle::borderAfterWidth() const
1720 switch (writingMode()) {
1721 case TopToBottomWritingMode:
1722 return borderBottomWidth();
1723 case BottomToTopWritingMode:
1724 return borderTopWidth();
1725 case LeftToRightWritingMode:
1726 return borderRightWidth();
1727 case RightToLeftWritingMode:
1728 return borderLeftWidth();
1730 ASSERT_NOT_REACHED();
1731 return borderBottomWidth();
1734 unsigned short RenderStyle::borderStartWidth() const
1736 if (isHorizontalWritingMode())
1737 return isLeftToRightDirection() ? borderLeftWidth() : borderRightWidth();
1738 return isLeftToRightDirection() ? borderTopWidth() : borderBottomWidth();
1741 unsigned short RenderStyle::borderEndWidth() const
1743 if (isHorizontalWritingMode())
1744 return isLeftToRightDirection() ? borderRightWidth() : borderLeftWidth();
1745 return isLeftToRightDirection() ? borderBottomWidth() : borderTopWidth();
1748 void RenderStyle::setMarginStart(Length margin)
1750 if (isHorizontalWritingMode()) {
1751 if (isLeftToRightDirection())
1752 setMarginLeft(margin);
1754 setMarginRight(margin);
1756 if (isLeftToRightDirection())
1757 setMarginTop(margin);
1759 setMarginBottom(margin);
1763 void RenderStyle::setMarginEnd(Length margin)
1765 if (isHorizontalWritingMode()) {
1766 if (isLeftToRightDirection())
1767 setMarginRight(margin);
1769 setMarginLeft(margin);
1771 if (isLeftToRightDirection())
1772 setMarginBottom(margin);
1774 setMarginTop(margin);
1778 TextEmphasisMark RenderStyle::textEmphasisMark() const
1780 TextEmphasisMark mark = static_cast<TextEmphasisMark>(rareInheritedData->textEmphasisMark);
1781 if (mark != TextEmphasisMarkAuto)
1784 if (isHorizontalWritingMode())
1785 return TextEmphasisMarkDot;
1787 return TextEmphasisMarkSesame;
1790 #if ENABLE(TOUCH_EVENTS)
1791 Color RenderStyle::initialTapHighlightColor()
1793 return RenderTheme::tapHighlightColor();
1797 LayoutBoxExtent RenderStyle::imageOutsets(const NinePieceImage& image) const
1799 return LayoutBoxExtent(NinePieceImage::computeOutset(image.outset().top(), borderTopWidth()),
1800 NinePieceImage::computeOutset(image.outset().right(), borderRightWidth()),
1801 NinePieceImage::computeOutset(image.outset().bottom(), borderBottomWidth()),
1802 NinePieceImage::computeOutset(image.outset().left(), borderLeftWidth()));
1805 void RenderStyle::getFontAndGlyphOrientation(FontOrientation& fontOrientation, NonCJKGlyphOrientation& glyphOrientation)
1807 if (isHorizontalWritingMode()) {
1808 fontOrientation = Horizontal;
1809 glyphOrientation = NonCJKGlyphOrientationVerticalRight;
1813 switch (textOrientation()) {
1814 case TextOrientationVerticalRight:
1815 fontOrientation = Vertical;
1816 glyphOrientation = NonCJKGlyphOrientationVerticalRight;
1818 case TextOrientationUpright:
1819 fontOrientation = Vertical;
1820 glyphOrientation = NonCJKGlyphOrientationUpright;
1822 case TextOrientationSideways:
1823 if (writingMode() == LeftToRightWritingMode) {
1824 // FIXME: This should map to sideways-left, which is not supported yet.
1825 fontOrientation = Vertical;
1826 glyphOrientation = NonCJKGlyphOrientationVerticalRight;
1829 fontOrientation = Horizontal;
1830 glyphOrientation = NonCJKGlyphOrientationVerticalRight;
1832 case TextOrientationSidewaysRight:
1833 fontOrientation = Horizontal;
1834 glyphOrientation = NonCJKGlyphOrientationVerticalRight;
1837 ASSERT_NOT_REACHED();
1838 fontOrientation = Horizontal;
1839 glyphOrientation = NonCJKGlyphOrientationVerticalRight;
1844 void RenderStyle::setBorderImageSource(PassRefPtr<StyleImage> image)
1846 if (surround->border.m_image.image() == image.get())
1848 surround.access()->border.m_image.setImage(image);
1851 void RenderStyle::setBorderImageSlices(LengthBox slices)
1853 if (surround->border.m_image.imageSlices() == slices)
1855 surround.access()->border.m_image.setImageSlices(slices);
1858 void RenderStyle::setBorderImageWidth(LengthBox slices)
1860 if (surround->border.m_image.borderSlices() == slices)
1862 surround.access()->border.m_image.setBorderSlices(slices);
1865 void RenderStyle::setBorderImageOutset(LengthBox outset)
1867 if (surround->border.m_image.outset() == outset)
1869 surround.access()->border.m_image.setOutset(outset);
1872 void RenderStyle::setColumnStylesFromPaginationMode(const Pagination::Mode& paginationMode)
1874 if (paginationMode == Pagination::Unpaginated)
1877 switch (paginationMode) {
1878 case Pagination::LeftToRightPaginated:
1879 setColumnAxis(HorizontalColumnAxis);
1880 if (isHorizontalWritingMode())
1881 setColumnProgression(isLeftToRightDirection() ? NormalColumnProgression : ReverseColumnProgression);
1883 setColumnProgression(isFlippedBlocksWritingMode() ? ReverseColumnProgression : NormalColumnProgression);
1885 case Pagination::RightToLeftPaginated:
1886 setColumnAxis(HorizontalColumnAxis);
1887 if (isHorizontalWritingMode())
1888 setColumnProgression(isLeftToRightDirection() ? ReverseColumnProgression : NormalColumnProgression);
1890 setColumnProgression(isFlippedBlocksWritingMode() ? NormalColumnProgression : ReverseColumnProgression);
1892 case Pagination::TopToBottomPaginated:
1893 setColumnAxis(VerticalColumnAxis);
1894 if (isHorizontalWritingMode())
1895 setColumnProgression(isFlippedBlocksWritingMode() ? ReverseColumnProgression : NormalColumnProgression);
1897 setColumnProgression(isLeftToRightDirection() ? NormalColumnProgression : ReverseColumnProgression);
1899 case Pagination::BottomToTopPaginated:
1900 setColumnAxis(VerticalColumnAxis);
1901 if (isHorizontalWritingMode())
1902 setColumnProgression(isFlippedBlocksWritingMode() ? NormalColumnProgression : ReverseColumnProgression);
1904 setColumnProgression(isLeftToRightDirection() ? ReverseColumnProgression : NormalColumnProgression);
1906 case Pagination::Unpaginated:
1907 ASSERT_NOT_REACHED();
1912 } // namespace WebCore