/* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2001 Dirk Mueller ( mueller@kde.org ) * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "config.h" #include "Length.h" #include "PlatformString.h" #include #include #include #include using namespace WTF; namespace WebCore { static Length parseLength(const UChar* data, unsigned length) { if (length == 0) return Length(1, Relative); unsigned i = 0; while (i < length && isSpaceOrNewline(data[i])) ++i; if (i < length && (data[i] == '+' || data[i] == '-')) ++i; while (i < length && isASCIIDigit(data[i])) ++i; unsigned intLength = i; while (i < length && (isASCIIDigit(data[i]) || data[i] == '.')) ++i; unsigned doubleLength = i; // IE quirk: Skip whitespace between the number and the % character (20 % => 20%). while (i < length && isSpaceOrNewline(data[i])) ++i; bool ok; UChar next = (i < length) ? data[i] : ' '; if (next == '%') { // IE quirk: accept decimal fractions for percentages. double r = charactersToDouble(data, doubleLength, &ok); if (ok) return Length(r, Percent); return Length(1, Relative); } int r = charactersToIntStrict(data, intLength, &ok); if (next == '*') { if (ok) return Length(r, Relative); return Length(1, Relative); } if (ok) return Length(r, Fixed); return Length(0, Relative); } static int countCharacter(const UChar* data, unsigned length, UChar character) { int count = 0; for (int i = 0; i < static_cast(length); ++i) count += data[i] == character; return count; } PassOwnArrayPtr newCoordsArray(const String& string, int& len) { unsigned length = string.length(); const UChar* data = string.characters(); StringBuffer spacified(length); for (unsigned i = 0; i < length; i++) { UChar cc = data[i]; if (cc > '9' || (cc < '0' && cc != '-' && cc != '*' && cc != '.')) spacified[i] = ' '; else spacified[i] = cc; } RefPtr str = StringImpl::adopt(spacified); str = str->simplifyWhiteSpace(); len = countCharacter(str->characters(), str->length(), ' ') + 1; OwnArrayPtr r = adoptArrayPtr(new Length[len]); int i = 0; unsigned pos = 0; size_t pos2; while ((pos2 = str->find(' ', pos)) != notFound) { r[i++] = parseLength(str->characters() + pos, pos2 - pos); pos = pos2+1; } r[i] = parseLength(str->characters() + pos, str->length() - pos); ASSERT(i == len - 1); return r.release(); } PassOwnArrayPtr newLengthArray(const String& string, int& len) { RefPtr str = string.impl()->simplifyWhiteSpace(); if (!str->length()) { len = 1; return nullptr; } len = countCharacter(str->characters(), str->length(), ',') + 1; OwnArrayPtr r = adoptArrayPtr(new Length[len]); int i = 0; unsigned pos = 0; size_t pos2; while ((pos2 = str->find(',', pos)) != notFound) { r[i++] = parseLength(str->characters() + pos, pos2 - pos); pos = pos2+1; } ASSERT(i == len - 1); // IE Quirk: If the last comma is the last char skip it and reduce len by one. if (str->length()-pos > 0) r[i] = parseLength(str->characters() + pos, str->length() - pos); else len--; return r.release(); } } // namespace WebCore