1 // Copyright 2018 The PDFium Authors
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_cssdata.h"
8
9 #include <algorithm>
10 #include <utility>
11
12 #include "core/fxcrt/css/cfx_cssstyleselector.h"
13 #include "core/fxcrt/css/cfx_cssvaluelistparser.h"
14 #include "core/fxcrt/fx_codepage.h"
15 #include "core/fxcrt/fx_extension.h"
16
17 namespace {
18
19 #undef CSS_PROP____
20 #define CSS_PROP____(a, b, c, d) {CFX_CSSProperty::a, c, d},
21 const CFX_CSSData::Property propertyTable[] = {
22 #include "core/fxcrt/css/properties.inc"
23 };
24 #undef CSS_PROP____
25
26 #undef CSS_PROP_VALUE____
27 #define CSS_PROP_VALUE____(a, b, c) {CFX_CSSPropertyValue::a, c},
28 const CFX_CSSData::PropertyValue propertyValueTable[] = {
29 #include "core/fxcrt/css/property_values.inc"
30 };
31 #undef CSS_PROP_VALUE____
32
33 const CFX_CSSData::LengthUnit lengthUnitTable[] = {
34 {L"cm", CFX_CSSNumberValue::Unit::kCentiMeters},
35 {L"em", CFX_CSSNumberValue::Unit::kEMS},
36 {L"ex", CFX_CSSNumberValue::Unit::kEXS},
37 {L"in", CFX_CSSNumberValue::Unit::kInches},
38 {L"mm", CFX_CSSNumberValue::Unit::kMilliMeters},
39 {L"pc", CFX_CSSNumberValue::Unit::kPicas},
40 {L"pt", CFX_CSSNumberValue::Unit::kPoints},
41 {L"px", CFX_CSSNumberValue::Unit::kPixels},
42 };
43
44 // 16 colours from CSS 2.0 + alternate spelling of grey/gray.
45 const CFX_CSSData::Color colorTable[] = {
46 {L"aqua", 0xff00ffff}, {L"black", 0xff000000}, {L"blue", 0xff0000ff},
47 {L"fuchsia", 0xffff00ff}, {L"gray", 0xff808080}, {L"green", 0xff008000},
48 {L"grey", 0xff808080}, {L"lime", 0xff00ff00}, {L"maroon", 0xff800000},
49 {L"navy", 0xff000080}, {L"olive", 0xff808000}, {L"orange", 0xffffa500},
50 {L"purple", 0xff800080}, {L"red", 0xffff0000}, {L"silver", 0xffc0c0c0},
51 {L"teal", 0xff008080}, {L"white", 0xffffffff}, {L"yellow", 0xffffff00},
52 };
53
54 } // namespace
55
GetPropertyByName(WideStringView name)56 const CFX_CSSData::Property* CFX_CSSData::GetPropertyByName(
57 WideStringView name) {
58 if (name.IsEmpty())
59 return nullptr;
60
61 uint32_t hash = FX_HashCode_GetLoweredW(name);
62 auto* result =
63 std::lower_bound(std::begin(propertyTable), std::end(propertyTable), hash,
64 [](const CFX_CSSData::Property& iter,
65 const uint32_t& hash) { return iter.dwHash < hash; });
66
67 if (result != std::end(propertyTable) && result->dwHash == hash)
68 return result;
69 return nullptr;
70 }
71
GetPropertyByEnum(CFX_CSSProperty property)72 const CFX_CSSData::Property* CFX_CSSData::GetPropertyByEnum(
73 CFX_CSSProperty property) {
74 return &propertyTable[static_cast<uint8_t>(property)];
75 }
76
GetPropertyValueByName(WideStringView wsName)77 const CFX_CSSData::PropertyValue* CFX_CSSData::GetPropertyValueByName(
78 WideStringView wsName) {
79 if (wsName.IsEmpty())
80 return nullptr;
81
82 uint32_t hash = FX_HashCode_GetLoweredW(wsName);
83 auto* result = std::lower_bound(
84 std::begin(propertyValueTable), std::end(propertyValueTable), hash,
85 [](const PropertyValue& iter, const uint32_t& hash) {
86 return iter.dwHash < hash;
87 });
88
89 if (result != std::end(propertyValueTable) && result->dwHash == hash)
90 return result;
91 return nullptr;
92 }
93
GetLengthUnitByName(WideStringView wsName)94 const CFX_CSSData::LengthUnit* CFX_CSSData::GetLengthUnitByName(
95 WideStringView wsName) {
96 if (wsName.IsEmpty() || wsName.GetLength() != 2)
97 return nullptr;
98
99 WideString lowerName = WideString(wsName);
100 lowerName.MakeLower();
101
102 for (auto* iter = std::begin(lengthUnitTable);
103 iter != std::end(lengthUnitTable); ++iter) {
104 if (lowerName == iter->value)
105 return iter;
106 }
107
108 return nullptr;
109 }
110
GetColorByName(WideStringView wsName)111 const CFX_CSSData::Color* CFX_CSSData::GetColorByName(WideStringView wsName) {
112 if (wsName.IsEmpty())
113 return nullptr;
114
115 WideString lowerName = WideString(wsName);
116 lowerName.MakeLower();
117
118 for (auto* iter = std::begin(colorTable); iter != std::end(colorTable);
119 ++iter) {
120 if (lowerName == iter->name)
121 return iter;
122 }
123 return nullptr;
124 }
125