1 /*
2  * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3  *           (C) 2000 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All
6  * rights reserved.
7  * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  *
24  */
25 
26 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_H_
27 #define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_H_
28 
29 #include <memory>
30 #include "base/util/type_safety/pass_key.h"
31 #include "third_party/blink/renderer/core/core_export.h"
32 #include "third_party/blink/renderer/core/css/css_property_names.h"
33 #include "third_party/blink/renderer/core/css/properties/css_property.h"
34 #include "third_party/blink/renderer/core/css/style_auto_color.h"
35 #include "third_party/blink/renderer/core/css/style_color.h"
36 #include "third_party/blink/renderer/core/layout/geometry/box_sides.h"
37 #include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
38 #include "third_party/blink/renderer/core/scroll/scroll_types.h"
39 #include "third_party/blink/renderer/core/style/border_value.h"
40 #include "third_party/blink/renderer/core/style/computed_style_base.h"
41 #include "third_party/blink/renderer/core/style/computed_style_constants.h"
42 #include "third_party/blink/renderer/core/style/computed_style_initial_values.h"
43 #include "third_party/blink/renderer/core/style/cursor_list.h"
44 #include "third_party/blink/renderer/core/style/data_ref.h"
45 #include "third_party/blink/renderer/core/style/svg_computed_style.h"
46 #include "third_party/blink/renderer/core/style/transform_origin.h"
47 #include "third_party/blink/renderer/platform/geometry/layout_rect_outsets.h"
48 #include "third_party/blink/renderer/platform/geometry/length.h"
49 #include "third_party/blink/renderer/platform/geometry/length_box.h"
50 #include "third_party/blink/renderer/platform/geometry/length_point.h"
51 #include "third_party/blink/renderer/platform/geometry/length_size.h"
52 #include "third_party/blink/renderer/platform/graphics/color.h"
53 #include "third_party/blink/renderer/platform/graphics/touch_action.h"
54 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
55 #include "third_party/blink/renderer/platform/text/text_direction.h"
56 #include "third_party/blink/renderer/platform/text/writing_direction_mode.h"
57 #include "third_party/blink/renderer/platform/text/writing_mode_utils.h"
58 #include "third_party/blink/renderer/platform/transforms/transform_operations.h"
59 #include "third_party/blink/renderer/platform/wtf/forward.h"
60 #include "third_party/blink/renderer/platform/wtf/leak_annotations.h"
61 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
62 #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
63 #include "third_party/blink/renderer/platform/wtf/vector.h"
64 
65 namespace blink {
66 
67 using std::max;
68 
69 class AppliedTextDecoration;
70 struct BorderEdge;
71 class ContentData;
72 class CounterDirectives;
73 class CSSAnimationData;
74 class FloodColor;
75 class CSSTransitionData;
76 class CSSVariableData;
77 class FilterOperations;
78 class Font;
79 class Hyphenation;
80 class LayoutTheme;
81 class NinePieceImage;
82 class ShadowList;
83 class ShapeValue;
84 class StyleAdjuster;
85 class StyleContentAlignmentData;
86 class StyleDifference;
87 class StyleImage;
88 class StyleInheritedVariables;
89 class StyleInitialData;
90 class StylePath;
91 class StyleResolver;
92 class StyleSelfAlignmentData;
93 class TransformationMatrix;
94 
95 typedef Vector<scoped_refptr<const ComputedStyle>, 4> PseudoElementStyleCache;
96 
97 namespace css_longhand {
98 
99 class Appearance;
100 class BackgroundColor;
101 class BorderBottomColor;
102 class BorderLeftColor;
103 class BorderRightColor;
104 class BorderTopColor;
105 class CaretColor;
106 class Clear;
107 class Color;
108 class ColumnRuleColor;
109 class Fill;
110 class Float;
111 class FloodColor;
112 class InternalVisitedBackgroundColor;
113 class InternalVisitedBorderBottomColor;
114 class InternalVisitedBorderLeftColor;
115 class InternalVisitedBorderRightColor;
116 class InternalVisitedBorderTopColor;
117 class InternalVisitedCaretColor;
118 class InternalVisitedColor;
119 class InternalVisitedColumnRuleColor;
120 class InternalVisitedOutlineColor;
121 class InternalVisitedTextDecorationColor;
122 class InternalVisitedTextEmphasisColor;
123 class InternalVisitedTextFillColor;
124 class InternalVisitedTextStrokeColor;
125 class LightingColor;
126 class OutlineColor;
127 class Resize;
128 class StopColor;
129 class Stroke;
130 class TextDecorationColor;
131 class WebkitTapHighlightColor;
132 class WebkitTextEmphasisColor;
133 class WebkitTextFillColor;
134 class WebkitTextStrokeColor;
135 
136 }  // namespace css_longhand
137 
138 // ComputedStyle stores the computed value [1] for every CSS property on an
139 // element and provides the interface between the style engine and the rest of
140 // Blink. It acts as a container where the computed value of every CSS property
141 // can be stored and retrieved:
142 //
143 //   auto style = ComputedStyle::Create();
144 //   style->SetDisplay(EDisplay::kNone); //'display' keyword property
145 //   style->Display();
146 //
147 // In addition to storing the computed value of every CSS property,
148 // ComputedStyle also contains various internal style information. Examples
149 // include cached_pseudo_element_styles_ (for storing pseudo element styles) and
150 // has_simple_underline_ (cached indicator flag of text-decoration). These are
151 // stored on ComputedStyle for two reasons:
152 //
153 //  1) They share the same lifetime as ComputedStyle, so it is convenient to
154 //  store them in the same object rather than a separate object that have to be
155 //  passed around as well.
156 //
157 //  2) Many of these data members can be packed as bit fields, so we use less
158 //  memory by packing them in this object with other bit fields.
159 //
160 // STORAGE:
161 //
162 // ComputedStyle is optimized for memory and performance. The data is not
163 // actually stored directly in ComputedStyle, but rather in a generated parent
164 // class ComputedStyleBase. This separation of concerns allows us to optimise
165 // the memory layout without affecting users of ComputedStyle. ComputedStyle
166 // inherits from ComputedStyleBase. For more about the memory layout, there is
167 // documentation in ComputedStyleBase and make_computed_style_base.py.
168 //
169 // INTERFACE:
170 //
171 // For most CSS properties, ComputedStyle provides a consistent interface which
172 // includes a getter, setter, and resetter (that resets the computed value to
173 // its initial value). Exceptions include vertical-align, which has a separate
174 // set of accessors for its length and its keyword components. Apart from
175 // accessors, ComputedStyle also has a wealth of helper functions.
176 //
177 // Because ComputedStyleBase defines simple accessors to every CSS property,
178 // ComputedStyle inherits these and so they are not redeclared in this file.
179 // This means that the interface to ComputedStyle is split between this file and
180 // ComputedStyleBase.h.
181 //
182 // [1] https://developer.mozilla.org/en-US/docs/Web/CSS/computed_value
183 //
184 // NOTE:
185 //
186 // Currently, some properties are stored in ComputedStyle and some in
187 // ComputedStyleBase. Eventually, the storage of all properties (except SVG
188 // ones) will be in ComputedStyleBase.
189 //
190 // Since this class is huge, do not mark all of it CORE_EXPORT.  Instead,
191 // export only the methods you need below.
192 class ComputedStyle : public ComputedStyleBase,
193                       public RefCounted<ComputedStyle> {
194   // Needed to allow access to private/protected getters of fields to allow diff
195   // generation
196   friend class ComputedStyleBase;
197   // Used by CSS animations. We can't allow them to animate based off visited
198   // colors.
199   friend class CSSPropertyEquality;
200 
201   // Accesses GetColor().
202   friend class ComputedStyleUtils;
203   // These get visited and unvisited colors separately.
204   friend class css_longhand::BackgroundColor;
205   friend class css_longhand::BorderBottomColor;
206   friend class css_longhand::BorderLeftColor;
207   friend class css_longhand::BorderRightColor;
208   friend class css_longhand::BorderTopColor;
209   friend class css_longhand::CaretColor;
210   friend class css_longhand::Clear;
211   friend class css_longhand::Color;
212   friend class css_longhand::ColumnRuleColor;
213   friend class css_longhand::Fill;
214   friend class css_longhand::Float;
215   friend class css_longhand::FloodColor;
216   friend class css_longhand::InternalVisitedBackgroundColor;
217   friend class css_longhand::InternalVisitedBorderBottomColor;
218   friend class css_longhand::InternalVisitedBorderLeftColor;
219   friend class css_longhand::InternalVisitedBorderRightColor;
220   friend class css_longhand::InternalVisitedBorderTopColor;
221   friend class css_longhand::InternalVisitedCaretColor;
222   friend class css_longhand::InternalVisitedColor;
223   friend class css_longhand::InternalVisitedColumnRuleColor;
224   friend class css_longhand::InternalVisitedOutlineColor;
225   friend class css_longhand::InternalVisitedTextDecorationColor;
226   friend class css_longhand::InternalVisitedTextEmphasisColor;
227   friend class css_longhand::InternalVisitedTextFillColor;
228   friend class css_longhand::InternalVisitedTextStrokeColor;
229   friend class css_longhand::LightingColor;
230   friend class css_longhand::OutlineColor;
231   friend class css_longhand::Resize;
232   friend class css_longhand::StopColor;
233   friend class css_longhand::Stroke;
234   friend class css_longhand::TextDecorationColor;
235   friend class css_longhand::WebkitTapHighlightColor;
236   friend class css_longhand::WebkitTextEmphasisColor;
237   friend class css_longhand::WebkitTextFillColor;
238   friend class css_longhand::WebkitTextStrokeColor;
239   // Access to private Appearance() and HasAppearance().
240   friend class LayoutTheme;
241   friend class StyleAdjuster;
242   friend class StyleCascade;
243   friend class css_longhand::Appearance;
244   // Editing has to only reveal unvisited info.
245   friend class ApplyStyleCommand;
246   // Editing has to only reveal unvisited info.
247   friend class EditingStyle;
248   // Needs to be able to see visited and unvisited colors for devtools.
249   friend class ComputedStyleCSSValueMapping;
250   // Sets color styles
251   friend class StyleBuilderFunctions;
252   // Saves Border/Background information for later comparison.
253   friend class CachedUAStyle;
254   // Accesses visited and unvisited colors.
255   friend class ColorPropertyFunctions;
256   // Edits the background for media controls.
257   friend class StyleAdjuster;
258   // Access to private SetFontInternal().
259   friend class FontBuilder;
260 
261   // FIXME: When we stop resolving currentColor at style time, these can be
262   // removed.
263   friend class CSSToStyleMap;
264   friend class FilterOperationResolver;
265   friend class StyleBuilderConverter;
266   friend class StyleResolverState;
267   friend class StyleResolver;
268 
269  protected:
270   // This cache stores ComputedStyles for pseudo elements originating from this
271   // ComputedStyle's element. Pseudo elements which are represented by
272   // PseudoElement in DOM store the ComputedStyle on those elements, so this
273   // cache is for:
274   //
275   // 1. Pseudo elements which do not generate a PseudoElement internally like
276   //    ::first-line and ::selection.
277   //
278   // 2. Pseudo element style requested from getComputedStyle() where the element
279   //    currently doesn't generate a PseudoElement. E.g.:
280   //
281   //    <style>
282   //      #div::before { color: green /* no content property! */}
283   //    </style>
284   //    <div id=div></div>
285   //    <script>
286   //      getComputedStyle(div, "::before").color // still green.
287   //    </script>
288   mutable std::unique_ptr<PseudoElementStyleCache>
289       cached_pseudo_element_styles_;
290 
291   DataRef<SVGComputedStyle> svg_style_;
292 
293  private:
294   // TODO(sashab): Move these private members to the bottom of ComputedStyle.
295   ALWAYS_INLINE ComputedStyle();
296   ALWAYS_INLINE ComputedStyle(const ComputedStyle&);
297 
298   static scoped_refptr<ComputedStyle> CreateInitialStyle();
299   // TODO(crbug.com/794841): Remove this. Initial style should not be mutable.
300   CORE_EXPORT static ComputedStyle& MutableInitialStyle();
301 
302  public:
303   using PassKey = util::PassKey<ComputedStyle>;
304 
305   ALWAYS_INLINE ComputedStyle(PassKey, const ComputedStyle&);
306   ALWAYS_INLINE explicit ComputedStyle(PassKey);
307 
308   CORE_EXPORT static scoped_refptr<ComputedStyle> Create();
309   static scoped_refptr<ComputedStyle> CreateAnonymousStyleWithDisplay(
310       const ComputedStyle& parent_style,
311       EDisplay);
312   static scoped_refptr<ComputedStyle>
313   CreateInheritedDisplayContentsStyleIfNeeded(
314       const ComputedStyle& parent_style,
315       const ComputedStyle& layout_parent_style);
316   CORE_EXPORT static scoped_refptr<ComputedStyle> Clone(const ComputedStyle&);
InitialStyle()317   static const ComputedStyle& InitialStyle() { return MutableInitialStyle(); }
318   static void InvalidateInitialStyle();
319 
320   // Find out how two ComputedStyles differ. Used for figuring out if style
321   // recalc needs to propagate style changes down the tree. The constants are
322   // listed in increasing severity. E.g. kInherited also means we need to update
323   // pseudo elements (kPseudoElementStyle).
324   enum class Difference {
325     // The ComputedStyle objects have the same computed style. The might have
326     // some different extra flags which means we still need to replace the old
327     // with the new instance.
328     kEqual,
329     // Non-inherited properties differ which means we need to apply visual
330     // difference changes to the layout tree through LayoutObject::SetStyle().
331     kNonInherited,
332     // Pseudo element style is different which means we have to update pseudo
333     // element existence and computed style.
334     kPseudoElementStyle,
335     // Inherited properties are different which means we need to recalc style
336     // for children. Only independent properties changed which means we can
337     // inherit by cloning the exiting ComputedStyle for children an set modified
338     // properties directly without re-matching rules.
339     kIndependentInherited,
340     // Inherited properties are different which means we need to recalc style
341     // for children.
342     kInherited,
343     // Display type changes for flex/grid/custom layout affects computed style
344     // adjustments for descendants. For instance flex/grid items are blockified
345     // at computed style time and such items can be arbitrarily deep down the
346     // flat tree in the presence of display:contents.
347     kDisplayAffectingDescendantStyles,
348   };
349   CORE_EXPORT static Difference ComputeDifference(
350       const ComputedStyle* old_style,
351       const ComputedStyle* new_style);
352 
353   // Returns true if the ComputedStyle change requires a LayoutObject re-attach.
354   static bool NeedsReattachLayoutTree(const Element& element,
355                                       const ComputedStyle* old_style,
356                                       const ComputedStyle* new_style);
357 
358   // Copies the values of any independent inherited properties from the parent
359   // that are not explicitly set in this style.
360   void PropagateIndependentInheritedProperties(
361       const ComputedStyle& parent_style);
362 
363   ContentPosition ResolvedJustifyContentPosition(
364       const StyleContentAlignmentData& normal_value_behavior) const;
365   ContentDistributionType ResolvedJustifyContentDistribution(
366       const StyleContentAlignmentData& normal_value_behavior) const;
367   ContentPosition ResolvedAlignContentPosition(
368       const StyleContentAlignmentData& normal_value_behavior) const;
369   ContentDistributionType ResolvedAlignContentDistribution(
370       const StyleContentAlignmentData& normal_value_behavior) const;
371   StyleSelfAlignmentData ResolvedAlignItems(
372       ItemPosition normal_value_behaviour) const;
373   StyleSelfAlignmentData ResolvedAlignSelf(
374       ItemPosition normal_value_behaviour,
375       const ComputedStyle* parent_style = nullptr) const;
376   StyleContentAlignmentData ResolvedAlignContent(
377       const StyleContentAlignmentData& normal_behaviour) const;
378   StyleSelfAlignmentData ResolvedJustifyItems(
379       ItemPosition normal_value_behaviour) const;
380   StyleSelfAlignmentData ResolvedJustifySelf(
381       ItemPosition normal_value_behaviour,
382       const ComputedStyle* parent_style = nullptr) const;
383   StyleContentAlignmentData ResolvedJustifyContent(
384       const StyleContentAlignmentData& normal_behaviour) const;
385 
386   CORE_EXPORT StyleDifference
387   VisualInvalidationDiff(const Document&, const ComputedStyle&) const;
388 
389   CORE_EXPORT void InheritFrom(const ComputedStyle& inherit_parent,
390                                IsAtShadowBoundary = kNotAtShadowBoundary);
391   void CopyNonInheritedFromCached(const ComputedStyle&);
392 
StyleType()393   PseudoId StyleType() const {
394     return static_cast<PseudoId>(StyleTypeInternal());
395   }
SetStyleType(PseudoId style_type)396   void SetStyleType(PseudoId style_type) { SetStyleTypeInternal(style_type); }
397 
398   CORE_EXPORT const ComputedStyle* GetCachedPseudoElementStyle(PseudoId) const;
399   const ComputedStyle* AddCachedPseudoElementStyle(
400       scoped_refptr<const ComputedStyle>) const;
ClearCachedPseudoElementStyles()401   void ClearCachedPseudoElementStyles() const {
402     if (cached_pseudo_element_styles_)
403       cached_pseudo_element_styles_->clear();
404   }
405 
406   /**
407    * ComputedStyle properties
408    *
409    * Each property stored in ComputedStyle is made up of fields. Fields have
410    * getters and setters. A field is preferably a basic data type or enum,
411    * but can be any type. A set of fields should be preceded by the property
412    * the field is stored for.
413    *
414    * Field method naming should be done like so:
415    *   // name-of-property
416    *   int nameOfProperty() const;
417    *   void SetNameOfProperty(int);
418    * If the property has multiple fields, add the field name to the end of the
419    * method name.
420    *
421    * Avoid nested types by splitting up fields where possible, e.g.:
422    *  int getBorderTopWidth();
423    *  int getBorderBottomWidth();
424    *  int getBorderLeftWidth();
425    *  int getBorderRightWidth();
426    * is preferable to:
427    *  BorderWidths getBorderWidths();
428    *
429    * Utility functions should go in a separate section at the end of the
430    * class, and be kept to a minimum.
431    */
432 
BackdropFilter()433   const FilterOperations& BackdropFilter() const {
434     DCHECK(BackdropFilterInternal().Get());
435     return BackdropFilterInternal()->operations_;
436   }
MutableBackdropFilter()437   FilterOperations& MutableBackdropFilter() {
438     DCHECK(BackdropFilterInternal().Get());
439     return MutableBackdropFilterInternal()->operations_;
440   }
441   // For containing blocks, use |HasNonInitialBackdropFilter()| which includes
442   // will-change: backdrop-filter.
HasBackdropFilter()443   bool HasBackdropFilter() const {
444     DCHECK(BackdropFilterInternal().Get());
445     return !BackdropFilterInternal()->operations_.Operations().IsEmpty();
446   }
SetBackdropFilter(const FilterOperations & ops)447   void SetBackdropFilter(const FilterOperations& ops) {
448     DCHECK(BackdropFilterInternal().Get());
449     if (BackdropFilterInternal()->operations_ != ops)
450       MutableBackdropFilterInternal()->operations_ = ops;
451   }
BackdropFilterDataEquivalent(const ComputedStyle & o)452   bool BackdropFilterDataEquivalent(const ComputedStyle& o) const {
453     return DataEquivalent(BackdropFilterInternal(), o.BackdropFilterInternal());
454   }
455 
456   // filter (aka -webkit-filter)
MutableFilter()457   FilterOperations& MutableFilter() {
458     DCHECK(FilterInternal().Get());
459     return MutableFilterInternal()->operations_;
460   }
Filter()461   const FilterOperations& Filter() const {
462     DCHECK(FilterInternal().Get());
463     return FilterInternal()->operations_;
464   }
465   // For containing blocks, use |HasNonInitialFilter()| which includes
466   // will-change: filter.
HasFilter()467   bool HasFilter() const {
468     DCHECK(FilterInternal().Get());
469     return !FilterInternal()->operations_.Operations().IsEmpty();
470   }
SetFilter(const FilterOperations & v)471   void SetFilter(const FilterOperations& v) {
472     DCHECK(FilterInternal().Get());
473     if (FilterInternal()->operations_ != v)
474       MutableFilterInternal()->operations_ = v;
475   }
FilterDataEquivalent(const ComputedStyle & o)476   bool FilterDataEquivalent(const ComputedStyle& o) const {
477     return DataEquivalent(FilterInternal(), o.FilterInternal());
478   }
479 
480 
481   // background-image
HasBackgroundImage()482   bool HasBackgroundImage() const {
483     return BackgroundInternal().AnyLayerHasImage();
484   }
HasUrlBackgroundImage()485   bool HasUrlBackgroundImage() const {
486     return BackgroundInternal().AnyLayerHasUrlImage();
487   }
HasFixedAttachmentBackgroundImage()488   bool HasFixedAttachmentBackgroundImage() const {
489     return BackgroundInternal().AnyLayerHasFixedAttachmentImage();
490   }
491 
492   // background-clip
BackgroundClip()493   EFillBox BackgroundClip() const {
494     return static_cast<EFillBox>(BackgroundInternal().Clip());
495   }
496 
497   // Returns true if the Element should stick to the viewport bottom as the URL
498   // bar hides.
IsFixedToBottom()499   bool IsFixedToBottom() const { return !Bottom().IsAuto() && Top().IsAuto(); }
500 
501   // Border properties.
502   // border-image-slice
BorderImageSlices()503   const LengthBox& BorderImageSlices() const {
504     return BorderImage().ImageSlices();
505   }
506   void SetBorderImageSlices(const LengthBox&);
507 
508   // border-image-source
BorderImageSource()509   StyleImage* BorderImageSource() const { return BorderImage().GetImage(); }
510   CORE_EXPORT void SetBorderImageSource(StyleImage*);
511 
512   // border-image-width
BorderImageWidth()513   const BorderImageLengthBox& BorderImageWidth() const {
514     return BorderImage().BorderSlices();
515   }
516   void SetBorderImageWidth(const BorderImageLengthBox&);
517 
518   // border-image-outset
BorderImageOutset()519   const BorderImageLengthBox& BorderImageOutset() const {
520     return BorderImage().Outset();
521   }
522   void SetBorderImageOutset(const BorderImageLengthBox&);
523 
524   // Border width properties.
BorderTopWidth()525   float BorderTopWidth() const {
526     if (BorderTopStyle() == EBorderStyle::kNone ||
527         BorderTopStyle() == EBorderStyle::kHidden)
528       return 0;
529     return BorderTopWidthInternal().ToFloat();
530   }
SetBorderTopWidth(float v)531   void SetBorderTopWidth(float v) { SetBorderTopWidthInternal(LayoutUnit(v)); }
BorderTopNonZero()532   bool BorderTopNonZero() const {
533     return BorderTopWidth() && (BorderTopStyle() != EBorderStyle::kNone);
534   }
535 
536   // border-bottom-width
BorderBottomWidth()537   float BorderBottomWidth() const {
538     if (BorderBottomStyle() == EBorderStyle::kNone ||
539         BorderBottomStyle() == EBorderStyle::kHidden)
540       return 0;
541     return BorderBottomWidthInternal().ToFloat();
542   }
SetBorderBottomWidth(float v)543   void SetBorderBottomWidth(float v) {
544     SetBorderBottomWidthInternal(LayoutUnit(v));
545   }
BorderBottomNonZero()546   bool BorderBottomNonZero() const {
547     return BorderBottomWidth() && (BorderBottomStyle() != EBorderStyle::kNone);
548   }
549 
550   // border-left-width
BorderLeftWidth()551   float BorderLeftWidth() const {
552     if (BorderLeftStyle() == EBorderStyle::kNone ||
553         BorderLeftStyle() == EBorderStyle::kHidden)
554       return 0;
555     return BorderLeftWidthInternal().ToFloat();
556   }
SetBorderLeftWidth(float v)557   void SetBorderLeftWidth(float v) {
558     SetBorderLeftWidthInternal(LayoutUnit(v));
559   }
BorderLeftNonZero()560   bool BorderLeftNonZero() const {
561     return BorderLeftWidth() && (BorderLeftStyle() != EBorderStyle::kNone);
562   }
563 
564   // border-right-width
BorderRightWidth()565   float BorderRightWidth() const {
566     if (BorderRightStyle() == EBorderStyle::kNone ||
567         BorderRightStyle() == EBorderStyle::kHidden)
568       return 0;
569     return BorderRightWidthInternal().ToFloat();
570   }
SetBorderRightWidth(float v)571   void SetBorderRightWidth(float v) {
572     SetBorderRightWidthInternal(LayoutUnit(v));
573   }
BorderRightNonZero()574   bool BorderRightNonZero() const {
575     return BorderRightWidth() && (BorderRightStyle() != EBorderStyle::kNone);
576   }
577 
578   // box-shadow (aka -webkit-box-shadow)
BoxShadowDataEquivalent(const ComputedStyle & other)579   bool BoxShadowDataEquivalent(const ComputedStyle& other) const {
580     return DataEquivalent(BoxShadow(), other.BoxShadow());
581   }
582 
583   // clip
SetClip(const LengthBox & box)584   void SetClip(const LengthBox& box) {
585     SetHasAutoClipInternal(false);
586     SetClipInternal(box);
587   }
SetHasAutoClip()588   void SetHasAutoClip() {
589     SetHasAutoClipInternal(true);
590     SetClipInternal(ComputedStyleInitialValues::InitialClip());
591   }
592 
593   // Column properties.
594   // column-count (aka -webkit-column-count)
SetColumnCount(uint16_t c)595   void SetColumnCount(uint16_t c) {
596     SetHasAutoColumnCountInternal(false);
597     SetColumnCountInternal(clampTo<uint16_t>(c, 1));
598   }
SetHasAutoColumnCount()599   void SetHasAutoColumnCount() {
600     SetHasAutoColumnCountInternal(true);
601     SetColumnCountInternal(ComputedStyleInitialValues::InitialColumnCount());
602   }
603 
604   // column-rule-width (aka -webkit-column-rule-width)
ColumnRuleWidth()605   uint16_t ColumnRuleWidth() const {
606     if (ColumnRuleStyle() == EBorderStyle::kNone ||
607         ColumnRuleStyle() == EBorderStyle::kHidden)
608       return 0;
609     return ColumnRuleWidthInternal().ToUnsigned();
610   }
SetColumnRuleWidth(uint16_t w)611   void SetColumnRuleWidth(uint16_t w) {
612     SetColumnRuleWidthInternal(LayoutUnit(w));
613   }
614 
615   // column-width (aka -webkit-column-width)
SetColumnWidth(float f)616   void SetColumnWidth(float f) {
617     SetHasAutoColumnWidthInternal(false);
618     SetColumnWidthInternal(f);
619   }
SetHasAutoColumnWidth()620   void SetHasAutoColumnWidth() {
621     SetHasAutoColumnWidthInternal(true);
622     SetColumnWidthInternal(0);
623   }
624 
625   // content
GetContentData()626   ContentData* GetContentData() const { return ContentInternal().Get(); }
627   void SetContent(ContentData*);
628 
629   // -webkit-line-clamp
HasLineClamp()630   bool HasLineClamp() const { return LineClamp() > 0; }
631 
632   // -webkit-box-ordinal-group
SetBoxOrdinalGroup(unsigned og)633   void SetBoxOrdinalGroup(unsigned og) {
634     SetBoxOrdinalGroupInternal(
635         std::min(std::numeric_limits<unsigned>::max() - 1, og));
636   }
637 
638   // opacity (aka -webkit-opacity)
SetOpacity(float f)639   void SetOpacity(float f) {
640     float v = clampTo<float>(f, 0, 1);
641     SetOpacityInternal(v);
642   }
643 
OpacityChangedStackingContext(const ComputedStyle & other)644   bool OpacityChangedStackingContext(const ComputedStyle& other) const {
645     // We only need do layout for opacity changes if adding or losing opacity
646     // could trigger a change
647     // in us being a stacking context.
648     if (IsStackingContextWithoutContainment() ==
649             other.IsStackingContextWithoutContainment() ||
650         HasOpacity() == other.HasOpacity()) {
651       // FIXME: We would like to use SimplifiedLayout here, but we can't quite
652       // do that yet.  We need to make sure SimplifiedLayout can operate
653       // correctly on LayoutInlines (we will need to add a
654       // selfNeedsSimplifiedLayout bit in order to not get confused and taint
655       // every line).  In addition we need to solve the floating object issue
656       // when layers come and go. Right now a full layout is necessary to keep
657       // floating object lists sane.
658       return true;
659     }
660     return false;
661   }
662 
663   // order (aka -webkit-order)
664   // We restrict the smallest value to int min + 2 because we use int min and
665   // int min + 1 as special values in a hash set.
SetOrder(int o)666   void SetOrder(int o) {
667     SetOrderInternal(max(std::numeric_limits<int>::min() + 2, o));
668   }
669 
670   // Outline properties.
671 
OutlineVisuallyEqual(const ComputedStyle & other)672   bool OutlineVisuallyEqual(const ComputedStyle& other) const {
673     if (OutlineStyle() == EBorderStyle::kNone &&
674         other.OutlineStyle() == EBorderStyle::kNone)
675       return true;
676     return OutlineWidthInternal() == other.OutlineWidthInternal() &&
677            OutlineColor() == other.OutlineColor() &&
678            OutlineStyle() == other.OutlineStyle() &&
679            OutlineOffset() == other.OutlineOffset() &&
680            OutlineStyleIsAuto() == other.OutlineStyleIsAuto();
681   }
682 
683   // outline-width
OutlineWidth()684   float OutlineWidth() const {
685     if (OutlineStyle() == EBorderStyle::kNone)
686       return 0;
687     return OutlineWidthInternal();
688   }
SetOutlineWidth(float v)689   void SetOutlineWidth(float v) { SetOutlineWidthInternal(LayoutUnit(v)); }
690   // TODO(rego): This is a temporal method that will be removed once we start
691   // using the float OutlineWidth() in the painting code.
OutlineWidthInt()692   uint16_t OutlineWidthInt() const {
693     if (OutlineStyle() == EBorderStyle::kNone)
694       return 0;
695     return OutlineWidthInternal().ToUnsigned();
696   }
697 
698   // outline-offset
OutlineOffsetInt()699   int16_t OutlineOffsetInt() const { return OutlineOffset().ToInt(); }
700 
701   // -webkit-perspective-origin-x
PerspectiveOriginX()702   const Length& PerspectiveOriginX() const { return PerspectiveOrigin().X(); }
SetPerspectiveOriginX(const Length & v)703   void SetPerspectiveOriginX(const Length& v) {
704     SetPerspectiveOrigin(LengthPoint(v, PerspectiveOriginY()));
705   }
706 
707   // -webkit-perspective-origin-y
PerspectiveOriginY()708   const Length& PerspectiveOriginY() const { return PerspectiveOrigin().Y(); }
SetPerspectiveOriginY(const Length & v)709   void SetPerspectiveOriginY(const Length& v) {
710     SetPerspectiveOrigin(LengthPoint(PerspectiveOriginX(), v));
711   }
712 
713   // Transform properties.
714   // -webkit-transform-origin-x
TransformOriginX()715   const Length& TransformOriginX() const { return GetTransformOrigin().X(); }
SetTransformOriginX(const Length & v)716   void SetTransformOriginX(const Length& v) {
717     SetTransformOrigin(
718         TransformOrigin(v, TransformOriginY(), TransformOriginZ()));
719   }
720 
721   // -webkit-transform-origin-y
TransformOriginY()722   const Length& TransformOriginY() const { return GetTransformOrigin().Y(); }
SetTransformOriginY(const Length & v)723   void SetTransformOriginY(const Length& v) {
724     SetTransformOrigin(
725         TransformOrigin(TransformOriginX(), v, TransformOriginZ()));
726   }
727 
728   // -webkit-transform-origin-z
TransformOriginZ()729   float TransformOriginZ() const { return GetTransformOrigin().Z(); }
SetTransformOriginZ(float f)730   void SetTransformOriginZ(float f) {
731     SetTransformOrigin(
732         TransformOrigin(TransformOriginX(), TransformOriginY(), f));
733   }
734 
735   // Scroll properties.
736   // scroll-padding-block-start
ScrollPaddingBlockStart()737   const Length& ScrollPaddingBlockStart() const {
738     return IsHorizontalWritingMode() ? ScrollPaddingTop() : ScrollPaddingLeft();
739   }
SetScrollPaddingBlockStart(const Length & v)740   void SetScrollPaddingBlockStart(const Length& v) {
741     if (IsHorizontalWritingMode())
742       SetScrollPaddingTop(v);
743     else
744       SetScrollPaddingLeft(v);
745   }
746 
747   // scroll-padding-block-end
ScrollPaddingBlockEnd()748   const Length& ScrollPaddingBlockEnd() const {
749     return IsHorizontalWritingMode() ? ScrollPaddingBottom()
750                                      : ScrollPaddingRight();
751   }
SetScrollPaddingBlockEnd(const Length & v)752   void SetScrollPaddingBlockEnd(const Length& v) {
753     if (IsHorizontalWritingMode())
754       SetScrollPaddingBottom(v);
755     else
756       SetScrollPaddingRight(v);
757   }
758 
759   // scroll-padding-inline-start
ScrollPaddingInlineStart()760   const Length& ScrollPaddingInlineStart() const {
761     return IsHorizontalWritingMode() ? ScrollPaddingLeft() : ScrollPaddingTop();
762   }
SetScrollPaddingInlineStart(const Length & v)763   void SetScrollPaddingInlineStart(const Length& v) {
764     if (IsHorizontalWritingMode())
765       SetScrollPaddingLeft(v);
766     else
767       SetScrollPaddingTop(v);
768   }
769 
770   // scroll-padding-inline-end
ScrollPaddingInlineEnd()771   const Length& ScrollPaddingInlineEnd() const {
772     return IsHorizontalWritingMode() ? ScrollPaddingRight()
773                                      : ScrollPaddingBottom();
774   }
SetScrollPaddingInlineEnd(const Length & v)775   void SetScrollPaddingInlineEnd(const Length& v) {
776     if (IsHorizontalWritingMode())
777       SetScrollPaddingRight(v);
778     else
779       SetScrollPaddingBottom(v);
780   }
781 
782   // scroll-margin-block-start
ScrollMarginBlockStart()783   float ScrollMarginBlockStart() const {
784     return IsHorizontalWritingMode() ? ScrollMarginTop() : ScrollMarginLeft();
785   }
SetScrollMarginBlockStart(float v)786   void SetScrollMarginBlockStart(float v) {
787     if (IsHorizontalWritingMode())
788       SetScrollMarginTop(v);
789     else
790       SetScrollMarginLeft(v);
791   }
792 
793   // scroll-margin-block-end
ScrollMarginBlockEnd()794   float ScrollMarginBlockEnd() const {
795     return IsHorizontalWritingMode() ? ScrollMarginBottom()
796                                      : ScrollMarginRight();
797   }
SetScrollMarginBlockEnd(float v)798   void SetScrollMarginBlockEnd(float v) {
799     if (IsHorizontalWritingMode())
800       SetScrollMarginBottom(v);
801     else
802       SetScrollMarginRight(v);
803   }
804 
805   // scroll-margin-inline-start
ScrollMarginInlineStart()806   float ScrollMarginInlineStart() const {
807     return IsHorizontalWritingMode() ? ScrollMarginLeft() : ScrollMarginTop();
808   }
SetScrollMarginInlineStart(float v)809   void SetScrollMarginInlineStart(float v) {
810     if (IsHorizontalWritingMode())
811       SetScrollMarginLeft(v);
812     else
813       SetScrollMarginTop(v);
814   }
815 
816   // scroll-margin-inline-end
ScrollMarginInlineEnd()817   float ScrollMarginInlineEnd() const {
818     return IsHorizontalWritingMode() ? ScrollMarginRight()
819                                      : ScrollMarginBottom();
820   }
SetScrollMarginInlineEnd(float v)821   void SetScrollMarginInlineEnd(float v) {
822     if (IsHorizontalWritingMode())
823       SetScrollMarginRight(v);
824     else
825       SetScrollMarginBottom(v);
826   }
827 
828   // scrollbar-gutter
IsScrollbarGutterAuto()829   inline bool IsScrollbarGutterAuto() const {
830     return ScrollbarGutter() == kScrollbarGutterAuto;
831   }
IsScrollbarGutterStable()832   inline bool IsScrollbarGutterStable() const {
833     return ScrollbarGutter() & kScrollbarGutterStable;
834   }
IsScrollbarGutterAlways()835   inline bool IsScrollbarGutterAlways() const {
836     return ScrollbarGutter() & kScrollbarGutterAlways;
837   }
IsScrollbarGutterBoth()838   inline bool IsScrollbarGutterBoth() const {
839     return ScrollbarGutter() & kScrollbarGutterBoth;
840   }
IsScrollbarGutterForce()841   inline bool IsScrollbarGutterForce() const {
842     return ScrollbarGutter() & kScrollbarGutterForce;
843   }
844 
845   // shape-image-threshold (aka -webkit-shape-image-threshold)
SetShapeImageThreshold(float shape_image_threshold)846   void SetShapeImageThreshold(float shape_image_threshold) {
847     float clamped_shape_image_threshold =
848         clampTo<float>(shape_image_threshold, 0, 1);
849     SetShapeImageThresholdInternal(clamped_shape_image_threshold);
850   }
851 
852   // shape-outside (aka -webkit-shape-outside)
ShapeOutside()853   ShapeValue* ShapeOutside() const { return ShapeOutsideInternal().Get(); }
ShapeOutsideDataEquivalent(const ComputedStyle & other)854   bool ShapeOutsideDataEquivalent(const ComputedStyle& other) const {
855     return DataEquivalent(ShapeOutside(), other.ShapeOutside());
856   }
857 
858   // touch-action
GetEffectiveTouchAction()859   TouchAction GetEffectiveTouchAction() const {
860     return EffectiveTouchActionInternal();
861   }
SetEffectiveTouchAction(TouchAction t)862   void SetEffectiveTouchAction(TouchAction t) {
863     return SetEffectiveTouchActionInternal(t);
864   }
865 
866   // vertical-align
VerticalAlign()867   EVerticalAlign VerticalAlign() const { return static_cast<EVerticalAlign>(VerticalAlignInternal()); }
SetVerticalAlign(EVerticalAlign v)868   void SetVerticalAlign(EVerticalAlign v) { SetVerticalAlignInternal(static_cast<unsigned>(v)); }
SetVerticalAlignLength(const Length & length)869   void SetVerticalAlignLength(const Length& length) {
870     SetVerticalAlignInternal(static_cast<unsigned>(EVerticalAlign::kLength));
871     SetVerticalAlignLengthInternal(length);
872   }
873 
874   // z-index
SetZIndex(int v)875   void SetZIndex(int v) {
876     SetHasAutoZIndexInternal(false);
877     SetZIndexInternal(v);
878   }
SetHasAutoZIndex()879   void SetHasAutoZIndex() {
880     SetHasAutoZIndexInternal(true);
881     SetZIndexInternal(0);
882   }
883   // This returns the z-index if it applies (i.e. positioned element or grid or
884   // flex children), and 0 otherwise. Note that for most situations,
885   // `EffectiveZIndex()` is what the code should use to determine how to stack
886   // the element. `ZIndex()` is still available and returns the value as
887   // specified in style (used for e.g. style comparisons and computed style
888   // reporting)
EffectiveZIndex()889   int EffectiveZIndex() const { return EffectiveZIndexZero() ? 0 : ZIndex(); }
890 
891   CORE_EXPORT bool SetEffectiveZoom(float);
892 
893   // -webkit-clip-path
ClipPathDataEquivalent(const ComputedStyle & other)894   bool ClipPathDataEquivalent(const ComputedStyle& other) const {
895     return DataEquivalent(ClipPath(), other.ClipPath());
896   }
897 
898   // Mask properties.
899   // -webkit-mask-box-image-outset
HasMaskBoxImageOutsets()900   bool HasMaskBoxImageOutsets() const {
901     return MaskBoxImageInternal().HasImage() && MaskBoxImageOutset().NonZero();
902   }
MaskBoxImageOutsets()903   LayoutRectOutsets MaskBoxImageOutsets() const {
904     return ImageOutsets(MaskBoxImageInternal());
905   }
MaskBoxImageOutset()906   const BorderImageLengthBox& MaskBoxImageOutset() const {
907     return MaskBoxImageInternal().Outset();
908   }
SetMaskBoxImageOutset(const BorderImageLengthBox & outset)909   void SetMaskBoxImageOutset(const BorderImageLengthBox& outset) {
910     MutableMaskBoxImageInternal().SetOutset(outset);
911   }
912 
913   // -webkit-mask-box-image-slice
MaskBoxImageSlices()914   const LengthBox& MaskBoxImageSlices() const {
915     return MaskBoxImageInternal().ImageSlices();
916   }
SetMaskBoxImageSlices(const LengthBox & slices)917   void SetMaskBoxImageSlices(const LengthBox& slices) {
918     MutableMaskBoxImageInternal().SetImageSlices(slices);
919   }
920 
921   // -webkit-mask-box-image-source
MaskBoxImageSource()922   StyleImage* MaskBoxImageSource() const {
923     return MaskBoxImageInternal().GetImage();
924   }
SetMaskBoxImageSource(StyleImage * v)925   void SetMaskBoxImageSource(StyleImage* v) {
926     MutableMaskBoxImageInternal().SetImage(v);
927   }
928 
929   // -webkit-mask-box-image-width
MaskBoxImageWidth()930   const BorderImageLengthBox& MaskBoxImageWidth() const {
931     return MaskBoxImageInternal().BorderSlices();
932   }
SetMaskBoxImageWidth(const BorderImageLengthBox & slices)933   void SetMaskBoxImageWidth(const BorderImageLengthBox& slices) {
934     MutableMaskBoxImageInternal().SetBorderSlices(slices);
935   }
936 
937   // Inherited properties.
938 
939   // line-height
940   Length LineHeight() const;
941 
942   // List style properties.
943   // list-style-image
944   CORE_EXPORT StyleImage* ListStyleImage() const;
945   void SetListStyleImage(StyleImage*);
946 
947   // quotes
948   bool QuotesDataEquivalent(const ComputedStyle&) const;
949 
950   // text-shadow
951   bool TextShadowDataEquivalent(const ComputedStyle&) const;
952 
953   // Text emphasis properties.
954   TextEmphasisMark GetTextEmphasisMark() const;
SetTextEmphasisMark(TextEmphasisMark mark)955   void SetTextEmphasisMark(TextEmphasisMark mark) {
956     SetTextEmphasisMarkInternal(mark);
957   }
958   const AtomicString& TextEmphasisMarkString() const;
959   LineLogicalSide GetTextEmphasisLineLogicalSide() const;
960 
961   // Font properties.
GetFont()962   CORE_EXPORT const Font& GetFont() const { return FontInternal(); }
SetFont(const Font & font)963   CORE_EXPORT void SetFont(const Font& font) { SetFontInternal(font); }
GetFontDescription()964   CORE_EXPORT const FontDescription& GetFontDescription() const {
965     return FontInternal().GetFontDescription();
966   }
967   CORE_EXPORT bool SetFontDescription(const FontDescription&);
968   bool HasIdenticalAscentDescentAndLineGap(const ComputedStyle& other) const;
HasFontRelativeUnits()969   bool HasFontRelativeUnits() const {
970     return HasEmUnits() || HasRemUnits() || HasGlyphRelativeUnits();
971   }
972 
973   // If true, the ComputedStyle must be recalculated when fonts are updated.
DependsOnFontMetrics()974   bool DependsOnFontMetrics() const {
975     return HasGlyphRelativeUnits() || HasFontSizeAdjust();
976   }
977   bool CachedPseudoElementStylesDependOnFontMetrics() const;
978 
979   // font-size
FontSize()980   int FontSize() const { return GetFontDescription().ComputedPixelSize(); }
SpecifiedFontSize()981   CORE_EXPORT float SpecifiedFontSize() const {
982     return GetFontDescription().SpecifiedSize();
983   }
ComputedFontSize()984   CORE_EXPORT float ComputedFontSize() const {
985     return GetFontDescription().ComputedSize();
986   }
ComputedFontSizeAsFixed()987   LayoutUnit ComputedFontSizeAsFixed() const {
988     return LayoutUnit::FromFloatRound(GetFontDescription().ComputedSize());
989   }
990 
991   // font-size-adjust
FontSizeAdjust()992   float FontSizeAdjust() const { return GetFontDescription().SizeAdjust(); }
HasFontSizeAdjust()993   bool HasFontSizeAdjust() const {
994     return GetFontDescription().HasSizeAdjust();
995   }
996 
997   // font-weight
GetFontWeight()998   CORE_EXPORT FontSelectionValue GetFontWeight() const {
999     return GetFontDescription().Weight();
1000   }
1001 
1002   // font-stretch
GetFontStretch()1003   FontSelectionValue GetFontStretch() const {
1004     return GetFontDescription().Stretch();
1005   }
1006 
1007   // Child is aligned to the parent by matching the parent’s dominant baseline
1008   // to the same baseline in the child.
1009   FontBaseline GetFontBaseline() const;
1010 
1011   FontHeight GetFontHeight(FontBaseline baseline) const;
GetFontHeight()1012   FontHeight GetFontHeight() const { return GetFontHeight(GetFontBaseline()); }
1013 
1014   // Compute FontOrientation from this style. It is derived from WritingMode and
1015   // TextOrientation.
1016   FontOrientation ComputeFontOrientation() const;
1017 
1018   // Update FontOrientation in FontDescription if it is different. FontBuilder
1019   // takes care of updating it, but if WritingMode or TextOrientation were
1020   // changed after the style was constructed, this function synchronizes
1021   // FontOrientation to match to this style.
1022   void UpdateFontOrientation();
1023 
1024   // -webkit-locale
Locale()1025   const AtomicString& Locale() const {
1026     return LayoutLocale::LocaleString(GetFontDescription().Locale());
1027   }
1028   AtomicString LocaleForLineBreakIterator() const;
1029 
1030   // FIXME: Remove letter-spacing/word-spacing and replace them with respective
1031   // FontBuilder calls.  letter-spacing
LetterSpacing()1032   float LetterSpacing() const { return GetFontDescription().LetterSpacing(); }
1033   void SetLetterSpacing(float);
1034 
1035   // tab-size
SetTabSize(const TabSize & t)1036   void SetTabSize(const TabSize& t) {
1037     if (t.GetPixelSize(1) < 0) {
1038       if (t.IsSpaces())
1039         SetTabSizeInternal(TabSize(0, TabSizeValueType::kSpace));
1040       else
1041         SetTabSizeInternal(TabSize(0, TabSizeValueType::kLength));
1042     } else {
1043       SetTabSizeInternal(t);
1044     }
1045   }
1046 
1047   // word-spacing
WordSpacing()1048   float WordSpacing() const { return GetFontDescription().WordSpacing(); }
1049   void SetWordSpacing(float);
1050 
1051   // orphans
SetOrphans(int16_t o)1052   void SetOrphans(int16_t o) { SetOrphansInternal(clampTo<int16_t>(o, 1)); }
1053 
1054   // widows
SetWidows(int16_t w)1055   void SetWidows(int16_t w) { SetWidowsInternal(clampTo<int16_t>(w, 1)); }
1056 
1057   // SVG properties.
SvgStyle()1058   const SVGComputedStyle& SvgStyle() const { return *svg_style_.Get(); }
AccessSVGStyle()1059   SVGComputedStyle& AccessSVGStyle() { return *svg_style_.Access(); }
1060 
1061   // baseline-shift
BaselineShift()1062   EBaselineShift BaselineShift() const { return SvgStyle().BaselineShift(); }
BaselineShiftValue()1063   const Length& BaselineShiftValue() const {
1064     return SvgStyle().BaselineShiftValue();
1065   }
SetBaselineShiftValue(const Length & value)1066   void SetBaselineShiftValue(const Length& value) {
1067     SVGComputedStyle& svg_style = AccessSVGStyle();
1068     svg_style.SetBaselineShift(BS_LENGTH);
1069     svg_style.SetBaselineShiftValue(value);
1070   }
1071 
1072   // cx
SetCx(const Length & cx)1073   void SetCx(const Length& cx) { AccessSVGStyle().SetCx(cx); }
1074 
1075   // cy
SetCy(const Length & cy)1076   void SetCy(const Length& cy) { AccessSVGStyle().SetCy(cy); }
1077 
1078   // d
SetD(scoped_refptr<StylePath> d)1079   void SetD(scoped_refptr<StylePath> d) { AccessSVGStyle().SetD(std::move(d)); }
1080 
1081   // x
SetX(const Length & x)1082   void SetX(const Length& x) { AccessSVGStyle().SetX(x); }
1083 
1084   // y
SetY(const Length & y)1085   void SetY(const Length& y) { AccessSVGStyle().SetY(y); }
1086 
1087   // r
SetR(const Length & r)1088   void SetR(const Length& r) { AccessSVGStyle().SetR(r); }
1089 
1090   // rx
SetRx(const Length & rx)1091   void SetRx(const Length& rx) { AccessSVGStyle().SetRx(rx); }
1092 
1093   // ry
SetRy(const Length & ry)1094   void SetRy(const Length& ry) { AccessSVGStyle().SetRy(ry); }
1095 
1096   // fill-opacity
FillOpacity()1097   float FillOpacity() const { return SvgStyle().FillOpacity(); }
SetFillOpacity(float f)1098   void SetFillOpacity(float f) { AccessSVGStyle().SetFillOpacity(f); }
1099 
1100   // stop-color
SetStopColor(const StyleColor & c)1101   void SetStopColor(const StyleColor& c) { AccessSVGStyle().SetStopColor(c); }
1102 
1103   // flood-color
SetFloodColor(const StyleColor & c)1104   void SetFloodColor(const StyleColor& c) { AccessSVGStyle().SetFloodColor(c); }
1105 
1106   // lighting-color
SetLightingColor(const StyleColor & c)1107   void SetLightingColor(const StyleColor& c) {
1108     AccessSVGStyle().SetLightingColor(c);
1109   }
1110 
1111   // flood-opacity
FloodOpacity()1112   float FloodOpacity() const { return SvgStyle().FloodOpacity(); }
SetFloodOpacity(float f)1113   void SetFloodOpacity(float f) { AccessSVGStyle().SetFloodOpacity(f); }
1114 
1115   // stop-opacity
StopOpacity()1116   float StopOpacity() const { return SvgStyle().StopOpacity(); }
SetStopOpacity(float f)1117   void SetStopOpacity(float f) { AccessSVGStyle().SetStopOpacity(f); }
1118 
1119   // stroke-dasharray
StrokeDashArray()1120   SVGDashArray* StrokeDashArray() const { return SvgStyle().StrokeDashArray(); }
SetStrokeDashArray(scoped_refptr<SVGDashArray> array)1121   void SetStrokeDashArray(scoped_refptr<SVGDashArray> array) {
1122     AccessSVGStyle().SetStrokeDashArray(std::move(array));
1123   }
1124 
1125   // stroke-dashoffset
StrokeDashOffset()1126   const Length& StrokeDashOffset() const {
1127     return SvgStyle().StrokeDashOffset();
1128   }
SetStrokeDashOffset(const Length & d)1129   void SetStrokeDashOffset(const Length& d) {
1130     AccessSVGStyle().SetStrokeDashOffset(d);
1131   }
1132 
1133   // stroke-miterlimit
StrokeMiterLimit()1134   float StrokeMiterLimit() const { return SvgStyle().StrokeMiterLimit(); }
SetStrokeMiterLimit(float f)1135   void SetStrokeMiterLimit(float f) { AccessSVGStyle().SetStrokeMiterLimit(f); }
1136 
1137   // stroke-opacity
StrokeOpacity()1138   float StrokeOpacity() const { return SvgStyle().StrokeOpacity(); }
SetStrokeOpacity(float f)1139   void SetStrokeOpacity(float f) { AccessSVGStyle().SetStrokeOpacity(f); }
1140 
1141   // stroke-width
StrokeWidth()1142   const UnzoomedLength& StrokeWidth() const { return SvgStyle().StrokeWidth(); }
SetStrokeWidth(const UnzoomedLength & w)1143   void SetStrokeWidth(const UnzoomedLength& w) {
1144     AccessSVGStyle().SetStrokeWidth(w);
1145   }
1146 
1147   // Comparison operators
1148   // FIXME: Replace callers of operator== wth a named method instead, e.g.
1149   // inheritedEquals().
1150   CORE_EXPORT bool operator==(const ComputedStyle& other) const;
1151   bool operator!=(const ComputedStyle& other) const {
1152     return !(*this == other);
1153   }
1154 
1155   bool InheritedEqual(const ComputedStyle&) const;
1156   bool NonInheritedEqual(const ComputedStyle&) const;
1157   inline bool IndependentInheritedEqual(const ComputedStyle&) const;
1158   inline bool NonIndependentInheritedEqual(const ComputedStyle&) const;
1159   bool InheritedDataShared(const ComputedStyle&) const;
1160 
HasChildDependentFlags()1161   bool HasChildDependentFlags() const { return ChildHasExplicitInheritance(); }
1162   void CopyChildDependentFlagsFrom(const ComputedStyle&);
1163 
1164   // Counters.
1165   const CounterDirectiveMap* GetCounterDirectives() const;
1166   CounterDirectiveMap& AccessCounterDirectives();
1167   const CounterDirectives GetCounterDirectives(
1168       const AtomicString& identifier) const;
CounterDirectivesEqual(const ComputedStyle & other)1169   bool CounterDirectivesEqual(const ComputedStyle& other) const {
1170     // If the counter directives change, trigger a relayout to re-calculate
1171     // counter values and rebuild the counter node tree.
1172     return DataEquivalent(CounterDirectivesInternal().get(),
1173                           other.CounterDirectivesInternal().get());
1174   }
1175   void ClearIncrementDirectives();
1176   void ClearResetDirectives();
1177   void ClearSetDirectives();
1178 
IsDeprecatedWebkitBox()1179   bool IsDeprecatedWebkitBox() const {
1180     return Display() == EDisplay::kWebkitBox ||
1181            Display() == EDisplay::kWebkitInlineBox;
1182   }
IsDeprecatedFlexboxUsingFlexLayout()1183   bool IsDeprecatedFlexboxUsingFlexLayout() const {
1184     return IsDeprecatedWebkitBox() &&
1185            !IsDeprecatedWebkitBoxWithVerticalLineClamp();
1186   }
IsDeprecatedWebkitBoxWithVerticalLineClamp()1187   bool IsDeprecatedWebkitBoxWithVerticalLineClamp() const {
1188     return IsDeprecatedWebkitBox() && BoxOrient() == EBoxOrient::kVertical &&
1189            HasLineClamp();
1190   }
1191 
1192   // Variables.
1193   bool HasVariables() const;
1194   CORE_EXPORT HashSet<AtomicString> GetVariableNames() const;
1195   CORE_EXPORT StyleInheritedVariables* InheritedVariables() const;
1196   CORE_EXPORT StyleNonInheritedVariables* NonInheritedVariables() const;
1197 
1198   CORE_EXPORT void SetVariableData(const AtomicString&,
1199                                    scoped_refptr<CSSVariableData>,
1200                                    bool is_inherited_property);
1201   CORE_EXPORT void SetVariableValue(const AtomicString&,
1202                                     const CSSValue*,
1203                                     bool is_inherited_property);
1204 
1205   // Handles both inherited and non-inherited variables
1206   CORE_EXPORT CSSVariableData* GetVariableData(const AtomicString&) const;
1207   CSSVariableData* GetVariableData(const AtomicString&,
1208                                    bool is_inherited_property) const;
1209 
1210   const CSSValue* GetVariableValue(const AtomicString&) const;
1211   const CSSValue* GetVariableValue(const AtomicString&,
1212                                    bool is_inherited_property) const;
1213 
1214   // Animations.
1215   CORE_EXPORT CSSAnimationData& AccessAnimations();
Animations()1216   const CSSAnimationData* Animations() const {
1217     return AnimationsInternal().get();
1218   }
1219 
1220   // Transitions.
Transitions()1221   const CSSTransitionData* Transitions() const {
1222     return TransitionsInternal().get();
1223   }
1224   CORE_EXPORT CSSTransitionData& AccessTransitions();
1225 
1226   // Callback selectors.
1227   void AddCallbackSelector(const String& selector);
1228 
1229   // Non-property flags.
1230   CORE_EXPORT void SetTextAutosizingMultiplier(float);
1231 
1232   // Column utility functions.
1233   void ClearMultiCol();
SpecifiesColumns()1234   bool SpecifiesColumns() const {
1235     return !HasAutoColumnCount() || !HasAutoColumnWidth();
1236   }
ColumnRuleIsTransparent()1237   bool ColumnRuleIsTransparent() const {
1238     return !ColumnRuleColorInternal()
1239                 .Resolve(GetCurrentColor(), UsedColorScheme())
1240                 .Alpha();
1241   }
1242   bool ColumnRuleEquivalent(const ComputedStyle& other_style) const;
HasColumnRule()1243   bool HasColumnRule() const {
1244     if (LIKELY(!SpecifiesColumns()))
1245       return false;
1246     return ColumnRuleWidth() && !ColumnRuleIsTransparent() &&
1247            BorderStyleIsVisible(ColumnRuleStyle());
1248   }
1249 
1250   // Flex utility functions.
ResolvedIsColumnFlexDirection()1251   bool ResolvedIsColumnFlexDirection() const {
1252     if (IsDeprecatedWebkitBox())
1253       return BoxOrient() == EBoxOrient::kVertical;
1254     return FlexDirection() == EFlexDirection::kColumn ||
1255            FlexDirection() == EFlexDirection::kColumnReverse;
1256   }
ResolvedIsColumnReverseFlexDirection()1257   bool ResolvedIsColumnReverseFlexDirection() const {
1258     if (IsDeprecatedWebkitBox()) {
1259       return BoxOrient() == EBoxOrient::kVertical &&
1260              BoxDirection() == EBoxDirection::kReverse;
1261     }
1262     return FlexDirection() == EFlexDirection::kColumnReverse;
1263   }
ResolvedIsRowReverseFlexDirection()1264   bool ResolvedIsRowReverseFlexDirection() const {
1265     if (IsDeprecatedWebkitBox()) {
1266       return BoxOrient() == EBoxOrient::kHorizontal &&
1267              BoxDirection() == EBoxDirection::kReverse;
1268     }
1269     return FlexDirection() == EFlexDirection::kRowReverse;
1270   }
HasBoxReflect()1271   bool HasBoxReflect() const { return BoxReflect(); }
ReflectionDataEquivalent(const ComputedStyle & other)1272   bool ReflectionDataEquivalent(const ComputedStyle& other) const {
1273     return DataEquivalent(BoxReflect(), other.BoxReflect());
1274   }
ResolvedFlexGrow(const ComputedStyle & box_style)1275   float ResolvedFlexGrow(const ComputedStyle& box_style) const {
1276     if (box_style.IsDeprecatedWebkitBox())
1277       return BoxFlex() > 0 ? BoxFlex() : 0.0f;
1278     return FlexGrow();
1279   }
ResolvedFlexShrink(const ComputedStyle & box_style)1280   float ResolvedFlexShrink(const ComputedStyle& box_style) const {
1281     if (box_style.IsDeprecatedWebkitBox())
1282       return BoxFlex() > 0 ? BoxFlex() : 0.0f;
1283     return FlexShrink();
1284   }
1285 
1286   // Mask utility functions.
HasMask()1287   bool HasMask() const {
1288     return MaskInternal().AnyLayerHasImage() ||
1289            MaskBoxImageInternal().HasImage();
1290   }
MaskImage()1291   StyleImage* MaskImage() const { return MaskInternal().GetImage(); }
AccessMaskLayers()1292   FillLayer& AccessMaskLayers() { return MutableMaskInternal(); }
MaskLayers()1293   const FillLayer& MaskLayers() const { return MaskInternal(); }
MaskBoxImage()1294   const NinePieceImage& MaskBoxImage() const { return MaskBoxImageInternal(); }
MaskBoxImageSlicesFill()1295   bool MaskBoxImageSlicesFill() const { return MaskBoxImageInternal().Fill(); }
AdjustMaskLayers()1296   void AdjustMaskLayers() {
1297     if (MaskLayers().Next()) {
1298       AccessMaskLayers().CullEmptyLayers();
1299       AccessMaskLayers().FillUnsetProperties();
1300     }
1301   }
SetMaskBoxImage(const NinePieceImage & b)1302   void SetMaskBoxImage(const NinePieceImage& b) { SetMaskBoxImageInternal(b); }
SetMaskBoxImageSlicesFill(bool fill)1303   void SetMaskBoxImageSlicesFill(bool fill) {
1304     MutableMaskBoxImageInternal().SetFill(fill);
1305   }
1306 
1307   // Text-combine utility functions.
HasTextCombine()1308   bool HasTextCombine() const { return TextCombine() != ETextCombine::kNone; }
1309 
1310   // Grid utility functions.
GetGridAutoFlow()1311   GridAutoFlow GetGridAutoFlow() const { return GridAutoFlowInternal(); }
IsGridAutoFlowDirectionRow()1312   bool IsGridAutoFlowDirectionRow() const {
1313     return (GridAutoFlowInternal() &
1314             static_cast<int>(kInternalAutoFlowDirectionRow)) ==
1315            kInternalAutoFlowDirectionRow;
1316   }
IsGridAutoFlowDirectionColumn()1317   bool IsGridAutoFlowDirectionColumn() const {
1318     return (GridAutoFlowInternal() &
1319             static_cast<int>(kInternalAutoFlowDirectionColumn)) ==
1320            kInternalAutoFlowDirectionColumn;
1321   }
IsGridAutoFlowAlgorithmSparse()1322   bool IsGridAutoFlowAlgorithmSparse() const {
1323     return (GridAutoFlowInternal() &
1324             static_cast<int>(kInternalAutoFlowAlgorithmSparse)) ==
1325            kInternalAutoFlowAlgorithmSparse;
1326   }
IsGridAutoFlowAlgorithmDense()1327   bool IsGridAutoFlowAlgorithmDense() const {
1328     return (GridAutoFlowInternal() &
1329             static_cast<int>(kInternalAutoFlowAlgorithmDense)) ==
1330            kInternalAutoFlowAlgorithmDense;
1331   }
1332 
1333   // align-content utility functions.
AlignContentPosition()1334   ContentPosition AlignContentPosition() const {
1335     return AlignContent().GetPosition();
1336   }
AlignContentDistribution()1337   ContentDistributionType AlignContentDistribution() const {
1338     return AlignContent().Distribution();
1339   }
AlignContentOverflowAlignment()1340   OverflowAlignment AlignContentOverflowAlignment() const {
1341     return AlignContent().Overflow();
1342   }
SetAlignContentPosition(ContentPosition position)1343   void SetAlignContentPosition(ContentPosition position) {
1344     MutableAlignContentInternal().SetPosition(position);
1345   }
SetAlignContentDistribution(ContentDistributionType distribution)1346   void SetAlignContentDistribution(ContentDistributionType distribution) {
1347     MutableAlignContentInternal().SetDistribution(distribution);
1348   }
SetAlignContentOverflow(OverflowAlignment overflow)1349   void SetAlignContentOverflow(OverflowAlignment overflow) {
1350     MutableAlignContentInternal().SetOverflow(overflow);
1351   }
1352 
1353   // justify-content utility functions.
JustifyContentPosition()1354   ContentPosition JustifyContentPosition() const {
1355     return JustifyContent().GetPosition();
1356   }
JustifyContentDistribution()1357   ContentDistributionType JustifyContentDistribution() const {
1358     return JustifyContent().Distribution();
1359   }
JustifyContentOverflowAlignment()1360   OverflowAlignment JustifyContentOverflowAlignment() const {
1361     return JustifyContent().Overflow();
1362   }
SetJustifyContentPosition(ContentPosition position)1363   void SetJustifyContentPosition(ContentPosition position) {
1364     MutableJustifyContentInternal().SetPosition(position);
1365   }
SetJustifyContentDistribution(ContentDistributionType distribution)1366   void SetJustifyContentDistribution(ContentDistributionType distribution) {
1367     MutableJustifyContentInternal().SetDistribution(distribution);
1368   }
SetJustifyContentOverflow(OverflowAlignment overflow)1369   void SetJustifyContentOverflow(OverflowAlignment overflow) {
1370     MutableJustifyContentInternal().SetOverflow(overflow);
1371   }
1372 
1373   // align-items utility functions.
AlignItemsPosition()1374   ItemPosition AlignItemsPosition() const { return AlignItems().GetPosition(); }
AlignItemsOverflowAlignment()1375   OverflowAlignment AlignItemsOverflowAlignment() const {
1376     return AlignItems().Overflow();
1377   }
SetAlignItemsPosition(ItemPosition position)1378   void SetAlignItemsPosition(ItemPosition position) {
1379     MutableAlignItemsInternal().SetPosition(position);
1380   }
SetAlignItemsOverflow(OverflowAlignment overflow)1381   void SetAlignItemsOverflow(OverflowAlignment overflow) {
1382     MutableAlignItemsInternal().SetOverflow(overflow);
1383   }
1384 
1385   // justify-items utility functions.
JustifyItemsPosition()1386   ItemPosition JustifyItemsPosition() const {
1387     return JustifyItems().GetPosition();
1388   }
JustifyItemsOverflowAlignment()1389   OverflowAlignment JustifyItemsOverflowAlignment() const {
1390     return JustifyItems().Overflow();
1391   }
JustifyItemsPositionType()1392   ItemPositionType JustifyItemsPositionType() const {
1393     return JustifyItems().PositionType();
1394   }
SetJustifyItemsPosition(ItemPosition position)1395   void SetJustifyItemsPosition(ItemPosition position) {
1396     MutableJustifyItemsInternal().SetPosition(position);
1397   }
SetJustifyItemsOverflow(OverflowAlignment overflow)1398   void SetJustifyItemsOverflow(OverflowAlignment overflow) {
1399     MutableJustifyItemsInternal().SetOverflow(overflow);
1400   }
SetJustifyItemsPositionType(ItemPositionType position_type)1401   void SetJustifyItemsPositionType(ItemPositionType position_type) {
1402     MutableJustifyItemsInternal().SetPositionType(position_type);
1403   }
1404 
1405   // align-self utility functions.
AlignSelfPosition()1406   ItemPosition AlignSelfPosition() const { return AlignSelf().GetPosition(); }
AlignSelfOverflowAlignment()1407   OverflowAlignment AlignSelfOverflowAlignment() const {
1408     return AlignSelf().Overflow();
1409   }
SetAlignSelfPosition(ItemPosition position)1410   void SetAlignSelfPosition(ItemPosition position) {
1411     MutableAlignSelfInternal().SetPosition(position);
1412   }
SetAlignSelfOverflow(OverflowAlignment overflow)1413   void SetAlignSelfOverflow(OverflowAlignment overflow) {
1414     MutableAlignSelfInternal().SetOverflow(overflow);
1415   }
1416 
1417   // justify-self utility functions.
JustifySelfPosition()1418   ItemPosition JustifySelfPosition() const {
1419     return JustifySelf().GetPosition();
1420   }
JustifySelfOverflowAlignment()1421   OverflowAlignment JustifySelfOverflowAlignment() const {
1422     return JustifySelf().Overflow();
1423   }
SetJustifySelfPosition(ItemPosition position)1424   void SetJustifySelfPosition(ItemPosition position) {
1425     MutableJustifySelfInternal().SetPosition(position);
1426   }
SetJustifySelfOverflow(OverflowAlignment overflow)1427   void SetJustifySelfOverflow(OverflowAlignment overflow) {
1428     MutableJustifySelfInternal().SetOverflow(overflow);
1429   }
1430 
1431   // Writing mode utility functions.
GetWritingDirection()1432   WritingDirectionMode GetWritingDirection() const {
1433     return {GetWritingMode(), Direction()};
1434   }
IsHorizontalWritingMode()1435   bool IsHorizontalWritingMode() const {
1436     return blink::IsHorizontalWritingMode(GetWritingMode());
1437   }
IsFlippedLinesWritingMode()1438   bool IsFlippedLinesWritingMode() const {
1439     return blink::IsFlippedLinesWritingMode(GetWritingMode());
1440   }
IsFlippedBlocksWritingMode()1441   bool IsFlippedBlocksWritingMode() const {
1442     return blink::IsFlippedBlocksWritingMode(GetWritingMode());
1443   }
1444 
1445   // Will-change utility functions.
1446   bool HasWillChangeCompositingHint() const;
HasWillChangeOpacityHint()1447   bool HasWillChangeOpacityHint() const {
1448     return WillChangeProperties().Contains(CSSPropertyID::kOpacity);
1449   }
1450   bool HasWillChangeTransformHint() const;
HasWillChangeFilterHint()1451   bool HasWillChangeFilterHint() const {
1452     return WillChangeProperties().Contains(CSSPropertyID::kFilter) ||
1453            WillChangeProperties().Contains(CSSPropertyID::kAliasWebkitFilter);
1454   }
HasWillChangeBackdropFilterHint()1455   bool HasWillChangeBackdropFilterHint() const {
1456     return WillChangeProperties().Contains(CSSPropertyID::kBackdropFilter);
1457   }
1458 
1459   // Hyphen utility functions.
1460   Hyphenation* GetHyphenation() const;
1461   const AtomicString& HyphenString() const;
1462 
1463   // text-align utility functions.
1464   using ComputedStyleBase::GetTextAlign;
1465   ETextAlign GetTextAlign(bool is_last_line) const;
1466 
1467   // text-indent utility functions.
1468   bool ShouldUseTextIndent(bool is_first_line,
1469                            bool is_after_forced_break) const;
1470 
1471   // text-transform utility functions.
1472   void ApplyTextTransform(String*, UChar previous_character = ' ') const;
1473 
1474   // Line-height utility functions.
SpecifiedLineHeight()1475   const Length& SpecifiedLineHeight() const { return LineHeightInternal(); }
1476   int ComputedLineHeight() const;
1477   LayoutUnit ComputedLineHeightAsFixed() const;
1478 
1479   // Width/height utility functions.
LogicalWidth()1480   const Length& LogicalWidth() const {
1481     return IsHorizontalWritingMode() ? Width() : Height();
1482   }
LogicalHeight()1483   const Length& LogicalHeight() const {
1484     return IsHorizontalWritingMode() ? Height() : Width();
1485   }
SetLogicalWidth(const Length & v)1486   void SetLogicalWidth(const Length& v) {
1487     if (IsHorizontalWritingMode()) {
1488       SetWidth(v);
1489     } else {
1490       SetHeight(v);
1491     }
1492   }
1493 
SetLogicalHeight(const Length & v)1494   void SetLogicalHeight(const Length& v) {
1495     if (IsHorizontalWritingMode()) {
1496       SetHeight(v);
1497     } else {
1498       SetWidth(v);
1499     }
1500   }
LogicalMaxWidth()1501   const Length& LogicalMaxWidth() const {
1502     return IsHorizontalWritingMode() ? MaxWidth() : MaxHeight();
1503   }
LogicalMaxHeight()1504   const Length& LogicalMaxHeight() const {
1505     return IsHorizontalWritingMode() ? MaxHeight() : MaxWidth();
1506   }
LogicalMinWidth()1507   const Length& LogicalMinWidth() const {
1508     return IsHorizontalWritingMode() ? MinWidth() : MinHeight();
1509   }
LogicalMinHeight()1510   const Length& LogicalMinHeight() const {
1511     return IsHorizontalWritingMode() ? MinHeight() : MinWidth();
1512   }
1513 
1514   // Margin utility functions.
SetMarginTop(const Length & v)1515   void SetMarginTop(const Length& v) {
1516     if (MarginTop() != v) {
1517       if (!v.IsZero() || v.IsAuto())
1518         SetMayHaveMargin();
1519       MutableMarginTopInternal() = v;
1520     }
1521   }
SetMarginRight(const Length & v)1522   void SetMarginRight(const Length& v) {
1523     if (MarginRight() != v) {
1524       if (!v.IsZero() || v.IsAuto())
1525         SetMayHaveMargin();
1526       MutableMarginRightInternal() = v;
1527     }
1528   }
SetMarginBottom(const Length & v)1529   void SetMarginBottom(const Length& v) {
1530     if (MarginBottom() != v) {
1531       if (!v.IsZero() || v.IsAuto())
1532         SetMayHaveMargin();
1533       MutableMarginBottomInternal() = v;
1534     }
1535   }
SetMarginLeft(const Length & v)1536   void SetMarginLeft(const Length& v) {
1537     if (MarginLeft() != v) {
1538       if (!v.IsZero() || v.IsAuto())
1539         SetMayHaveMargin();
1540       MutableMarginLeftInternal() = v;
1541     }
1542   }
HasMarginBeforeQuirk()1543   bool HasMarginBeforeQuirk() const {
1544     return MayHaveMargin() && MarginBefore().Quirk();
1545   }
HasMarginAfterQuirk()1546   bool HasMarginAfterQuirk() const {
1547     return MayHaveMargin() && MarginAfter().Quirk();
1548   }
MarginBefore()1549   const Length& MarginBefore() const { return MarginBeforeUsing(*this); }
MarginAfter()1550   const Length& MarginAfter() const { return MarginAfterUsing(*this); }
MarginStart()1551   const Length& MarginStart() const { return MarginStartUsing(*this); }
MarginEnd()1552   const Length& MarginEnd() const { return MarginEndUsing(*this); }
MarginOver()1553   const Length& MarginOver() const {
1554     return PhysicalMarginToLogical(*this).Over();
1555   }
MarginUnder()1556   const Length& MarginUnder() const {
1557     return PhysicalMarginToLogical(*this).Under();
1558   }
MarginStartUsing(const ComputedStyle & other)1559   const Length& MarginStartUsing(const ComputedStyle& other) const {
1560     return PhysicalMarginToLogical(other).Start();
1561   }
MarginEndUsing(const ComputedStyle & other)1562   const Length& MarginEndUsing(const ComputedStyle& other) const {
1563     return PhysicalMarginToLogical(other).End();
1564   }
MarginBeforeUsing(const ComputedStyle & other)1565   const Length& MarginBeforeUsing(const ComputedStyle& other) const {
1566     return PhysicalMarginToLogical(other).Before();
1567   }
MarginAfterUsing(const ComputedStyle & other)1568   const Length& MarginAfterUsing(const ComputedStyle& other) const {
1569     return PhysicalMarginToLogical(other).After();
1570   }
1571   void SetMarginStart(const Length&);
1572   void SetMarginEnd(const Length&);
MarginEqual(const ComputedStyle & other)1573   bool MarginEqual(const ComputedStyle& other) const {
1574     return MarginTop() == other.MarginTop() &&
1575            MarginLeft() == other.MarginLeft() &&
1576            MarginRight() == other.MarginRight() &&
1577            MarginBottom() == other.MarginBottom();
1578   }
1579 
1580   // Padding utility functions.
SetPaddingTop(const Length & v)1581   void SetPaddingTop(const Length& v) {
1582     if (PaddingTop() != v) {
1583       if (!v.IsZero())
1584         SetMayHavePadding();
1585       MutablePaddingTopInternal() = v;
1586     }
1587   }
SetPaddingRight(const Length & v)1588   void SetPaddingRight(const Length& v) {
1589     if (PaddingRight() != v) {
1590       if (!v.IsZero())
1591         SetMayHavePadding();
1592       MutablePaddingRightInternal() = v;
1593     }
1594   }
SetPaddingBottom(const Length & v)1595   void SetPaddingBottom(const Length& v) {
1596     if (PaddingBottom() != v) {
1597       if (!v.IsZero())
1598         SetMayHavePadding();
1599       MutablePaddingBottomInternal() = v;
1600     }
1601   }
SetPaddingLeft(const Length & v)1602   void SetPaddingLeft(const Length& v) {
1603     if (PaddingLeft() != v) {
1604       if (!v.IsZero())
1605         SetMayHavePadding();
1606       MutablePaddingLeftInternal() = v;
1607     }
1608   }
1609 
PaddingBefore()1610   const Length& PaddingBefore() const {
1611     return PhysicalPaddingToLogical().Before();
1612   }
PaddingAfter()1613   const Length& PaddingAfter() const {
1614     return PhysicalPaddingToLogical().After();
1615   }
PaddingStart()1616   const Length& PaddingStart() const {
1617     return PhysicalPaddingToLogical().Start();
1618   }
PaddingEnd()1619   const Length& PaddingEnd() const { return PhysicalPaddingToLogical().End(); }
PaddingOver()1620   const Length& PaddingOver() const {
1621     return PhysicalPaddingToLogical().Over();
1622   }
PaddingUnder()1623   const Length& PaddingUnder() const {
1624     return PhysicalPaddingToLogical().Under();
1625   }
ResetPadding()1626   void ResetPadding() {
1627     SetPaddingTop(Length::Fixed());
1628     SetPaddingBottom(Length::Fixed());
1629     SetPaddingLeft(Length::Fixed());
1630     SetPaddingRight(Length::Fixed());
1631   }
SetPadding(const LengthBox & b)1632   void SetPadding(const LengthBox& b) {
1633     SetPaddingTop(b.top_);
1634     SetPaddingBottom(b.bottom_);
1635     SetPaddingLeft(b.left_);
1636     SetPaddingRight(b.right_);
1637   }
PaddingEqual(const ComputedStyle & other)1638   bool PaddingEqual(const ComputedStyle& other) const {
1639     return PaddingTop() == other.PaddingTop() &&
1640            PaddingLeft() == other.PaddingLeft() &&
1641            PaddingRight() == other.PaddingRight() &&
1642            PaddingBottom() == other.PaddingBottom();
1643   }
PaddingEqual(const LengthBox & other)1644   bool PaddingEqual(const LengthBox& other) const {
1645     return PaddingTop() == other.Top() && PaddingLeft() == other.Left() &&
1646            PaddingRight() == other.Right() && PaddingBottom() == other.Bottom();
1647   }
1648 
1649   // Border utility functions
1650   LayoutRectOutsets ImageOutsets(const NinePieceImage&) const;
HasBorderImageOutsets()1651   bool HasBorderImageOutsets() const {
1652     return BorderImage().HasImage() && BorderImage().Outset().NonZero();
1653   }
BorderImageOutsets()1654   LayoutRectOutsets BorderImageOutsets() const {
1655     return ImageOutsets(BorderImage());
1656   }
BorderImageSlicesFill()1657   bool BorderImageSlicesFill() const { return BorderImage().Fill(); }
1658 
1659   void SetBorderImageSlicesFill(bool);
BorderLeft()1660   const BorderValue BorderLeft() const {
1661     return BorderValue(BorderLeftStyle(), BorderLeftColor(),
1662                        BorderLeftWidthInternal().ToFloat());
1663   }
BorderRight()1664   const BorderValue BorderRight() const {
1665     return BorderValue(BorderRightStyle(), BorderRightColor(),
1666                        BorderRightWidthInternal().ToFloat());
1667   }
BorderTop()1668   const BorderValue BorderTop() const {
1669     return BorderValue(BorderTopStyle(), BorderTopColor(),
1670                        BorderTopWidthInternal().ToFloat());
1671   }
BorderBottom()1672   const BorderValue BorderBottom() const {
1673     return BorderValue(BorderBottomStyle(), BorderBottomColor(),
1674                        BorderBottomWidthInternal().ToFloat());
1675   }
1676 
BorderSizeEquals(const ComputedStyle & o)1677   bool BorderSizeEquals(const ComputedStyle& o) const {
1678     return BorderLeftWidth() == o.BorderLeftWidth() &&
1679            BorderTopWidth() == o.BorderTopWidth() &&
1680            BorderRightWidth() == o.BorderRightWidth() &&
1681            BorderBottomWidth() == o.BorderBottomWidth();
1682   }
1683 
BorderBeforeUsing(const ComputedStyle & other)1684   BorderValue BorderBeforeUsing(const ComputedStyle& other) const {
1685     return PhysicalBorderToLogical(other).Before();
1686   }
BorderAfterUsing(const ComputedStyle & other)1687   BorderValue BorderAfterUsing(const ComputedStyle& other) const {
1688     return PhysicalBorderToLogical(other).After();
1689   }
BorderStartUsing(const ComputedStyle & other)1690   BorderValue BorderStartUsing(const ComputedStyle& other) const {
1691     return PhysicalBorderToLogical(other).Start();
1692   }
BorderEndUsing(const ComputedStyle & other)1693   BorderValue BorderEndUsing(const ComputedStyle& other) const {
1694     return PhysicalBorderToLogical(other).End();
1695   }
1696 
BorderBefore()1697   BorderValue BorderBefore() const { return BorderBeforeUsing(*this); }
BorderAfter()1698   BorderValue BorderAfter() const { return BorderAfterUsing(*this); }
BorderStart()1699   BorderValue BorderStart() const { return BorderStartUsing(*this); }
BorderEnd()1700   BorderValue BorderEnd() const { return BorderEndUsing(*this); }
1701 
BorderAfterWidth()1702   float BorderAfterWidth() const {
1703     return PhysicalBorderWidthToLogical().After();
1704   }
BorderBeforeWidth()1705   float BorderBeforeWidth() const {
1706     return PhysicalBorderWidthToLogical().Before();
1707   }
BorderEndWidth()1708   float BorderEndWidth() const { return PhysicalBorderWidthToLogical().End(); }
BorderStartWidth()1709   float BorderStartWidth() const {
1710     return PhysicalBorderWidthToLogical().Start();
1711   }
BorderOverWidth()1712   float BorderOverWidth() const {
1713     return PhysicalBorderWidthToLogical().Over();
1714   }
BorderUnderWidth()1715   float BorderUnderWidth() const {
1716     return PhysicalBorderWidthToLogical().Under();
1717   }
1718 
BorderAfterStyle()1719   EBorderStyle BorderAfterStyle() const {
1720     return PhysicalBorderStyleToLogical().After();
1721   }
BorderBeforeStyle()1722   EBorderStyle BorderBeforeStyle() const {
1723     return PhysicalBorderStyleToLogical().Before();
1724   }
BorderEndStyle()1725   EBorderStyle BorderEndStyle() const {
1726     return PhysicalBorderStyleToLogical().End();
1727   }
BorderStartStyle()1728   EBorderStyle BorderStartStyle() const {
1729     return PhysicalBorderStyleToLogical().Start();
1730   }
1731 
HasBorderFill()1732   bool HasBorderFill() const {
1733     return BorderImage().HasImage() && BorderImage().Fill();
1734   }
HasBorder()1735   bool HasBorder() const {
1736     return BorderLeftNonZero() || BorderRightNonZero() || BorderTopNonZero() ||
1737            BorderBottomNonZero();
1738   }
HasBorderDecoration()1739   bool HasBorderDecoration() const { return HasBorder() || HasBorderFill(); }
HasBorderRadius()1740   bool HasBorderRadius() const {
1741     if (!BorderTopLeftRadius().Width().IsZero())
1742       return true;
1743     if (!BorderTopRightRadius().Width().IsZero())
1744       return true;
1745     if (!BorderBottomLeftRadius().Width().IsZero())
1746       return true;
1747     if (!BorderBottomRightRadius().Width().IsZero())
1748       return true;
1749     return false;
1750   }
HasBorderColorReferencingCurrentColor()1751   bool HasBorderColorReferencingCurrentColor() const {
1752     return (BorderLeftNonZero() && BorderLeftColor().IsCurrentColor()) ||
1753            (BorderRightNonZero() && BorderRightColor().IsCurrentColor()) ||
1754            (BorderTopNonZero() && BorderTopColor().IsCurrentColor()) ||
1755            (BorderBottomNonZero() && BorderBottomColor().IsCurrentColor());
1756   }
1757 
RadiiEqual(const ComputedStyle & o)1758   bool RadiiEqual(const ComputedStyle& o) const {
1759     return BorderTopLeftRadius() == o.BorderTopLeftRadius() &&
1760            BorderTopRightRadius() == o.BorderTopRightRadius() &&
1761            BorderBottomLeftRadius() == o.BorderBottomLeftRadius() &&
1762            BorderBottomRightRadius() == o.BorderBottomRightRadius();
1763   }
1764 
BorderLeftEquals(const ComputedStyle & o)1765   bool BorderLeftEquals(const ComputedStyle& o) const {
1766     return BorderLeftWidthInternal() == o.BorderLeftWidthInternal() &&
1767            BorderLeftStyle() == o.BorderLeftStyle() &&
1768            BorderLeftColor() == o.BorderLeftColor();
1769   }
BorderLeftEquals(const BorderValue & o)1770   bool BorderLeftEquals(const BorderValue& o) const {
1771     return BorderLeftWidthInternal().ToFloat() == o.Width() &&
1772            BorderLeftStyle() == o.Style() && BorderLeftColor() == o.GetColor();
1773   }
1774 
BorderLeftVisuallyEqual(const ComputedStyle & o)1775   bool BorderLeftVisuallyEqual(const ComputedStyle& o) const {
1776     if (BorderLeftStyle() == EBorderStyle::kNone &&
1777         o.BorderLeftStyle() == EBorderStyle::kNone)
1778       return true;
1779     if (BorderLeftStyle() == EBorderStyle::kHidden &&
1780         o.BorderLeftStyle() == EBorderStyle::kHidden)
1781       return true;
1782     return BorderLeftEquals(o);
1783   }
1784 
BorderRightEquals(const ComputedStyle & o)1785   bool BorderRightEquals(const ComputedStyle& o) const {
1786     return BorderRightWidthInternal() == o.BorderRightWidthInternal() &&
1787            BorderRightStyle() == o.BorderRightStyle() &&
1788            BorderRightColor() == o.BorderRightColor();
1789   }
BorderRightEquals(const BorderValue & o)1790   bool BorderRightEquals(const BorderValue& o) const {
1791     return BorderRightWidthInternal().ToFloat() == o.Width() &&
1792            BorderRightStyle() == o.Style() &&
1793            BorderRightColor() == o.GetColor();
1794   }
1795 
BorderRightVisuallyEqual(const ComputedStyle & o)1796   bool BorderRightVisuallyEqual(const ComputedStyle& o) const {
1797     if (BorderRightStyle() == EBorderStyle::kNone &&
1798         o.BorderRightStyle() == EBorderStyle::kNone)
1799       return true;
1800     if (BorderRightStyle() == EBorderStyle::kHidden &&
1801         o.BorderRightStyle() == EBorderStyle::kHidden)
1802       return true;
1803     return BorderRightEquals(o);
1804   }
1805 
BorderTopVisuallyEqual(const ComputedStyle & o)1806   bool BorderTopVisuallyEqual(const ComputedStyle& o) const {
1807     if (BorderTopStyle() == EBorderStyle::kNone &&
1808         o.BorderTopStyle() == EBorderStyle::kNone)
1809       return true;
1810     if (BorderTopStyle() == EBorderStyle::kHidden &&
1811         o.BorderTopStyle() == EBorderStyle::kHidden)
1812       return true;
1813     return BorderTopEquals(o);
1814   }
1815 
BorderTopEquals(const ComputedStyle & o)1816   bool BorderTopEquals(const ComputedStyle& o) const {
1817     return BorderTopWidthInternal() == o.BorderTopWidthInternal() &&
1818            BorderTopStyle() == o.BorderTopStyle() &&
1819            BorderTopColor() == o.BorderTopColor();
1820   }
BorderTopEquals(const BorderValue & o)1821   bool BorderTopEquals(const BorderValue& o) const {
1822     return BorderTopWidthInternal().ToFloat() == o.Width() &&
1823            BorderTopStyle() == o.Style() && BorderTopColor() == o.GetColor();
1824   }
1825 
BorderBottomVisuallyEqual(const ComputedStyle & o)1826   bool BorderBottomVisuallyEqual(const ComputedStyle& o) const {
1827     if (BorderBottomStyle() == EBorderStyle::kNone &&
1828         o.BorderBottomStyle() == EBorderStyle::kNone)
1829       return true;
1830     if (BorderBottomStyle() == EBorderStyle::kHidden &&
1831         o.BorderBottomStyle() == EBorderStyle::kHidden)
1832       return true;
1833     return BorderBottomEquals(o);
1834   }
1835 
BorderBottomEquals(const ComputedStyle & o)1836   bool BorderBottomEquals(const ComputedStyle& o) const {
1837     return BorderBottomWidthInternal() == o.BorderBottomWidthInternal() &&
1838            BorderBottomStyle() == o.BorderBottomStyle() &&
1839            BorderBottomColor() == o.BorderBottomColor();
1840   }
BorderBottomEquals(const BorderValue & o)1841   bool BorderBottomEquals(const BorderValue& o) const {
1842     return BorderBottomWidthInternal().ToFloat() == o.Width() &&
1843            BorderBottomStyle() == o.Style() &&
1844            BorderBottomColor() == o.GetColor();
1845   }
1846 
BorderEquals(const ComputedStyle & o)1847   bool BorderEquals(const ComputedStyle& o) const {
1848     return BorderLeftEquals(o) && BorderRightEquals(o) && BorderTopEquals(o) &&
1849            BorderBottomEquals(o) && BorderImage() == o.BorderImage();
1850   }
1851 
BorderVisuallyEqual(const ComputedStyle & o)1852   bool BorderVisuallyEqual(const ComputedStyle& o) const {
1853     return BorderLeftVisuallyEqual(o) && BorderRightVisuallyEqual(o) &&
1854            BorderTopVisuallyEqual(o) && BorderBottomVisuallyEqual(o) &&
1855            BorderImage() == o.BorderImage();
1856   }
1857 
BorderVisualOverflowEqual(const ComputedStyle & o)1858   bool BorderVisualOverflowEqual(const ComputedStyle& o) const {
1859     return BorderImage().Outset() == o.BorderImage().Outset();
1860   }
1861 
1862   CORE_EXPORT void AdjustDiffForBackgroundVisuallyEqual(
1863       const ComputedStyle& o,
1864       StyleDifference& diff) const;
1865 
ResetBorder()1866   void ResetBorder() {
1867     ResetBorderImage();
1868     ResetBorderTop();
1869     ResetBorderRight();
1870     ResetBorderBottom();
1871     ResetBorderLeft();
1872     ResetBorderTopLeftRadius();
1873     ResetBorderTopRightRadius();
1874     ResetBorderBottomLeftRadius();
1875     ResetBorderBottomRightRadius();
1876   }
1877 
ResetBorderTop()1878   void ResetBorderTop() {
1879     SetBorderTopStyle(EBorderStyle::kNone);
1880     SetBorderTopWidth(3);
1881     SetBorderTopColorInternal(StyleColor::CurrentColor());
1882   }
ResetBorderRight()1883   void ResetBorderRight() {
1884     SetBorderRightStyle(EBorderStyle::kNone);
1885     SetBorderRightWidth(3);
1886     SetBorderRightColorInternal(StyleColor::CurrentColor());
1887   }
ResetBorderBottom()1888   void ResetBorderBottom() {
1889     SetBorderBottomStyle(EBorderStyle::kNone);
1890     SetBorderBottomWidth(3);
1891     SetBorderBottomColorInternal(StyleColor::CurrentColor());
1892   }
ResetBorderLeft()1893   void ResetBorderLeft() {
1894     SetBorderLeftStyle(EBorderStyle::kNone);
1895     SetBorderLeftWidth(3);
1896     SetBorderLeftColorInternal(StyleColor::CurrentColor());
1897   }
1898 
SetBorderRadius(const LengthSize & s)1899   void SetBorderRadius(const LengthSize& s) {
1900     SetBorderTopLeftRadius(s);
1901     SetBorderTopRightRadius(s);
1902     SetBorderBottomLeftRadius(s);
1903     SetBorderBottomRightRadius(s);
1904   }
SetBorderRadius(const IntSize & s)1905   void SetBorderRadius(const IntSize& s) {
1906     SetBorderRadius(
1907         LengthSize(Length::Fixed(s.Width()), Length::Fixed(s.Height())));
1908   }
1909 
1910   bool CanRenderBorderImage() const;
1911 
1912   // Float utility functions.
IsFloating()1913   bool IsFloating() const { return FloatingInternal() != EFloat::kNone; }
UnresolvedFloating()1914   EFloat UnresolvedFloating() const { return FloatingInternal(); }
1915 
Floating(const ComputedStyle & cb_style)1916   EFloat Floating(const ComputedStyle& cb_style) const {
1917     return Floating(cb_style.Direction());
1918   }
1919 
Floating(TextDirection cb_direction)1920   EFloat Floating(TextDirection cb_direction) const {
1921     const EFloat value = FloatingInternal();
1922     switch (value) {
1923       case EFloat::kInlineStart:
1924       case EFloat::kInlineEnd: {
1925         return IsLtr(cb_direction) == (value == EFloat::kInlineStart)
1926                    ? EFloat::kLeft
1927                    : EFloat::kRight;
1928       }
1929       default:
1930         return value;
1931     }
1932   }
1933 
1934   // Mix-blend-mode utility functions.
HasBlendMode()1935   bool HasBlendMode() const { return GetBlendMode() != BlendMode::kNormal; }
1936 
1937   // Motion utility functions.
HasOffset()1938   bool HasOffset() const {
1939     return !OffsetPosition().X().IsAuto() || OffsetPath();
1940   }
1941 
1942   // Direction utility functions.
IsLeftToRightDirection()1943   bool IsLeftToRightDirection() const {
1944     return Direction() == TextDirection::kLtr;
1945   }
1946 
1947   // Perspective utility functions.
HasPerspective()1948   bool HasPerspective() const { return Perspective() > 0; }
1949 
1950   // Outline utility functions.
1951   // HasOutline is insufficient to determine whether Node has an outline.
1952   // Use NGOutlineUtils::HasPaintedOutline instead.
HasOutline()1953   bool HasOutline() const {
1954     return OutlineWidth() > 0 && OutlineStyle() > EBorderStyle::kHidden;
1955   }
1956   CORE_EXPORT int OutlineOutsetExtent() const;
1957   CORE_EXPORT float GetOutlineStrokeWidthForFocusRing() const;
HasOutlineWithCurrentColor()1958   bool HasOutlineWithCurrentColor() const {
1959     return HasOutline() && OutlineColor().IsCurrentColor();
1960   }
1961 
1962   // Position utility functions.
HasOutOfFlowPosition()1963   bool HasOutOfFlowPosition() const {
1964     return GetPosition() == EPosition::kAbsolute ||
1965            GetPosition() == EPosition::kFixed;
1966   }
HasInFlowPosition()1967   bool HasInFlowPosition() const {
1968     return GetPosition() == EPosition::kRelative ||
1969            GetPosition() == EPosition::kSticky;
1970   }
HasViewportConstrainedPosition()1971   bool HasViewportConstrainedPosition() const {
1972     return GetPosition() == EPosition::kFixed;
1973   }
HasStickyConstrainedPosition()1974   bool HasStickyConstrainedPosition() const {
1975     return GetPosition() == EPosition::kSticky &&
1976            (!Top().IsAuto() || !Left().IsAuto() || !Right().IsAuto() ||
1977             !Bottom().IsAuto());
1978   }
1979 
1980   // Clear utility functions.
HasClear()1981   bool HasClear() const { return ClearInternal() != EClear::kNone; }
UnresolvedClear()1982   EClear UnresolvedClear() const { return ClearInternal(); }
1983 
Clear(const ComputedStyle & cb_style)1984   EClear Clear(const ComputedStyle& cb_style) const {
1985     return Clear(cb_style.Direction());
1986   }
1987 
Clear(TextDirection cb_direction)1988   EClear Clear(TextDirection cb_direction) const {
1989     const EClear value = ClearInternal();
1990     switch (value) {
1991       case EClear::kInlineStart:
1992       case EClear::kInlineEnd: {
1993         return IsLtr(cb_direction) == (value == EClear::kInlineStart)
1994                    ? EClear::kLeft
1995                    : EClear::kRight;
1996       }
1997       default:
1998         return value;
1999     }
2000   }
2001 
2002   // Clip utility functions.
ClipLeft()2003   const Length& ClipLeft() const { return Clip().Left(); }
ClipRight()2004   const Length& ClipRight() const { return Clip().Right(); }
ClipTop()2005   const Length& ClipTop() const { return Clip().Top(); }
ClipBottom()2006   const Length& ClipBottom() const { return Clip().Bottom(); }
2007 
2008   // Offset utility functions.
2009   // Accessors for positioned object edges that take into account writing mode.
LogicalInlineStart()2010   const Length& LogicalInlineStart() const {
2011     return PhysicalBoundsToLogical().InlineStart();
2012   }
LogicalInlineEnd()2013   const Length& LogicalInlineEnd() const {
2014     return PhysicalBoundsToLogical().InlineEnd();
2015   }
LogicalLeft()2016   const Length& LogicalLeft() const {
2017     return PhysicalBoundsToLogical().LineLeft();
2018   }
LogicalRight()2019   const Length& LogicalRight() const {
2020     return PhysicalBoundsToLogical().LineRight();
2021   }
LogicalTop()2022   const Length& LogicalTop() const {
2023     return PhysicalBoundsToLogical().Before();
2024   }
LogicalBottom()2025   const Length& LogicalBottom() const {
2026     return PhysicalBoundsToLogical().After();
2027   }
OffsetEqual(const ComputedStyle & other)2028   bool OffsetEqual(const ComputedStyle& other) const {
2029     return Left() == other.Left() && Right() == other.Right() &&
2030            Top() == other.Top() && Bottom() == other.Bottom();
2031   }
2032 
2033   // Whether or not a positioned element requires normal flow x/y to be computed
2034   // to determine its position.
HasAutoLeftAndRight()2035   bool HasAutoLeftAndRight() const {
2036     return Left().IsAuto() && Right().IsAuto();
2037   }
HasAutoTopAndBottom()2038   bool HasAutoTopAndBottom() const {
2039     return Top().IsAuto() && Bottom().IsAuto();
2040   }
HasStaticInlinePosition(bool horizontal)2041   bool HasStaticInlinePosition(bool horizontal) const {
2042     return horizontal ? HasAutoLeftAndRight() : HasAutoTopAndBottom();
2043   }
HasStaticBlockPosition(bool horizontal)2044   bool HasStaticBlockPosition(bool horizontal) const {
2045     return horizontal ? HasAutoTopAndBottom() : HasAutoLeftAndRight();
2046   }
2047 
2048   // Content utility functions.
ContentDataEquivalent(const ComputedStyle & other)2049   bool ContentDataEquivalent(const ComputedStyle& other) const {
2050     return DataEquivalent(GetContentData(), other.GetContentData());
2051   }
2052 
2053   // Contain utility functions.
ContainsPaint()2054   bool ContainsPaint() const { return Contain() & kContainsPaint; }
ContainsStyle()2055   bool ContainsStyle() const { return Contain() & kContainsStyle; }
ContainsLayout()2056   bool ContainsLayout() const { return Contain() & kContainsLayout; }
ContainsSize()2057   bool ContainsSize() const { return Contain() & kContainsSize; }
2058 
2059   // Display utility functions.
IsDisplayReplacedType()2060   bool IsDisplayReplacedType() const {
2061     return IsDisplayReplacedType(Display());
2062   }
IsDisplayInlineType()2063   bool IsDisplayInlineType() const { return IsDisplayInlineType(Display()); }
IsOriginalDisplayInlineType()2064   bool IsOriginalDisplayInlineType() const {
2065     return IsDisplayInlineType(OriginalDisplay());
2066   }
IsDisplayBlockContainer()2067   bool IsDisplayBlockContainer() const {
2068     return IsDisplayBlockContainer(Display());
2069   }
IsDisplayTableBox()2070   bool IsDisplayTableBox() const { return IsDisplayTableBox(Display()); }
IsDisplayFlexibleBox()2071   bool IsDisplayFlexibleBox() const { return IsDisplayFlexibleBox(Display()); }
IsDisplayFlexibleOrGridBox()2072   bool IsDisplayFlexibleOrGridBox() const {
2073     return IsDisplayFlexibleBox(Display()) || IsDisplayGridBox(Display());
2074   }
IsDisplayLayoutCustomBox()2075   bool IsDisplayLayoutCustomBox() const {
2076     return IsDisplayLayoutCustomBox(Display());
2077   }
2078 
IsDisplayTableType()2079   bool IsDisplayTableType() const { return IsDisplayTableType(Display()); }
2080 
IsDisplayMathType()2081   bool IsDisplayMathType() const { return IsDisplayMathBox(Display()); }
2082 
BlockifiesChildren()2083   bool BlockifiesChildren() const {
2084     return IsDisplayFlexibleOrGridBox() || IsDisplayMathType() ||
2085            IsDisplayLayoutCustomBox() ||
2086            (Display() == EDisplay::kContents && IsInBlockifyingDisplay());
2087   }
2088 
2089   // Return true if an element with this computed style requires LayoutNG
2090   // (i.e. has no legacy layout implementation).
DisplayTypeRequiresLayoutNG()2091   bool DisplayTypeRequiresLayoutNG() const {
2092     return IsDisplayMathType() || IsDisplayLayoutCustomBox();
2093   }
2094 
2095   // Isolation utility functions.
HasIsolation()2096   bool HasIsolation() const { return Isolation() != EIsolation::kAuto; }
2097 
2098   // Content utility functions.
ContentBehavesAsNormal()2099   bool ContentBehavesAsNormal() const {
2100     switch (StyleType()) {
2101       case kPseudoIdMarker:
2102         return !GetContentData();
2103       default:
2104         return !GetContentData() || GetContentData()->IsNone();
2105     }
2106   }
ContentPreventsBoxGeneration()2107   bool ContentPreventsBoxGeneration() const {
2108     switch (StyleType()) {
2109       case kPseudoIdBefore:
2110       case kPseudoIdAfter:
2111         return ContentBehavesAsNormal();
2112       case kPseudoIdMarker:
2113         return GetContentData() && GetContentData()->IsNone();
2114       default:
2115         return false;
2116     }
2117   }
2118 
2119   // Cursor utility functions.
Cursors()2120   CursorList* Cursors() const { return CursorDataInternal().Get(); }
2121   CORE_EXPORT void AddCursor(StyleImage*,
2122                              bool hot_spot_specified,
2123                              const IntPoint& hot_spot = IntPoint());
2124   void SetCursorList(CursorList*);
2125   void ClearCursorList();
2126 
2127   // Resize utility functions.
HasResize()2128   bool HasResize() const { return ResizeInternal() != EResize::kNone; }
UnresolvedResize()2129   EResize UnresolvedResize() const { return ResizeInternal(); }
2130 
Resize(const ComputedStyle & cb_style)2131   EResize Resize(const ComputedStyle& cb_style) const {
2132     EResize value = ResizeInternal();
2133     switch (value) {
2134       case EResize::kBlock:
2135       case EResize::kInline: {
2136         return ::blink::IsHorizontalWritingMode(cb_style.GetWritingMode()) ==
2137                        (value == EResize::kBlock)
2138                    ? EResize::kVertical
2139                    : EResize::kHorizontal;
2140       }
2141       default:
2142         return value;
2143     }
2144   }
2145 
2146   // Text decoration utility functions.
2147   bool TextDecorationVisualOverflowEqual(const ComputedStyle& o) const;
2148   void ApplyTextDecorations(const Color& parent_text_decoration_color,
2149                             bool override_existing_colors);
2150   void ClearAppliedTextDecorations();
2151   void RestoreParentTextDecorations(const ComputedStyle& parent_style);
2152   CORE_EXPORT const Vector<AppliedTextDecoration>& AppliedTextDecorations()
2153       const;
2154   CORE_EXPORT TextDecoration TextDecorationsInEffect() const;
2155 
2156   // Overflow utility functions.
2157 
OverflowInlineDirection()2158   EOverflow OverflowInlineDirection() const {
2159     return IsHorizontalWritingMode() ? OverflowX() : OverflowY();
2160   }
OverflowBlockDirection()2161   EOverflow OverflowBlockDirection() const {
2162     return IsHorizontalWritingMode() ? OverflowY() : OverflowX();
2163   }
2164 
2165   // Returns true if 'overflow' is 'visible' along both axes. When 'clip' is
2166   // used the other axis may be 'visible'. In other words, if one axis is
2167   // 'visible' the other axis is not necessarily 'visible.'
IsOverflowVisibleAlongBothAxes()2168   bool IsOverflowVisibleAlongBothAxes() const {
2169     // Overflip clip and overflow visible may be used along different axis.
2170     return OverflowX() == EOverflow::kVisible &&
2171            OverflowY() == EOverflow::kVisible;
2172   }
2173 
2174   // An overflow value of visible or clip is not a scroll container, all other
2175   // values result in a scroll container. Also note that if visible or clip is
2176   // set on one axis, then the other axis must also be visible or clip. For
2177   // example, "overflow-x: clip; overflow-y: visible" is allowed, but
2178   // "overflow-x: clip; overflow-y: hidden" is not.
IsScrollContainer()2179   bool IsScrollContainer() const {
2180     return OverflowX() != EOverflow::kVisible &&
2181            OverflowX() != EOverflow::kClip;
2182   }
2183 
IsDisplayTableRowOrColumnType()2184   bool IsDisplayTableRowOrColumnType() const {
2185     return Display() == EDisplay::kTableRow ||
2186            Display() == EDisplay::kTableRowGroup ||
2187            Display() == EDisplay::kTableColumn ||
2188            Display() == EDisplay::kTableColumnGroup;
2189   }
2190 
HasAutoHorizontalScroll()2191   bool HasAutoHorizontalScroll() const {
2192     return OverflowX() == EOverflow::kAuto ||
2193            OverflowX() == EOverflow::kOverlay;
2194   }
2195 
HasAutoVerticalScroll()2196   bool HasAutoVerticalScroll() const {
2197     return OverflowY() == EOverflow::kAuto ||
2198            OverflowY() == EOverflow::kOverlay;
2199   }
2200 
ScrollsOverflowX()2201   bool ScrollsOverflowX() const {
2202     return OverflowX() == EOverflow::kScroll || HasAutoHorizontalScroll();
2203   }
2204 
ScrollsOverflowY()2205   bool ScrollsOverflowY() const {
2206     return OverflowY() == EOverflow::kScroll || HasAutoVerticalScroll();
2207   }
2208 
ScrollsOverflow()2209   bool ScrollsOverflow() const {
2210     return ScrollsOverflowX() || ScrollsOverflowY();
2211   }
2212 
2213   // Visibility utility functions.
VisibleToHitTesting()2214   bool VisibleToHitTesting() const {
2215     return Visibility() == EVisibility::kVisible &&
2216            PointerEvents() != EPointerEvents::kNone;
2217   }
2218 
2219   // Animation utility functions.
ShouldCompositeForCurrentAnimations()2220   bool ShouldCompositeForCurrentAnimations() const {
2221     return HasCurrentOpacityAnimation() || HasCurrentTransformAnimation() ||
2222            HasCurrentFilterAnimation() || HasCurrentBackdropFilterAnimation();
2223   }
IsRunningAnimationOnCompositor()2224   bool IsRunningAnimationOnCompositor() const {
2225     return IsRunningOpacityAnimationOnCompositor() ||
2226            IsRunningTransformAnimationOnCompositor() ||
2227            IsRunningFilterAnimationOnCompositor() ||
2228            IsRunningBackdropFilterAnimationOnCompositor();
2229   }
2230 
2231   // Opacity utility functions.
HasOpacity()2232   bool HasOpacity() const { return Opacity() < 1.0f; }
2233 
2234   // Table layout utility functions.
IsFixedTableLayout()2235   bool IsFixedTableLayout() const {
2236     return TableLayout() == ETableLayout::kFixed && !LogicalWidth().IsAuto();
2237   }
2238 
TableBorderSpacing()2239   LogicalSize TableBorderSpacing() const {
2240     if (BorderCollapse() == EBorderCollapse::kCollapse)
2241       return LogicalSize();
2242     return LogicalSize(LayoutUnit(HorizontalBorderSpacing()),
2243                        LayoutUnit(VerticalBorderSpacing()));
2244   }
2245 
2246   // Returns true if the computed style contains a 3D transform operation. This
2247   // can be individual operations from the transform property, or individual
2248   // values from translate/rotate/scale properties. Perspective is omitted since
2249   // it does not, by itself, specify a 3D transform.
Has3DTransformOperation()2250   bool Has3DTransformOperation() const {
2251     return Transform().HasNonPerspective3DOperation() ||
2252            (Translate() && Translate()->Z() != 0) ||
2253            (Rotate() && (Rotate()->X() != 0 || Rotate()->Y() != 0)) ||
2254            (Scale() && Scale()->Z() != 1);
2255   }
2256   // Returns true if the computed style contains a 3D transform operation with a
2257   // non-trivial component in the Z axis. This can be individual operations from
2258   // the transform property, or individual values from translate/rotate/scale
2259   // properties. Perspective is omitted since it does not, by itself, specify a
2260   // 3D transform.
HasNonTrivial3DTransformOperation()2261   bool HasNonTrivial3DTransformOperation() const {
2262     return Transform().HasNonTrivial3DComponent() ||
2263            (Translate() && Translate()->Z() != 0) ||
2264            (Rotate() && Rotate()->Angle() != 0 &&
2265             (Rotate()->X() != 0 || Rotate()->Y() != 0)) ||
2266            (Scale() && Scale()->Z() != 1);
2267   }
HasTransform()2268   bool HasTransform() const {
2269     return HasTransformOperations() || HasOffset() ||
2270            HasCurrentTransformAnimation() || Translate() || Rotate() || Scale();
2271   }
HasTransformOperations()2272   bool HasTransformOperations() const {
2273     return !Transform().Operations().IsEmpty();
2274   }
UsedTransformStyle3D()2275   ETransformStyle3D UsedTransformStyle3D() const {
2276     return HasGroupingPropertyForUsedTransformStyle3D()
2277                ? ETransformStyle3D::kFlat
2278                : TransformStyle3D();
2279   }
2280   // Returns whether the transform operations for |otherStyle| differ from the
2281   // operations for this style instance. Note that callers may want to also
2282   // check hasTransform(), as it is possible for two styles to have matching
2283   // transform operations but differ in other transform-impacting style
2284   // respects.
TransformDataEquivalent(const ComputedStyle & other)2285   bool TransformDataEquivalent(const ComputedStyle& other) const {
2286     return !DiffTransformData(*this, other);
2287   }
Preserves3D()2288   bool Preserves3D() const {
2289     return UsedTransformStyle3D() != ETransformStyle3D::kFlat;
2290   }
2291   enum ApplyTransformOrigin {
2292     kIncludeTransformOrigin,
2293     kExcludeTransformOrigin
2294   };
2295   enum ApplyMotionPath { kIncludeMotionPath, kExcludeMotionPath };
2296   enum ApplyIndependentTransformProperties {
2297     kIncludeIndependentTransformProperties,
2298     kExcludeIndependentTransformProperties
2299   };
2300   void ApplyTransform(TransformationMatrix&,
2301                       const LayoutSize& border_box_data_size,
2302                       ApplyTransformOrigin,
2303                       ApplyMotionPath,
2304                       ApplyIndependentTransformProperties) const;
2305   void ApplyTransform(TransformationMatrix&,
2306                       const FloatRect& bounding_box,
2307                       ApplyTransformOrigin,
2308                       ApplyMotionPath,
2309                       ApplyIndependentTransformProperties) const;
2310 
2311   bool HasFilters() const;
2312 
2313   // Returns |true| if any property that renders using filter operations is
2314   // used (including, but not limited to, 'filter' and 'box-reflect').
HasFilterInducingProperty()2315   bool HasFilterInducingProperty() const {
2316     return HasNonInitialFilter() || HasBoxReflect();
2317   }
2318 
2319   // Returns |true| if filter should be considered to have non-initial value
2320   // for the purposes of containing blocks.
HasNonInitialFilter()2321   bool HasNonInitialFilter() const {
2322     return HasFilter() || HasWillChangeFilterHint();
2323   }
2324 
2325   // Returns |true| if backdrop-filter should be considered to have non-initial
2326   // value for the purposes of containing blocks.
HasNonInitialBackdropFilter()2327   bool HasNonInitialBackdropFilter() const {
2328     return HasBackdropFilter() || HasWillChangeBackdropFilterHint();
2329   }
2330 
2331   // Returns |true| if opacity should be considered to have non-initial value
2332   // for the purpose of creating stacking contexts.
HasNonInitialOpacity()2333   bool HasNonInitialOpacity() const {
2334     return HasOpacity() || HasWillChangeOpacityHint() ||
2335            HasCurrentOpacityAnimation();
2336   }
2337 
2338   // Returns whether this style contains any grouping property as defined by
2339   // https://drafts.csswg.org/css-transforms-2/#grouping-property-values.
2340   //
2341   // |has_box_reflection| is a parameter instead of checking |BoxReflect()|
2342   // because box reflection styles only apply for some objects (see:
2343   // |LayoutObject::HasReflection()|).
HasGroupingProperty(bool has_box_reflection)2344   bool HasGroupingProperty(bool has_box_reflection) const {
2345     if (HasStackingGroupingProperty(has_box_reflection))
2346       return true;
2347     // TODO(pdr): Also check for overflow because the spec requires "overflow:
2348     // any value other than visible or clip."
2349     if (!HasAutoClip() && HasOutOfFlowPosition())
2350       return true;
2351     return false;
2352   }
2353 
2354   // This is the subset of grouping properties (see: |HasGroupingProperty|) that
2355   // also create stacking contexts.
HasStackingGroupingProperty(bool has_box_reflection)2356   bool HasStackingGroupingProperty(bool has_box_reflection) const {
2357     if (HasNonInitialOpacity())
2358       return true;
2359     if (HasNonInitialFilter())
2360       return true;
2361     if (has_box_reflection)
2362       return true;
2363     if (ClipPath())
2364       return true;
2365     if (HasIsolation())
2366       return true;
2367     if (HasMask())
2368       return true;
2369     if (HasBlendMode())
2370       return true;
2371     if (HasNonInitialBackdropFilter())
2372       return true;
2373     return false;
2374   }
2375 
2376   // Grouping requires creating a flattened representation of the descendant
2377   // elements before they can be applied, and therefore force the element to
2378   // have a used style of flat for preserve-3d.
HasGroupingPropertyForUsedTransformStyle3D()2379   CORE_EXPORT bool HasGroupingPropertyForUsedTransformStyle3D() const {
2380     return HasGroupingProperty(BoxReflect()) ||
2381            !IsOverflowVisibleAlongBothAxes();
2382   }
2383 
2384   // Return true if any transform related property (currently
2385   // transform/motionPath, transformStyle3D, perspective, or
2386   // will-change:transform) indicates that we are transforming.
2387   // will-change:transform should result in the same rendering behavior as
2388   // having a transform, including the creation of a containing block for fixed
2389   // position descendants.
HasTransformRelatedProperty()2390   bool HasTransformRelatedProperty() const {
2391     return HasTransform() || Preserves3D() || HasPerspective() ||
2392            HasWillChangeTransformHint();
2393   }
2394 
2395   // Paint utility functions.
2396   CORE_EXPORT void AddPaintImage(StyleImage*);
2397 
2398   // Returns true if any property has an <image> value that is a CSS paint
2399   // function that is using a given custom property.
2400   bool HasCSSPaintImagesUsingCustomProperty(
2401       const AtomicString& custom_property_name,
2402       const Document&) const;
2403 
2404   // FIXME: reflections should belong to this helper function but they are
2405   // currently handled through their self-painting layers. So the layout code
2406   // doesn't account for them.
HasVisualOverflowingEffect()2407   bool HasVisualOverflowingEffect() const {
2408     return BoxShadow() || HasBorderImageOutsets() || HasOutline() ||
2409            HasMaskBoxImageOutsets();
2410   }
2411 
2412   // Stacking contexts and positioned elements[1] are stacked (sorted in
2413   // negZOrderList
2414   // and posZOrderList) in their enclosing stacking contexts.
2415   //
2416   // [1] According to CSS2.1, Appendix E.2.8
2417   // (https://www.w3.org/TR/CSS21/zindex.html),
2418   // positioned elements with 'z-index: auto' are "treated as if it created a
2419   // new stacking context" and z-ordered together with other elements with
2420   // 'z-index: 0'.  The difference of them from normal stacking contexts is that
2421   // they don't determine the stacking of the elements underneath them.  (Note:
2422   // There are also other elements treated as stacking context during painting,
2423   // but not managed in stacks. See ObjectPainter::PaintAllPhasesAtomically().)
2424   CORE_EXPORT void UpdateIsStackingContextWithoutContainment(
2425       bool is_document_element,
2426       bool is_in_top_layer,
2427       bool is_svg_stacking);
IsStackedWithoutContainment()2428   bool IsStackedWithoutContainment() const {
2429     return IsStackingContextWithoutContainment() ||
2430            GetPosition() != EPosition::kStatic;
2431   }
2432 
2433   // Pseudo element styles.
2434   bool HasAnyPseudoElementStyles() const;
2435   bool HasPseudoElementStyle(PseudoId) const;
2436   void SetHasPseudoElementStyle(PseudoId);
2437 
2438   // Note: CanContainAbsolutePositionObjects should return true if
2439   // CanContainFixedPositionObjects.  We currently never use this value
2440   // directly, always OR'ing it with CanContainFixedPositionObjects.
CanContainAbsolutePositionObjects()2441   bool CanContainAbsolutePositionObjects() const {
2442     return GetPosition() != EPosition::kStatic;
2443   }
2444 
2445   // Whitespace utility functions.
Is(EWhiteSpace a,EWhiteSpace b)2446   static bool Is(EWhiteSpace a, EWhiteSpace b) {
2447     return static_cast<unsigned>(a) & static_cast<unsigned>(b);
2448   }
IsNot(EWhiteSpace a,EWhiteSpace b)2449   static bool IsNot(EWhiteSpace a, EWhiteSpace b) { return !Is(a, b); }
AutoWrap(EWhiteSpace ws)2450   static bool AutoWrap(EWhiteSpace ws) {
2451     // Nowrap and pre don't automatically wrap.
2452     return IsNot(ws, EWhiteSpace::kNowrap | EWhiteSpace::kPre);
2453   }
2454 
AutoWrap()2455   bool AutoWrap() const { return AutoWrap(WhiteSpace()); }
2456 
PreserveNewline(EWhiteSpace ws)2457   static bool PreserveNewline(EWhiteSpace ws) {
2458     // Normal and nowrap do not preserve newlines.
2459     return ws != EWhiteSpace::kNormal && ws != EWhiteSpace::kNowrap;
2460   }
2461 
PreserveNewline()2462   bool PreserveNewline() const { return PreserveNewline(WhiteSpace()); }
2463 
BorderStyleIsVisible(EBorderStyle style)2464   static bool BorderStyleIsVisible(EBorderStyle style) {
2465     return style != EBorderStyle::kNone && style != EBorderStyle::kHidden;
2466   }
2467 
CollapseWhiteSpace(EWhiteSpace ws)2468   static bool CollapseWhiteSpace(EWhiteSpace ws) {
2469     // Pre and prewrap do not collapse whitespace.
2470     return IsNot(ws, EWhiteSpace::kPre | EWhiteSpace::kPreWrap |
2471                          EWhiteSpace::kBreakSpaces);
2472   }
2473 
CollapseWhiteSpace()2474   bool CollapseWhiteSpace() const { return CollapseWhiteSpace(WhiteSpace()); }
2475 
IsCollapsibleWhiteSpace(UChar c)2476   bool IsCollapsibleWhiteSpace(UChar c) const {
2477     switch (c) {
2478       case ' ':
2479       case '\t':
2480         return CollapseWhiteSpace();
2481       case '\n':
2482         return !PreserveNewline();
2483     }
2484     return false;
2485   }
BreakOnlyAfterWhiteSpace()2486   bool BreakOnlyAfterWhiteSpace() const {
2487     return Is(WhiteSpace(),
2488               EWhiteSpace::kPreWrap | EWhiteSpace::kBreakSpaces) ||
2489            GetLineBreak() == LineBreak::kAfterWhiteSpace;
2490   }
2491 
BreakWords()2492   bool BreakWords() const {
2493     return (WordBreak() == EWordBreak::kBreakWord ||
2494             OverflowWrap() != EOverflowWrap::kNormal) &&
2495            IsNot(WhiteSpace(), EWhiteSpace::kPre | EWhiteSpace::kNowrap);
2496   }
2497 
2498   // Text direction utility functions.
ShouldPlaceBlockDirectionScrollbarOnLogicalLeft()2499   bool ShouldPlaceBlockDirectionScrollbarOnLogicalLeft() const {
2500     return !IsLeftToRightDirection() && IsHorizontalWritingMode();
2501   }
2502 
2503   // Border utility functions.
2504   bool BorderObscuresBackground() const;
2505   void GetBorderEdgeInfo(
2506       BorderEdge edges[],
2507       PhysicalBoxSides sides_to_include = PhysicalBoxSides()) const;
2508 
HasBoxDecorations()2509   bool HasBoxDecorations() const {
2510     return HasBorderDecoration() || HasBorderRadius() || HasOutline() ||
2511            HasEffectiveAppearance() || BoxShadow() ||
2512            HasFilterInducingProperty() || HasNonInitialBackdropFilter() ||
2513            HasResize();
2514   }
2515 
2516   // "Box decoration background" includes all box decorations and backgrounds
2517   // that are painted as the background of the object. It includes borders,
2518   // box-shadows, background-color and background-image, etc.
HasBoxDecorationBackground()2519   bool HasBoxDecorationBackground() const {
2520     return HasBackground() || HasBorderDecoration() ||
2521            HasEffectiveAppearance() || BoxShadow();
2522   }
2523 
2524   LayoutRectOutsets BoxDecorationOutsets() const;
2525 
2526   // Background utility functions.
AccessBackgroundLayers()2527   FillLayer& AccessBackgroundLayers() { return MutableBackgroundInternal(); }
BackgroundLayers()2528   const FillLayer& BackgroundLayers() const { return BackgroundInternal(); }
AdjustBackgroundLayers()2529   void AdjustBackgroundLayers() {
2530     if (BackgroundLayers().Next()) {
2531       AccessBackgroundLayers().CullEmptyLayers();
2532       AccessBackgroundLayers().FillUnsetProperties();
2533     }
2534   }
HasBackgroundRelatedColorReferencingCurrentColor()2535   bool HasBackgroundRelatedColorReferencingCurrentColor() const {
2536     if (BackgroundColor().IsCurrentColor() ||
2537         InternalVisitedBackgroundColor().IsCurrentColor())
2538       return true;
2539     if (!BoxShadow())
2540       return false;
2541     return ShadowListHasCurrentColor(BoxShadow());
2542   }
HasBackground()2543   bool HasBackground() const {
2544     Color color = VisitedDependentColor(GetCSSPropertyBackgroundColor());
2545     if (color.Alpha())
2546       return true;
2547     return HasBackgroundImage();
2548   }
2549 
2550   // Color utility functions.
2551   CORE_EXPORT Color
2552   VisitedDependentColor(const CSSProperty& color_property) const;
2553 
2554   // Helper for resolving a StyleColor which may contain currentColor or a
2555   // system color keyword. This is intended for cases such as SVG <paint> where
2556   // a given property consists of a StyleColor plus additional information. For
2557   // <color> properties, prefer VisitedDependentColor() or
2558   // Longhand::ColorIncludingFallback() instead.
2559   Color ResolvedColor(const StyleColor& color) const;
2560 
2561   // -webkit-appearance utility functions.
HasEffectiveAppearance()2562   bool HasEffectiveAppearance() const {
2563     return EffectiveAppearance() != kNoControlPart;
2564   }
IsCheckboxOrRadioPart()2565   bool IsCheckboxOrRadioPart() const {
2566     return HasEffectiveAppearance() &&
2567            (EffectiveAppearance() == kCheckboxPart ||
2568             EffectiveAppearance() == kRadioPart);
2569   }
2570 
2571   // Other utility functions.
2572   bool RequireTransformOrigin(ApplyTransformOrigin apply_origin,
2573                               ApplyMotionPath) const;
2574 
2575   InterpolationQuality GetInterpolationQuality() const;
2576 
CanGeneratePseudoElement(PseudoId pseudo)2577   bool CanGeneratePseudoElement(PseudoId pseudo) const {
2578     if (Display() == EDisplay::kNone)
2579       return false;
2580     if (IsEnsuredInDisplayNone())
2581       return false;
2582     if (pseudo == kPseudoIdMarker)
2583       return Display() == EDisplay::kListItem;
2584     if (!HasPseudoElementStyle(pseudo))
2585       return false;
2586     if (Display() != EDisplay::kContents)
2587       return true;
2588     // For display: contents elements, we still need to generate ::before and
2589     // ::after, but the rest of the pseudo-elements should only be used for
2590     // elements with an actual layout object.
2591     return pseudo == kPseudoIdBefore || pseudo == kPseudoIdAfter;
2592   }
2593 
2594   // Load the images of CSS properties that were deferred by LazyLoad.
2595   void LoadDeferredImages(Document&) const;
2596 
ComputedColorScheme()2597   mojom::blink::ColorScheme ComputedColorScheme() const {
2598     return DarkColorScheme() ? mojom::blink::ColorScheme::kDark
2599                              : mojom::blink::ColorScheme::kLight;
2600   }
2601 
UsedColorScheme()2602   mojom::blink::ColorScheme UsedColorScheme() const {
2603     return RuntimeEnabledFeatures::CSSColorSchemeUARenderingEnabled()
2604                ? ComputedColorScheme()
2605                : mojom::blink::ColorScheme::kLight;
2606   }
2607 
UsedColorSchemeForInitialColors()2608   mojom::blink::ColorScheme UsedColorSchemeForInitialColors() const {
2609     return ComputedColorScheme();
2610   }
2611 
InitialColorForColorScheme()2612   StyleColor InitialColorForColorScheme() const {
2613     // TODO(crbug.com/1046753, crbug.com/929098): The initial value of the color
2614     // property should be canvastext, but since we do not yet ship color-scheme
2615     // aware system colors, we use this method instead. This should be replaced
2616     // by default_value:"canvastext" in css_properties.json5.
2617     return StyleColor(DarkColorScheme() ? Color::kWhite : Color::kBlack);
2618   }
2619 
GeneratesMarkerImage()2620   bool GeneratesMarkerImage() const {
2621     return Display() == EDisplay::kListItem && ListStyleImage() &&
2622            !ListStyleImage()->ErrorOccurred();
2623   }
2624 
LogicalAspectRatio()2625   LogicalSize LogicalAspectRatio() const {
2626     DCHECK_NE(AspectRatio().GetType(), EAspectRatioType::kAuto);
2627     FloatSize ratio = AspectRatio().GetRatio();
2628     if (!IsHorizontalWritingMode())
2629       ratio = ratio.TransposedSize();
2630     return LogicalSize(LayoutUnit(ratio.Width()), LayoutUnit(ratio.Height()));
2631   }
2632 
2633  private:
Clear()2634   EClear Clear() const { return ClearInternal(); }
Floating()2635   EFloat Floating() const { return FloatingInternal(); }
Resize()2636   EResize Resize() const { return ResizeInternal(); }
2637 
SetInternalVisitedColor(const StyleColor & v)2638   void SetInternalVisitedColor(const StyleColor& v) {
2639     SetInternalVisitedColorInternal(v);
2640   }
SetInternalVisitedBackgroundColor(const StyleColor & v)2641   void SetInternalVisitedBackgroundColor(const StyleColor& v) {
2642     SetInternalVisitedBackgroundColorInternal(v);
2643   }
SetInternalVisitedBorderLeftColor(const StyleColor & v)2644   void SetInternalVisitedBorderLeftColor(const StyleColor& v) {
2645     SetInternalVisitedBorderLeftColorInternal(v);
2646   }
SetInternalVisitedBorderRightColor(const StyleColor & v)2647   void SetInternalVisitedBorderRightColor(const StyleColor& v) {
2648     SetInternalVisitedBorderRightColorInternal(v);
2649   }
SetInternalVisitedBorderBottomColor(const StyleColor & v)2650   void SetInternalVisitedBorderBottomColor(const StyleColor& v) {
2651     SetInternalVisitedBorderBottomColorInternal(v);
2652   }
SetInternalVisitedBorderTopColor(const StyleColor & v)2653   void SetInternalVisitedBorderTopColor(const StyleColor& v) {
2654     SetInternalVisitedBorderTopColorInternal(v);
2655   }
SetInternalVisitedOutlineColor(const StyleColor & v)2656   void SetInternalVisitedOutlineColor(const StyleColor& v) {
2657     SetInternalVisitedOutlineColorInternal(v);
2658   }
SetInternalVisitedColumnRuleColor(const StyleColor & v)2659   void SetInternalVisitedColumnRuleColor(const StyleColor& v) {
2660     SetInternalVisitedColumnRuleColorInternal(v);
2661   }
SetInternalVisitedTextDecorationColor(const StyleColor & v)2662   void SetInternalVisitedTextDecorationColor(const StyleColor& v) {
2663     SetInternalVisitedTextDecorationColorInternal(v);
2664   }
SetInternalVisitedTextEmphasisColor(const StyleColor & color)2665   void SetInternalVisitedTextEmphasisColor(const StyleColor& color) {
2666     SetInternalVisitedTextEmphasisColorInternal(color);
2667   }
SetInternalVisitedTextFillColor(const StyleColor & color)2668   void SetInternalVisitedTextFillColor(const StyleColor& color) {
2669     SetInternalVisitedTextFillColorInternal(color);
2670   }
SetInternalVisitedTextStrokeColor(const StyleColor & color)2671   void SetInternalVisitedTextStrokeColor(const StyleColor& color) {
2672     SetInternalVisitedTextStrokeColorInternal(color);
2673   }
2674 
IsDisplayBlockContainer(EDisplay display)2675   static bool IsDisplayBlockContainer(EDisplay display) {
2676     return display == EDisplay::kBlock || display == EDisplay::kListItem ||
2677            display == EDisplay::kInlineBlock ||
2678            display == EDisplay::kFlowRoot || display == EDisplay::kTableCell ||
2679            display == EDisplay::kTableCaption;
2680   }
2681 
IsDisplayTableBox(EDisplay display)2682   static bool IsDisplayTableBox(EDisplay display) {
2683     return display == EDisplay::kTable || display == EDisplay::kInlineTable;
2684   }
2685 
IsDisplayFlexibleBox(EDisplay display)2686   static bool IsDisplayFlexibleBox(EDisplay display) {
2687     return display == EDisplay::kFlex || display == EDisplay::kInlineFlex;
2688   }
2689 
IsDisplayGridBox(EDisplay display)2690   static bool IsDisplayGridBox(EDisplay display) {
2691     return display == EDisplay::kGrid || display == EDisplay::kInlineGrid;
2692   }
2693 
IsDisplayMathBox(EDisplay display)2694   static bool IsDisplayMathBox(EDisplay display) {
2695     return display == EDisplay::kMath || display == EDisplay::kBlockMath;
2696   }
2697 
IsDisplayLayoutCustomBox(EDisplay display)2698   static bool IsDisplayLayoutCustomBox(EDisplay display) {
2699     return display == EDisplay::kLayoutCustom ||
2700            display == EDisplay::kInlineLayoutCustom;
2701   }
2702 
IsDisplayReplacedType(EDisplay display)2703   static bool IsDisplayReplacedType(EDisplay display) {
2704     return display == EDisplay::kInlineBlock ||
2705            display == EDisplay::kWebkitInlineBox ||
2706            display == EDisplay::kInlineFlex ||
2707            display == EDisplay::kInlineTable ||
2708            display == EDisplay::kInlineGrid || display == EDisplay::kMath ||
2709            display == EDisplay::kInlineLayoutCustom;
2710   }
2711 
IsDisplayInlineType(EDisplay display)2712   static bool IsDisplayInlineType(EDisplay display) {
2713     return display == EDisplay::kInline || IsDisplayReplacedType(display);
2714   }
2715 
IsDisplayTableType(EDisplay display)2716   static bool IsDisplayTableType(EDisplay display) {
2717     return display == EDisplay::kTable || display == EDisplay::kInlineTable ||
2718            display == EDisplay::kTableRowGroup ||
2719            display == EDisplay::kTableHeaderGroup ||
2720            display == EDisplay::kTableFooterGroup ||
2721            display == EDisplay::kTableRow ||
2722            display == EDisplay::kTableColumnGroup ||
2723            display == EDisplay::kTableColumn ||
2724            display == EDisplay::kTableCell ||
2725            display == EDisplay::kTableCaption;
2726   }
2727 
2728   // Color accessors are all private to make sure callers use
2729   // VisitedDependentColor instead to access them.
BorderLeftColor()2730   const StyleColor& BorderLeftColor() const {
2731     return BorderLeftColorInternal();
2732   }
BorderRightColor()2733   const StyleColor& BorderRightColor() const {
2734     return BorderRightColorInternal();
2735   }
BorderTopColor()2736   const StyleColor& BorderTopColor() const { return BorderTopColorInternal(); }
BorderBottomColor()2737   const StyleColor& BorderBottomColor() const {
2738     return BorderBottomColorInternal();
2739   }
2740 
BackgroundColor()2741   const StyleColor& BackgroundColor() const {
2742     return BackgroundColorInternal();
2743   }
CaretColor()2744   const StyleAutoColor& CaretColor() const { return CaretColorInternal(); }
GetColor()2745   const StyleColor& GetColor() const { return ColorInternal(); }
ColumnRuleColor()2746   const StyleColor& ColumnRuleColor() const {
2747     return ColumnRuleColorInternal();
2748   }
OutlineColor()2749   const StyleColor& OutlineColor() const { return OutlineColorInternal(); }
TextDecorationColor()2750   const StyleColor& TextDecorationColor() const {
2751     return TextDecorationColorInternal();
2752   }
TextEmphasisColor()2753   const StyleColor& TextEmphasisColor() const {
2754     return TextEmphasisColorInternal();
2755   }
TextFillColor()2756   const StyleColor& TextFillColor() const { return TextFillColorInternal(); }
TextStrokeColor()2757   const StyleColor& TextStrokeColor() const {
2758     return TextStrokeColorInternal();
2759   }
InternalVisitedColor()2760   const StyleColor& InternalVisitedColor() const {
2761     return InternalVisitedColorInternal();
2762   }
InternalVisitedCaretColor()2763   const StyleAutoColor& InternalVisitedCaretColor() const {
2764     return InternalVisitedCaretColorInternal();
2765   }
InternalVisitedBackgroundColor()2766   const StyleColor& InternalVisitedBackgroundColor() const {
2767     return InternalVisitedBackgroundColorInternal();
2768   }
InternalVisitedBorderLeftColor()2769   const StyleColor& InternalVisitedBorderLeftColor() const {
2770     return InternalVisitedBorderLeftColorInternal();
2771   }
InternalVisitedBorderLeftColorHasNotChanged(const ComputedStyle & other)2772   bool InternalVisitedBorderLeftColorHasNotChanged(
2773       const ComputedStyle& other) const {
2774     return (InternalVisitedBorderLeftColor() ==
2775                 other.InternalVisitedBorderLeftColor() ||
2776             !BorderLeftWidth());
2777   }
InternalVisitedBorderRightColor()2778   const StyleColor& InternalVisitedBorderRightColor() const {
2779     return InternalVisitedBorderRightColorInternal();
2780   }
InternalVisitedBorderRightColorHasNotChanged(const ComputedStyle & other)2781   bool InternalVisitedBorderRightColorHasNotChanged(
2782       const ComputedStyle& other) const {
2783     return (InternalVisitedBorderRightColor() ==
2784                 other.InternalVisitedBorderRightColor() ||
2785             !BorderRightWidth());
2786   }
InternalVisitedBorderBottomColor()2787   const StyleColor& InternalVisitedBorderBottomColor() const {
2788     return InternalVisitedBorderBottomColorInternal();
2789   }
InternalVisitedBorderBottomColorHasNotChanged(const ComputedStyle & other)2790   bool InternalVisitedBorderBottomColorHasNotChanged(
2791       const ComputedStyle& other) const {
2792     return (InternalVisitedBorderBottomColor() ==
2793                 other.InternalVisitedBorderBottomColor() ||
2794             !BorderBottomWidth());
2795   }
InternalVisitedBorderTopColor()2796   const StyleColor& InternalVisitedBorderTopColor() const {
2797     return InternalVisitedBorderTopColorInternal();
2798   }
InternalVisitedBorderTopColorHasNotChanged(const ComputedStyle & other)2799   bool InternalVisitedBorderTopColorHasNotChanged(
2800       const ComputedStyle& other) const {
2801     return (InternalVisitedBorderTopColor() ==
2802                 other.InternalVisitedBorderTopColor() ||
2803             !BorderTopWidth());
2804   }
InternalVisitedOutlineColor()2805   const StyleColor& InternalVisitedOutlineColor() const {
2806     return InternalVisitedOutlineColorInternal();
2807   }
InternalVisitedOutlineColorHasNotChanged(const ComputedStyle & other)2808   bool InternalVisitedOutlineColorHasNotChanged(
2809       const ComputedStyle& other) const {
2810     return (InternalVisitedOutlineColor() ==
2811                 other.InternalVisitedOutlineColor() ||
2812             !OutlineWidth());
2813   }
InternalVisitedColumnRuleColor()2814   const StyleColor& InternalVisitedColumnRuleColor() const {
2815     return InternalVisitedColumnRuleColorInternal();
2816   }
InternalVisitedTextDecorationColor()2817   const StyleColor& InternalVisitedTextDecorationColor() const {
2818     return InternalVisitedTextDecorationColorInternal();
2819   }
InternalVisitedTextEmphasisColor()2820   const StyleColor& InternalVisitedTextEmphasisColor() const {
2821     return InternalVisitedTextEmphasisColorInternal();
2822   }
InternalVisitedTextFillColor()2823   const StyleColor& InternalVisitedTextFillColor() const {
2824     return InternalVisitedTextFillColorInternal();
2825   }
InternalVisitedTextStrokeColor()2826   const StyleColor& InternalVisitedTextStrokeColor() const {
2827     return InternalVisitedTextStrokeColorInternal();
2828   }
2829 
2830   StyleColor DecorationColorIncludingFallback(bool visited_link) const;
2831 
StopColor()2832   const StyleColor& StopColor() const { return SvgStyle().StopColor(); }
FloodColor()2833   const StyleColor& FloodColor() const { return SvgStyle().FloodColor(); }
LightingColor()2834   const StyleColor& LightingColor() const { return SvgStyle().LightingColor(); }
2835 
2836   // Appearance accessors are private to make sure callers use
2837   // EffectiveAppearance in almost all cases.
Appearance()2838   ControlPart Appearance() const { return AppearanceInternal(); }
HasAppearance()2839   bool HasAppearance() const { return Appearance() != kNoControlPart; }
2840 
2841   void AddAppliedTextDecoration(const AppliedTextDecoration&);
2842   void OverrideTextDecorationColors(Color propagated_color);
2843   void ApplyMotionPathTransform(float origin_x,
2844                                 float origin_y,
2845                                 const FloatRect& bounding_box,
2846                                 TransformationMatrix&) const;
2847 
2848   bool ScrollAnchorDisablingPropertyChanged(const ComputedStyle& other,
2849                                             const StyleDifference&) const;
2850   bool DiffNeedsFullLayoutAndPaintInvalidation(
2851       const ComputedStyle& other) const;
2852   bool DiffNeedsFullLayout(const Document&, const ComputedStyle& other) const;
2853   bool DiffNeedsFullLayoutForLayoutCustom(const Document&,
2854                                           const ComputedStyle& other) const;
2855   bool DiffNeedsFullLayoutForLayoutCustomChild(
2856       const Document&,
2857       const ComputedStyle& other) const;
2858   void AdjustDiffForNeedsPaintInvalidation(const ComputedStyle& other,
2859                                            StyleDifference&,
2860                                            const Document&) const;
2861   bool DiffNeedsPaintInvalidationForPaintImage(const StyleImage&,
2862                                                const ComputedStyle& other,
2863                                                const Document&) const;
2864   bool DiffNeedsVisualRectUpdate(const ComputedStyle& other) const;
2865   CORE_EXPORT void UpdatePropertySpecificDifferences(const ComputedStyle& other,
2866                                                      StyleDifference&) const;
2867 
2868   bool PropertiesEqual(const Vector<CSSPropertyID>& properties,
2869                        const ComputedStyle& other) const;
2870   CORE_EXPORT bool CustomPropertiesEqual(const Vector<AtomicString>& properties,
2871                                          const ComputedStyle& other) const;
2872 
2873   Color GetCurrentColor() const;
2874   Color GetInternalVisitedCurrentColor() const;
2875 
2876   static bool ShadowListHasCurrentColor(const ShadowList*);
2877 
2878   StyleInheritedVariables& MutableInheritedVariables();
2879   StyleNonInheritedVariables& MutableNonInheritedVariables();
2880 
2881   CORE_EXPORT void SetInitialData(scoped_refptr<StyleInitialData>);
2882 
PhysicalMarginToLogical(const ComputedStyle & other)2883   PhysicalToLogical<const Length&> PhysicalMarginToLogical(
2884       const ComputedStyle& other) const {
2885     return PhysicalToLogical<const Length&>(other.GetWritingDirection(),
2886                                             MarginTop(), MarginRight(),
2887                                             MarginBottom(), MarginLeft());
2888   }
2889 
PhysicalPaddingToLogical()2890   PhysicalToLogical<const Length&> PhysicalPaddingToLogical() const {
2891     return PhysicalToLogical<const Length&>(GetWritingDirection(), PaddingTop(),
2892                                             PaddingRight(), PaddingBottom(),
2893                                             PaddingLeft());
2894   }
2895 
PhysicalBorderToLogical(const ComputedStyle & other)2896   PhysicalToLogical<BorderValue> PhysicalBorderToLogical(
2897       const ComputedStyle& other) const {
2898     return PhysicalToLogical<BorderValue>(other.GetWritingDirection(),
2899                                           BorderTop(), BorderRight(),
2900                                           BorderBottom(), BorderLeft());
2901   }
2902 
PhysicalBorderWidthToLogical()2903   PhysicalToLogical<float> PhysicalBorderWidthToLogical() const {
2904     return PhysicalToLogical<float>(GetWritingDirection(), BorderTopWidth(),
2905                                     BorderRightWidth(), BorderBottomWidth(),
2906                                     BorderLeftWidth());
2907   }
2908 
PhysicalBorderStyleToLogical()2909   PhysicalToLogical<EBorderStyle> PhysicalBorderStyleToLogical() const {
2910     return PhysicalToLogical<EBorderStyle>(
2911         GetWritingDirection(), BorderTopStyle(), BorderRightStyle(),
2912         BorderBottomStyle(), BorderLeftStyle());
2913   }
2914 
PhysicalBoundsToLogical()2915   PhysicalToLogical<const Length&> PhysicalBoundsToLogical() const {
2916     return PhysicalToLogical<const Length&>(GetWritingDirection(), Top(),
2917                                             Right(), Bottom(), Left());
2918   }
2919 
2920   static Difference ComputeDifferenceIgnoringInheritedFirstLineStyle(
2921       const ComputedStyle& old_style,
2922       const ComputedStyle& new_style);
2923 
2924   FRIEND_TEST_ALL_PREFIXES(
2925       ComputedStyleTest,
2926       UpdatePropertySpecificDifferencesRespectsTransformAnimation);
2927   FRIEND_TEST_ALL_PREFIXES(
2928       ComputedStyleTest,
2929       UpdatePropertySpecificDifferencesCompositingReasonsTransforom);
2930   FRIEND_TEST_ALL_PREFIXES(
2931       ComputedStyleTest,
2932       UpdatePropertySpecificDifferencesCompositingReasonsOpacity);
2933   FRIEND_TEST_ALL_PREFIXES(
2934       ComputedStyleTest,
2935       UpdatePropertySpecificDifferencesCompositingReasonsFilter);
2936   FRIEND_TEST_ALL_PREFIXES(
2937       ComputedStyleTest,
2938       UpdatePropertySpecificDifferencesCompositingReasonsBackdropFilter);
2939   FRIEND_TEST_ALL_PREFIXES(
2940       ComputedStyleTest,
2941       UpdatePropertySpecificDifferencesCompositingReasonsInlineTransform);
2942   FRIEND_TEST_ALL_PREFIXES(
2943       ComputedStyleTest,
2944       UpdatePropertySpecificDifferencesCompositingReasonsBackfaceVisibility);
2945   FRIEND_TEST_ALL_PREFIXES(
2946       ComputedStyleTest,
2947       UpdatePropertySpecificDifferencesCompositingReasonsWillChange);
2948   FRIEND_TEST_ALL_PREFIXES(
2949       ComputedStyleTest,
2950       UpdatePropertySpecificDifferencesCompositingReasonsUsedStylePreserve3D);
2951   FRIEND_TEST_ALL_PREFIXES(
2952       ComputedStyleTest,
2953       UpdatePropertySpecificDifferencesCompositingReasonsOverflow);
2954   FRIEND_TEST_ALL_PREFIXES(
2955       ComputedStyleTest,
2956       UpdatePropertySpecificDifferencesCompositingReasonsContainsPaint);
2957   FRIEND_TEST_ALL_PREFIXES(ComputedStyleTest,
2958                            UpdatePropertySpecificDifferencesHasAlpha);
2959   FRIEND_TEST_ALL_PREFIXES(ComputedStyleTest, CustomPropertiesEqual_Values);
2960   FRIEND_TEST_ALL_PREFIXES(ComputedStyleTest, CustomPropertiesEqual_Data);
2961   FRIEND_TEST_ALL_PREFIXES(ComputedStyleTest, InitialVariableNames);
2962   FRIEND_TEST_ALL_PREFIXES(ComputedStyleTest,
2963                            InitialAndInheritedAndNonInheritedVariableNames);
2964   FRIEND_TEST_ALL_PREFIXES(StyleCascadeTest, ForcedVisitedBackgroundColor);
2965   FRIEND_TEST_ALL_PREFIXES(
2966       ComputedStyleTest,
2967       TextDecorationEqualDoesNotRequireRecomputeInkOverflow);
2968   FRIEND_TEST_ALL_PREFIXES(ComputedStyleTest,
2969                            TextDecorationNotEqualRequiresRecomputeInkOverflow);
2970 };
2971 
HasAnyPseudoElementStyles()2972 inline bool ComputedStyle::HasAnyPseudoElementStyles() const {
2973   return !!PseudoBitsInternal();
2974 }
2975 
HasPseudoElementStyle(PseudoId pseudo)2976 inline bool ComputedStyle::HasPseudoElementStyle(PseudoId pseudo) const {
2977   DCHECK(pseudo >= kFirstPublicPseudoId);
2978   DCHECK(pseudo < kFirstInternalPseudoId);
2979   return (1 << (pseudo - kFirstPublicPseudoId)) & PseudoBitsInternal();
2980 }
2981 
SetHasPseudoElementStyle(PseudoId pseudo)2982 inline void ComputedStyle::SetHasPseudoElementStyle(PseudoId pseudo) {
2983   DCHECK(pseudo >= kFirstPublicPseudoId);
2984   DCHECK(pseudo < kFirstInternalPseudoId);
2985   // TODO: Fix up this code. It is hard to understand.
2986   SetPseudoBitsInternal(PseudoBitsInternal() |
2987                         1 << (pseudo - kFirstPublicPseudoId));
2988 }
2989 
2990 }  // namespace blink
2991 
2992 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_H_
2993