/src/serenity/Userland/Libraries/LibWeb/CSS/CSSStyleValue.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2018-2023, Andreas Kling <kling@serenityos.org> |
3 | | * Copyright (c) 2021-2024, Sam Atkins <sam@ladybird.org> |
4 | | * Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org> |
5 | | * Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech> |
6 | | * |
7 | | * SPDX-License-Identifier: BSD-2-Clause |
8 | | */ |
9 | | |
10 | | #include <LibGfx/Font/FontStyleMapping.h> |
11 | | #include <LibGfx/Font/FontWeight.h> |
12 | | #include <LibWeb/CSS/CSSStyleValue.h> |
13 | | #include <LibWeb/CSS/StyleValues/AbstractImageStyleValue.h> |
14 | | #include <LibWeb/CSS/StyleValues/AngleStyleValue.h> |
15 | | #include <LibWeb/CSS/StyleValues/BackgroundRepeatStyleValue.h> |
16 | | #include <LibWeb/CSS/StyleValues/BackgroundSizeStyleValue.h> |
17 | | #include <LibWeb/CSS/StyleValues/BasicShapeStyleValue.h> |
18 | | #include <LibWeb/CSS/StyleValues/BorderRadiusStyleValue.h> |
19 | | #include <LibWeb/CSS/StyleValues/CSSColorValue.h> |
20 | | #include <LibWeb/CSS/StyleValues/CSSKeywordValue.h> |
21 | | #include <LibWeb/CSS/StyleValues/CSSMathValue.h> |
22 | | #include <LibWeb/CSS/StyleValues/ConicGradientStyleValue.h> |
23 | | #include <LibWeb/CSS/StyleValues/ContentStyleValue.h> |
24 | | #include <LibWeb/CSS/StyleValues/CounterDefinitionsStyleValue.h> |
25 | | #include <LibWeb/CSS/StyleValues/CounterStyleValue.h> |
26 | | #include <LibWeb/CSS/StyleValues/CustomIdentStyleValue.h> |
27 | | #include <LibWeb/CSS/StyleValues/DisplayStyleValue.h> |
28 | | #include <LibWeb/CSS/StyleValues/EasingStyleValue.h> |
29 | | #include <LibWeb/CSS/StyleValues/EdgeStyleValue.h> |
30 | | #include <LibWeb/CSS/StyleValues/FilterValueListStyleValue.h> |
31 | | #include <LibWeb/CSS/StyleValues/FlexStyleValue.h> |
32 | | #include <LibWeb/CSS/StyleValues/FrequencyStyleValue.h> |
33 | | #include <LibWeb/CSS/StyleValues/GridAutoFlowStyleValue.h> |
34 | | #include <LibWeb/CSS/StyleValues/GridTemplateAreaStyleValue.h> |
35 | | #include <LibWeb/CSS/StyleValues/GridTrackPlacementStyleValue.h> |
36 | | #include <LibWeb/CSS/StyleValues/GridTrackSizeListStyleValue.h> |
37 | | #include <LibWeb/CSS/StyleValues/ImageStyleValue.h> |
38 | | #include <LibWeb/CSS/StyleValues/IntegerStyleValue.h> |
39 | | #include <LibWeb/CSS/StyleValues/LengthStyleValue.h> |
40 | | #include <LibWeb/CSS/StyleValues/LinearGradientStyleValue.h> |
41 | | #include <LibWeb/CSS/StyleValues/MathDepthStyleValue.h> |
42 | | #include <LibWeb/CSS/StyleValues/NumberStyleValue.h> |
43 | | #include <LibWeb/CSS/StyleValues/OpenTypeTaggedStyleValue.h> |
44 | | #include <LibWeb/CSS/StyleValues/PercentageStyleValue.h> |
45 | | #include <LibWeb/CSS/StyleValues/PositionStyleValue.h> |
46 | | #include <LibWeb/CSS/StyleValues/RadialGradientStyleValue.h> |
47 | | #include <LibWeb/CSS/StyleValues/RatioStyleValue.h> |
48 | | #include <LibWeb/CSS/StyleValues/RectStyleValue.h> |
49 | | #include <LibWeb/CSS/StyleValues/ResolutionStyleValue.h> |
50 | | #include <LibWeb/CSS/StyleValues/RotationStyleValue.h> |
51 | | #include <LibWeb/CSS/StyleValues/ScrollbarGutterStyleValue.h> |
52 | | #include <LibWeb/CSS/StyleValues/ShadowStyleValue.h> |
53 | | #include <LibWeb/CSS/StyleValues/ShorthandStyleValue.h> |
54 | | #include <LibWeb/CSS/StyleValues/StringStyleValue.h> |
55 | | #include <LibWeb/CSS/StyleValues/StyleValueList.h> |
56 | | #include <LibWeb/CSS/StyleValues/TimeStyleValue.h> |
57 | | #include <LibWeb/CSS/StyleValues/TransformationStyleValue.h> |
58 | | #include <LibWeb/CSS/StyleValues/TransitionStyleValue.h> |
59 | | #include <LibWeb/CSS/StyleValues/URLStyleValue.h> |
60 | | #include <LibWeb/CSS/StyleValues/UnresolvedStyleValue.h> |
61 | | |
62 | | namespace Web::CSS { |
63 | | |
64 | | CSSStyleValue::CSSStyleValue(Type type) |
65 | 0 | : m_type(type) |
66 | 0 | { |
67 | 0 | } |
68 | | |
69 | | AbstractImageStyleValue const& CSSStyleValue::as_abstract_image() const |
70 | 0 | { |
71 | 0 | VERIFY(is_abstract_image()); |
72 | 0 | return static_cast<AbstractImageStyleValue const&>(*this); |
73 | 0 | } |
74 | | |
75 | | AngleStyleValue const& CSSStyleValue::as_angle() const |
76 | 0 | { |
77 | 0 | VERIFY(is_angle()); |
78 | 0 | return static_cast<AngleStyleValue const&>(*this); |
79 | 0 | } |
80 | | |
81 | | BackgroundRepeatStyleValue const& CSSStyleValue::as_background_repeat() const |
82 | 0 | { |
83 | 0 | VERIFY(is_background_repeat()); |
84 | 0 | return static_cast<BackgroundRepeatStyleValue const&>(*this); |
85 | 0 | } |
86 | | |
87 | | BackgroundSizeStyleValue const& CSSStyleValue::as_background_size() const |
88 | 0 | { |
89 | 0 | VERIFY(is_background_size()); |
90 | 0 | return static_cast<BackgroundSizeStyleValue const&>(*this); |
91 | 0 | } |
92 | | |
93 | | BasicShapeStyleValue const& CSSStyleValue::as_basic_shape() const |
94 | 0 | { |
95 | 0 | VERIFY(is_basic_shape()); |
96 | 0 | return static_cast<BasicShapeStyleValue const&>(*this); |
97 | 0 | } |
98 | | |
99 | | BorderRadiusStyleValue const& CSSStyleValue::as_border_radius() const |
100 | 0 | { |
101 | 0 | VERIFY(is_border_radius()); |
102 | 0 | return static_cast<BorderRadiusStyleValue const&>(*this); |
103 | 0 | } |
104 | | |
105 | | CSSMathValue const& CSSStyleValue::as_math() const |
106 | 0 | { |
107 | 0 | VERIFY(is_math()); |
108 | 0 | return static_cast<CSSMathValue const&>(*this); |
109 | 0 | } |
110 | | |
111 | | CSSColorValue const& CSSStyleValue::as_color() const |
112 | 0 | { |
113 | 0 | VERIFY(is_color()); |
114 | 0 | return static_cast<CSSColorValue const&>(*this); |
115 | 0 | } |
116 | | |
117 | | ConicGradientStyleValue const& CSSStyleValue::as_conic_gradient() const |
118 | 0 | { |
119 | 0 | VERIFY(is_conic_gradient()); |
120 | 0 | return static_cast<ConicGradientStyleValue const&>(*this); |
121 | 0 | } |
122 | | |
123 | | ContentStyleValue const& CSSStyleValue::as_content() const |
124 | 0 | { |
125 | 0 | VERIFY(is_content()); |
126 | 0 | return static_cast<ContentStyleValue const&>(*this); |
127 | 0 | } |
128 | | |
129 | | CounterStyleValue const& CSSStyleValue::as_counter() const |
130 | 0 | { |
131 | 0 | VERIFY(is_counter()); |
132 | 0 | return static_cast<CounterStyleValue const&>(*this); |
133 | 0 | } |
134 | | |
135 | | CounterDefinitionsStyleValue const& CSSStyleValue::as_counter_definitions() const |
136 | 0 | { |
137 | 0 | VERIFY(is_counter_definitions()); |
138 | 0 | return static_cast<CounterDefinitionsStyleValue const&>(*this); |
139 | 0 | } |
140 | | |
141 | | CustomIdentStyleValue const& CSSStyleValue::as_custom_ident() const |
142 | 0 | { |
143 | 0 | VERIFY(is_custom_ident()); |
144 | 0 | return static_cast<CustomIdentStyleValue const&>(*this); |
145 | 0 | } |
146 | | |
147 | | DisplayStyleValue const& CSSStyleValue::as_display() const |
148 | 0 | { |
149 | 0 | VERIFY(is_display()); |
150 | 0 | return static_cast<DisplayStyleValue const&>(*this); |
151 | 0 | } |
152 | | |
153 | | EasingStyleValue const& CSSStyleValue::as_easing() const |
154 | 0 | { |
155 | 0 | VERIFY(is_easing()); |
156 | 0 | return static_cast<EasingStyleValue const&>(*this); |
157 | 0 | } |
158 | | |
159 | | EdgeStyleValue const& CSSStyleValue::as_edge() const |
160 | 0 | { |
161 | 0 | VERIFY(is_edge()); |
162 | 0 | return static_cast<EdgeStyleValue const&>(*this); |
163 | 0 | } |
164 | | |
165 | | FilterValueListStyleValue const& CSSStyleValue::as_filter_value_list() const |
166 | 0 | { |
167 | 0 | VERIFY(is_filter_value_list()); |
168 | 0 | return static_cast<FilterValueListStyleValue const&>(*this); |
169 | 0 | } |
170 | | |
171 | | FlexStyleValue const& CSSStyleValue::as_flex() const |
172 | 0 | { |
173 | 0 | VERIFY(is_flex()); |
174 | 0 | return static_cast<FlexStyleValue const&>(*this); |
175 | 0 | } |
176 | | |
177 | | FrequencyStyleValue const& CSSStyleValue::as_frequency() const |
178 | 0 | { |
179 | 0 | VERIFY(is_frequency()); |
180 | 0 | return static_cast<FrequencyStyleValue const&>(*this); |
181 | 0 | } |
182 | | |
183 | | GridAutoFlowStyleValue const& CSSStyleValue::as_grid_auto_flow() const |
184 | 0 | { |
185 | 0 | VERIFY(is_grid_auto_flow()); |
186 | 0 | return static_cast<GridAutoFlowStyleValue const&>(*this); |
187 | 0 | } |
188 | | |
189 | | GridTemplateAreaStyleValue const& CSSStyleValue::as_grid_template_area() const |
190 | 0 | { |
191 | 0 | VERIFY(is_grid_template_area()); |
192 | 0 | return static_cast<GridTemplateAreaStyleValue const&>(*this); |
193 | 0 | } |
194 | | |
195 | | GridTrackPlacementStyleValue const& CSSStyleValue::as_grid_track_placement() const |
196 | 0 | { |
197 | 0 | VERIFY(is_grid_track_placement()); |
198 | 0 | return static_cast<GridTrackPlacementStyleValue const&>(*this); |
199 | 0 | } |
200 | | |
201 | | GridTrackSizeListStyleValue const& CSSStyleValue::as_grid_track_size_list() const |
202 | 0 | { |
203 | 0 | VERIFY(is_grid_track_size_list()); |
204 | 0 | return static_cast<GridTrackSizeListStyleValue const&>(*this); |
205 | 0 | } |
206 | | |
207 | | CSSKeywordValue const& CSSStyleValue::as_keyword() const |
208 | 0 | { |
209 | 0 | VERIFY(is_keyword()); |
210 | 0 | return static_cast<CSSKeywordValue const&>(*this); |
211 | 0 | } |
212 | | |
213 | | ImageStyleValue const& CSSStyleValue::as_image() const |
214 | 0 | { |
215 | 0 | VERIFY(is_image()); |
216 | 0 | return static_cast<ImageStyleValue const&>(*this); |
217 | 0 | } |
218 | | |
219 | | IntegerStyleValue const& CSSStyleValue::as_integer() const |
220 | 0 | { |
221 | 0 | VERIFY(is_integer()); |
222 | 0 | return static_cast<IntegerStyleValue const&>(*this); |
223 | 0 | } |
224 | | |
225 | | LengthStyleValue const& CSSStyleValue::as_length() const |
226 | 0 | { |
227 | 0 | VERIFY(is_length()); |
228 | 0 | return static_cast<LengthStyleValue const&>(*this); |
229 | 0 | } |
230 | | |
231 | | LinearGradientStyleValue const& CSSStyleValue::as_linear_gradient() const |
232 | 0 | { |
233 | 0 | VERIFY(is_linear_gradient()); |
234 | 0 | return static_cast<LinearGradientStyleValue const&>(*this); |
235 | 0 | } |
236 | | |
237 | | MathDepthStyleValue const& CSSStyleValue::as_math_depth() const |
238 | 0 | { |
239 | 0 | VERIFY(is_math_depth()); |
240 | 0 | return static_cast<MathDepthStyleValue const&>(*this); |
241 | 0 | } |
242 | | |
243 | | NumberStyleValue const& CSSStyleValue::as_number() const |
244 | 0 | { |
245 | 0 | VERIFY(is_number()); |
246 | 0 | return static_cast<NumberStyleValue const&>(*this); |
247 | 0 | } |
248 | | |
249 | | OpenTypeTaggedStyleValue const& CSSStyleValue::as_open_type_tagged() const |
250 | 0 | { |
251 | 0 | VERIFY(is_open_type_tagged()); |
252 | 0 | return static_cast<OpenTypeTaggedStyleValue const&>(*this); |
253 | 0 | } |
254 | | |
255 | | PercentageStyleValue const& CSSStyleValue::as_percentage() const |
256 | 0 | { |
257 | 0 | VERIFY(is_percentage()); |
258 | 0 | return static_cast<PercentageStyleValue const&>(*this); |
259 | 0 | } |
260 | | |
261 | | PositionStyleValue const& CSSStyleValue::as_position() const |
262 | 0 | { |
263 | 0 | VERIFY(is_position()); |
264 | 0 | return static_cast<PositionStyleValue const&>(*this); |
265 | 0 | } |
266 | | |
267 | | RadialGradientStyleValue const& CSSStyleValue::as_radial_gradient() const |
268 | 0 | { |
269 | 0 | VERIFY(is_radial_gradient()); |
270 | 0 | return static_cast<RadialGradientStyleValue const&>(*this); |
271 | 0 | } |
272 | | |
273 | | RatioStyleValue const& CSSStyleValue::as_ratio() const |
274 | 0 | { |
275 | 0 | VERIFY(is_ratio()); |
276 | 0 | return static_cast<RatioStyleValue const&>(*this); |
277 | 0 | } |
278 | | |
279 | | RectStyleValue const& CSSStyleValue::as_rect() const |
280 | 0 | { |
281 | 0 | VERIFY(is_rect()); |
282 | 0 | return static_cast<RectStyleValue const&>(*this); |
283 | 0 | } |
284 | | |
285 | | ResolutionStyleValue const& CSSStyleValue::as_resolution() const |
286 | 0 | { |
287 | 0 | VERIFY(is_resolution()); |
288 | 0 | return static_cast<ResolutionStyleValue const&>(*this); |
289 | 0 | } |
290 | | |
291 | | RotationStyleValue const& CSSStyleValue::as_rotation() const |
292 | 0 | { |
293 | 0 | VERIFY(is_rotation()); |
294 | 0 | return static_cast<RotationStyleValue const&>(*this); |
295 | 0 | } |
296 | | |
297 | | ScrollbarGutterStyleValue const& CSSStyleValue::as_scrollbar_gutter() const |
298 | 0 | { |
299 | 0 | VERIFY(is_scrollbar_gutter()); |
300 | 0 | return static_cast<ScrollbarGutterStyleValue const&>(*this); |
301 | 0 | } |
302 | | |
303 | | ShadowStyleValue const& CSSStyleValue::as_shadow() const |
304 | 0 | { |
305 | 0 | VERIFY(is_shadow()); |
306 | 0 | return static_cast<ShadowStyleValue const&>(*this); |
307 | 0 | } |
308 | | |
309 | | ShorthandStyleValue const& CSSStyleValue::as_shorthand() const |
310 | 0 | { |
311 | 0 | VERIFY(is_shorthand()); |
312 | 0 | return static_cast<ShorthandStyleValue const&>(*this); |
313 | 0 | } |
314 | | |
315 | | StringStyleValue const& CSSStyleValue::as_string() const |
316 | 0 | { |
317 | 0 | VERIFY(is_string()); |
318 | 0 | return static_cast<StringStyleValue const&>(*this); |
319 | 0 | } |
320 | | |
321 | | TimeStyleValue const& CSSStyleValue::as_time() const |
322 | 0 | { |
323 | 0 | VERIFY(is_time()); |
324 | 0 | return static_cast<TimeStyleValue const&>(*this); |
325 | 0 | } |
326 | | |
327 | | TransformationStyleValue const& CSSStyleValue::as_transformation() const |
328 | 0 | { |
329 | 0 | VERIFY(is_transformation()); |
330 | 0 | return static_cast<TransformationStyleValue const&>(*this); |
331 | 0 | } |
332 | | |
333 | | TransitionStyleValue const& CSSStyleValue::as_transition() const |
334 | 0 | { |
335 | 0 | VERIFY(is_transition()); |
336 | 0 | return static_cast<TransitionStyleValue const&>(*this); |
337 | 0 | } |
338 | | |
339 | | UnresolvedStyleValue const& CSSStyleValue::as_unresolved() const |
340 | 0 | { |
341 | 0 | VERIFY(is_unresolved()); |
342 | 0 | return static_cast<UnresolvedStyleValue const&>(*this); |
343 | 0 | } |
344 | | |
345 | | URLStyleValue const& CSSStyleValue::as_url() const |
346 | 0 | { |
347 | 0 | VERIFY(is_url()); |
348 | 0 | return static_cast<URLStyleValue const&>(*this); |
349 | 0 | } |
350 | | |
351 | | StyleValueList const& CSSStyleValue::as_value_list() const |
352 | 0 | { |
353 | 0 | VERIFY(is_value_list()); |
354 | 0 | return static_cast<StyleValueList const&>(*this); |
355 | 0 | } |
356 | | |
357 | | ValueComparingNonnullRefPtr<CSSStyleValue const> CSSStyleValue::absolutized(CSSPixelRect const&, Length::FontMetrics const&, Length::FontMetrics const&) const |
358 | 0 | { |
359 | 0 | return *this; |
360 | 0 | } |
361 | | |
362 | | bool CSSStyleValue::has_auto() const |
363 | 0 | { |
364 | 0 | return is_keyword() && as_keyword().keyword() == Keyword::Auto; |
365 | 0 | } |
366 | | |
367 | | Keyword CSSStyleValue::to_keyword() const |
368 | 0 | { |
369 | 0 | if (is_keyword()) |
370 | 0 | return as_keyword().keyword(); |
371 | 0 | return Keyword::Invalid; |
372 | 0 | } |
373 | | |
374 | | int CSSStyleValue::to_font_weight() const |
375 | 0 | { |
376 | 0 | if (is_keyword()) { |
377 | 0 | switch (as_keyword().keyword()) { |
378 | 0 | case Keyword::Normal: |
379 | 0 | return Gfx::FontWeight::Regular; |
380 | 0 | case Keyword::Bold: |
381 | 0 | return Gfx::FontWeight::Bold; |
382 | 0 | case Keyword::Lighter: |
383 | | // FIXME: This should be relative to the parent. |
384 | 0 | return Gfx::FontWeight::Regular; |
385 | 0 | case Keyword::Bolder: |
386 | | // FIXME: This should be relative to the parent. |
387 | 0 | return Gfx::FontWeight::Bold; |
388 | 0 | default: |
389 | 0 | return Gfx::FontWeight::Regular; |
390 | 0 | } |
391 | 0 | } |
392 | 0 | if (is_number()) { |
393 | 0 | return round_to<int>(as_number().number()); |
394 | 0 | } |
395 | 0 | if (is_math()) { |
396 | 0 | auto maybe_weight = const_cast<CSSMathValue&>(as_math()).resolve_integer(); |
397 | 0 | if (maybe_weight.has_value()) |
398 | 0 | return maybe_weight.value(); |
399 | 0 | } |
400 | 0 | return Gfx::FontWeight::Regular; |
401 | 0 | } |
402 | | |
403 | | int CSSStyleValue::to_font_slope() const |
404 | 0 | { |
405 | | // FIXME: Implement oblique <angle> |
406 | 0 | if (is_keyword()) { |
407 | 0 | switch (as_keyword().keyword()) { |
408 | 0 | case Keyword::Italic: { |
409 | 0 | static int italic_slope = Gfx::name_to_slope("Italic"sv); |
410 | 0 | return italic_slope; |
411 | 0 | } |
412 | 0 | case Keyword::Oblique: |
413 | 0 | static int oblique_slope = Gfx::name_to_slope("Oblique"sv); |
414 | 0 | return oblique_slope; |
415 | 0 | case Keyword::Normal: |
416 | 0 | default: |
417 | 0 | break; |
418 | 0 | } |
419 | 0 | } |
420 | 0 | static int normal_slope = Gfx::name_to_slope("Normal"sv); |
421 | 0 | return normal_slope; |
422 | 0 | } |
423 | | |
424 | | int CSSStyleValue::to_font_width() const |
425 | 0 | { |
426 | 0 | int width = Gfx::FontWidth::Normal; |
427 | 0 | if (is_keyword()) { |
428 | 0 | switch (as_keyword().keyword()) { |
429 | 0 | case Keyword::UltraCondensed: |
430 | 0 | width = Gfx::FontWidth::UltraCondensed; |
431 | 0 | break; |
432 | 0 | case Keyword::ExtraCondensed: |
433 | 0 | width = Gfx::FontWidth::ExtraCondensed; |
434 | 0 | break; |
435 | 0 | case Keyword::Condensed: |
436 | 0 | width = Gfx::FontWidth::Condensed; |
437 | 0 | break; |
438 | 0 | case Keyword::SemiCondensed: |
439 | 0 | width = Gfx::FontWidth::SemiCondensed; |
440 | 0 | break; |
441 | 0 | case Keyword::Normal: |
442 | 0 | width = Gfx::FontWidth::Normal; |
443 | 0 | break; |
444 | 0 | case Keyword::SemiExpanded: |
445 | 0 | width = Gfx::FontWidth::SemiExpanded; |
446 | 0 | break; |
447 | 0 | case Keyword::Expanded: |
448 | 0 | width = Gfx::FontWidth::Expanded; |
449 | 0 | break; |
450 | 0 | case Keyword::ExtraExpanded: |
451 | 0 | width = Gfx::FontWidth::ExtraExpanded; |
452 | 0 | break; |
453 | 0 | case Keyword::UltraExpanded: |
454 | 0 | width = Gfx::FontWidth::UltraExpanded; |
455 | 0 | break; |
456 | 0 | default: |
457 | 0 | break; |
458 | 0 | } |
459 | 0 | } else if (is_percentage()) { |
460 | 0 | float percentage = as_percentage().percentage().value(); |
461 | 0 | if (percentage <= 50) { |
462 | 0 | width = Gfx::FontWidth::UltraCondensed; |
463 | 0 | } else if (percentage <= 62.5f) { |
464 | 0 | width = Gfx::FontWidth::ExtraCondensed; |
465 | 0 | } else if (percentage <= 75.0f) { |
466 | 0 | width = Gfx::FontWidth::Condensed; |
467 | 0 | } else if (percentage <= 87.5f) { |
468 | 0 | width = Gfx::FontWidth::SemiCondensed; |
469 | 0 | } else if (percentage <= 100.0f) { |
470 | 0 | width = Gfx::FontWidth::Normal; |
471 | 0 | } else if (percentage <= 112.5f) { |
472 | 0 | width = Gfx::FontWidth::SemiExpanded; |
473 | 0 | } else if (percentage <= 125.0f) { |
474 | 0 | width = Gfx::FontWidth::Expanded; |
475 | 0 | } else if (percentage <= 150.0f) { |
476 | 0 | width = Gfx::FontWidth::ExtraExpanded; |
477 | 0 | } else { |
478 | 0 | width = Gfx::FontWidth::UltraExpanded; |
479 | 0 | } |
480 | 0 | } |
481 | 0 | return width; |
482 | 0 | } |
483 | | |
484 | | } |