289 |
289 |
290 // color will only be changed when string contains a valid css color, making it |
290 // color will only be changed when string contains a valid css color, making it |
291 // possible to set up a default color. |
291 // possible to set up a default color. |
292 bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict) |
292 bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict) |
293 { |
293 { |
294 // First try creating a color specified by name, rgb() or "#" syntax. |
294 // First try creating a color specified by name, rgba(), rgb() or "#" syntax. |
295 if (parseColor(string, color, strict)) |
295 if (parseColor(string, color, strict)) |
296 return true; |
296 return true; |
297 |
297 |
298 CSSParser parser(true); |
298 CSSParser parser(true); |
299 RefPtr<CSSMutableStyleDeclaration> dummyStyleDeclaration = CSSMutableStyleDeclaration::create(); |
299 RefPtr<CSSMutableStyleDeclaration> dummyStyleDeclaration = CSSMutableStyleDeclaration::create(); |
1747 case CSSPropertyTextLineThrough: |
1747 case CSSPropertyTextLineThrough: |
1748 case CSSPropertyTextOverline: |
1748 case CSSPropertyTextOverline: |
1749 case CSSPropertyTextUnderline: |
1749 case CSSPropertyTextUnderline: |
1750 case CSSPropertyWebkitVariableDeclarationBlock: |
1750 case CSSPropertyWebkitVariableDeclarationBlock: |
1751 return false; |
1751 return false; |
1752 #if 0 // :HACK: |
1752 #if ENABLE(HAPTICS) |
1753 case CSSPropertyWebkitHapticTapType: |
1753 case CSSPropertyWebkitHapticTapType: |
1754 if (id == CSSValueButton || id == CSSValueLatchedButtonDown || id == CSSValueLatchedButtonUp || id == CSSValueLatchedButtonStuck |
1754 if (id == CSSValueButton || id == CSSValueLatchedButtonDown || id == CSSValueLatchedButtonUp || id == CSSValueLatchedButtonStuck |
1755 || id == CSSValueLink || id == CSSValueCheckedCheckbox || id == CSSValueUncheckedCheckbox) |
1755 || id == CSSValueLink || id == CSSValueCheckedCheckbox || id == CSSValueUncheckedCheckbox) |
1756 validPrimitive = true; |
1756 validPrimitive = true; |
1757 break; |
1757 break; |
3747 value = negative ? 0 : localValue; |
3747 value = negative ? 0 : localValue; |
3748 string = current; |
3748 string = current; |
3749 return true; |
3749 return true; |
3750 } |
3750 } |
3751 |
3751 |
|
3752 static inline bool isTenthAlpha(const UChar* string, const int length) |
|
3753 { |
|
3754 // "0.X" |
|
3755 if (length == 3 && string[0] == '0' && string[1] == '.' && isASCIIDigit(string[2])) |
|
3756 return true; |
|
3757 |
|
3758 // ".X" |
|
3759 if (length == 2 && string[0] == '.' && isASCIIDigit(string[1])) |
|
3760 return true; |
|
3761 |
|
3762 return false; |
|
3763 } |
|
3764 |
|
3765 static inline bool parseAlphaValue(const UChar*& string, const UChar* end, UChar terminator, int& value) |
|
3766 { |
|
3767 while (string != end && isCSSWhitespace(*string)) |
|
3768 string++; |
|
3769 |
|
3770 value = 0; |
|
3771 |
|
3772 int length = end - string; |
|
3773 if (length < 2) |
|
3774 return false; |
|
3775 |
|
3776 if (string[0] != '0' && string[0] != '1' && string[0] != '.') |
|
3777 return false; |
|
3778 |
|
3779 if (string[length - 1] != terminator) |
|
3780 return false; |
|
3781 |
|
3782 if (length == 2 && string[0] != '.') { |
|
3783 value = string[0] == '1' ? 255 : 0; |
|
3784 string = end; |
|
3785 return true; |
|
3786 } |
|
3787 |
|
3788 if (isTenthAlpha(string, length - 1)) { |
|
3789 static const int tenthAlphaValues[] = { 0, 25, 51, 76, 102, 127, 153, 179, 204, 230 }; |
|
3790 value = tenthAlphaValues[string[length - 2] - '0']; |
|
3791 string = end; |
|
3792 return true; |
|
3793 } |
|
3794 |
|
3795 Vector<char, 8> bytes(length + 1); |
|
3796 for (int i = 0; i < length; ++i) { |
|
3797 if (!isASCIIDigit(string[i]) && string[i] != '.' && string[i] != terminator) |
|
3798 return false; |
|
3799 bytes[i] = string[i]; |
|
3800 } |
|
3801 bytes[length] = '\0'; |
|
3802 char* foundTerminator; |
|
3803 double d = WTF::strtod(bytes.data(), &foundTerminator); |
|
3804 value = static_cast<int>(d * nextafter(256.0, 0.0)); |
|
3805 string += (foundTerminator - bytes.data()) + 1; |
|
3806 return *foundTerminator == terminator; |
|
3807 } |
|
3808 |
3752 bool CSSParser::parseColor(const String &name, RGBA32& rgb, bool strict) |
3809 bool CSSParser::parseColor(const String &name, RGBA32& rgb, bool strict) |
3753 { |
3810 { |
3754 const UChar* characters = name.characters(); |
3811 const UChar* characters = name.characters(); |
3755 unsigned length = name.length(); |
3812 unsigned length = name.length(); |
3756 |
3813 |
3760 return true; |
3817 return true; |
3761 } else { |
3818 } else { |
3762 if (Color::parseHexColor(characters, length, rgb)) |
3819 if (Color::parseHexColor(characters, length, rgb)) |
3763 return true; |
3820 return true; |
3764 } |
3821 } |
|
3822 } |
|
3823 |
|
3824 // Try rgba() syntax. |
|
3825 if (name.startsWith("rgba(")) { |
|
3826 const UChar* current = characters + 5; |
|
3827 const UChar* end = characters + length; |
|
3828 int red; |
|
3829 int green; |
|
3830 int blue; |
|
3831 int alpha; |
|
3832 if (!parseColorInt(current, end, ',', red)) |
|
3833 return false; |
|
3834 if (!parseColorInt(current, end, ',', green)) |
|
3835 return false; |
|
3836 if (!parseColorInt(current, end, ',', blue)) |
|
3837 return false; |
|
3838 if (!parseAlphaValue(current, end, ')', alpha)) |
|
3839 return false; |
|
3840 if (current != end) |
|
3841 return false; |
|
3842 rgb = makeRGBA(red, green, blue, alpha); |
|
3843 return true; |
3765 } |
3844 } |
3766 |
3845 |
3767 // Try rgb() syntax. |
3846 // Try rgb() syntax. |
3768 if (name.startsWith("rgb(")) { |
3847 if (name.startsWith("rgb(")) { |
3769 const UChar* current = characters + 4; |
3848 const UChar* current = characters + 4; |