diff -r 4f2f89ce4247 -r 303757a437d3 WebCore/css/CSSParser.cpp --- a/WebCore/css/CSSParser.cpp Fri Sep 17 09:02:29 2010 +0300 +++ b/WebCore/css/CSSParser.cpp Mon Oct 04 01:32:07 2010 +0300 @@ -291,7 +291,7 @@ // possible to set up a default color. bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict) { - // First try creating a color specified by name, rgb() or "#" syntax. + // First try creating a color specified by name, rgba(), rgb() or "#" syntax. if (parseColor(string, color, strict)) return true; @@ -1749,7 +1749,7 @@ case CSSPropertyTextUnderline: case CSSPropertyWebkitVariableDeclarationBlock: return false; -#if 0 // :HACK: +#if ENABLE(HAPTICS) case CSSPropertyWebkitHapticTapType: if (id == CSSValueButton || id == CSSValueLatchedButtonDown || id == CSSValueLatchedButtonUp || id == CSSValueLatchedButtonStuck || id == CSSValueLink || id == CSSValueCheckedCheckbox || id == CSSValueUncheckedCheckbox) @@ -3749,6 +3749,63 @@ return true; } +static inline bool isTenthAlpha(const UChar* string, const int length) +{ + // "0.X" + if (length == 3 && string[0] == '0' && string[1] == '.' && isASCIIDigit(string[2])) + return true; + + // ".X" + if (length == 2 && string[0] == '.' && isASCIIDigit(string[1])) + return true; + + return false; +} + +static inline bool parseAlphaValue(const UChar*& string, const UChar* end, UChar terminator, int& value) +{ + while (string != end && isCSSWhitespace(*string)) + string++; + + value = 0; + + int length = end - string; + if (length < 2) + return false; + + if (string[0] != '0' && string[0] != '1' && string[0] != '.') + return false; + + if (string[length - 1] != terminator) + return false; + + if (length == 2 && string[0] != '.') { + value = string[0] == '1' ? 255 : 0; + string = end; + return true; + } + + if (isTenthAlpha(string, length - 1)) { + static const int tenthAlphaValues[] = { 0, 25, 51, 76, 102, 127, 153, 179, 204, 230 }; + value = tenthAlphaValues[string[length - 2] - '0']; + string = end; + return true; + } + + Vector bytes(length + 1); + for (int i = 0; i < length; ++i) { + if (!isASCIIDigit(string[i]) && string[i] != '.' && string[i] != terminator) + return false; + bytes[i] = string[i]; + } + bytes[length] = '\0'; + char* foundTerminator; + double d = WTF::strtod(bytes.data(), &foundTerminator); + value = static_cast(d * nextafter(256.0, 0.0)); + string += (foundTerminator - bytes.data()) + 1; + return *foundTerminator == terminator; +} + bool CSSParser::parseColor(const String &name, RGBA32& rgb, bool strict) { const UChar* characters = name.characters(); @@ -3764,6 +3821,28 @@ } } + // Try rgba() syntax. + if (name.startsWith("rgba(")) { + const UChar* current = characters + 5; + const UChar* end = characters + length; + int red; + int green; + int blue; + int alpha; + if (!parseColorInt(current, end, ',', red)) + return false; + if (!parseColorInt(current, end, ',', green)) + return false; + if (!parseColorInt(current, end, ',', blue)) + return false; + if (!parseAlphaValue(current, end, ')', alpha)) + return false; + if (current != end) + return false; + rgb = makeRGBA(red, green, blue, alpha); + return true; + } + // Try rgb() syntax. if (name.startsWith("rgb(")) { const UChar* current = characters + 4; @@ -3782,6 +3861,7 @@ rgb = makeRGB(red, green, blue); return true; } + // Try named colors. Color tc; tc.setNamedColor(name);