1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "core/fxcrt/css/cfx_cssstyleselector.h"
8
9 #include <algorithm>
10 #include <utility>
11
12 #include "core/fxcrt/css/cfx_csscolorvalue.h"
13 #include "core/fxcrt/css/cfx_csscomputedstyle.h"
14 #include "core/fxcrt/css/cfx_csscustomproperty.h"
15 #include "core/fxcrt/css/cfx_cssdeclaration.h"
16 #include "core/fxcrt/css/cfx_cssenumvalue.h"
17 #include "core/fxcrt/css/cfx_csspropertyholder.h"
18 #include "core/fxcrt/css/cfx_cssselector.h"
19 #include "core/fxcrt/css/cfx_cssstylesheet.h"
20 #include "core/fxcrt/css/cfx_csssyntaxparser.h"
21 #include "core/fxcrt/css/cfx_cssvaluelist.h"
22 #include "third_party/base/logging.h"
23 #include "third_party/base/ptr_util.h"
24
CFX_CSSStyleSelector()25 CFX_CSSStyleSelector::CFX_CSSStyleSelector() : m_fDefFontSize(12.0f) {}
26
~CFX_CSSStyleSelector()27 CFX_CSSStyleSelector::~CFX_CSSStyleSelector() {}
28
SetDefFontSize(float fFontSize)29 void CFX_CSSStyleSelector::SetDefFontSize(float fFontSize) {
30 ASSERT(fFontSize > 0);
31 m_fDefFontSize = fFontSize;
32 }
33
CreateComputedStyle(CFX_CSSComputedStyle * pParentStyle)34 RetainPtr<CFX_CSSComputedStyle> CFX_CSSStyleSelector::CreateComputedStyle(
35 CFX_CSSComputedStyle* pParentStyle) {
36 auto pStyle = pdfium::MakeRetain<CFX_CSSComputedStyle>();
37 if (pParentStyle)
38 pStyle->m_InheritedData = pParentStyle->m_InheritedData;
39 return pStyle;
40 }
41
SetUAStyleSheet(std::unique_ptr<CFX_CSSStyleSheet> pSheet)42 void CFX_CSSStyleSelector::SetUAStyleSheet(
43 std::unique_ptr<CFX_CSSStyleSheet> pSheet) {
44 m_UAStyles = std::move(pSheet);
45 }
46
UpdateStyleIndex()47 void CFX_CSSStyleSelector::UpdateStyleIndex() {
48 m_UARules.Clear();
49 m_UARules.AddRulesFrom(m_UAStyles.get());
50 }
51
MatchDeclarations(const WideString & tagname)52 std::vector<const CFX_CSSDeclaration*> CFX_CSSStyleSelector::MatchDeclarations(
53 const WideString& tagname) {
54 std::vector<const CFX_CSSDeclaration*> matchedDecls;
55 if (m_UARules.CountSelectors() == 0 || tagname.IsEmpty())
56 return matchedDecls;
57
58 auto* rules = m_UARules.GetTagRuleData(tagname);
59 if (!rules)
60 return matchedDecls;
61
62 for (const auto& d : *rules) {
63 if (MatchSelector(tagname, d->pSelector))
64 matchedDecls.push_back(d->pDeclaration);
65 }
66 return matchedDecls;
67 }
68
MatchSelector(const WideString & tagname,CFX_CSSSelector * pSel)69 bool CFX_CSSStyleSelector::MatchSelector(const WideString& tagname,
70 CFX_CSSSelector* pSel) {
71 // TODO(dsinclair): The code only supports a single level of selector at this
72 // point. None of the code using selectors required the complexity so lets
73 // just say we don't support them to simplify the code for now.
74 if (!pSel || pSel->GetNextSelector() ||
75 pSel->GetType() == CFX_CSSSelectorType::Descendant) {
76 return false;
77 }
78 return pSel->GetNameHash() == FX_HashCode_GetW(tagname.c_str(), true);
79 }
80
ComputeStyle(const std::vector<const CFX_CSSDeclaration * > & declArray,const WideString & styleString,const WideString & alignString,CFX_CSSComputedStyle * pDest)81 void CFX_CSSStyleSelector::ComputeStyle(
82 const std::vector<const CFX_CSSDeclaration*>& declArray,
83 const WideString& styleString,
84 const WideString& alignString,
85 CFX_CSSComputedStyle* pDest) {
86 std::unique_ptr<CFX_CSSDeclaration> pDecl;
87 if (!styleString.IsEmpty() || !alignString.IsEmpty()) {
88 pDecl = pdfium::MakeUnique<CFX_CSSDeclaration>();
89
90 if (!styleString.IsEmpty())
91 AppendInlineStyle(pDecl.get(), styleString);
92 if (!alignString.IsEmpty()) {
93 pDecl->AddProperty(CFX_GetCSSPropertyByEnum(CFX_CSSProperty::TextAlign),
94 alignString.AsStringView());
95 }
96 }
97 ApplyDeclarations(declArray, pDecl.get(), pDest);
98 }
99
ApplyDeclarations(const std::vector<const CFX_CSSDeclaration * > & declArray,const CFX_CSSDeclaration * extraDecl,CFX_CSSComputedStyle * pComputedStyle)100 void CFX_CSSStyleSelector::ApplyDeclarations(
101 const std::vector<const CFX_CSSDeclaration*>& declArray,
102 const CFX_CSSDeclaration* extraDecl,
103 CFX_CSSComputedStyle* pComputedStyle) {
104 std::vector<const CFX_CSSPropertyHolder*> importants;
105 std::vector<const CFX_CSSPropertyHolder*> normals;
106 std::vector<const CFX_CSSCustomProperty*> customs;
107
108 for (auto* decl : declArray)
109 ExtractValues(decl, &importants, &normals, &customs);
110
111 if (extraDecl)
112 ExtractValues(extraDecl, &importants, &normals, &customs);
113
114 for (auto* prop : normals)
115 ApplyProperty(prop->eProperty, prop->pValue, pComputedStyle);
116
117 for (auto* prop : customs)
118 pComputedStyle->AddCustomStyle(*prop);
119
120 for (auto* prop : importants)
121 ApplyProperty(prop->eProperty, prop->pValue, pComputedStyle);
122 }
123
ExtractValues(const CFX_CSSDeclaration * decl,std::vector<const CFX_CSSPropertyHolder * > * importants,std::vector<const CFX_CSSPropertyHolder * > * normals,std::vector<const CFX_CSSCustomProperty * > * custom)124 void CFX_CSSStyleSelector::ExtractValues(
125 const CFX_CSSDeclaration* decl,
126 std::vector<const CFX_CSSPropertyHolder*>* importants,
127 std::vector<const CFX_CSSPropertyHolder*>* normals,
128 std::vector<const CFX_CSSCustomProperty*>* custom) {
129 for (const auto& holder : *decl) {
130 if (holder->bImportant)
131 importants->push_back(holder.get());
132 else
133 normals->push_back(holder.get());
134 }
135 for (auto it = decl->custom_begin(); it != decl->custom_end(); it++)
136 custom->push_back(it->get());
137 }
138
AppendInlineStyle(CFX_CSSDeclaration * pDecl,const WideString & style)139 void CFX_CSSStyleSelector::AppendInlineStyle(CFX_CSSDeclaration* pDecl,
140 const WideString& style) {
141 ASSERT(pDecl && !style.IsEmpty());
142
143 auto pSyntax = pdfium::MakeUnique<CFX_CSSSyntaxParser>(
144 style.c_str(), style.GetLength(), 32, true);
145 int32_t iLen2 = 0;
146 const CFX_CSSPropertyTable* table = nullptr;
147 WideString wsName;
148 while (1) {
149 CFX_CSSSyntaxStatus eStatus = pSyntax->DoSyntaxParse();
150 if (eStatus == CFX_CSSSyntaxStatus::PropertyName) {
151 WideStringView strValue = pSyntax->GetCurrentString();
152 table = CFX_GetCSSPropertyByName(strValue);
153 if (!table)
154 wsName = WideString(strValue);
155 } else if (eStatus == CFX_CSSSyntaxStatus::PropertyValue) {
156 if (table || iLen2 > 0) {
157 WideStringView strValue = pSyntax->GetCurrentString();
158 if (!strValue.IsEmpty()) {
159 if (table)
160 pDecl->AddProperty(table, strValue);
161 else if (iLen2 > 0)
162 pDecl->AddProperty(wsName, WideString(strValue));
163 }
164 }
165 } else {
166 break;
167 }
168 }
169 }
170
ApplyProperty(CFX_CSSProperty eProperty,const RetainPtr<CFX_CSSValue> & pValue,CFX_CSSComputedStyle * pComputedStyle)171 void CFX_CSSStyleSelector::ApplyProperty(CFX_CSSProperty eProperty,
172 const RetainPtr<CFX_CSSValue>& pValue,
173 CFX_CSSComputedStyle* pComputedStyle) {
174 if (pValue->GetType() != CFX_CSSPrimitiveType::List) {
175 CFX_CSSPrimitiveType eType = pValue->GetType();
176 switch (eProperty) {
177 case CFX_CSSProperty::Display:
178 if (eType == CFX_CSSPrimitiveType::Enum) {
179 pComputedStyle->m_NonInheritedData.m_eDisplay =
180 ToDisplay(pValue.As<CFX_CSSEnumValue>()->Value());
181 }
182 break;
183 case CFX_CSSProperty::FontSize: {
184 float& fFontSize = pComputedStyle->m_InheritedData.m_fFontSize;
185 if (eType == CFX_CSSPrimitiveType::Number) {
186 fFontSize = pValue.As<CFX_CSSNumberValue>()->Apply(fFontSize);
187 } else if (eType == CFX_CSSPrimitiveType::Enum) {
188 fFontSize =
189 ToFontSize(pValue.As<CFX_CSSEnumValue>()->Value(), fFontSize);
190 }
191 } break;
192 case CFX_CSSProperty::LineHeight:
193 if (eType == CFX_CSSPrimitiveType::Number) {
194 RetainPtr<CFX_CSSNumberValue> v = pValue.As<CFX_CSSNumberValue>();
195 if (v->Kind() == CFX_CSSNumberType::Number) {
196 pComputedStyle->m_InheritedData.m_fLineHeight =
197 v->Value() * pComputedStyle->m_InheritedData.m_fFontSize;
198 } else {
199 pComputedStyle->m_InheritedData.m_fLineHeight =
200 v->Apply(pComputedStyle->m_InheritedData.m_fFontSize);
201 }
202 }
203 break;
204 case CFX_CSSProperty::TextAlign:
205 if (eType == CFX_CSSPrimitiveType::Enum) {
206 pComputedStyle->m_InheritedData.m_eTextAlign =
207 ToTextAlign(pValue.As<CFX_CSSEnumValue>()->Value());
208 }
209 break;
210 case CFX_CSSProperty::TextIndent:
211 SetLengthWithPercent(pComputedStyle->m_InheritedData.m_TextIndent,
212 eType, pValue,
213 pComputedStyle->m_InheritedData.m_fFontSize);
214 break;
215 case CFX_CSSProperty::FontWeight:
216 if (eType == CFX_CSSPrimitiveType::Enum) {
217 pComputedStyle->m_InheritedData.m_wFontWeight =
218 ToFontWeight(pValue.As<CFX_CSSEnumValue>()->Value());
219 } else if (eType == CFX_CSSPrimitiveType::Number) {
220 int32_t iValue =
221 (int32_t)pValue.As<CFX_CSSNumberValue>()->Value() / 100;
222 if (iValue >= 1 && iValue <= 9) {
223 pComputedStyle->m_InheritedData.m_wFontWeight = iValue * 100;
224 }
225 }
226 break;
227 case CFX_CSSProperty::FontStyle:
228 if (eType == CFX_CSSPrimitiveType::Enum) {
229 pComputedStyle->m_InheritedData.m_eFontStyle =
230 ToFontStyle(pValue.As<CFX_CSSEnumValue>()->Value());
231 }
232 break;
233 case CFX_CSSProperty::Color:
234 if (eType == CFX_CSSPrimitiveType::RGB) {
235 pComputedStyle->m_InheritedData.m_dwFontColor =
236 pValue.As<CFX_CSSColorValue>()->Value();
237 }
238 break;
239 case CFX_CSSProperty::MarginLeft:
240 if (SetLengthWithPercent(
241 pComputedStyle->m_NonInheritedData.m_MarginWidth.left, eType,
242 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
243 pComputedStyle->m_NonInheritedData.m_bHasMargin = true;
244 }
245 break;
246 case CFX_CSSProperty::MarginTop:
247 if (SetLengthWithPercent(
248 pComputedStyle->m_NonInheritedData.m_MarginWidth.top, eType,
249 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
250 pComputedStyle->m_NonInheritedData.m_bHasMargin = true;
251 }
252 break;
253 case CFX_CSSProperty::MarginRight:
254 if (SetLengthWithPercent(
255 pComputedStyle->m_NonInheritedData.m_MarginWidth.right, eType,
256 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
257 pComputedStyle->m_NonInheritedData.m_bHasMargin = true;
258 }
259 break;
260 case CFX_CSSProperty::MarginBottom:
261 if (SetLengthWithPercent(
262 pComputedStyle->m_NonInheritedData.m_MarginWidth.bottom, eType,
263 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
264 pComputedStyle->m_NonInheritedData.m_bHasMargin = true;
265 }
266 break;
267 case CFX_CSSProperty::PaddingLeft:
268 if (SetLengthWithPercent(
269 pComputedStyle->m_NonInheritedData.m_PaddingWidth.left, eType,
270 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
271 pComputedStyle->m_NonInheritedData.m_bHasPadding = true;
272 }
273 break;
274 case CFX_CSSProperty::PaddingTop:
275 if (SetLengthWithPercent(
276 pComputedStyle->m_NonInheritedData.m_PaddingWidth.top, eType,
277 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
278 pComputedStyle->m_NonInheritedData.m_bHasPadding = true;
279 }
280 break;
281 case CFX_CSSProperty::PaddingRight:
282 if (SetLengthWithPercent(
283 pComputedStyle->m_NonInheritedData.m_PaddingWidth.right, eType,
284 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
285 pComputedStyle->m_NonInheritedData.m_bHasPadding = true;
286 }
287 break;
288 case CFX_CSSProperty::PaddingBottom:
289 if (SetLengthWithPercent(
290 pComputedStyle->m_NonInheritedData.m_PaddingWidth.bottom, eType,
291 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
292 pComputedStyle->m_NonInheritedData.m_bHasPadding = true;
293 }
294 break;
295 case CFX_CSSProperty::BorderLeftWidth:
296 if (SetLengthWithPercent(
297 pComputedStyle->m_NonInheritedData.m_BorderWidth.left, eType,
298 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
299 pComputedStyle->m_NonInheritedData.m_bHasBorder = true;
300 }
301 break;
302 case CFX_CSSProperty::BorderTopWidth:
303 if (SetLengthWithPercent(
304 pComputedStyle->m_NonInheritedData.m_BorderWidth.top, eType,
305 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
306 pComputedStyle->m_NonInheritedData.m_bHasBorder = true;
307 }
308 break;
309 case CFX_CSSProperty::BorderRightWidth:
310 if (SetLengthWithPercent(
311 pComputedStyle->m_NonInheritedData.m_BorderWidth.right, eType,
312 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
313 pComputedStyle->m_NonInheritedData.m_bHasBorder = true;
314 }
315 break;
316 case CFX_CSSProperty::BorderBottomWidth:
317 if (SetLengthWithPercent(
318 pComputedStyle->m_NonInheritedData.m_BorderWidth.bottom, eType,
319 pValue, pComputedStyle->m_InheritedData.m_fFontSize)) {
320 pComputedStyle->m_NonInheritedData.m_bHasBorder = true;
321 }
322 break;
323 case CFX_CSSProperty::VerticalAlign:
324 if (eType == CFX_CSSPrimitiveType::Enum) {
325 pComputedStyle->m_NonInheritedData.m_eVerticalAlign =
326 ToVerticalAlign(pValue.As<CFX_CSSEnumValue>()->Value());
327 } else if (eType == CFX_CSSPrimitiveType::Number) {
328 pComputedStyle->m_NonInheritedData.m_eVerticalAlign =
329 CFX_CSSVerticalAlign::Number;
330 pComputedStyle->m_NonInheritedData.m_fVerticalAlign =
331 pValue.As<CFX_CSSNumberValue>()->Apply(
332 pComputedStyle->m_InheritedData.m_fFontSize);
333 }
334 break;
335 case CFX_CSSProperty::FontVariant:
336 if (eType == CFX_CSSPrimitiveType::Enum) {
337 pComputedStyle->m_InheritedData.m_eFontVariant =
338 ToFontVariant(pValue.As<CFX_CSSEnumValue>()->Value());
339 }
340 break;
341 case CFX_CSSProperty::LetterSpacing:
342 if (eType == CFX_CSSPrimitiveType::Enum) {
343 pComputedStyle->m_InheritedData.m_LetterSpacing.Set(
344 CFX_CSSLengthUnit::Normal);
345 } else if (eType == CFX_CSSPrimitiveType::Number) {
346 if (pValue.As<CFX_CSSNumberValue>()->Kind() ==
347 CFX_CSSNumberType::Percent) {
348 break;
349 }
350
351 SetLengthWithPercent(pComputedStyle->m_InheritedData.m_LetterSpacing,
352 eType, pValue,
353 pComputedStyle->m_InheritedData.m_fFontSize);
354 }
355 break;
356 case CFX_CSSProperty::WordSpacing:
357 if (eType == CFX_CSSPrimitiveType::Enum) {
358 pComputedStyle->m_InheritedData.m_WordSpacing.Set(
359 CFX_CSSLengthUnit::Normal);
360 } else if (eType == CFX_CSSPrimitiveType::Number) {
361 if (pValue.As<CFX_CSSNumberValue>()->Kind() ==
362 CFX_CSSNumberType::Percent) {
363 break;
364 }
365 SetLengthWithPercent(pComputedStyle->m_InheritedData.m_WordSpacing,
366 eType, pValue,
367 pComputedStyle->m_InheritedData.m_fFontSize);
368 }
369 break;
370 case CFX_CSSProperty::Top:
371 SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Top, eType,
372 pValue,
373 pComputedStyle->m_InheritedData.m_fFontSize);
374 break;
375 case CFX_CSSProperty::Bottom:
376 SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Bottom, eType,
377 pValue,
378 pComputedStyle->m_InheritedData.m_fFontSize);
379 break;
380 case CFX_CSSProperty::Left:
381 SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Left, eType,
382 pValue,
383 pComputedStyle->m_InheritedData.m_fFontSize);
384 break;
385 case CFX_CSSProperty::Right:
386 SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Right, eType,
387 pValue,
388 pComputedStyle->m_InheritedData.m_fFontSize);
389 break;
390 default:
391 break;
392 }
393 } else if (pValue->GetType() == CFX_CSSPrimitiveType::List) {
394 RetainPtr<CFX_CSSValueList> pList = pValue.As<CFX_CSSValueList>();
395 int32_t iCount = pList->CountValues();
396 if (iCount > 0) {
397 switch (eProperty) {
398 case CFX_CSSProperty::FontFamily:
399 pComputedStyle->m_InheritedData.m_pFontFamily = pList;
400 break;
401 case CFX_CSSProperty::TextDecoration:
402 pComputedStyle->m_NonInheritedData.m_dwTextDecoration =
403 ToTextDecoration(pList);
404 break;
405 default:
406 break;
407 }
408 }
409 } else {
410 NOTREACHED();
411 }
412 }
413
ToDisplay(CFX_CSSPropertyValue eValue)414 CFX_CSSDisplay CFX_CSSStyleSelector::ToDisplay(CFX_CSSPropertyValue eValue) {
415 switch (eValue) {
416 case CFX_CSSPropertyValue::Block:
417 return CFX_CSSDisplay::Block;
418 case CFX_CSSPropertyValue::None:
419 return CFX_CSSDisplay::None;
420 case CFX_CSSPropertyValue::ListItem:
421 return CFX_CSSDisplay::ListItem;
422 case CFX_CSSPropertyValue::InlineTable:
423 return CFX_CSSDisplay::InlineTable;
424 case CFX_CSSPropertyValue::InlineBlock:
425 return CFX_CSSDisplay::InlineBlock;
426 case CFX_CSSPropertyValue::Inline:
427 default:
428 return CFX_CSSDisplay::Inline;
429 }
430 }
431
ToTextAlign(CFX_CSSPropertyValue eValue)432 CFX_CSSTextAlign CFX_CSSStyleSelector::ToTextAlign(
433 CFX_CSSPropertyValue eValue) {
434 switch (eValue) {
435 case CFX_CSSPropertyValue::Center:
436 return CFX_CSSTextAlign::Center;
437 case CFX_CSSPropertyValue::Right:
438 return CFX_CSSTextAlign::Right;
439 case CFX_CSSPropertyValue::Justify:
440 return CFX_CSSTextAlign::Justify;
441 case CFX_CSSPropertyValue::Left:
442 default:
443 return CFX_CSSTextAlign::Left;
444 }
445 }
446
ToFontWeight(CFX_CSSPropertyValue eValue)447 uint16_t CFX_CSSStyleSelector::ToFontWeight(CFX_CSSPropertyValue eValue) {
448 switch (eValue) {
449 case CFX_CSSPropertyValue::Bold:
450 return 700;
451 case CFX_CSSPropertyValue::Bolder:
452 return 900;
453 case CFX_CSSPropertyValue::Lighter:
454 return 200;
455 case CFX_CSSPropertyValue::Normal:
456 default:
457 return 400;
458 }
459 }
460
ToFontStyle(CFX_CSSPropertyValue eValue)461 CFX_CSSFontStyle CFX_CSSStyleSelector::ToFontStyle(
462 CFX_CSSPropertyValue eValue) {
463 switch (eValue) {
464 case CFX_CSSPropertyValue::Italic:
465 case CFX_CSSPropertyValue::Oblique:
466 return CFX_CSSFontStyle::Italic;
467 default:
468 return CFX_CSSFontStyle::Normal;
469 }
470 }
471
SetLengthWithPercent(CFX_CSSLength & width,CFX_CSSPrimitiveType eType,const RetainPtr<CFX_CSSValue> & pValue,float fFontSize)472 bool CFX_CSSStyleSelector::SetLengthWithPercent(
473 CFX_CSSLength& width,
474 CFX_CSSPrimitiveType eType,
475 const RetainPtr<CFX_CSSValue>& pValue,
476 float fFontSize) {
477 if (eType == CFX_CSSPrimitiveType::Number) {
478 RetainPtr<CFX_CSSNumberValue> v = pValue.As<CFX_CSSNumberValue>();
479 if (v->Kind() == CFX_CSSNumberType::Percent) {
480 width.Set(CFX_CSSLengthUnit::Percent,
481 pValue.As<CFX_CSSNumberValue>()->Value() / 100.0f);
482 return width.NonZero();
483 }
484
485 float fValue = v->Apply(fFontSize);
486 width.Set(CFX_CSSLengthUnit::Point, fValue);
487 return width.NonZero();
488 } else if (eType == CFX_CSSPrimitiveType::Enum) {
489 switch (pValue.As<CFX_CSSEnumValue>()->Value()) {
490 case CFX_CSSPropertyValue::Auto:
491 width.Set(CFX_CSSLengthUnit::Auto);
492 return true;
493 case CFX_CSSPropertyValue::None:
494 width.Set(CFX_CSSLengthUnit::None);
495 return true;
496 case CFX_CSSPropertyValue::Thin:
497 width.Set(CFX_CSSLengthUnit::Point, 2);
498 return true;
499 case CFX_CSSPropertyValue::Medium:
500 width.Set(CFX_CSSLengthUnit::Point, 3);
501 return true;
502 case CFX_CSSPropertyValue::Thick:
503 width.Set(CFX_CSSLengthUnit::Point, 4);
504 return true;
505 default:
506 return false;
507 }
508 }
509 return false;
510 }
511
ToFontSize(CFX_CSSPropertyValue eValue,float fCurFontSize)512 float CFX_CSSStyleSelector::ToFontSize(CFX_CSSPropertyValue eValue,
513 float fCurFontSize) {
514 switch (eValue) {
515 case CFX_CSSPropertyValue::XxSmall:
516 return m_fDefFontSize / 1.2f / 1.2f / 1.2f;
517 case CFX_CSSPropertyValue::XSmall:
518 return m_fDefFontSize / 1.2f / 1.2f;
519 case CFX_CSSPropertyValue::Small:
520 return m_fDefFontSize / 1.2f;
521 case CFX_CSSPropertyValue::Medium:
522 return m_fDefFontSize;
523 case CFX_CSSPropertyValue::Large:
524 return m_fDefFontSize * 1.2f;
525 case CFX_CSSPropertyValue::XLarge:
526 return m_fDefFontSize * 1.2f * 1.2f;
527 case CFX_CSSPropertyValue::XxLarge:
528 return m_fDefFontSize * 1.2f * 1.2f * 1.2f;
529 case CFX_CSSPropertyValue::Larger:
530 return fCurFontSize * 1.2f;
531 case CFX_CSSPropertyValue::Smaller:
532 return fCurFontSize / 1.2f;
533 default:
534 return fCurFontSize;
535 }
536 }
537
ToVerticalAlign(CFX_CSSPropertyValue eValue)538 CFX_CSSVerticalAlign CFX_CSSStyleSelector::ToVerticalAlign(
539 CFX_CSSPropertyValue eValue) {
540 switch (eValue) {
541 case CFX_CSSPropertyValue::Middle:
542 return CFX_CSSVerticalAlign::Middle;
543 case CFX_CSSPropertyValue::Bottom:
544 return CFX_CSSVerticalAlign::Bottom;
545 case CFX_CSSPropertyValue::Super:
546 return CFX_CSSVerticalAlign::Super;
547 case CFX_CSSPropertyValue::Sub:
548 return CFX_CSSVerticalAlign::Sub;
549 case CFX_CSSPropertyValue::Top:
550 return CFX_CSSVerticalAlign::Top;
551 case CFX_CSSPropertyValue::TextTop:
552 return CFX_CSSVerticalAlign::TextTop;
553 case CFX_CSSPropertyValue::TextBottom:
554 return CFX_CSSVerticalAlign::TextBottom;
555 case CFX_CSSPropertyValue::Baseline:
556 default:
557 return CFX_CSSVerticalAlign::Baseline;
558 }
559 }
560
ToTextDecoration(const RetainPtr<CFX_CSSValueList> & pValue)561 uint32_t CFX_CSSStyleSelector::ToTextDecoration(
562 const RetainPtr<CFX_CSSValueList>& pValue) {
563 uint32_t dwDecoration = 0;
564 for (int32_t i = pValue->CountValues() - 1; i >= 0; --i) {
565 const RetainPtr<CFX_CSSValue> pVal = pValue->GetValue(i);
566 if (pVal->GetType() != CFX_CSSPrimitiveType::Enum)
567 continue;
568
569 switch (pVal.As<CFX_CSSEnumValue>()->Value()) {
570 case CFX_CSSPropertyValue::Underline:
571 dwDecoration |= CFX_CSSTEXTDECORATION_Underline;
572 break;
573 case CFX_CSSPropertyValue::LineThrough:
574 dwDecoration |= CFX_CSSTEXTDECORATION_LineThrough;
575 break;
576 case CFX_CSSPropertyValue::Overline:
577 dwDecoration |= CFX_CSSTEXTDECORATION_Overline;
578 break;
579 case CFX_CSSPropertyValue::Blink:
580 dwDecoration |= CFX_CSSTEXTDECORATION_Blink;
581 break;
582 case CFX_CSSPropertyValue::Double:
583 dwDecoration |= CFX_CSSTEXTDECORATION_Double;
584 break;
585 default:
586 break;
587 }
588 }
589 return dwDecoration;
590 }
591
ToFontVariant(CFX_CSSPropertyValue eValue)592 CFX_CSSFontVariant CFX_CSSStyleSelector::ToFontVariant(
593 CFX_CSSPropertyValue eValue) {
594 return eValue == CFX_CSSPropertyValue::SmallCaps
595 ? CFX_CSSFontVariant::SmallCaps
596 : CFX_CSSFontVariant::Normal;
597 }
598