1 /*
2  * Copyright (C) 2013 Google Inc. All rights reserved.
3  *
4  *     * Redistributions of source code must retain the above copyright
5  * notice, this list of conditions and the following disclaimer.
6  *     * Redistributions in binary form must reproduce the above
7  * copyright notice, this list of conditions and the following disclaimer
8  * in the documentation and/or other materials provided with the
9  * distribution.
10  *     * Neither the name of Google Inc. nor the names of its
11  * contributors may be used to endorse or promote products derived from
12  * this software without specific prior written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_STYLE_BUILDER_CONVERTER_H_
28 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_STYLE_BUILDER_CONVERTER_H_
29 
30 #include "cc/input/scroll_snap_data.h"
31 #include "third_party/blink/renderer/core/css/css_function_value.h"
32 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
33 #include "third_party/blink/renderer/core/css/css_primitive_value.h"
34 #include "third_party/blink/renderer/core/css/css_string_value.h"
35 #include "third_party/blink/renderer/core/css/css_value.h"
36 #include "third_party/blink/renderer/core/css/css_value_list.h"
37 #include "third_party/blink/renderer/core/css/css_value_pair.h"
38 #include "third_party/blink/renderer/core/css/css_variable_data.h"
39 #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
40 #include "third_party/blink/renderer/core/style/computed_style.h"
41 #include "third_party/blink/renderer/core/style/grid_area.h"
42 #include "third_party/blink/renderer/core/style/grid_positions_resolver.h"
43 #include "third_party/blink/renderer/core/style/named_grid_lines_map.h"
44 #include "third_party/blink/renderer/core/style/ordered_named_grid_lines.h"
45 #include "third_party/blink/renderer/core/style/quotes_data.h"
46 #include "third_party/blink/renderer/core/style/shadow_list.h"
47 #include "third_party/blink/renderer/core/style/style_offset_rotation.h"
48 #include "third_party/blink/renderer/core/style/style_reflection.h"
49 #include "third_party/blink/renderer/core/style/svg_computed_style_defs.h"
50 #include "third_party/blink/renderer/core/style/transform_origin.h"
51 #include "third_party/blink/renderer/platform/fonts/font_description.h"
52 #include "third_party/blink/renderer/platform/geometry/length_size.h"
53 #include "third_party/blink/renderer/platform/graphics/image_orientation.h"
54 #include "third_party/blink/renderer/platform/text/tab_size.h"
55 #include "third_party/blink/renderer/platform/transforms/rotation.h"
56 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
57 #include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
58 
59 namespace blink {
60 
61 class ClipPathOperation;
62 class CSSToLengthConversionData;
63 class Font;
64 class FontBuilder;
65 class RotateTransformOperation;
66 class ScaleTransformOperation;
67 class StyleAutoColor;
68 class StylePath;
69 class StyleResolverState;
70 class StyleSVGResource;
71 class TextSizeAdjust;
72 class TranslateTransformOperation;
73 class UnzoomedLength;
74 
75 class StyleBuilderConverterBase {
76   STATIC_ONLY(StyleBuilderConverterBase);
77 
78  public:
79   static FontSelectionValue ConvertFontStretch(const CSSValue&);
80   static FontSelectionValue ConvertFontStyle(const CSSValue&);
81   static FontSelectionValue ConvertFontWeight(const CSSValue&,
82                                               FontSelectionValue);
83   static FontDescription::FontVariantCaps ConvertFontVariantCaps(
84       const CSSValue&);
85   static FontDescription::FamilyDescription ConvertFontFamily(
86       const CSSValue&,
87       FontBuilder*,
88       const Document* document_for_count);
89   static FontDescription::Size ConvertFontSize(
90       const CSSValue&,
91       const CSSToLengthConversionData&,
92       FontDescription::Size parent_size);
93 };
94 
95 // Note that we assume the parser only allows valid CSSValue types.
96 class StyleBuilderConverter {
97   STATIC_ONLY(StyleBuilderConverter);
98 
99  public:
100   static scoped_refptr<StyleReflection> ConvertBoxReflect(StyleResolverState&,
101                                                           const CSSValue&);
102   static Color ConvertColor(StyleResolverState&,
103                             const CSSValue&,
104                             bool for_visited_link = false);
105   template <typename T>
106   static T ConvertComputedLength(StyleResolverState&, const CSSValue&);
107   static LengthBox ConvertClip(StyleResolverState&, const CSSValue&);
108   static scoped_refptr<ClipPathOperation> ConvertClipPath(StyleResolverState&,
109                                                           const CSSValue&);
110   static scoped_refptr<StyleSVGResource> ConvertElementReference(
111       StyleResolverState&,
112       const CSSValue&);
113   static FilterOperations ConvertFilterOperations(StyleResolverState&,
114                                                   const CSSValue&);
115   static FilterOperations ConvertOffscreenFilterOperations(const CSSValue&,
116                                                            const Font&);
117   template <typename T>
118   static T ConvertFlags(StyleResolverState&, const CSSValue&);
119   static FontDescription::FamilyDescription ConvertFontFamily(
120       StyleResolverState&,
121       const CSSValue&);
122   static scoped_refptr<FontFeatureSettings> ConvertFontFeatureSettings(
123       StyleResolverState&,
124       const CSSValue&);
125   static scoped_refptr<FontVariationSettings> ConvertFontVariationSettings(
126       const StyleResolverState&,
127       const CSSValue&);
128   static FontDescription::Size ConvertFontSize(StyleResolverState&,
129                                                const CSSValue&);
130   static float ConvertFontSizeAdjust(StyleResolverState&, const CSSValue&);
131 
132   static FontSelectionValue ConvertFontStretch(StyleResolverState&,
133                                                const CSSValue&);
134   static FontSelectionValue ConvertFontStyle(StyleResolverState&,
135                                              const CSSValue&);
136   static FontSelectionValue ConvertFontWeight(StyleResolverState&,
137                                               const CSSValue&);
138 
139   static FontDescription::FontVariantCaps ConvertFontVariantCaps(
140       StyleResolverState&,
141       const CSSValue&);
142   static FontDescription::VariantLigatures ConvertFontVariantLigatures(
143       StyleResolverState&,
144       const CSSValue&);
145   static FontVariantNumeric ConvertFontVariantNumeric(StyleResolverState&,
146                                                       const CSSValue&);
147   static FontVariantEastAsian ConvertFontVariantEastAsian(StyleResolverState&,
148                                                           const CSSValue&);
149   static StyleSelfAlignmentData ConvertSelfOrDefaultAlignmentData(
150       StyleResolverState&,
151       const CSSValue&);
152   static StyleContentAlignmentData ConvertContentAlignmentData(
153       StyleResolverState&,
154       const CSSValue&);
155   static GridAutoFlow ConvertGridAutoFlow(StyleResolverState&, const CSSValue&);
156   static GridPosition ConvertGridPosition(StyleResolverState&, const CSSValue&);
157   static GridTrackSize ConvertGridTrackSize(StyleResolverState&,
158                                             const CSSValue&);
159   static GridTrackList ConvertGridTrackSizeList(StyleResolverState&,
160                                                 const CSSValue&);
161   template <typename T>
162   static T ConvertLineWidth(StyleResolverState&, const CSSValue&);
163   static float ConvertBorderWidth(StyleResolverState&, const CSSValue&);
164   static LayoutUnit ConvertLayoutUnit(StyleResolverState&, const CSSValue&);
165   static base::Optional<Length> ConvertGapLength(const StyleResolverState&,
166                                                  const CSSValue&);
167   static Length ConvertLength(const StyleResolverState&, const CSSValue&);
168   static UnzoomedLength ConvertUnzoomedLength(const StyleResolverState&,
169                                               const CSSValue&);
170   static float ConvertZoom(const StyleResolverState&, const CSSValue&);
171   static Length ConvertLengthOrAuto(const StyleResolverState&, const CSSValue&);
172   static Length ConvertLengthSizing(StyleResolverState&, const CSSValue&);
173   static Length ConvertLengthMaxSizing(StyleResolverState&, const CSSValue&);
174   static TabSize ConvertLengthOrTabSpaces(StyleResolverState&, const CSSValue&);
175   static Length ConvertLineHeight(StyleResolverState&, const CSSValue&);
176   static float ConvertNumberOrPercentage(StyleResolverState&, const CSSValue&);
177   static float ConvertAlpha(StyleResolverState&,
178                             const CSSValue&);  // clamps to [0,1]
179   static StyleOffsetRotation ConvertOffsetRotate(StyleResolverState&,
180                                                  const CSSValue&);
181   static LengthPoint ConvertPosition(StyleResolverState&, const CSSValue&);
182   static LengthPoint ConvertPositionOrAuto(StyleResolverState&,
183                                            const CSSValue&);
184   static float ConvertPerspective(StyleResolverState&, const CSSValue&);
185   static Length ConvertQuirkyLength(StyleResolverState&, const CSSValue&);
186   static scoped_refptr<QuotesData> ConvertQuotes(StyleResolverState&,
187                                                  const CSSValue&);
188   static LengthSize ConvertRadius(StyleResolverState&, const CSSValue&);
189   static EPaintOrder ConvertPaintOrder(StyleResolverState&, const CSSValue&);
190   static ShadowData ConvertShadow(const CSSToLengthConversionData&,
191                                   StyleResolverState*,
192                                   const CSSValue&);
193   static scoped_refptr<ShadowList> ConvertShadowList(StyleResolverState&,
194                                                      const CSSValue&);
195   static ShapeValue* ConvertShapeValue(StyleResolverState&, const CSSValue&);
196   static float ConvertSpacing(StyleResolverState&, const CSSValue&);
197   template <CSSValueID IdForNone>
198   static AtomicString ConvertString(StyleResolverState&, const CSSValue&);
199   static scoped_refptr<SVGDashArray> ConvertStrokeDasharray(StyleResolverState&,
200                                                             const CSSValue&);
201   static StyleColor ConvertStyleColor(StyleResolverState&,
202                                       const CSSValue&,
203                                       bool for_visited_link = false);
204   static StyleAutoColor ConvertStyleAutoColor(StyleResolverState&,
205                                               const CSSValue&,
206                                               bool for_visited_link = false);
207   static SVGPaint ConvertSVGPaint(StyleResolverState&, const CSSValue&);
208   static TextDecorationThickness ConvertTextDecorationThickness(
209       StyleResolverState&,
210       const CSSValue&);
211   static TextEmphasisPosition ConvertTextTextEmphasisPosition(
212       StyleResolverState&,
213       const CSSValue&);
214   static float ConvertTextStrokeWidth(StyleResolverState&, const CSSValue&);
215   static TextSizeAdjust ConvertTextSizeAdjust(StyleResolverState&,
216                                               const CSSValue&);
217   static TextUnderlinePosition ConvertTextUnderlinePosition(
218       StyleResolverState& state,
219       const CSSValue& value);
220   static Length ConvertTextUnderlineOffset(StyleResolverState& state,
221                                            const CSSValue& value);
222   static TransformOperations ConvertTransformOperations(StyleResolverState&,
223                                                         const CSSValue&);
224   static TransformOrigin ConvertTransformOrigin(StyleResolverState&,
225                                                 const CSSValue&);
226 
227   static void ConvertGridTrackList(
228       const CSSValue&,
229       GridTrackList&,
230       NamedGridLinesMap&,
231       OrderedNamedGridLines&,
232       Vector<GridTrackSize>& auto_repeat_track_sizes,
233       NamedGridLinesMap&,
234       OrderedNamedGridLines&,
235       size_t& auto_repeat_insertion_point,
236       AutoRepeatType&,
237       StyleResolverState&);
238   static void CreateImplicitNamedGridLinesFromGridArea(
239       const NamedGridAreaMap&,
240       NamedGridLinesMap&,
241       GridTrackSizingDirection);
242 
243   static cc::ScrollSnapType ConvertSnapType(StyleResolverState&,
244                                             const CSSValue&);
245   static cc::ScrollSnapAlign ConvertSnapAlign(StyleResolverState&,
246                                               const CSSValue&);
247   static scoped_refptr<TranslateTransformOperation> ConvertTranslate(
248       StyleResolverState&,
249       const CSSValue&);
250   static scoped_refptr<RotateTransformOperation> ConvertRotate(
251       StyleResolverState&,
252       const CSSValue&);
253   static scoped_refptr<ScaleTransformOperation> ConvertScale(
254       StyleResolverState&,
255       const CSSValue&);
256   static RespectImageOrientationEnum ConvertImageOrientation(
257       StyleResolverState&,
258       const CSSValue&);
259   static scoped_refptr<StylePath> ConvertPathOrNone(StyleResolverState&,
260                                                     const CSSValue&);
261   static scoped_refptr<BasicShape> ConvertOffsetPath(StyleResolverState&,
262                                                      const CSSValue&);
263   static StyleOffsetRotation ConvertOffsetRotate(const CSSValue&);
264   template <CSSValueID cssValueFor0, CSSValueID cssValueFor100>
265   static Length ConvertPositionLength(StyleResolverState&, const CSSValue&);
266   static Rotation ConvertRotation(const CSSValue&);
267 
268   static const CSSValue& ConvertRegisteredPropertyInitialValue(const Document&,
269                                                                const CSSValue&);
270   static const CSSValue& ConvertRegisteredPropertyValue(
271       const StyleResolverState&,
272       const CSSValue&,
273       const String& base_url,
274       const WTF::TextEncoding&);
275 
276   static scoped_refptr<CSSVariableData> ConvertRegisteredPropertyVariableData(
277       const CSSValue&,
278       bool is_animation_tainted);
279 
280   static LengthSize ConvertIntrinsicSize(StyleResolverState&, const CSSValue&);
281 
282   static StyleAspectRatio ConvertAspectRatio(StyleResolverState&,
283                                              const CSSValue&);
284 
285   static bool ConvertInternalAlignSelfBlock(StyleResolverState& state,
286                                             const CSSValue& value);
287   static bool ConvertInternalEmptyLineHeight(StyleResolverState& state,
288                                              const CSSValue& value);
289 
290   static AtomicString ConvertPage(StyleResolverState&, const CSSValue&);
291 
292   static RubyPosition ConvertRubyPosition(StyleResolverState& state,
293                                           const CSSValue& value);
294 
295   static ScrollbarGutter ConvertScrollbarGutter(StyleResolverState& state,
296                                                 const CSSValue& value);
297 
298   static void CountSystemColorComputeToSelfUsage(
299       const StyleResolverState& state);
300 };
301 
302 template <typename T>
ConvertComputedLength(StyleResolverState & state,const CSSValue & value)303 T StyleBuilderConverter::ConvertComputedLength(StyleResolverState& state,
304                                                const CSSValue& value) {
305   return To<CSSPrimitiveValue>(value).ComputeLength<T>(
306       state.CssToLengthConversionData());
307 }
308 
309 template <typename T>
ConvertFlags(StyleResolverState & state,const CSSValue & value)310 T StyleBuilderConverter::ConvertFlags(StyleResolverState& state,
311                                       const CSSValue& value) {
312   T flags = static_cast<T>(0);
313   auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
314   if (identifier_value && identifier_value->GetValueID() == CSSValueID::kNone)
315     return flags;
316   for (auto& flag_value : To<CSSValueList>(value))
317     flags |= To<CSSIdentifierValue>(*flag_value).ConvertTo<T>();
318   return flags;
319 }
320 
321 template <typename T>
ConvertLineWidth(StyleResolverState & state,const CSSValue & value)322 T StyleBuilderConverter::ConvertLineWidth(StyleResolverState& state,
323                                           const CSSValue& value) {
324   double result = 0;
325   if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) {
326     switch (identifier_value->GetValueID()) {
327       case CSSValueID::kThin:
328         result = 1;
329         break;
330       case CSSValueID::kMedium:
331         result = 3;
332         break;
333       case CSSValueID::kThick:
334         result = 5;
335         break;
336       default:
337         NOTREACHED();
338         break;
339     }
340     result = state.CssToLengthConversionData().ZoomedComputedPixels(
341         result, CSSPrimitiveValue::UnitType::kPixels);
342   } else {
343     result = To<CSSPrimitiveValue>(value).ComputeLength<double>(
344         state.CssToLengthConversionData());
345   }
346   // TODO(crbug.com/485650, crbug.com/382483): We are moving to use the full
347   // page zoom implementation to handle high-dpi.  In that case specyfing a
348   // border-width of less than 1px would result in a border that is one device
349   // pixel thick.  With this change that would instead be rounded up to 2
350   // device pixels.  Consider clamping it to device pixels or zoom adjusted CSS
351   // pixels instead of raw CSS pixels.
352   double zoomed_result = state.StyleRef().EffectiveZoom() * result;
353   if (zoomed_result > 0.0 && zoomed_result < 1.0)
354     return 1.0;
355   return clampTo<T>(RoundForImpreciseConversion<T>(result),
356                     defaultMinimumForClamp<T>(), defaultMaximumForClamp<T>());
357 }
358 
359 template <CSSValueID cssValueFor0, CSSValueID cssValueFor100>
ConvertPositionLength(StyleResolverState & state,const CSSValue & value)360 Length StyleBuilderConverter::ConvertPositionLength(StyleResolverState& state,
361                                                     const CSSValue& value) {
362   if (const auto* pair = DynamicTo<CSSValuePair>(value)) {
363     Length length = StyleBuilderConverter::ConvertLength(state, pair->Second());
364     if (To<CSSIdentifierValue>(pair->First()).GetValueID() == cssValueFor0)
365       return length;
366     DCHECK_EQ(To<CSSIdentifierValue>(pair->First()).GetValueID(),
367               cssValueFor100);
368     return length.SubtractFromOneHundredPercent();
369   }
370 
371   if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) {
372     switch (identifier_value->GetValueID()) {
373       case cssValueFor0:
374         return Length::Percent(0);
375       case cssValueFor100:
376         return Length::Percent(100);
377       case CSSValueID::kCenter:
378         return Length::Percent(50);
379       default:
380         NOTREACHED();
381     }
382   }
383 
384   return StyleBuilderConverter::ConvertLength(state,
385                                               To<CSSPrimitiveValue>(value));
386 }
387 
388 template <CSSValueID IdForNone>
ConvertString(StyleResolverState &,const CSSValue & value)389 AtomicString StyleBuilderConverter::ConvertString(StyleResolverState&,
390                                                   const CSSValue& value) {
391   if (auto* string_value = DynamicTo<CSSStringValue>(value))
392     return AtomicString(string_value->Value());
393   DCHECK_EQ(To<CSSIdentifierValue>(value).GetValueID(), IdForNone);
394   return g_null_atom;
395 }
396 
397 }  // namespace blink
398 
399 #endif
400