1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 1999 Antti Koivisto (koivisto (at) kde.org) 4 * (C) 2000 Simon Hausmann <hausmann (at) 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 "Attribute.h" 27 #include "CSSPropertyNames.h" 28 #include "CSSValueKeywords.h" 29 #include "HTMLNames.h" 30 #include "HTMLParserIdioms.h" 31 32 using namespace WTF; 33 34 namespace WebCore { 35 36 using namespace HTMLNames; 37 38 HTMLFontElement::HTMLFontElement(const QualifiedName& tagName, Document* document) 39 : HTMLElement(tagName, document) 40 { 41 ASSERT(hasTagName(fontTag)); 42 } 43 44 PassRefPtr<HTMLFontElement> HTMLFontElement::create(const QualifiedName& tagName, Document* document) 45 { 46 return adoptRef(new HTMLFontElement(tagName, document)); 47 } 48 49 // http://www.whatwg.org/specs/web-apps/current-work/multipage/rendering.html#fonts-and-colors 50 static bool parseFontSize(const String& input, int& size) 51 { 52 53 // Step 1 54 // Step 2 55 const UChar* position = input.characters(); 56 const UChar* end = position + input.length(); 57 58 // Step 3 59 while (position < end) { 60 if (!isHTMLSpace(*position)) 61 break; 62 ++position; 63 } 64 65 // Step 4 66 if (position == end) 67 return false; 68 ASSERT(position < end); 69 70 // Step 5 71 enum { 72 RelativePlus, 73 RelativeMinus, 74 Absolute 75 } mode; 76 77 switch (*position) { 78 case '+': 79 mode = RelativePlus; 80 ++position; 81 break; 82 case '-': 83 mode = RelativeMinus; 84 ++position; 85 break; 86 default: 87 mode = Absolute; 88 break; 89 } 90 91 // Step 6 92 Vector<UChar, 16> digits; 93 while (position < end) { 94 if (!isASCIIDigit(*position)) 95 break; 96 digits.append(*position++); 97 } 98 99 // Step 7 100 if (digits.isEmpty()) 101 return false; 102 103 // Step 8 104 int value = charactersToIntStrict(digits.data(), digits.size()); 105 106 // Step 9 107 if (mode == RelativePlus) 108 value += 3; 109 else if (mode == RelativeMinus) 110 value = 3 - value; 111 112 // Step 10 113 if (value > 7) 114 value = 7; 115 116 // Step 11 117 if (value < 1) 118 value = 1; 119 120 size = value; 121 return true; 122 } 123 124 bool HTMLFontElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const 125 { 126 if (attrName == sizeAttr || 127 attrName == colorAttr || 128 attrName == faceAttr) { 129 result = eUniversal; 130 return false; 131 } 132 133 return HTMLElement::mapToEntry(attrName, result); 134 } 135 136 bool HTMLFontElement::cssValueFromFontSizeNumber(const String& s, int& size) 137 { 138 int num = 0; 139 if (!parseFontSize(s, num)) 140 return false; 141 142 switch (num) { 143 case 1: 144 // FIXME: The spec says that we're supposed to use CSSValueXxSmall here. 145 size = CSSValueXSmall; 146 break; 147 case 2: 148 size = CSSValueSmall; 149 break; 150 case 3: 151 size = CSSValueMedium; 152 break; 153 case 4: 154 size = CSSValueLarge; 155 break; 156 case 5: 157 size = CSSValueXLarge; 158 break; 159 case 6: 160 size = CSSValueXxLarge; 161 break; 162 case 7: 163 size = CSSValueWebkitXxxLarge; 164 break; 165 default: 166 ASSERT_NOT_REACHED(); 167 } 168 return true; 169 } 170 171 void HTMLFontElement::parseMappedAttribute(Attribute* attr) 172 { 173 if (attr->name() == sizeAttr) { 174 int size = 0; 175 if (cssValueFromFontSizeNumber(attr->value(), size)) 176 addCSSProperty(attr, CSSPropertyFontSize, size); 177 } else if (attr->name() == colorAttr) { 178 addCSSColor(attr, CSSPropertyColor, attr->value()); 179 } else if (attr->name() == faceAttr) { 180 addCSSProperty(attr, CSSPropertyFontFamily, attr->value()); 181 } else 182 HTMLElement::parseMappedAttribute(attr); 183 } 184 185 } 186