WebCore/css/CSSParser.cpp
changeset 2 303757a437d3
parent 0 4f2f89ce4247
--- 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<char, 8> 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<int>(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);