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 "core/html/HTMLFontElement.h" 25 26#include "CSSPropertyNames.h" 27#include "CSSValueKeywords.h" 28#include "HTMLNames.h" 29#include "core/css/CSSValueList.h" 30#include "core/css/CSSValuePool.h" 31#include "core/css/StylePropertySet.h" 32#include "core/html/parser/HTMLParserIdioms.h" 33#include "wtf/text/StringBuilder.h" 34 35using namespace WTF; 36 37namespace WebCore { 38 39using namespace HTMLNames; 40 41HTMLFontElement::HTMLFontElement(Document& document) 42 : HTMLElement(fontTag, document) 43{ 44 ScriptWrappable::init(this); 45} 46 47PassRefPtr<HTMLFontElement> HTMLFontElement::create(Document& document) 48{ 49 return adoptRef(new HTMLFontElement(document)); 50} 51 52// http://www.whatwg.org/specs/web-apps/current-work/multipage/rendering.html#fonts-and-colors 53template <typename CharacterType> 54static bool parseFontSize(const CharacterType* characters, unsigned length, int& size) 55{ 56 57 // Step 1 58 // Step 2 59 const CharacterType* position = characters; 60 const CharacterType* end = characters + length; 61 62 // Step 3 63 while (position < end) { 64 if (!isHTMLSpace<CharacterType>(*position)) 65 break; 66 ++position; 67 } 68 69 // Step 4 70 if (position == end) 71 return false; 72 ASSERT(position < end); 73 74 // Step 5 75 enum { 76 RelativePlus, 77 RelativeMinus, 78 Absolute 79 } mode; 80 81 switch (*position) { 82 case '+': 83 mode = RelativePlus; 84 ++position; 85 break; 86 case '-': 87 mode = RelativeMinus; 88 ++position; 89 break; 90 default: 91 mode = Absolute; 92 break; 93 } 94 95 // Step 6 96 StringBuilder digits; 97 digits.reserveCapacity(16); 98 while (position < end) { 99 if (!isASCIIDigit(*position)) 100 break; 101 digits.append(*position++); 102 } 103 104 // Step 7 105 if (digits.isEmpty()) 106 return false; 107 108 // Step 8 109 int value; 110 111 if (digits.is8Bit()) 112 value = charactersToIntStrict(digits.characters8(), digits.length()); 113 else 114 value = charactersToIntStrict(digits.characters16(), digits.length()); 115 116 // Step 9 117 if (mode == RelativePlus) 118 value += 3; 119 else if (mode == RelativeMinus) 120 value = 3 - value; 121 122 // Step 10 123 if (value > 7) 124 value = 7; 125 126 // Step 11 127 if (value < 1) 128 value = 1; 129 130 size = value; 131 return true; 132} 133 134static bool parseFontSize(const String& input, int& size) 135{ 136 if (input.isEmpty()) 137 return false; 138 139 if (input.is8Bit()) 140 return parseFontSize(input.characters8(), input.length(), size); 141 142 return parseFontSize(input.characters16(), input.length(), size); 143} 144 145bool HTMLFontElement::cssValueFromFontSizeNumber(const String& s, CSSValueID& size) 146{ 147 int num = 0; 148 if (!parseFontSize(s, num)) 149 return false; 150 151 switch (num) { 152 case 1: 153 // FIXME: The spec says that we're supposed to use CSSValueXxSmall here. 154 size = CSSValueXSmall; 155 break; 156 case 2: 157 size = CSSValueSmall; 158 break; 159 case 3: 160 size = CSSValueMedium; 161 break; 162 case 4: 163 size = CSSValueLarge; 164 break; 165 case 5: 166 size = CSSValueXLarge; 167 break; 168 case 6: 169 size = CSSValueXxLarge; 170 break; 171 case 7: 172 size = CSSValueWebkitXxxLarge; 173 break; 174 default: 175 ASSERT_NOT_REACHED(); 176 } 177 return true; 178} 179 180bool HTMLFontElement::isPresentationAttribute(const QualifiedName& name) const 181{ 182 if (name == sizeAttr || name == colorAttr || name == faceAttr) 183 return true; 184 return HTMLElement::isPresentationAttribute(name); 185} 186 187void HTMLFontElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style) 188{ 189 if (name == sizeAttr) { 190 CSSValueID size = CSSValueInvalid; 191 if (cssValueFromFontSizeNumber(value, size)) 192 addPropertyToPresentationAttributeStyle(style, CSSPropertyFontSize, size); 193 } else if (name == colorAttr) 194 addHTMLColorToStyle(style, CSSPropertyColor, value); 195 else if (name == faceAttr) { 196 if (RefPtr<CSSValueList> fontFaceValue = cssValuePool().createFontFaceValue(value)) 197 style->setProperty(CSSProperty(CSSPropertyFontFamily, fontFaceValue.release())); 198 } else 199 HTMLElement::collectStyleForPresentationAttribute(name, value, style); 200} 201 202} 203