1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 1999 Antti Koivisto (koivisto (at) kde.org) 4 * (C) 2001 Dirk Mueller ( mueller (at) kde.org ) 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 6 * Copyright (C) 2006 Andrew Wellington (proton (at) wiretapped.net) 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Library General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU Library General Public License 19 * along with this library; see the file COPYING.LIB. If not, write to 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 * Boston, MA 02110-1301, USA. 22 * 23 */ 24 25 #include "config.h" 26 #include "Length.h" 27 28 #include "PlatformString.h" 29 #include "StringBuffer.h" 30 #include <wtf/ASCIICType.h> 31 #include <wtf/Assertions.h> 32 33 using namespace WTF; 34 35 namespace WebCore { 36 37 static Length parseLength(const UChar* data, unsigned length) 38 { 39 if (length == 0) 40 return Length(1, Relative); 41 42 unsigned i = 0; 43 while (i < length && isSpaceOrNewline(data[i])) 44 ++i; 45 if (i < length && (data[i] == '+' || data[i] == '-')) 46 ++i; 47 while (i < length && isASCIIDigit(data[i])) 48 ++i; 49 unsigned intLength = i; 50 while (i < length && (isASCIIDigit(data[i]) || data[i] == '.')) 51 ++i; 52 unsigned doubleLength = i; 53 54 // IE quirk: Skip whitespace between the number and the % character (20 % => 20%). 55 while (i < length && isSpaceOrNewline(data[i])) 56 ++i; 57 58 bool ok; 59 UChar next = (i < length) ? data[i] : ' '; 60 if (next == '%') { 61 // IE quirk: accept decimal fractions for percentages. 62 double r = charactersToDouble(data, doubleLength, &ok); 63 if (ok) 64 return Length(r, Percent); 65 return Length(1, Relative); 66 } 67 int r = charactersToIntStrict(data, intLength, &ok); 68 if (next == '*') { 69 if (ok) 70 return Length(r, Relative); 71 return Length(1, Relative); 72 } 73 if (ok) 74 return Length(r, Fixed); 75 return Length(0, Relative); 76 } 77 78 static int countCharacter(const UChar* data, unsigned length, UChar character) 79 { 80 int count = 0; 81 for (int i = 0; i < static_cast<int>(length); ++i) 82 count += data[i] == character; 83 return count; 84 } 85 86 Length* newCoordsArray(const String& string, int& len) 87 { 88 unsigned length = string.length(); 89 const UChar* data = string.characters(); 90 StringBuffer spacified(length); 91 for (unsigned i = 0; i < length; i++) { 92 UChar cc = data[i]; 93 if (cc > '9' || (cc < '0' && cc != '-' && cc != '*' && cc != '.')) 94 spacified[i] = ' '; 95 else 96 spacified[i] = cc; 97 } 98 RefPtr<StringImpl> str = StringImpl::adopt(spacified); 99 100 str = str->simplifyWhiteSpace(); 101 102 len = countCharacter(str->characters(), str->length(), ' ') + 1; 103 Length* r = new Length[len]; 104 105 int i = 0; 106 int pos = 0; 107 int pos2; 108 109 while ((pos2 = str->find(' ', pos)) != -1) { 110 r[i++] = parseLength(str->characters() + pos, pos2 - pos); 111 pos = pos2+1; 112 } 113 r[i] = parseLength(str->characters() + pos, str->length() - pos); 114 115 ASSERT(i == len - 1); 116 117 return r; 118 } 119 120 Length* newLengthArray(const String& string, int& len) 121 { 122 RefPtr<StringImpl> str = string.impl()->simplifyWhiteSpace(); 123 if (!str->length()) { 124 len = 1; 125 return 0; 126 } 127 128 len = countCharacter(str->characters(), str->length(), ',') + 1; 129 Length* r = new Length[len]; 130 131 int i = 0; 132 int pos = 0; 133 int pos2; 134 135 while ((pos2 = str->find(',', pos)) != -1) { 136 r[i++] = parseLength(str->characters() + pos, pos2 - pos); 137 pos = pos2+1; 138 } 139 140 ASSERT(i == len - 1); 141 142 // IE Quirk: If the last comma is the last char skip it and reduce len by one. 143 if (str->length()-pos > 0) 144 r[i] = parseLength(str->characters() + pos, str->length() - pos); 145 else 146 len--; 147 148 return r; 149 } 150 151 } // namespace WebCore 152