15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 1999 Antti Koivisto (koivisto@kde.org)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 2000 Simon Hausmann <hausmann@kde.org>
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2003, 2006, 2008, 2010 Apple Inc. All rights reserved.
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLFontElement.h"
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/CSSPropertyNames.h"
275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/CSSValueKeywords.h"
285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSValueList.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSValuePool.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/StylePropertySet.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/parser/HTMLParserIdioms.h"
33e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/text/StringBuilder.h"
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace WTF;
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames;
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
415d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)inline HTMLFontElement::HTMLFontElement(Document& document)
4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    : HTMLElement(fontTag, document)
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
465d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)DEFINE_NODE_FACTORY(HTMLFontElement)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// http://www.whatwg.org/specs/web-apps/current-work/multipage/rendering.html#fonts-and-colors
49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template <typename CharacterType>
50926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static bool parseFontSize(const CharacterType* characters, unsigned length, int& size)
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Step 1
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Step 2
55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const CharacterType* position = characters;
56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const CharacterType* end = characters + length;
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Step 3
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (position < end) {
6006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (!isHTMLSpace<CharacterType>(*position))
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ++position;
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Step 4
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (position == end)
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(position < end);
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Step 5
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    enum {
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RelativePlus,
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RelativeMinus,
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Absolute
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } mode;
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (*position) {
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case '+':
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        mode = RelativePlus;
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ++position;
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case '-':
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        mode = RelativeMinus;
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ++position;
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    default:
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        mode = Absolute;
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Step 6
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder digits;
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    digits.reserveCapacity(16);
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (position < end) {
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!isASCIIDigit(*position))
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        digits.append(*position++);
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Step 7
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (digits.isEmpty())
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Step 8
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    int value;
106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (digits.is8Bit())
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        value = charactersToIntStrict(digits.characters8(), digits.length());
109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    else
110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        value = charactersToIntStrict(digits.characters16(), digits.length());
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Step 9
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (mode == RelativePlus)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        value += 3;
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else if (mode == RelativeMinus)
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        value = 3 - value;
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Step 10
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (value > 7)
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        value = 7;
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Step 11
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (value < 1)
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        value = 1;
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size = value;
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static bool parseFontSize(const String& input, int& size)
131926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
132926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (input.isEmpty())
133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return false;
134926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
135926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (input.is8Bit())
136926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return parseFontSize(input.characters8(), input.length(), size);
137926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
138926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return parseFontSize(input.characters16(), input.length(), size);
139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)bool HTMLFontElement::cssValueFromFontSizeNumber(const String& s, CSSValueID& size)
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int num = 0;
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!parseFontSize(s, num))
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (num) {
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case 1:
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: The spec says that we're supposed to use CSSValueXxSmall here.
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size = CSSValueXSmall;
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
15202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    case 2:
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size = CSSValueSmall;
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
15502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    case 3:
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size = CSSValueMedium;
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
15802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    case 4:
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size = CSSValueLarge;
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
16102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    case 5:
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size = CSSValueXLarge;
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
16402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    case 6:
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size = CSSValueXxLarge;
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case 7:
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size = CSSValueWebkitXxxLarge;
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    default:
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT_NOT_REACHED();
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool HTMLFontElement::isPresentationAttribute(const QualifiedName& name) const
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (name == sizeAttr || name == colorAttr || name == faceAttr)
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return HTMLElement::isPresentationAttribute(name);
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
183926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void HTMLFontElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
185926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (name == sizeAttr) {
1865267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        CSSValueID size = CSSValueInvalid;
187926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (cssValueFromFontSizeNumber(value, size))
188926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            addPropertyToPresentationAttributeStyle(style, CSSPropertyFontSize, size);
189926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    } else if (name == colorAttr)
190926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        addHTMLColorToStyle(style, CSSPropertyColor, value);
191926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    else if (name == faceAttr) {
19209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (RefPtrWillBeRawPtr<CSSValueList> fontFaceValue = cssValuePool().createFontFaceValue(value))
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            style->setProperty(CSSProperty(CSSPropertyFontFamily, fontFaceValue.release()));
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else
195926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        HTMLElement::collectStyleForPresentationAttribute(name, value, style);
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
199