Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: Source/core/layout/style/LayoutStyle.cpp

Issue 1033943002: Rename LayoutStyle to papayawhip (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: ensureComputedStyle Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/layout/style/LayoutStyle.h ('k') | Source/core/layout/style/LayoutStyleConstants.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "core/layout/style/LayoutStyle.h"
25
26 #include "core/css/resolver/StyleResolver.h"
27 #include "core/layout/LayoutTheme.h"
28 #include "core/layout/TextAutosizer.h"
29 #include "core/layout/style/AppliedTextDecoration.h"
30 #include "core/layout/style/BorderEdge.h"
31 #include "core/layout/style/ContentData.h"
32 #include "core/layout/style/DataEquivalency.h"
33 #include "core/layout/style/LayoutStyleConstants.h"
34 #include "core/layout/style/PathStyleMotionPath.h"
35 #include "core/layout/style/QuotesData.h"
36 #include "core/layout/style/ShadowList.h"
37 #include "core/layout/style/StyleImage.h"
38 #include "core/layout/style/StyleInheritedData.h"
39 #include "platform/LengthFunctions.h"
40 #include "platform/RuntimeEnabledFeatures.h"
41 #include "platform/fonts/Font.h"
42 #include "platform/fonts/FontSelector.h"
43 #include "platform/geometry/FloatRoundedRect.h"
44 #include "wtf/MathExtras.h"
45
46 #include <algorithm>
47
48 namespace blink {
49
50 struct SameSizeAsBorderValue {
51 RGBA32 m_color;
52 unsigned m_width;
53 };
54
55 static_assert(sizeof(BorderValue) == sizeof(SameSizeAsBorderValue), "BorderValue should stay small");
56
57 struct SameSizeAsLayoutStyle : public RefCounted<SameSizeAsLayoutStyle> {
58 void* dataRefs[7];
59 void* ownPtrs[1];
60 void* dataRefSvgStyle;
61
62 struct InheritedFlags {
63 unsigned m_bitfields[2];
64 } inherited_flags;
65
66 struct NonInheritedFlags {
67 unsigned m_bitfields[2];
68 } noninherited_flags;
69 };
70
71 static_assert(sizeof(LayoutStyle) == sizeof(SameSizeAsLayoutStyle), "LayoutStyle should stay small");
72
73 PassRefPtr<LayoutStyle> LayoutStyle::create()
74 {
75 return adoptRef(new LayoutStyle());
76 }
77
78 PassRefPtr<LayoutStyle> LayoutStyle::createInitialStyle()
79 {
80 return adoptRef(new LayoutStyle(InitialStyle));
81 }
82
83 PassRefPtr<LayoutStyle> LayoutStyle::createAnonymousStyleWithDisplay(const Layou tStyle& parentStyle, EDisplay display)
84 {
85 RefPtr<LayoutStyle> newStyle = LayoutStyle::create();
86 newStyle->inheritFrom(parentStyle);
87 newStyle->inheritUnicodeBidiFrom(parentStyle);
88 newStyle->setDisplay(display);
89 return newStyle;
90 }
91
92 PassRefPtr<LayoutStyle> LayoutStyle::clone(const LayoutStyle& other)
93 {
94 return adoptRef(new LayoutStyle(other));
95 }
96
97 ALWAYS_INLINE LayoutStyle::LayoutStyle()
98 : m_box(initialStyle()->m_box)
99 , visual(initialStyle()->visual)
100 , m_background(initialStyle()->m_background)
101 , surround(initialStyle()->surround)
102 , rareNonInheritedData(initialStyle()->rareNonInheritedData)
103 , rareInheritedData(initialStyle()->rareInheritedData)
104 , inherited(initialStyle()->inherited)
105 , m_svgStyle(initialStyle()->m_svgStyle)
106 {
107 setBitDefaults(); // Would it be faster to copy this from the default style?
108 static_assert((sizeof(InheritedFlags) <= 8), "InheritedFlags should not grow ");
109 static_assert((sizeof(NonInheritedFlags) <= 8), "NonInheritedFlags should no t grow");
110 }
111
112 ALWAYS_INLINE LayoutStyle::LayoutStyle(InitialStyleTag)
113 {
114 setBitDefaults();
115
116 m_box.init();
117 visual.init();
118 m_background.init();
119 surround.init();
120 rareNonInheritedData.init();
121 rareNonInheritedData.access()->m_deprecatedFlexibleBox.init();
122 rareNonInheritedData.access()->m_flexibleBox.init();
123 rareNonInheritedData.access()->m_multiCol.init();
124 rareNonInheritedData.access()->m_transform.init();
125 rareNonInheritedData.access()->m_willChange.init();
126 rareNonInheritedData.access()->m_filter.init();
127 rareNonInheritedData.access()->m_grid.init();
128 rareNonInheritedData.access()->m_gridItem.init();
129 rareInheritedData.init();
130 inherited.init();
131 m_svgStyle.init();
132 }
133
134 ALWAYS_INLINE LayoutStyle::LayoutStyle(const LayoutStyle& o)
135 : RefCounted<LayoutStyle>()
136 , m_box(o.m_box)
137 , visual(o.visual)
138 , m_background(o.m_background)
139 , surround(o.surround)
140 , rareNonInheritedData(o.rareNonInheritedData)
141 , rareInheritedData(o.rareInheritedData)
142 , inherited(o.inherited)
143 , m_svgStyle(o.m_svgStyle)
144 , inherited_flags(o.inherited_flags)
145 , noninherited_flags(o.noninherited_flags)
146 {
147 }
148
149 static StyleRecalcChange diffPseudoStyles(const LayoutStyle& oldStyle, const Lay outStyle& newStyle)
150 {
151 // If the pseudoStyles have changed, we want any StyleRecalcChange that is n ot NoChange
152 // because setStyle will do the right thing with anything else.
153 if (!oldStyle.hasAnyPublicPseudoStyles())
154 return NoChange;
155 for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < FIRST_INTERNAL_PS EUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) {
156 if (!oldStyle.hasPseudoStyle(pseudoId))
157 continue;
158 const LayoutStyle* newPseudoStyle = newStyle.getCachedPseudoStyle(pseudo Id);
159 if (!newPseudoStyle)
160 return NoInherit;
161 const LayoutStyle* oldPseudoStyle = oldStyle.getCachedPseudoStyle(pseudo Id);
162 if (oldPseudoStyle && *oldPseudoStyle != *newPseudoStyle)
163 return NoInherit;
164 }
165 return NoChange;
166 }
167
168 StyleRecalcChange LayoutStyle::stylePropagationDiff(const LayoutStyle* oldStyle, const LayoutStyle* newStyle)
169 {
170 if ((!oldStyle && newStyle) || (oldStyle && !newStyle))
171 return Reattach;
172
173 if (!oldStyle && !newStyle)
174 return NoChange;
175
176 if (oldStyle->display() != newStyle->display()
177 || oldStyle->hasPseudoStyle(FIRST_LETTER) != newStyle->hasPseudoStyle(FI RST_LETTER)
178 || oldStyle->columnSpan() != newStyle->columnSpan()
179 || !oldStyle->contentDataEquivalent(newStyle)
180 || oldStyle->hasTextCombine() != newStyle->hasTextCombine()
181 || oldStyle->justifyItems() != newStyle->justifyItems()
182 || oldStyle->alignItems() != newStyle->alignItems())
183 return Reattach;
184
185 if (oldStyle->inheritedNotEqual(*newStyle))
186 return Inherit;
187
188 if (*oldStyle == *newStyle)
189 return diffPseudoStyles(*oldStyle, *newStyle);
190
191 if (oldStyle->hasExplicitlyInheritedProperties())
192 return Inherit;
193
194 return NoInherit;
195 }
196
197 ItemPosition LayoutStyle::resolveAlignment(const LayoutStyle& parentStyle, const LayoutStyle& childStyle, ItemPosition resolvedAutoPositionForLayoutObject)
198 {
199 // The auto keyword computes to the parent's align-items computed value, or to "stretch", if not set or "auto".
200 if (childStyle.alignSelf() == ItemPositionAuto)
201 return (parentStyle.alignItems() == ItemPositionAuto) ? resolvedAutoPosi tionForLayoutObject : parentStyle.alignItems();
202 return childStyle.alignSelf();
203 }
204
205 ItemPosition LayoutStyle::resolveJustification(const LayoutStyle& parentStyle, c onst LayoutStyle& childStyle, ItemPosition resolvedAutoPositionForLayoutObject)
206 {
207 if (childStyle.justifySelf() == ItemPositionAuto)
208 return (parentStyle.justifyItems() == ItemPositionAuto) ? resolvedAutoPo sitionForLayoutObject : parentStyle.justifyItems();
209 return childStyle.justifySelf();
210 }
211
212 void LayoutStyle::inheritFrom(const LayoutStyle& inheritParent, IsAtShadowBounda ry isAtShadowBoundary)
213 {
214 if (isAtShadowBoundary == AtShadowBoundary) {
215 // Even if surrounding content is user-editable, shadow DOM should act a s a single unit, and not necessarily be editable
216 EUserModify currentUserModify = userModify();
217 rareInheritedData = inheritParent.rareInheritedData;
218 setUserModify(currentUserModify);
219 } else {
220 rareInheritedData = inheritParent.rareInheritedData;
221 }
222 inherited = inheritParent.inherited;
223 inherited_flags = inheritParent.inherited_flags;
224 if (m_svgStyle != inheritParent.m_svgStyle)
225 m_svgStyle.access()->inheritFrom(inheritParent.m_svgStyle.get());
226 }
227
228 void LayoutStyle::copyNonInheritedFromCached(const LayoutStyle& other)
229 {
230 m_box = other.m_box;
231 visual = other.visual;
232 m_background = other.m_background;
233 surround = other.surround;
234 rareNonInheritedData = other.rareNonInheritedData;
235
236 // The flags are copied one-by-one because noninherited_flags contains a bun ch of stuff other than real style data.
237 // See comments for each skipped flag below.
238 noninherited_flags.effectiveDisplay = other.noninherited_flags.effectiveDisp lay;
239 noninherited_flags.originalDisplay = other.noninherited_flags.originalDispla y;
240 noninherited_flags.overflowX = other.noninherited_flags.overflowX;
241 noninherited_flags.overflowY = other.noninherited_flags.overflowY;
242 noninherited_flags.verticalAlign = other.noninherited_flags.verticalAlign;
243 noninherited_flags.clear = other.noninherited_flags.clear;
244 noninherited_flags.position = other.noninherited_flags.position;
245 noninherited_flags.floating = other.noninherited_flags.floating;
246 noninherited_flags.tableLayout = other.noninherited_flags.tableLayout;
247 noninherited_flags.unicodeBidi = other.noninherited_flags.unicodeBidi;
248 noninherited_flags.hasViewportUnits = other.noninherited_flags.hasViewportUn its;
249 noninherited_flags.pageBreakBefore = other.noninherited_flags.pageBreakBefor e;
250 noninherited_flags.pageBreakAfter = other.noninherited_flags.pageBreakAfter;
251 noninherited_flags.pageBreakInside = other.noninherited_flags.pageBreakInsid e;
252
253 // Correctly set during selector matching:
254 // noninherited_flags.styleType
255 // noninherited_flags.pseudoBits
256
257 // Set correctly while computing style for children:
258 // noninherited_flags.explicitInheritance
259
260 // unique() styles are not cacheable.
261 ASSERT(!other.noninherited_flags.unique);
262
263 // The following flags are set during matching before we decide that we get a
264 // match in the MatchedPropertiesCache which in turn calls this method. The
265 // reason why we don't copy these flags is that they're already correctly se t
266 // and that they may differ between elements which have the same set of matc hed
267 // properties. For instance, given the rule:
268 //
269 // :-webkit-any(:hover, :focus) { background-color: green }"
270 //
271 // A hovered element, and a focused element may use the same cached matched
272 // properties here, but the affectedBy flags will be set differently based o n
273 // the matching order of the :-webkit-any components.
274 //
275 // noninherited_flags.emptyState
276 // noninherited_flags.affectedByFocus
277 // noninherited_flags.affectedByHover
278 // noninherited_flags.affectedByActive
279 // noninherited_flags.affectedByDrag
280 // noninherited_flags.isLink
281
282 if (m_svgStyle != other.m_svgStyle)
283 m_svgStyle.access()->copyNonInheritedFromCached(other.m_svgStyle.get());
284 ASSERT(zoom() == initialZoom());
285 }
286
287 bool LayoutStyle::operator==(const LayoutStyle& o) const
288 {
289 // compare everything except the pseudoStyle pointer
290 return inherited_flags == o.inherited_flags
291 && noninherited_flags == o.noninherited_flags
292 && m_box == o.m_box
293 && visual == o.visual
294 && m_background == o.m_background
295 && surround == o.surround
296 && rareNonInheritedData == o.rareNonInheritedData
297 && rareInheritedData == o.rareInheritedData
298 && inherited == o.inherited
299 && m_svgStyle == o.m_svgStyle;
300 }
301
302 bool LayoutStyle::isStyleAvailable() const
303 {
304 return this != StyleResolver::styleNotYetAvailable();
305 }
306
307 bool LayoutStyle::hasUniquePseudoStyle() const
308 {
309 if (!m_cachedPseudoStyles || styleType() != NOPSEUDO)
310 return false;
311
312 for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) {
313 const LayoutStyle& pseudoStyle = *m_cachedPseudoStyles->at(i);
314 if (pseudoStyle.unique())
315 return true;
316 }
317
318 return false;
319 }
320
321 LayoutStyle* LayoutStyle::getCachedPseudoStyle(PseudoId pid) const
322 {
323 if (!m_cachedPseudoStyles || !m_cachedPseudoStyles->size())
324 return 0;
325
326 if (styleType() != NOPSEUDO)
327 return 0;
328
329 for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) {
330 LayoutStyle* pseudoStyle = m_cachedPseudoStyles->at(i).get();
331 if (pseudoStyle->styleType() == pid)
332 return pseudoStyle;
333 }
334
335 return 0;
336 }
337
338 LayoutStyle* LayoutStyle::addCachedPseudoStyle(PassRefPtr<LayoutStyle> pseudo)
339 {
340 if (!pseudo)
341 return 0;
342
343 ASSERT(pseudo->styleType() > NOPSEUDO);
344
345 LayoutStyle* result = pseudo.get();
346
347 if (!m_cachedPseudoStyles)
348 m_cachedPseudoStyles = adoptPtr(new PseudoStyleCache);
349
350 m_cachedPseudoStyles->append(pseudo);
351
352 return result;
353 }
354
355 void LayoutStyle::removeCachedPseudoStyle(PseudoId pid)
356 {
357 if (!m_cachedPseudoStyles)
358 return;
359 for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) {
360 LayoutStyle* pseudoStyle = m_cachedPseudoStyles->at(i).get();
361 if (pseudoStyle->styleType() == pid) {
362 m_cachedPseudoStyles->remove(i);
363 return;
364 }
365 }
366 }
367
368 bool LayoutStyle::inheritedNotEqual(const LayoutStyle& other) const
369 {
370 return inherited_flags != other.inherited_flags
371 || inherited != other.inherited
372 || font().loadingCustomFonts() != other.font().loadingCustomFonts()
373 || m_svgStyle->inheritedNotEqual(other.m_svgStyle.get())
374 || rareInheritedData != other.rareInheritedData;
375 }
376
377 bool LayoutStyle::inheritedDataShared(const LayoutStyle& other) const
378 {
379 // This is a fast check that only looks if the data structures are shared.
380 return inherited_flags == other.inherited_flags
381 && inherited.get() == other.inherited.get()
382 && m_svgStyle.get() == other.m_svgStyle.get()
383 && rareInheritedData.get() == other.rareInheritedData.get();
384 }
385
386 static bool dependenceOnContentHeightHasChanged(const LayoutStyle& a, const Layo utStyle& b)
387 {
388 // If top or bottom become auto/non-auto then it means we either have to sol ve height based
389 // on the content or stop doing so (http://www.w3.org/TR/CSS2/visudet.html#a bs-non-replaced-height)
390 // - either way requires a layout.
391 return a.logicalTop().isAuto() != b.logicalTop().isAuto() || a.logicalBottom ().isAuto() != b.logicalBottom().isAuto();
392 }
393
394 StyleDifference LayoutStyle::visualInvalidationDiff(const LayoutStyle& other) co nst
395 {
396 // Note, we use .get() on each DataRef below because DataRef::operator== wil l do a deep
397 // compare, which is duplicate work when we're going to compare each propert y inside
398 // this function anyway.
399
400 StyleDifference diff;
401 if (m_svgStyle.get() != other.m_svgStyle.get())
402 diff = m_svgStyle->diff(other.m_svgStyle.get());
403
404 if ((!diff.needsFullLayout() || !diff.needsPaintInvalidation()) && diffNeeds FullLayoutAndPaintInvalidation(other)) {
405 diff.setNeedsFullLayout();
406 diff.setNeedsPaintInvalidationObject();
407 }
408
409 if (!diff.needsFullLayout() && diffNeedsFullLayout(other))
410 diff.setNeedsFullLayout();
411
412 if (!diff.needsFullLayout() && surround->margin != other.surround->margin) {
413 // Relative-positioned elements collapse their margins so need a full la yout.
414 if (position() == AbsolutePosition || position() == FixedPosition)
415 diff.setNeedsPositionedMovementLayout();
416 else
417 diff.setNeedsFullLayout();
418 }
419
420 if (!diff.needsFullLayout() && position() != StaticPosition && surround->off set != other.surround->offset) {
421 // Optimize for the case where a positioned layer is moving but not chan ging size.
422 if (dependenceOnContentHeightHasChanged(*this, other))
423 diff.setNeedsFullLayout();
424 else
425 diff.setNeedsPositionedMovementLayout();
426 }
427
428 if (diffNeedsPaintInvalidationLayer(other))
429 diff.setNeedsPaintInvalidationLayer();
430 else if (diffNeedsPaintInvalidationObject(other))
431 diff.setNeedsPaintInvalidationObject();
432
433 updatePropertySpecificDifferences(other, diff);
434
435 // Cursors are not checked, since they will be set appropriately in response to mouse events,
436 // so they don't need to cause any paint invalidation or layout.
437
438 // Animations don't need to be checked either. We always set the new style o n the layoutObject, so we will get a chance to fire off
439 // the resulting transition properly.
440
441 return diff;
442 }
443
444 bool LayoutStyle::diffNeedsFullLayoutAndPaintInvalidation(const LayoutStyle& oth er) const
445 {
446 // FIXME: Not all cases in this method need both full layout and paint inval idation.
447 // Should move cases into diffNeedsFullLayout() if
448 // - don't need paint invalidation at all;
449 // - or the layoutObject knows how to exactly invalidate paints caused by th e layout change
450 // instead of forced full paint invalidation.
451
452 if (surround.get() != other.surround.get()) {
453 // If our border widths change, then we need to layout. Other changes to borders only necessitate a paint invalidation.
454 if (borderLeftWidth() != other.borderLeftWidth()
455 || borderTopWidth() != other.borderTopWidth()
456 || borderBottomWidth() != other.borderBottomWidth()
457 || borderRightWidth() != other.borderRightWidth())
458 return true;
459 }
460
461 if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
462 if (rareNonInheritedData->m_appearance != other.rareNonInheritedData->m_ appearance
463 || rareNonInheritedData->marginBeforeCollapse != other.rareNonInheri tedData->marginBeforeCollapse
464 || rareNonInheritedData->marginAfterCollapse != other.rareNonInherit edData->marginAfterCollapse
465 || rareNonInheritedData->lineClamp != other.rareNonInheritedData->li neClamp
466 || rareNonInheritedData->textOverflow != other.rareNonInheritedData- >textOverflow
467 || rareNonInheritedData->m_wrapFlow != other.rareNonInheritedData->m _wrapFlow
468 || rareNonInheritedData->m_wrapThrough != other.rareNonInheritedData ->m_wrapThrough
469 || rareNonInheritedData->m_shapeMargin != other.rareNonInheritedData ->m_shapeMargin
470 || rareNonInheritedData->m_order != other.rareNonInheritedData->m_or der
471 || rareNonInheritedData->m_justifyContent != other.rareNonInheritedD ata->m_justifyContent
472 || rareNonInheritedData->m_grid.get() != other.rareNonInheritedData- >m_grid.get()
473 || rareNonInheritedData->m_gridItem.get() != other.rareNonInheritedD ata->m_gridItem.get()
474 || rareNonInheritedData->m_textCombine != other.rareNonInheritedData ->m_textCombine
475 || rareNonInheritedData->hasFilters() != other.rareNonInheritedData- >hasFilters())
476 return true;
477
478 if (rareNonInheritedData->m_deprecatedFlexibleBox.get() != other.rareNon InheritedData->m_deprecatedFlexibleBox.get()
479 && *rareNonInheritedData->m_deprecatedFlexibleBox.get() != *other.ra reNonInheritedData->m_deprecatedFlexibleBox.get())
480 return true;
481
482 if (rareNonInheritedData->m_flexibleBox.get() != other.rareNonInheritedD ata->m_flexibleBox.get()
483 && *rareNonInheritedData->m_flexibleBox.get() != *other.rareNonInher itedData->m_flexibleBox.get())
484 return true;
485
486 // FIXME: We should add an optimized form of layout that just recomputes visual overflow.
487 if (!rareNonInheritedData->shadowDataEquivalent(*other.rareNonInheritedD ata.get()))
488 return true;
489
490 if (!rareNonInheritedData->reflectionDataEquivalent(*other.rareNonInheri tedData.get()))
491 return true;
492
493 if (rareNonInheritedData->m_multiCol.get() != other.rareNonInheritedData ->m_multiCol.get()
494 && *rareNonInheritedData->m_multiCol.get() != *other.rareNonInherite dData->m_multiCol.get())
495 return true;
496
497 // If the counter directives change, trigger a relayout to re-calculate counter values and rebuild the counter node tree.
498 const CounterDirectiveMap* mapA = rareNonInheritedData->m_counterDirecti ves.get();
499 const CounterDirectiveMap* mapB = other.rareNonInheritedData->m_counterD irectives.get();
500 if (!(mapA == mapB || (mapA && mapB && *mapA == *mapB)))
501 return true;
502
503 // We only need do layout for opacity changes if adding or losing opacit y could trigger a change
504 // in us being a stacking context.
505 if (hasAutoZIndex() != other.hasAutoZIndex() && rareNonInheritedData->ha sOpacity() != other.rareNonInheritedData->hasOpacity()) {
506 // FIXME: We would like to use SimplifiedLayout here, but we can't q uite do that yet.
507 // We need to make sure SimplifiedLayout can operate correctly on La youtInlines (we will need
508 // to add a selfNeedsSimplifiedLayout bit in order to not get confus ed and taint every line).
509 // In addition we need to solve the floating object issue when layer s come and go. Right now
510 // a full layout is necessary to keep floating object lists sane.
511 return true;
512 }
513 }
514
515 if (rareInheritedData.get() != other.rareInheritedData.get()) {
516 if (rareInheritedData->highlight != other.rareInheritedData->highlight
517 || rareInheritedData->indent != other.rareInheritedData->indent
518 || rareInheritedData->m_textAlignLast != other.rareInheritedData->m_ textAlignLast
519 || rareInheritedData->m_textIndentLine != other.rareInheritedData->m _textIndentLine
520 || rareInheritedData->m_effectiveZoom != other.rareInheritedData->m_ effectiveZoom
521 || rareInheritedData->wordBreak != other.rareInheritedData->wordBrea k
522 || rareInheritedData->overflowWrap != other.rareInheritedData->overf lowWrap
523 || rareInheritedData->lineBreak != other.rareInheritedData->lineBrea k
524 || rareInheritedData->textSecurity != other.rareInheritedData->textS ecurity
525 || rareInheritedData->hyphens != other.rareInheritedData->hyphens
526 || rareInheritedData->hyphenationLimitBefore != other.rareInheritedD ata->hyphenationLimitBefore
527 || rareInheritedData->hyphenationLimitAfter != other.rareInheritedDa ta->hyphenationLimitAfter
528 || rareInheritedData->hyphenationString != other.rareInheritedData-> hyphenationString
529 || rareInheritedData->locale != other.rareInheritedData->locale
530 || rareInheritedData->m_rubyPosition != other.rareInheritedData->m_r ubyPosition
531 || rareInheritedData->textEmphasisMark != other.rareInheritedData->t extEmphasisMark
532 || rareInheritedData->textEmphasisPosition != other.rareInheritedDat a->textEmphasisPosition
533 || rareInheritedData->textEmphasisCustomMark != other.rareInheritedD ata->textEmphasisCustomMark
534 || rareInheritedData->m_textJustify != other.rareInheritedData->m_te xtJustify
535 || rareInheritedData->m_textOrientation != other.rareInheritedData-> m_textOrientation
536 || rareInheritedData->m_tabSize != other.rareInheritedData->m_tabSiz e
537 || rareInheritedData->m_lineBoxContain != other.rareInheritedData->m _lineBoxContain
538 || rareInheritedData->listStyleImage != other.rareInheritedData->lis tStyleImage
539 || rareInheritedData->textStrokeWidth != other.rareInheritedData->te xtStrokeWidth)
540 return true;
541
542 if (!rareInheritedData->shadowDataEquivalent(*other.rareInheritedData.ge t()))
543 return true;
544
545 if (!rareInheritedData->quotesDataEquivalent(*other.rareInheritedData.ge t()))
546 return true;
547 }
548
549 if (inherited->textAutosizingMultiplier != other.inherited->textAutosizingMu ltiplier)
550 return true;
551
552 if (inherited->font.loadingCustomFonts() != other.inherited->font.loadingCus tomFonts())
553 return true;
554
555 if (inherited.get() != other.inherited.get()) {
556 if (inherited->line_height != other.inherited->line_height
557 || inherited->font != other.inherited->font
558 || inherited->horizontal_border_spacing != other.inherited->horizont al_border_spacing
559 || inherited->vertical_border_spacing != other.inherited->vertical_b order_spacing)
560 return true;
561 }
562
563 if (inherited_flags._box_direction != other.inherited_flags._box_direction
564 || inherited_flags.m_rtlOrdering != other.inherited_flags.m_rtlOrdering
565 || inherited_flags._text_align != other.inherited_flags._text_align
566 || inherited_flags._text_transform != other.inherited_flags._text_transf orm
567 || inherited_flags._direction != other.inherited_flags._direction
568 || inherited_flags._white_space != other.inherited_flags._white_space
569 || inherited_flags.m_writingMode != other.inherited_flags.m_writingMode)
570 return true;
571
572 if (noninherited_flags.overflowX != other.noninherited_flags.overflowX
573 || noninherited_flags.overflowY != other.noninherited_flags.overflowY
574 || noninherited_flags.clear != other.noninherited_flags.clear
575 || noninherited_flags.unicodeBidi != other.noninherited_flags.unicodeBid i
576 || noninherited_flags.floating != other.noninherited_flags.floating
577 || noninherited_flags.originalDisplay != other.noninherited_flags.origin alDisplay)
578 return true;
579
580 if (noninherited_flags.effectiveDisplay >= FIRST_TABLE_DISPLAY && noninherit ed_flags.effectiveDisplay <= LAST_TABLE_DISPLAY) {
581 if (inherited_flags._border_collapse != other.inherited_flags._border_co llapse
582 || inherited_flags._empty_cells != other.inherited_flags._empty_cell s
583 || inherited_flags._caption_side != other.inherited_flags._caption_s ide
584 || noninherited_flags.tableLayout != other.noninherited_flags.tableL ayout)
585 return true;
586
587 // In the collapsing border model, 'hidden' suppresses other borders, wh ile 'none'
588 // does not, so these style differences can be width differences.
589 if (inherited_flags._border_collapse
590 && ((borderTopStyle() == BHIDDEN && other.borderTopStyle() == BNONE)
591 || (borderTopStyle() == BNONE && other.borderTopStyle() == BHIDD EN)
592 || (borderBottomStyle() == BHIDDEN && other.borderBottomStyle() == BNONE)
593 || (borderBottomStyle() == BNONE && other.borderBottomStyle() == BHIDDEN)
594 || (borderLeftStyle() == BHIDDEN && other.borderLeftStyle() == B NONE)
595 || (borderLeftStyle() == BNONE && other.borderLeftStyle() == BHI DDEN)
596 || (borderRightStyle() == BHIDDEN && other.borderRightStyle() == BNONE)
597 || (borderRightStyle() == BNONE && other.borderRightStyle() == B HIDDEN)))
598 return true;
599 } else if (noninherited_flags.effectiveDisplay == LIST_ITEM) {
600 if (inherited_flags._list_style_type != other.inherited_flags._list_styl e_type
601 || inherited_flags._list_style_position != other.inherited_flags._li st_style_position)
602 return true;
603 }
604
605 if ((visibility() == COLLAPSE) != (other.visibility() == COLLAPSE))
606 return true;
607
608 if (!m_background->outline().visuallyEqual(other.m_background->outline())) {
609 // FIXME: We only really need to recompute the overflow but we don't hav e an optimized layout for it.
610 return true;
611 }
612
613 if (hasPseudoStyle(SCROLLBAR) != other.hasPseudoStyle(SCROLLBAR))
614 return true;
615
616 // Movement of non-static-positioned object is special cased in LayoutStyle: :visualInvalidationDiff().
617
618 return false;
619 }
620
621 bool LayoutStyle::diffNeedsFullLayout(const LayoutStyle& other) const
622 {
623 if (m_box.get() != other.m_box.get()) {
624 if (m_box->width() != other.m_box->width()
625 || m_box->minWidth() != other.m_box->minWidth()
626 || m_box->maxWidth() != other.m_box->maxWidth()
627 || m_box->height() != other.m_box->height()
628 || m_box->minHeight() != other.m_box->minHeight()
629 || m_box->maxHeight() != other.m_box->maxHeight())
630 return true;
631
632 if (m_box->verticalAlign() != other.m_box->verticalAlign())
633 return true;
634
635 if (m_box->boxSizing() != other.m_box->boxSizing())
636 return true;
637 }
638
639 if (noninherited_flags.verticalAlign != other.noninherited_flags.verticalAli gn
640 || noninherited_flags.position != other.noninherited_flags.position)
641 return true;
642
643 if (surround.get() != other.surround.get()) {
644 if (surround->padding != other.surround->padding)
645 return true;
646 }
647
648 if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
649 if (rareNonInheritedData->m_alignContent != other.rareNonInheritedData-> m_alignContent
650 || rareNonInheritedData->m_alignContentDistribution != other.rareNon InheritedData->m_alignContentDistribution
651 || rareNonInheritedData->m_alignItems != other.rareNonInheritedData- >m_alignItems
652 || rareNonInheritedData->m_alignSelf != other.rareNonInheritedData-> m_alignSelf)
653 return true;
654 }
655
656 return false;
657 }
658
659 bool LayoutStyle::diffNeedsPaintInvalidationLayer(const LayoutStyle& other) cons t
660 {
661 if (position() != StaticPosition && (visual->clip != other.visual->clip || v isual->hasAutoClip != other.visual->hasAutoClip))
662 return true;
663
664 if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
665 if (RuntimeEnabledFeatures::cssCompositingEnabled()
666 && (rareNonInheritedData->m_effectiveBlendMode != other.rareNonInher itedData->m_effectiveBlendMode
667 || rareNonInheritedData->m_isolation != other.rareNonInheritedDa ta->m_isolation))
668 return true;
669
670 if (rareNonInheritedData->m_mask != other.rareNonInheritedData->m_mask
671 || rareNonInheritedData->m_maskBoxImage != other.rareNonInheritedDat a->m_maskBoxImage)
672 return true;
673 }
674
675 return false;
676 }
677
678 bool LayoutStyle::diffNeedsPaintInvalidationObject(const LayoutStyle& other) con st
679 {
680 if (inherited_flags._visibility != other.inherited_flags._visibility
681 || inherited_flags.m_printColorAdjust != other.inherited_flags.m_printCo lorAdjust
682 || inherited_flags._insideLink != other.inherited_flags._insideLink
683 || !surround->border.visuallyEqual(other.surround->border)
684 || !m_background->visuallyEqual(*other.m_background))
685 return true;
686
687 if (rareInheritedData.get() != other.rareInheritedData.get()) {
688 if (rareInheritedData->userModify != other.rareInheritedData->userModify
689 || rareInheritedData->userSelect != other.rareInheritedData->userSel ect
690 || rareInheritedData->m_imageRendering != other.rareInheritedData->m _imageRendering)
691 return true;
692 }
693
694 if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
695 if (rareNonInheritedData->userDrag != other.rareNonInheritedData->userDr ag
696 || rareNonInheritedData->m_objectFit != other.rareNonInheritedData-> m_objectFit
697 || rareNonInheritedData->m_objectPosition != other.rareNonInheritedD ata->m_objectPosition
698 || !rareNonInheritedData->shapeOutsideDataEquivalent(*other.rareNonI nheritedData.get())
699 || !rareNonInheritedData->clipPathDataEquivalent(*other.rareNonInher itedData.get())
700 || (visitedLinkBorderLeftColor() != other.visitedLinkBorderLeftColor () && borderLeftWidth())
701 || (visitedLinkBorderRightColor() != other.visitedLinkBorderRightCol or() && borderRightWidth())
702 || (visitedLinkBorderBottomColor() != other.visitedLinkBorderBottomC olor() && borderBottomWidth())
703 || (visitedLinkBorderTopColor() != other.visitedLinkBorderTopColor() && borderTopWidth())
704 || (visitedLinkOutlineColor() != other.visitedLinkOutlineColor() && outlineWidth())
705 || (visitedLinkBackgroundColor() != other.visitedLinkBackgroundColor ()))
706 return true;
707 }
708
709 if (resize() != other.resize())
710 return true;
711
712 return false;
713 }
714
715 void LayoutStyle::updatePropertySpecificDifferences(const LayoutStyle& other, St yleDifference& diff) const
716 {
717 // StyleAdjuster has ensured that zIndex is non-auto only if it's applicable .
718 if (m_box->zIndex() != other.m_box->zIndex() || m_box->hasAutoZIndex() != ot her.m_box->hasAutoZIndex())
719 diff.setZIndexChanged();
720
721 if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
722 if (!transformDataEquivalent(other))
723 diff.setTransformChanged();
724
725 if (rareNonInheritedData->opacity != other.rareNonInheritedData->opacity )
726 diff.setOpacityChanged();
727
728 if (rareNonInheritedData->m_filter != other.rareNonInheritedData->m_filt er)
729 diff.setFilterChanged();
730 }
731
732 if (!diff.needsPaintInvalidation()) {
733 if (inherited->color != other.inherited->color
734 || inherited->visitedLinkColor != other.inherited->visitedLinkColor
735 || inherited_flags.m_textUnderline != other.inherited_flags.m_textUn derline
736 || visual->textDecoration != other.visual->textDecoration) {
737 diff.setTextOrColorChanged();
738 } else if (rareNonInheritedData.get() != other.rareNonInheritedData.get( )
739 && (rareNonInheritedData->m_textDecorationStyle != other.rareNonInhe ritedData->m_textDecorationStyle
740 || rareNonInheritedData->m_textDecorationColor != other.rareNonI nheritedData->m_textDecorationColor
741 || rareNonInheritedData->m_visitedLinkTextDecorationColor != oth er.rareNonInheritedData->m_visitedLinkTextDecorationColor)) {
742 diff.setTextOrColorChanged();
743 } else if (rareInheritedData.get() != other.rareInheritedData.get()
744 && (rareInheritedData->textFillColor() != other.rareInheritedData->t extFillColor()
745 || rareInheritedData->textStrokeColor() != other.rareInheritedDa ta->textStrokeColor()
746 || rareInheritedData->textEmphasisColor() != other.rareInherited Data->textEmphasisColor()
747 || rareInheritedData->visitedLinkTextFillColor() != other.rareIn heritedData->visitedLinkTextFillColor()
748 || rareInheritedData->visitedLinkTextStrokeColor() != other.rare InheritedData->visitedLinkTextStrokeColor()
749 || rareInheritedData->visitedLinkTextEmphasisColor() != other.ra reInheritedData->visitedLinkTextEmphasisColor()
750 || rareInheritedData->textEmphasisFill != other.rareInheritedDat a->textEmphasisFill
751 || rareInheritedData->appliedTextDecorations != other.rareInheri tedData->appliedTextDecorations)) {
752 diff.setTextOrColorChanged();
753 }
754 }
755 }
756
757 void LayoutStyle::addCursor(PassRefPtr<StyleImage> image, bool hotSpotSpecified, const IntPoint& hotSpot)
758 {
759 if (!rareInheritedData.access()->cursorData)
760 rareInheritedData.access()->cursorData = CursorList::create();
761 rareInheritedData.access()->cursorData->append(CursorData(image, hotSpotSpec ified, hotSpot));
762 }
763
764 void LayoutStyle::setCursorList(PassRefPtr<CursorList> other)
765 {
766 rareInheritedData.access()->cursorData = other;
767 }
768
769 void LayoutStyle::setQuotes(PassRefPtr<QuotesData> q)
770 {
771 rareInheritedData.access()->quotes = q;
772 }
773
774 void LayoutStyle::clearCursorList()
775 {
776 if (rareInheritedData->cursorData)
777 rareInheritedData.access()->cursorData = nullptr;
778 }
779
780 void LayoutStyle::addCallbackSelector(const String& selector)
781 {
782 if (!rareNonInheritedData->m_callbackSelectors.contains(selector))
783 rareNonInheritedData.access()->m_callbackSelectors.append(selector);
784 }
785
786 void LayoutStyle::clearContent()
787 {
788 if (rareNonInheritedData->m_content)
789 rareNonInheritedData.access()->m_content = nullptr;
790 }
791
792 void LayoutStyle::appendContent(PassOwnPtr<ContentData> contentData)
793 {
794 OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content;
795 ContentData* lastContent = content.get();
796 while (lastContent && lastContent->next())
797 lastContent = lastContent->next();
798
799 if (lastContent)
800 lastContent->setNext(contentData);
801 else
802 content = contentData;
803 }
804
805 void LayoutStyle::setContent(PassRefPtr<StyleImage> image, bool add)
806 {
807 if (!image)
808 return;
809
810 if (add) {
811 appendContent(ContentData::create(image));
812 return;
813 }
814
815 rareNonInheritedData.access()->m_content = ContentData::create(image);
816 }
817
818 void LayoutStyle::setContent(const String& string, bool add)
819 {
820 OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content;
821 if (add) {
822 ContentData* lastContent = content.get();
823 while (lastContent && lastContent->next())
824 lastContent = lastContent->next();
825
826 if (lastContent) {
827 // We attempt to merge with the last ContentData if possible.
828 if (lastContent->isText()) {
829 TextContentData* textContent = toTextContentData(lastContent);
830 textContent->setText(textContent->text() + string);
831 } else {
832 lastContent->setNext(ContentData::create(string));
833 }
834
835 return;
836 }
837 }
838
839 content = ContentData::create(string);
840 }
841
842 void LayoutStyle::setContent(PassOwnPtr<CounterContent> counter, bool add)
843 {
844 if (!counter)
845 return;
846
847 if (add) {
848 appendContent(ContentData::create(counter));
849 return;
850 }
851
852 rareNonInheritedData.access()->m_content = ContentData::create(counter);
853 }
854
855 void LayoutStyle::setContent(QuoteType quote, bool add)
856 {
857 if (add) {
858 appendContent(ContentData::create(quote));
859 return;
860 }
861
862 rareNonInheritedData.access()->m_content = ContentData::create(quote);
863 }
864
865 bool LayoutStyle::hasWillChangeCompositingHint() const
866 {
867 for (size_t i = 0; i < rareNonInheritedData->m_willChange->m_properties.size (); ++i) {
868 switch (rareNonInheritedData->m_willChange->m_properties[i]) {
869 case CSSPropertyOpacity:
870 case CSSPropertyTransform:
871 case CSSPropertyWebkitTransform:
872 case CSSPropertyTop:
873 case CSSPropertyLeft:
874 case CSSPropertyBottom:
875 case CSSPropertyRight:
876 return true;
877 default:
878 break;
879 }
880 }
881 return false;
882 }
883
884 inline bool requireTransformOrigin(const Vector<RefPtr<TransformOperation>>& tra nsformOperations, LayoutStyle::ApplyTransformOrigin applyOrigin, LayoutStyle::Ap plyMotionPath applyMotionPath)
885 {
886 // transform-origin brackets the transform with translate operations.
887 // Optimize for the case where the only transform is a translation, since th e transform-origin is irrelevant
888 // in that case.
889 if (applyOrigin != LayoutStyle::IncludeTransformOrigin)
890 return false;
891
892 if (applyMotionPath == LayoutStyle::IncludeMotionPath)
893 return true;
894
895 unsigned size = transformOperations.size();
896 for (unsigned i = 0; i < size; ++i) {
897 TransformOperation::OperationType type = transformOperations[i]->type();
898 if (type != TransformOperation::TranslateX
899 && type != TransformOperation::TranslateY
900 && type != TransformOperation::Translate
901 && type != TransformOperation::TranslateZ
902 && type != TransformOperation::Translate3D)
903 return true;
904 }
905
906 return false;
907 }
908
909 void LayoutStyle::applyTransform(TransformationMatrix& transform, const LayoutSi ze& borderBoxSize, ApplyTransformOrigin applyOrigin, ApplyMotionPath applyMotion Path) const
910 {
911 applyTransform(transform, FloatRect(FloatPoint(), FloatSize(borderBoxSize)), applyOrigin, applyMotionPath);
912 }
913
914 void LayoutStyle::applyTransform(TransformationMatrix& transform, const FloatRec t& boundingBox, ApplyTransformOrigin applyOrigin, ApplyMotionPath applyMotionPat h) const
915 {
916 if (!hasMotionPath())
917 applyMotionPath = ExcludeMotionPath;
918 const Vector<RefPtr<TransformOperation>>& transformOperations = rareNonInher itedData->m_transform->m_operations.operations();
919 bool applyTransformOrigin = requireTransformOrigin(transformOperations, appl yOrigin, applyMotionPath);
920
921 float offsetX = transformOriginX().type() == Percent ? boundingBox.x() : 0;
922 float offsetY = transformOriginY().type() == Percent ? boundingBox.y() : 0;
923
924 if (applyTransformOrigin) {
925 transform.translate3d(floatValueForLength(transformOriginX(), boundingBo x.width()) + offsetX,
926 floatValueForLength(transformOriginY(), boundingBox.height()) + offs etY,
927 transformOriginZ());
928 }
929
930 if (applyMotionPath == LayoutStyle::IncludeMotionPath)
931 applyMotionPathTransform(transform);
932
933 unsigned size = transformOperations.size();
934 for (unsigned i = 0; i < size; ++i)
935 transformOperations[i]->apply(transform, boundingBox.size());
936
937 if (applyTransformOrigin) {
938 transform.translate3d(-floatValueForLength(transformOriginX(), boundingB ox.width()) - offsetX,
939 -floatValueForLength(transformOriginY(), boundingBox.height()) - off setY,
940 -transformOriginZ());
941 }
942 }
943
944 void LayoutStyle::applyMotionPathTransform(TransformationMatrix& transform) cons t
945 {
946 const StyleMotionData& motionData = rareNonInheritedData->m_transform->m_mot ion;
947 ASSERT(motionData.m_path && motionData.m_path->isPathStyleMotionPath());
948 const PathStyleMotionPath& motionPath = toPathStyleMotionPath(*motionData.m_ path);
949 float pathLength = motionPath.length();
950 float distance = floatValueForLength(motionData.m_offset, pathLength);
951 float computedDistance;
952 if (motionPath.isClosed() && pathLength > 0) {
953 computedDistance = fmod(distance, pathLength);
954 if (computedDistance < 0)
955 computedDistance += pathLength;
956 } else {
957 computedDistance = clampTo<float>(distance, 0, pathLength);
958 }
959
960 FloatPoint point;
961 float angle;
962 if (!motionPath.path().pointAndNormalAtLength(computedDistance, point, angle ))
963 return;
964 if (motionData.m_rotationType == MotionRotationFixed)
965 angle = 0;
966
967 transform.translate(point.x(), point.y());
968 transform.rotate(angle + motionData.m_rotation);
969 }
970
971 void LayoutStyle::setTextShadow(PassRefPtr<ShadowList> s)
972 {
973 rareInheritedData.access()->textShadow = s;
974 }
975
976 void LayoutStyle::setBoxShadow(PassRefPtr<ShadowList> s)
977 {
978 rareNonInheritedData.access()->m_boxShadow = s;
979 }
980
981 static FloatRoundedRect::Radii calcRadiiFor(const BorderData& border, LayoutSize size)
982 {
983 return FloatRoundedRect::Radii(
984 IntSize(valueForLength(border.topLeft().width(), size.width()),
985 valueForLength(border.topLeft().height(), size.height())),
986 IntSize(valueForLength(border.topRight().width(), size.width()),
987 valueForLength(border.topRight().height(), size.height())),
988 IntSize(valueForLength(border.bottomLeft().width(), size.width()),
989 valueForLength(border.bottomLeft().height(), size.height())),
990 IntSize(valueForLength(border.bottomRight().width(), size.width()),
991 valueForLength(border.bottomRight().height(), size.height())));
992 }
993
994 StyleImage* LayoutStyle::listStyleImage() const { return rareInheritedData->list StyleImage.get(); }
995 void LayoutStyle::setListStyleImage(PassRefPtr<StyleImage> v)
996 {
997 if (rareInheritedData->listStyleImage != v)
998 rareInheritedData.access()->listStyleImage = v;
999 }
1000
1001 Color LayoutStyle::color() const { return inherited->color; }
1002 Color LayoutStyle::visitedLinkColor() const { return inherited->visitedLinkColor ; }
1003 void LayoutStyle::setColor(const Color& v) { SET_VAR(inherited, color, v); }
1004 void LayoutStyle::setVisitedLinkColor(const Color& v) { SET_VAR(inherited, visit edLinkColor, v); }
1005
1006 short LayoutStyle::horizontalBorderSpacing() const { return inherited->horizonta l_border_spacing; }
1007 short LayoutStyle::verticalBorderSpacing() const { return inherited->vertical_bo rder_spacing; }
1008 void LayoutStyle::setHorizontalBorderSpacing(short v) { SET_VAR(inherited, horiz ontal_border_spacing, v); }
1009 void LayoutStyle::setVerticalBorderSpacing(short v) { SET_VAR(inherited, vertica l_border_spacing, v); }
1010
1011 FloatRoundedRect LayoutStyle::getRoundedBorderFor(const LayoutRect& borderRect, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
1012 {
1013 FloatRoundedRect roundedRect(pixelSnappedIntRect(borderRect));
1014 if (hasBorderRadius()) {
1015 FloatRoundedRect::Radii radii = calcRadiiFor(surround->border, borderRec t.size());
1016 roundedRect.includeLogicalEdges(radii, isHorizontalWritingMode(), includ eLogicalLeftEdge, includeLogicalRightEdge);
1017 roundedRect.constrainRadii();
1018 }
1019 return roundedRect;
1020 }
1021
1022 FloatRoundedRect LayoutStyle::getRoundedInnerBorderFor(const LayoutRect& borderR ect, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
1023 {
1024 bool horizontal = isHorizontalWritingMode();
1025
1026 int leftWidth = (!horizontal || includeLogicalLeftEdge) ? borderLeftWidth() : 0;
1027 int rightWidth = (!horizontal || includeLogicalRightEdge) ? borderRightWidth () : 0;
1028 int topWidth = (horizontal || includeLogicalLeftEdge) ? borderTopWidth() : 0 ;
1029 int bottomWidth = (horizontal || includeLogicalRightEdge) ? borderBottomWidt h() : 0;
1030
1031 return getRoundedInnerBorderFor(borderRect, topWidth, bottomWidth, leftWidth , rightWidth, includeLogicalLeftEdge, includeLogicalRightEdge);
1032 }
1033
1034 FloatRoundedRect LayoutStyle::getRoundedInnerBorderFor(const LayoutRect& borderR ect,
1035 int topWidth, int bottomWidth, int leftWidth, int rightWidth, bool includeLo gicalLeftEdge, bool includeLogicalRightEdge) const
1036 {
1037 LayoutRect innerRect(borderRect.x() + leftWidth,
1038 borderRect.y() + topWidth,
1039 borderRect.width() - leftWidth - rightWidth,
1040 borderRect.height() - topWidth - bottomWidth);
1041
1042 FloatRoundedRect roundedRect(pixelSnappedIntRect(innerRect));
1043
1044 if (hasBorderRadius()) {
1045 FloatRoundedRect::Radii radii = getRoundedBorderFor(borderRect).radii();
1046 radii.shrink(topWidth, bottomWidth, leftWidth, rightWidth);
1047 roundedRect.includeLogicalEdges(radii, isHorizontalWritingMode(), includ eLogicalLeftEdge, includeLogicalRightEdge);
1048 }
1049 return roundedRect;
1050 }
1051
1052 static bool allLayersAreFixed(const FillLayer& layer)
1053 {
1054 for (const FillLayer* currLayer = &layer; currLayer; currLayer = currLayer-> next()) {
1055 if (!currLayer->image() || currLayer->attachment() != FixedBackgroundAtt achment)
1056 return false;
1057 }
1058
1059 return true;
1060 }
1061
1062 bool LayoutStyle::hasEntirelyFixedBackground() const
1063 {
1064 return allLayersAreFixed(backgroundLayers());
1065 }
1066
1067 const CounterDirectiveMap* LayoutStyle::counterDirectives() const
1068 {
1069 return rareNonInheritedData->m_counterDirectives.get();
1070 }
1071
1072 CounterDirectiveMap& LayoutStyle::accessCounterDirectives()
1073 {
1074 OwnPtr<CounterDirectiveMap>& map = rareNonInheritedData.access()->m_counterD irectives;
1075 if (!map)
1076 map = adoptPtr(new CounterDirectiveMap);
1077 return *map;
1078 }
1079
1080 const CounterDirectives LayoutStyle::getCounterDirectives(const AtomicString& id entifier) const
1081 {
1082 if (const CounterDirectiveMap* directives = counterDirectives())
1083 return directives->get(identifier);
1084 return CounterDirectives();
1085 }
1086
1087 void LayoutStyle::clearIncrementDirectives()
1088 {
1089 if (!counterDirectives())
1090 return;
1091
1092 // This makes us copy even if we may not be removing any items.
1093 CounterDirectiveMap& map = accessCounterDirectives();
1094 typedef CounterDirectiveMap::iterator Iterator;
1095
1096 Iterator end = map.end();
1097 for (Iterator it = map.begin(); it != end; ++it)
1098 it->value.clearIncrement();
1099 }
1100
1101 void LayoutStyle::clearResetDirectives()
1102 {
1103 if (!counterDirectives())
1104 return;
1105
1106 // This makes us copy even if we may not be removing any items.
1107 CounterDirectiveMap& map = accessCounterDirectives();
1108 typedef CounterDirectiveMap::iterator Iterator;
1109
1110 Iterator end = map.end();
1111 for (Iterator it = map.begin(); it != end; ++it)
1112 it->value.clearReset();
1113 }
1114
1115 const AtomicString& LayoutStyle::hyphenString() const
1116 {
1117 const AtomicString& hyphenationString = rareInheritedData.get()->hyphenation String;
1118 if (!hyphenationString.isNull())
1119 return hyphenationString;
1120
1121 // FIXME: This should depend on locale.
1122 DEFINE_STATIC_LOCAL(AtomicString, hyphenMinusString, (&hyphenMinus, 1));
1123 DEFINE_STATIC_LOCAL(AtomicString, hyphenString, (&hyphen, 1));
1124 return font().primaryFontHasGlyphForCharacter(hyphen) ? hyphenString : hyphe nMinusString;
1125 }
1126
1127 const AtomicString& LayoutStyle::textEmphasisMarkString() const
1128 {
1129 switch (textEmphasisMark()) {
1130 case TextEmphasisMarkNone:
1131 return nullAtom;
1132 case TextEmphasisMarkCustom:
1133 return textEmphasisCustomMark();
1134 case TextEmphasisMarkDot: {
1135 DEFINE_STATIC_LOCAL(AtomicString, filledDotString, (&bullet, 1));
1136 DEFINE_STATIC_LOCAL(AtomicString, openDotString, (&whiteBullet, 1));
1137 return textEmphasisFill() == TextEmphasisFillFilled ? filledDotString : openDotString;
1138 }
1139 case TextEmphasisMarkCircle: {
1140 DEFINE_STATIC_LOCAL(AtomicString, filledCircleString, (&blackCircle, 1)) ;
1141 DEFINE_STATIC_LOCAL(AtomicString, openCircleString, (&whiteCircle, 1));
1142 return textEmphasisFill() == TextEmphasisFillFilled ? filledCircleString : openCircleString;
1143 }
1144 case TextEmphasisMarkDoubleCircle: {
1145 DEFINE_STATIC_LOCAL(AtomicString, filledDoubleCircleString, (&fisheye, 1 ));
1146 DEFINE_STATIC_LOCAL(AtomicString, openDoubleCircleString, (&bullseye, 1) );
1147 return textEmphasisFill() == TextEmphasisFillFilled ? filledDoubleCircle String : openDoubleCircleString;
1148 }
1149 case TextEmphasisMarkTriangle: {
1150 DEFINE_STATIC_LOCAL(AtomicString, filledTriangleString, (&blackUpPointin gTriangle, 1));
1151 DEFINE_STATIC_LOCAL(AtomicString, openTriangleString, (&whiteUpPointingT riangle, 1));
1152 return textEmphasisFill() == TextEmphasisFillFilled ? filledTriangleStri ng : openTriangleString;
1153 }
1154 case TextEmphasisMarkSesame: {
1155 DEFINE_STATIC_LOCAL(AtomicString, filledSesameString, (&sesameDot, 1));
1156 DEFINE_STATIC_LOCAL(AtomicString, openSesameString, (&whiteSesameDot, 1) );
1157 return textEmphasisFill() == TextEmphasisFillFilled ? filledSesameString : openSesameString;
1158 }
1159 case TextEmphasisMarkAuto:
1160 ASSERT_NOT_REACHED();
1161 return nullAtom;
1162 }
1163
1164 ASSERT_NOT_REACHED();
1165 return nullAtom;
1166 }
1167
1168 CSSAnimationData& LayoutStyle::accessAnimations()
1169 {
1170 if (!rareNonInheritedData.access()->m_animations)
1171 rareNonInheritedData.access()->m_animations = CSSAnimationData::create() ;
1172 return *rareNonInheritedData->m_animations;
1173 }
1174
1175 CSSTransitionData& LayoutStyle::accessTransitions()
1176 {
1177 if (!rareNonInheritedData.access()->m_transitions)
1178 rareNonInheritedData.access()->m_transitions = CSSTransitionData::create ();
1179 return *rareNonInheritedData->m_transitions;
1180 }
1181
1182 const Font& LayoutStyle::font() const { return inherited->font; }
1183 const FontMetrics& LayoutStyle::fontMetrics() const { return inherited->font.fon tMetrics(); }
1184 const FontDescription& LayoutStyle::fontDescription() const { return inherited-> font.fontDescription(); }
1185 float LayoutStyle::specifiedFontSize() const { return fontDescription().specifie dSize(); }
1186 float LayoutStyle::computedFontSize() const { return fontDescription().computedS ize(); }
1187 int LayoutStyle::fontSize() const { return fontDescription().computedPixelSize() ; }
1188 float LayoutStyle::fontSizeAdjust() const { return fontDescription().sizeAdjust( ); }
1189 bool LayoutStyle::hasFontSizeAdjust() const { return fontDescription().hasSizeAd just(); }
1190 FontWeight LayoutStyle::fontWeight() const { return fontDescription().weight(); }
1191 FontStretch LayoutStyle::fontStretch() const { return fontDescription().stretch( ); }
1192
1193 TextDecoration LayoutStyle::textDecorationsInEffect() const
1194 {
1195 int decorations = 0;
1196
1197 const Vector<AppliedTextDecoration>& applied = appliedTextDecorations();
1198
1199 for (size_t i = 0; i < applied.size(); ++i)
1200 decorations |= applied[i].line();
1201
1202 return static_cast<TextDecoration>(decorations);
1203 }
1204
1205 const Vector<AppliedTextDecoration>& LayoutStyle::appliedTextDecorations() const
1206 {
1207 if (!inherited_flags.m_textUnderline && !rareInheritedData->appliedTextDecor ations) {
1208 DEFINE_STATIC_LOCAL(Vector<AppliedTextDecoration>, empty, ());
1209 return empty;
1210 }
1211 if (inherited_flags.m_textUnderline) {
1212 DEFINE_STATIC_LOCAL(Vector<AppliedTextDecoration>, underline, (1, Applie dTextDecoration(TextDecorationUnderline)));
1213 return underline;
1214 }
1215
1216 return rareInheritedData->appliedTextDecorations->vector();
1217 }
1218
1219 float LayoutStyle::wordSpacing() const { return fontDescription().wordSpacing(); }
1220 float LayoutStyle::letterSpacing() const { return fontDescription().letterSpacin g(); }
1221
1222 bool LayoutStyle::setFontDescription(const FontDescription& v)
1223 {
1224 if (inherited->font.fontDescription() != v) {
1225 inherited.access()->font = Font(v);
1226 return true;
1227 }
1228 return false;
1229 }
1230
1231 const Length& LayoutStyle::specifiedLineHeight() const { return inherited->line_ height; }
1232 Length LayoutStyle::lineHeight() const
1233 {
1234 const Length& lh = inherited->line_height;
1235 // Unlike fontDescription().computedSize() and hence fontSize(), this is
1236 // recalculated on demand as we only store the specified line height.
1237 // FIXME: Should consider scaling the fixed part of any calc expressions
1238 // too, though this involves messily poking into CalcExpressionLength.
1239 float multiplier = textAutosizingMultiplier();
1240 if (multiplier > 1 && lh.isFixed())
1241 return Length(TextAutosizer::computeAutosizedFontSize(lh.value(), multip lier), Fixed);
1242
1243 return lh;
1244 }
1245
1246 void LayoutStyle::setLineHeight(const Length& specifiedLineHeight) { SET_VAR(inh erited, line_height, specifiedLineHeight); }
1247
1248 int LayoutStyle::computedLineHeight() const
1249 {
1250 const Length& lh = lineHeight();
1251
1252 // Negative value means the line height is not set. Use the font's built-in spacing.
1253 if (lh.isNegative())
1254 return fontMetrics().lineSpacing();
1255
1256 if (lh.isPercent())
1257 return minimumValueForLength(lh, fontSize());
1258
1259 return lh.value();
1260 }
1261
1262 void LayoutStyle::setWordSpacing(float wordSpacing)
1263 {
1264 FontSelector* currentFontSelector = font().fontSelector();
1265 FontDescription desc(fontDescription());
1266 desc.setWordSpacing(wordSpacing);
1267 setFontDescription(desc);
1268 font().update(currentFontSelector);
1269 }
1270
1271 void LayoutStyle::setLetterSpacing(float letterSpacing)
1272 {
1273 FontSelector* currentFontSelector = font().fontSelector();
1274 FontDescription desc(fontDescription());
1275 desc.setLetterSpacing(letterSpacing);
1276 setFontDescription(desc);
1277 font().update(currentFontSelector);
1278 }
1279
1280 void LayoutStyle::setTextAutosizingMultiplier(float multiplier)
1281 {
1282 SET_VAR(inherited, textAutosizingMultiplier, multiplier);
1283
1284 float size = specifiedFontSize();
1285
1286 ASSERT(std::isfinite(size));
1287 if (!std::isfinite(size) || size < 0)
1288 size = 0;
1289 else
1290 size = std::min(maximumAllowedFontSize, size);
1291
1292 FontSelector* currentFontSelector = font().fontSelector();
1293 FontDescription desc(fontDescription());
1294 desc.setSpecifiedSize(size);
1295 desc.setComputedSize(size);
1296
1297 if (multiplier > 1) {
1298 float autosizedFontSize = TextAutosizer::computeAutosizedFontSize(size, multiplier);
1299 desc.setComputedSize(std::min(maximumAllowedFontSize, autosizedFontSize) );
1300 }
1301
1302 setFontDescription(desc);
1303 font().update(currentFontSelector);
1304 }
1305
1306 void LayoutStyle::addAppliedTextDecoration(const AppliedTextDecoration& decorati on)
1307 {
1308 RefPtr<AppliedTextDecorationList>& list = rareInheritedData.access()->applie dTextDecorations;
1309
1310 if (!list)
1311 list = AppliedTextDecorationList::create();
1312 else if (!list->hasOneRef())
1313 list = list->copy();
1314
1315 if (inherited_flags.m_textUnderline) {
1316 inherited_flags.m_textUnderline = false;
1317 list->append(AppliedTextDecoration(TextDecorationUnderline));
1318 }
1319
1320 list->append(decoration);
1321 }
1322
1323 void LayoutStyle::applyTextDecorations()
1324 {
1325 if (textDecoration() == TextDecorationNone)
1326 return;
1327
1328 TextDecorationStyle style = textDecorationStyle();
1329 StyleColor styleColor = decorationColorIncludingFallback(insideLink() == Ins ideVisitedLink);
1330
1331 int decorations = textDecoration();
1332
1333 if (decorations & TextDecorationUnderline) {
1334 // To save memory, we don't use AppliedTextDecoration objects in the
1335 // common case of a single simple underline.
1336 AppliedTextDecoration underline(TextDecorationUnderline, style, styleCol or);
1337
1338 if (!rareInheritedData->appliedTextDecorations && underline.isSimpleUnde rline())
1339 inherited_flags.m_textUnderline = true;
1340 else
1341 addAppliedTextDecoration(underline);
1342 }
1343 if (decorations & TextDecorationOverline)
1344 addAppliedTextDecoration(AppliedTextDecoration(TextDecorationOverline, s tyle, styleColor));
1345 if (decorations & TextDecorationLineThrough)
1346 addAppliedTextDecoration(AppliedTextDecoration(TextDecorationLineThrough , style, styleColor));
1347 }
1348
1349 void LayoutStyle::clearAppliedTextDecorations()
1350 {
1351 inherited_flags.m_textUnderline = false;
1352
1353 if (rareInheritedData->appliedTextDecorations)
1354 rareInheritedData.access()->appliedTextDecorations = nullptr;
1355 }
1356
1357 void LayoutStyle::clearMultiCol()
1358 {
1359 rareNonInheritedData.access()->m_multiCol = nullptr;
1360 rareNonInheritedData.access()->m_multiCol.init();
1361 }
1362
1363 StyleColor LayoutStyle::decorationColorIncludingFallback(bool visitedLink) const
1364 {
1365 StyleColor styleColor = visitedLink ? visitedLinkTextDecorationColor() : tex tDecorationColor();
1366
1367 if (!styleColor.isCurrentColor())
1368 return styleColor;
1369
1370 if (textStrokeWidth()) {
1371 // Prefer stroke color if possible, but not if it's fully transparent.
1372 StyleColor textStrokeStyleColor = visitedLink ? visitedLinkTextStrokeCol or() : textStrokeColor();
1373 if (!textStrokeStyleColor.isCurrentColor() && textStrokeStyleColor.color ().alpha())
1374 return textStrokeStyleColor;
1375 }
1376
1377 return visitedLink ? visitedLinkTextFillColor() : textFillColor();
1378 }
1379
1380 Color LayoutStyle::colorIncludingFallback(int colorProperty, bool visitedLink) c onst
1381 {
1382 StyleColor result(StyleColor::currentColor());
1383 EBorderStyle borderStyle = BNONE;
1384 switch (colorProperty) {
1385 case CSSPropertyBackgroundColor:
1386 result = visitedLink ? visitedLinkBackgroundColor() : backgroundColor();
1387 break;
1388 case CSSPropertyBorderLeftColor:
1389 result = visitedLink ? visitedLinkBorderLeftColor() : borderLeftColor();
1390 borderStyle = borderLeftStyle();
1391 break;
1392 case CSSPropertyBorderRightColor:
1393 result = visitedLink ? visitedLinkBorderRightColor() : borderRightColor( );
1394 borderStyle = borderRightStyle();
1395 break;
1396 case CSSPropertyBorderTopColor:
1397 result = visitedLink ? visitedLinkBorderTopColor() : borderTopColor();
1398 borderStyle = borderTopStyle();
1399 break;
1400 case CSSPropertyBorderBottomColor:
1401 result = visitedLink ? visitedLinkBorderBottomColor() : borderBottomColo r();
1402 borderStyle = borderBottomStyle();
1403 break;
1404 case CSSPropertyColor:
1405 result = visitedLink ? visitedLinkColor() : color();
1406 break;
1407 case CSSPropertyOutlineColor:
1408 result = visitedLink ? visitedLinkOutlineColor() : outlineColor();
1409 break;
1410 case CSSPropertyWebkitColumnRuleColor:
1411 result = visitedLink ? visitedLinkColumnRuleColor() : columnRuleColor();
1412 break;
1413 case CSSPropertyWebkitTextEmphasisColor:
1414 result = visitedLink ? visitedLinkTextEmphasisColor() : textEmphasisColo r();
1415 break;
1416 case CSSPropertyWebkitTextFillColor:
1417 result = visitedLink ? visitedLinkTextFillColor() : textFillColor();
1418 break;
1419 case CSSPropertyWebkitTextStrokeColor:
1420 result = visitedLink ? visitedLinkTextStrokeColor() : textStrokeColor();
1421 break;
1422 case CSSPropertyFloodColor:
1423 result = floodColor();
1424 break;
1425 case CSSPropertyLightingColor:
1426 result = lightingColor();
1427 break;
1428 case CSSPropertyStopColor:
1429 result = stopColor();
1430 break;
1431 case CSSPropertyWebkitTapHighlightColor:
1432 result = tapHighlightColor();
1433 break;
1434 case CSSPropertyTextDecorationColor:
1435 result = decorationColorIncludingFallback(visitedLink);
1436 break;
1437 default:
1438 ASSERT_NOT_REACHED();
1439 break;
1440 }
1441
1442 if (!result.isCurrentColor())
1443 return result.color();
1444
1445 // FIXME: Treating styled borders with initial color differently causes prob lems
1446 // See crbug.com/316559, crbug.com/276231
1447 if (!visitedLink && (borderStyle == INSET || borderStyle == OUTSET || border Style == RIDGE || borderStyle == GROOVE))
1448 return Color(238, 238, 238);
1449 return visitedLink ? visitedLinkColor() : color();
1450 }
1451
1452 Color LayoutStyle::visitedDependentColor(int colorProperty) const
1453 {
1454 Color unvisitedColor = colorIncludingFallback(colorProperty, false);
1455 if (insideLink() != InsideVisitedLink)
1456 return unvisitedColor;
1457
1458 Color visitedColor = colorIncludingFallback(colorProperty, true);
1459
1460 // FIXME: Technically someone could explicitly specify the color transparent , but for now we'll just
1461 // assume that if the background color is transparent that it wasn't set. No te that it's weird that
1462 // we're returning unvisited info for a visited link, but given our restrict ion that the alpha values
1463 // have to match, it makes more sense to return the unvisited background col or if specified than it
1464 // does to return black. This behavior matches what Firefox 4 does as well.
1465 if (colorProperty == CSSPropertyBackgroundColor && visitedColor == Color::tr ansparent)
1466 return unvisitedColor;
1467
1468 // Take the alpha from the unvisited color, but get the RGB values from the visited color.
1469 return Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), unvisitedColor.alpha());
1470 }
1471
1472 const BorderValue& LayoutStyle::borderBefore() const
1473 {
1474 switch (writingMode()) {
1475 case TopToBottomWritingMode:
1476 return borderTop();
1477 case BottomToTopWritingMode:
1478 return borderBottom();
1479 case LeftToRightWritingMode:
1480 return borderLeft();
1481 case RightToLeftWritingMode:
1482 return borderRight();
1483 }
1484 ASSERT_NOT_REACHED();
1485 return borderTop();
1486 }
1487
1488 const BorderValue& LayoutStyle::borderAfter() const
1489 {
1490 switch (writingMode()) {
1491 case TopToBottomWritingMode:
1492 return borderBottom();
1493 case BottomToTopWritingMode:
1494 return borderTop();
1495 case LeftToRightWritingMode:
1496 return borderRight();
1497 case RightToLeftWritingMode:
1498 return borderLeft();
1499 }
1500 ASSERT_NOT_REACHED();
1501 return borderBottom();
1502 }
1503
1504 const BorderValue& LayoutStyle::borderStart() const
1505 {
1506 if (isHorizontalWritingMode())
1507 return isLeftToRightDirection() ? borderLeft() : borderRight();
1508 return isLeftToRightDirection() ? borderTop() : borderBottom();
1509 }
1510
1511 const BorderValue& LayoutStyle::borderEnd() const
1512 {
1513 if (isHorizontalWritingMode())
1514 return isLeftToRightDirection() ? borderRight() : borderLeft();
1515 return isLeftToRightDirection() ? borderBottom() : borderTop();
1516 }
1517
1518 unsigned short LayoutStyle::borderBeforeWidth() const
1519 {
1520 switch (writingMode()) {
1521 case TopToBottomWritingMode:
1522 return borderTopWidth();
1523 case BottomToTopWritingMode:
1524 return borderBottomWidth();
1525 case LeftToRightWritingMode:
1526 return borderLeftWidth();
1527 case RightToLeftWritingMode:
1528 return borderRightWidth();
1529 }
1530 ASSERT_NOT_REACHED();
1531 return borderTopWidth();
1532 }
1533
1534 unsigned short LayoutStyle::borderAfterWidth() const
1535 {
1536 switch (writingMode()) {
1537 case TopToBottomWritingMode:
1538 return borderBottomWidth();
1539 case BottomToTopWritingMode:
1540 return borderTopWidth();
1541 case LeftToRightWritingMode:
1542 return borderRightWidth();
1543 case RightToLeftWritingMode:
1544 return borderLeftWidth();
1545 }
1546 ASSERT_NOT_REACHED();
1547 return borderBottomWidth();
1548 }
1549
1550 unsigned short LayoutStyle::borderStartWidth() const
1551 {
1552 if (isHorizontalWritingMode())
1553 return isLeftToRightDirection() ? borderLeftWidth() : borderRightWidth() ;
1554 return isLeftToRightDirection() ? borderTopWidth() : borderBottomWidth();
1555 }
1556
1557 unsigned short LayoutStyle::borderEndWidth() const
1558 {
1559 if (isHorizontalWritingMode())
1560 return isLeftToRightDirection() ? borderRightWidth() : borderLeftWidth() ;
1561 return isLeftToRightDirection() ? borderBottomWidth() : borderTopWidth();
1562 }
1563
1564 void LayoutStyle::setMarginStart(const Length& margin)
1565 {
1566 if (isHorizontalWritingMode()) {
1567 if (isLeftToRightDirection())
1568 setMarginLeft(margin);
1569 else
1570 setMarginRight(margin);
1571 } else {
1572 if (isLeftToRightDirection())
1573 setMarginTop(margin);
1574 else
1575 setMarginBottom(margin);
1576 }
1577 }
1578
1579 void LayoutStyle::setMarginEnd(const Length& margin)
1580 {
1581 if (isHorizontalWritingMode()) {
1582 if (isLeftToRightDirection())
1583 setMarginRight(margin);
1584 else
1585 setMarginLeft(margin);
1586 } else {
1587 if (isLeftToRightDirection())
1588 setMarginBottom(margin);
1589 else
1590 setMarginTop(margin);
1591 }
1592 }
1593
1594 void LayoutStyle::setMotionPath(PassRefPtr<StyleMotionPath> path)
1595 {
1596 ASSERT(path);
1597 rareNonInheritedData.access()->m_transform.access()->m_motion.m_path = path;
1598 }
1599
1600 void LayoutStyle::resetMotionPath()
1601 {
1602 rareNonInheritedData.access()->m_transform.access()->m_motion.m_path = nullp tr;
1603 }
1604
1605 bool LayoutStyle::columnRuleEquivalent(const LayoutStyle* otherStyle) const
1606 {
1607 return columnRuleStyle() == otherStyle->columnRuleStyle()
1608 && columnRuleWidth() == otherStyle->columnRuleWidth()
1609 && visitedDependentColor(CSSPropertyWebkitColumnRuleColor) == otherStyle ->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
1610 }
1611
1612 TextEmphasisMark LayoutStyle::textEmphasisMark() const
1613 {
1614 TextEmphasisMark mark = static_cast<TextEmphasisMark>(rareInheritedData->tex tEmphasisMark);
1615 if (mark != TextEmphasisMarkAuto)
1616 return mark;
1617
1618 if (isHorizontalWritingMode())
1619 return TextEmphasisMarkDot;
1620
1621 return TextEmphasisMarkSesame;
1622 }
1623
1624 Color LayoutStyle::initialTapHighlightColor()
1625 {
1626 return LayoutTheme::tapHighlightColor();
1627 }
1628
1629 #if ENABLE(OILPAN)
1630 const FilterOperations& LayoutStyle::initialFilter()
1631 {
1632 DEFINE_STATIC_LOCAL(Persistent<FilterOperationsWrapper>, ops, (FilterOperati onsWrapper::create()));
1633 return ops->operations();
1634 }
1635 #endif
1636
1637 LayoutRectOutsets LayoutStyle::imageOutsets(const NinePieceImage& image) const
1638 {
1639 return LayoutRectOutsets(
1640 NinePieceImage::computeOutset(image.outset().top(), borderTopWidth()),
1641 NinePieceImage::computeOutset(image.outset().right(), borderRightWidth() ),
1642 NinePieceImage::computeOutset(image.outset().bottom(), borderBottomWidth ()),
1643 NinePieceImage::computeOutset(image.outset().left(), borderLeftWidth())) ;
1644 }
1645
1646 void LayoutStyle::setBorderImageSource(PassRefPtr<StyleImage> image)
1647 {
1648 if (surround->border.m_image.image() == image.get())
1649 return;
1650 surround.access()->border.m_image.setImage(image);
1651 }
1652
1653 void LayoutStyle::setBorderImageSlices(const LengthBox& slices)
1654 {
1655 if (surround->border.m_image.imageSlices() == slices)
1656 return;
1657 surround.access()->border.m_image.setImageSlices(slices);
1658 }
1659
1660 void LayoutStyle::setBorderImageSlicesFill(bool fill)
1661 {
1662 if (surround->border.m_image.fill() == fill)
1663 return;
1664 surround.access()->border.m_image.setFill(fill);
1665 }
1666
1667 void LayoutStyle::setBorderImageWidth(const BorderImageLengthBox& slices)
1668 {
1669 if (surround->border.m_image.borderSlices() == slices)
1670 return;
1671 surround.access()->border.m_image.setBorderSlices(slices);
1672 }
1673
1674 void LayoutStyle::setBorderImageOutset(const BorderImageLengthBox& outset)
1675 {
1676 if (surround->border.m_image.outset() == outset)
1677 return;
1678 surround.access()->border.m_image.setOutset(outset);
1679 }
1680
1681 bool LayoutStyle::borderObscuresBackground() const
1682 {
1683 if (!hasBorder())
1684 return false;
1685
1686 // Bail if we have any border-image for now. We could look at the image alph a to improve this.
1687 if (borderImage().image())
1688 return false;
1689
1690 BorderEdge edges[4];
1691 getBorderEdgeInfo(edges);
1692
1693 for (int i = BSTop; i <= BSLeft; ++i) {
1694 const BorderEdge& currEdge = edges[i];
1695 if (!currEdge.obscuresBackground())
1696 return false;
1697 }
1698
1699 return true;
1700 }
1701
1702 void LayoutStyle::getBorderEdgeInfo(BorderEdge edges[], bool includeLogicalLeftE dge, bool includeLogicalRightEdge) const
1703 {
1704 bool horizontal = isHorizontalWritingMode();
1705
1706 edges[BSTop] = BorderEdge(borderTopWidth(),
1707 visitedDependentColor(CSSPropertyBorderTopColor),
1708 borderTopStyle(),
1709 borderTopIsTransparent(),
1710 horizontal || includeLogicalLeftEdge);
1711
1712 edges[BSRight] = BorderEdge(borderRightWidth(),
1713 visitedDependentColor(CSSPropertyBorderRightColor),
1714 borderRightStyle(),
1715 borderRightIsTransparent(),
1716 !horizontal || includeLogicalRightEdge);
1717
1718 edges[BSBottom] = BorderEdge(borderBottomWidth(),
1719 visitedDependentColor(CSSPropertyBorderBottomColor),
1720 borderBottomStyle(),
1721 borderBottomIsTransparent(),
1722 horizontal || includeLogicalRightEdge);
1723
1724 edges[BSLeft] = BorderEdge(borderLeftWidth(),
1725 visitedDependentColor(CSSPropertyBorderLeftColor),
1726 borderLeftStyle(),
1727 borderLeftIsTransparent(),
1728 !horizontal || includeLogicalLeftEdge);
1729 }
1730
1731 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/layout/style/LayoutStyle.h ('k') | Source/core/layout/style/LayoutStyleConstants.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698