1 | /* |
2 | * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 | * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 | * (C) 2000 Simon Hausmann <hausmann@kde.org> |
5 | * Copyright (C) 2003, 2006, 2008, 2010 Apple Inc. All rights reserved. |
6 | * |
7 | * This library is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. |
11 | * |
12 | * This library is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Library General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU Library General Public License |
18 | * along with this library; see the file COPYING.LIB. If not, write to |
19 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 | * Boston, MA 02110-1301, USA. |
21 | */ |
22 | |
23 | #include "config.h" |
24 | #include "HTMLFontElement.h" |
25 | |
26 | #include "CSSPropertyNames.h" |
27 | #include "CSSStyleSheet.h" |
28 | #include "CSSValueKeywords.h" |
29 | #include "CSSValueList.h" |
30 | #include "CSSValuePool.h" |
31 | #include "HTMLNames.h" |
32 | #include "HTMLParserIdioms.h" |
33 | #include "StyleProperties.h" |
34 | #include <wtf/IsoMallocInlines.h> |
35 | #include <wtf/text/StringBuilder.h> |
36 | |
37 | namespace WebCore { |
38 | |
39 | WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLFontElement); |
40 | |
41 | using namespace HTMLNames; |
42 | |
43 | HTMLFontElement::HTMLFontElement(const QualifiedName& tagName, Document& document) |
44 | : HTMLElement(tagName, document) |
45 | { |
46 | ASSERT(hasTagName(fontTag)); |
47 | } |
48 | |
49 | Ref<HTMLFontElement> HTMLFontElement::create(const QualifiedName& tagName, Document& document) |
50 | { |
51 | return adoptRef(*new HTMLFontElement(tagName, document)); |
52 | } |
53 | |
54 | // http://www.whatwg.org/specs/web-apps/current-work/multipage/rendering.html#fonts-and-colors |
55 | template <typename CharacterType> |
56 | static bool parseFontSize(const CharacterType* characters, unsigned length, int& size) |
57 | { |
58 | |
59 | // Step 1 |
60 | // Step 2 |
61 | const CharacterType* position = characters; |
62 | const CharacterType* end = characters + length; |
63 | |
64 | // Step 3 |
65 | while (position < end) { |
66 | if (!isHTMLSpace(*position)) |
67 | break; |
68 | ++position; |
69 | } |
70 | |
71 | // Step 4 |
72 | if (position == end) |
73 | return false; |
74 | ASSERT_WITH_SECURITY_IMPLICATION(position < end); |
75 | |
76 | // Step 5 |
77 | enum { |
78 | RelativePlus, |
79 | RelativeMinus, |
80 | Absolute |
81 | } mode; |
82 | |
83 | switch (*position) { |
84 | case '+': |
85 | mode = RelativePlus; |
86 | ++position; |
87 | break; |
88 | case '-': |
89 | mode = RelativeMinus; |
90 | ++position; |
91 | break; |
92 | default: |
93 | mode = Absolute; |
94 | break; |
95 | } |
96 | |
97 | // Step 6 |
98 | StringBuilder digits; |
99 | digits.reserveCapacity(16); |
100 | while (position < end) { |
101 | if (!isASCIIDigit(*position)) |
102 | break; |
103 | digits.append(*position++); |
104 | } |
105 | |
106 | // Step 7 |
107 | if (digits.isEmpty()) |
108 | return false; |
109 | |
110 | // Step 8 |
111 | int value; |
112 | |
113 | if (digits.is8Bit()) |
114 | value = charactersToIntStrict(digits.characters8(), digits.length()); |
115 | else |
116 | value = charactersToIntStrict(digits.characters16(), digits.length()); |
117 | |
118 | // Step 9 |
119 | if (mode == RelativePlus) |
120 | value += 3; |
121 | else if (mode == RelativeMinus) |
122 | value = 3 - value; |
123 | |
124 | // Step 10 |
125 | if (value > 7) |
126 | value = 7; |
127 | |
128 | // Step 11 |
129 | if (value < 1) |
130 | value = 1; |
131 | |
132 | size = value; |
133 | return true; |
134 | } |
135 | |
136 | static bool parseFontSize(const String& input, int& size) |
137 | { |
138 | if (input.isEmpty()) |
139 | return false; |
140 | |
141 | if (input.is8Bit()) |
142 | return parseFontSize(input.characters8(), input.length(), size); |
143 | |
144 | return parseFontSize(input.characters16(), input.length(), size); |
145 | } |
146 | |
147 | bool HTMLFontElement::cssValueFromFontSizeNumber(const String& s, CSSValueID& size) |
148 | { |
149 | int num = 0; |
150 | if (!parseFontSize(s, num)) |
151 | return false; |
152 | |
153 | switch (num) { |
154 | case 1: |
155 | // FIXME: The spec says that we're supposed to use CSSValueXxSmall here. |
156 | size = CSSValueXSmall; |
157 | break; |
158 | case 2: |
159 | size = CSSValueSmall; |
160 | break; |
161 | case 3: |
162 | size = CSSValueMedium; |
163 | break; |
164 | case 4: |
165 | size = CSSValueLarge; |
166 | break; |
167 | case 5: |
168 | size = CSSValueXLarge; |
169 | break; |
170 | case 6: |
171 | size = CSSValueXxLarge; |
172 | break; |
173 | case 7: |
174 | size = CSSValueWebkitXxxLarge; |
175 | break; |
176 | default: |
177 | ASSERT_NOT_REACHED(); |
178 | } |
179 | return true; |
180 | } |
181 | |
182 | bool HTMLFontElement::isPresentationAttribute(const QualifiedName& name) const |
183 | { |
184 | if (name == sizeAttr || name == colorAttr || name == faceAttr) |
185 | return true; |
186 | return HTMLElement::isPresentationAttribute(name); |
187 | } |
188 | |
189 | void HTMLFontElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style) |
190 | { |
191 | if (name == sizeAttr) { |
192 | CSSValueID size = CSSValueInvalid; |
193 | if (cssValueFromFontSizeNumber(value, size)) |
194 | addPropertyToPresentationAttributeStyle(style, CSSPropertyFontSize, size); |
195 | } else if (name == colorAttr) |
196 | addHTMLColorToStyle(style, CSSPropertyColor, value); |
197 | else if (name == faceAttr) { |
198 | if (auto fontFaceValue = CSSValuePool::singleton().createFontFaceValue(value)) |
199 | style.setProperty(CSSProperty(CSSPropertyFontFamily, WTFMove(fontFaceValue))); |
200 | } else |
201 | HTMLElement::collectStyleForPresentationAttribute(name, value, style); |
202 | } |
203 | |
204 | } |
205 | |