2010-10-14 Andreas Kling <kling@webkit.org>
authorandreas.kling@nokia.com <andreas.kling@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Oct 2010 10:47:24 +0000 (10:47 +0000)
committerandreas.kling@nokia.com <andreas.kling@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Oct 2010 10:47:24 +0000 (10:47 +0000)
        Reviewed by Darin Adler.

        Canvas: "currentColor" should inherit the canvas element's color
        https://bugs.webkit.org/show_bug.cgi?id=40273

        Add support for "currentColor" in CanvasRenderingContext2D APIs.
        If the canvas is in-document, "currentColor" is replaced by canvas.style.color,
        otherwise we use fully opaque black.

        For gradient addColorStop(), "currentColor" always means fully opaque black.

        Spec link:
        http://www.whatwg.org/specs/web-apps/current-work/#2dcontext

        Test: fast/canvas/canvas-currentColor.html

        * html/canvas/CanvasGradient.cpp:
        (WebCore::CanvasGradient::addColorStop):
        * html/canvas/CanvasRenderingContext2D.cpp:
        (WebCore::CanvasRenderingContext2D::setStrokeStyle):
        (WebCore::CanvasRenderingContext2D::setFillStyle):
        (WebCore::CanvasRenderingContext2D::setShadowColor):
        (WebCore::CanvasRenderingContext2D::setShadow):
        * html/canvas/CanvasStyle.cpp:
        (WebCore::parseColor):
        (WebCore::currentColor):
        (WebCore::parseColorOrCurrentColor):
        (WebCore::CanvasStyle::CanvasStyle):
        (WebCore::CanvasStyle::createFromString):
        (WebCore::CanvasStyle::createFromStringWithOverrideAlpha):
        (WebCore::CanvasStyle::isEquivalentColor):
        (WebCore::CanvasStyle::applyStrokeColor):
        (WebCore::CanvasStyle::applyFillColor):
        * html/canvas/CanvasStyle.h:
        (WebCore::CanvasStyle::isCurrentColor):
        (WebCore::CanvasStyle::hasOverrideAlpha):
        (WebCore::CanvasStyle::overrideAlpha):
2010-10-14  Andreas Kling  <kling@webkit.org>

        Reviewed by Darin Adler.

        Canvas: "currentColor" should inherit the canvas element's color
        https://bugs.webkit.org/show_bug.cgi?id=40273

        Added test to verify support for "currentColor" value in CanvasRenderingContext2D.

        Also unskipped 3 tests which now pass:
        - canvas/philip/tests/2d.fillStyle.parse.current.basic.html
        - canvas/philip/tests/2d.fillStyle.parse.current.changed.html
        - canvas/philip/tests/2d.fillStyle.parse.current.removed.html

        Spec link:
        http://www.whatwg.org/specs/web-apps/current-work/#2dcontext

        * fast/canvas/canvas-currentColor-expected.txt: Added.
        * fast/canvas/canvas-currentColor.html: Added.
        * fast/canvas/script-tests/canvas-currentColor.js: Added.
        (attachCanvasToDocument):
        (tryLinearGradientColor):
        (tryRadialGradientColor):
        * platform/gtk/Skipped:
        * platform/mac/Skipped:
        * platform/qt/Skipped:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@69755 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/canvas/canvas-currentColor-expected.txt [new file with mode: 0644]
LayoutTests/fast/canvas/canvas-currentColor.html [new file with mode: 0644]
LayoutTests/fast/canvas/script-tests/canvas-currentColor.js [new file with mode: 0644]
LayoutTests/platform/gtk/Skipped
LayoutTests/platform/mac/Skipped
LayoutTests/platform/qt/Skipped
WebCore/ChangeLog
WebCore/html/canvas/CanvasGradient.cpp
WebCore/html/canvas/CanvasRenderingContext2D.cpp
WebCore/html/canvas/CanvasStyle.cpp
WebCore/html/canvas/CanvasStyle.h

index 27247b8c48bcc2da80b602c17c846d2e90fb173f..b8029be5c11835676e6008a1f0bb175da4e57e03 100644 (file)
@@ -1,3 +1,30 @@
+2010-10-14  Andreas Kling  <kling@webkit.org>
+
+        Reviewed by Darin Adler.
+
+        Canvas: "currentColor" should inherit the canvas element's color
+        https://bugs.webkit.org/show_bug.cgi?id=40273
+
+        Added test to verify support for "currentColor" value in CanvasRenderingContext2D.
+
+        Also unskipped 3 tests which now pass:
+        - canvas/philip/tests/2d.fillStyle.parse.current.basic.html
+        - canvas/philip/tests/2d.fillStyle.parse.current.changed.html
+        - canvas/philip/tests/2d.fillStyle.parse.current.removed.html
+
+        Spec link:
+        http://www.whatwg.org/specs/web-apps/current-work/#2dcontext
+
+        * fast/canvas/canvas-currentColor-expected.txt: Added.
+        * fast/canvas/canvas-currentColor.html: Added.
+        * fast/canvas/script-tests/canvas-currentColor.js: Added.
+        (attachCanvasToDocument):
+        (tryLinearGradientColor):
+        (tryRadialGradientColor):
+        * platform/gtk/Skipped:
+        * platform/mac/Skipped:
+        * platform/qt/Skipped:
+
 2010-10-14  Csaba Osztrogon√°c  <ossy@webkit.org>
 
         Unreviewed fix after r69749.
diff --git a/LayoutTests/fast/canvas/canvas-currentColor-expected.txt b/LayoutTests/fast/canvas/canvas-currentColor-expected.txt
new file mode 100644 (file)
index 0000000..7854c6d
--- /dev/null
@@ -0,0 +1,57 @@
+Test that CanvasRenderingContext2D supports the 'currentColor' value.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS ctx.shadowColor = '#f00'; ctx.shadowColor is '#ff0000'
+PASS ctx.shadowColor = 'currentColor'; ctx.shadowColor is '#000000'
+PASS ctx.fillStyle = '#f00'; ctx.fillStyle is '#ff0000'
+PASS ctx.fillStyle = 'currentColor'; ctx.fillStyle is '#000000'
+PASS ctx.strokeStyle = '#f00'; ctx.strokeStyle is '#ff0000'
+PASS ctx.strokeStyle = 'currentColor'; ctx.strokeStyle is '#000000'
+PASS ctx.setShadow(0, 0, 0, '#f00'); ctx.shadowColor is '#ff0000'
+PASS ctx.setShadow(0, 0, 0, 'currentColor'); ctx.shadowColor is '#000000'
+PASS ctx.setShadow(0, 0, 0, '#f00', 0.0); ctx.shadowColor is 'rgba(255, 0, 0, 0.0)'
+PASS ctx.setShadow(0, 0, 0, 'currentColor', 0.0); ctx.shadowColor is 'rgba(0, 0, 0, 0.0)'
+PASS ctx.setStrokeColor('#f00'); ctx.strokeStyle is '#ff0000'
+PASS ctx.setStrokeColor('currentColor'); ctx.strokeStyle is '#000000'
+PASS ctx.setStrokeColor('#f00', 0.0); ctx.strokeStyle is 'rgba(255, 0, 0, 0.0)'
+PASS ctx.setStrokeColor('currentColor', 0.0); ctx.strokeStyle is 'rgba(0, 0, 0, 0.0)'
+PASS ctx.setFillColor('#f00'); ctx.fillStyle is '#ff0000'
+PASS ctx.setFillColor('currentColor'); ctx.fillStyle is '#000000'
+PASS ctx.setFillColor('#f00', 0.0); ctx.fillStyle is 'rgba(255, 0, 0, 0.0)'
+PASS ctx.setFillColor('currentColor', 0.0); ctx.fillStyle is 'rgba(0, 0, 0, 0.0)'
+PASS tryLinearGradientColor('#f00') is '255,0,0,255'
+PASS tryLinearGradientColor('currentColor') is '0,0,0,255'
+PASS tryRadialGradientColor('#f00') is '255,0,0,255'
+PASS tryRadialGradientColor('currentColor') is '0,0,0,255'
+PASS attachCanvasToDocument() is true
+PASS canvas.style.color = '#123456'; canvas.style.color is 'rgb(18, 52, 86)'
+PASS ctx.shadowColor = '#f00'; ctx.shadowColor is '#ff0000'
+PASS ctx.shadowColor = 'currentColor'; ctx.shadowColor is '#123456'
+PASS ctx.fillStyle = '#f00'; ctx.fillStyle is '#ff0000'
+PASS ctx.fillStyle = 'currentColor'; ctx.fillStyle is '#123456'
+PASS ctx.strokeStyle = '#f00'; ctx.strokeStyle is '#ff0000'
+PASS ctx.strokeStyle = 'currentColor'; ctx.strokeStyle is '#123456'
+PASS ctx.setShadow(0, 0, 0, '#f00'); ctx.shadowColor is '#ff0000'
+PASS ctx.setShadow(0, 0, 0, 'currentColor'); ctx.shadowColor is '#123456'
+PASS ctx.setShadow(0, 0, 0, '#f00', 0.0); ctx.shadowColor is 'rgba(255, 0, 0, 0.0)'
+PASS ctx.setShadow(0, 0, 0, 'currentColor', 0.0); ctx.shadowColor is 'rgba(18, 52, 86, 0.0)'
+PASS ctx.setStrokeColor('#f00'); ctx.strokeStyle is '#ff0000'
+PASS ctx.setStrokeColor('currentColor'); ctx.strokeStyle is '#123456'
+PASS ctx.setStrokeColor('#f00', 0.0); ctx.strokeStyle is 'rgba(255, 0, 0, 0.0)'
+PASS ctx.setStrokeColor('currentColor', 0.0); ctx.strokeStyle is 'rgba(18, 52, 86, 0.0)'
+PASS ctx.setFillColor('#f00'); ctx.fillStyle is '#ff0000'
+PASS ctx.setFillColor('currentColor'); ctx.fillStyle is '#123456'
+PASS ctx.setFillColor('#f00', 0.0); ctx.fillStyle is 'rgba(255, 0, 0, 0.0)'
+PASS ctx.setFillColor('currentColor', 0.0); ctx.fillStyle is 'rgba(18, 52, 86, 0.0)'
+PASS tryLinearGradientColor('#f00') is '255,0,0,255'
+PASS tryLinearGradientColor('currentColor') is '0,0,0,255'
+PASS tryRadialGradientColor('#f00') is '255,0,0,255'
+PASS tryRadialGradientColor('currentColor') is '0,0,0,255'
+PASS ctx.shadowColor = '#f00'; ctx.shadowColor is '#ff0000'
+PASS ctx.shadowColor = 'CURRENTCOLOR'; ctx.shadowColor is '#123456'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/canvas-currentColor.html b/LayoutTests/fast/canvas/canvas-currentColor.html
new file mode 100644 (file)
index 0000000..69b7244
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/canvas-currentColor.js"></script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/canvas/script-tests/canvas-currentColor.js b/LayoutTests/fast/canvas/script-tests/canvas-currentColor.js
new file mode 100644 (file)
index 0000000..3407be9
--- /dev/null
@@ -0,0 +1,89 @@
+description("Test that CanvasRenderingContext2D supports the 'currentColor' value.");
+
+canvas = document.createElement('canvas');
+canvas.width = 100;
+canvas.height = 100;
+ctx = canvas.getContext('2d');
+
+function attachCanvasToDocument() {
+    document.body.appendChild(canvas);
+    return document.body.parentNode != null;
+}
+
+function tryLinearGradientColor(color) {
+    var gradient = ctx.createLinearGradient(0, 0, 100, 100);
+    gradient.addColorStop(0, color);
+    gradient.addColorStop(1, color);
+    ctx.fillStyle = gradient;
+    ctx.fillRect(0, 0, 100, 100);
+    var data = ctx.getImageData(0, 0, 1, 1).data;
+    return '' + data[0] + ',' + data[1] + ',' + data[2] + ',' + data[3];
+}
+
+function tryRadialGradientColor(color) {
+    var gradient = ctx.createRadialGradient(0, 0, 100, 100, 100, 100);
+    gradient.addColorStop(0, color);
+    gradient.addColorStop(1, color);
+    ctx.fillStyle = gradient;
+    ctx.fillRect(0, 0, 100, 100);
+    var data = ctx.getImageData(0, 0, 1, 1).data;
+    return '' + data[0] + ',' + data[1] + ',' + data[2] + ',' + data[3];
+}
+
+// First we test with the canvas out-of-document, 'currentColor' should mean black
+shouldBe("ctx.shadowColor = '#f00'; ctx.shadowColor", "'#ff0000'");
+shouldBe("ctx.shadowColor = 'currentColor'; ctx.shadowColor", "'#000000'");
+shouldBe("ctx.fillStyle = '#f00'; ctx.fillStyle", "'#ff0000'");
+shouldBe("ctx.fillStyle = 'currentColor'; ctx.fillStyle", "'#000000'");
+shouldBe("ctx.strokeStyle = '#f00'; ctx.strokeStyle", "'#ff0000'");
+shouldBe("ctx.strokeStyle = 'currentColor'; ctx.strokeStyle", "'#000000'");
+shouldBe("ctx.setShadow(0, 0, 0, '#f00'); ctx.shadowColor", "'#ff0000'");
+shouldBe("ctx.setShadow(0, 0, 0, 'currentColor'); ctx.shadowColor", "'#000000'");
+shouldBe("ctx.setShadow(0, 0, 0, '#f00', 0.0); ctx.shadowColor", "'rgba(255, 0, 0, 0.0)'");
+shouldBe("ctx.setShadow(0, 0, 0, 'currentColor', 0.0); ctx.shadowColor", "'rgba(0, 0, 0, 0.0)'");
+shouldBe("ctx.setStrokeColor('#f00'); ctx.strokeStyle", "'#ff0000'");
+shouldBe("ctx.setStrokeColor('currentColor'); ctx.strokeStyle", "'#000000'");
+shouldBe("ctx.setStrokeColor('#f00', 0.0); ctx.strokeStyle", "'rgba(255, 0, 0, 0.0)'");
+shouldBe("ctx.setStrokeColor('currentColor', 0.0); ctx.strokeStyle", "'rgba(0, 0, 0, 0.0)'");
+shouldBe("ctx.setFillColor('#f00'); ctx.fillStyle", "'#ff0000'");
+shouldBe("ctx.setFillColor('currentColor'); ctx.fillStyle", "'#000000'");
+shouldBe("ctx.setFillColor('#f00', 0.0); ctx.fillStyle", "'rgba(255, 0, 0, 0.0)'");
+shouldBe("ctx.setFillColor('currentColor', 0.0); ctx.fillStyle", "'rgba(0, 0, 0, 0.0)'");
+shouldBe("tryLinearGradientColor('#f00')", "'255,0,0,255'");
+shouldBe("tryLinearGradientColor('currentColor')", "'0,0,0,255'");
+shouldBe("tryRadialGradientColor('#f00')", "'255,0,0,255'");
+shouldBe("tryRadialGradientColor('currentColor')", "'0,0,0,255'");
+
+// Attach to the document and set the canvas's color to #123456
+shouldBe("attachCanvasToDocument()", "true");
+shouldBe("canvas.style.color = '#123456'; canvas.style.color", "'rgb(18, 52, 86)'");
+
+// 'currentColor' should now mean #123456
+shouldBe("ctx.shadowColor = '#f00'; ctx.shadowColor", "'#ff0000'");
+shouldBe("ctx.shadowColor = 'currentColor'; ctx.shadowColor", "'#123456'");
+shouldBe("ctx.fillStyle = '#f00'; ctx.fillStyle", "'#ff0000'");
+shouldBe("ctx.fillStyle = 'currentColor'; ctx.fillStyle", "'#123456'");
+shouldBe("ctx.strokeStyle = '#f00'; ctx.strokeStyle", "'#ff0000'");
+shouldBe("ctx.strokeStyle = 'currentColor'; ctx.strokeStyle", "'#123456'");
+shouldBe("ctx.setShadow(0, 0, 0, '#f00'); ctx.shadowColor", "'#ff0000'");
+shouldBe("ctx.setShadow(0, 0, 0, 'currentColor'); ctx.shadowColor", "'#123456'");
+shouldBe("ctx.setShadow(0, 0, 0, '#f00', 0.0); ctx.shadowColor", "'rgba(255, 0, 0, 0.0)'");
+shouldBe("ctx.setShadow(0, 0, 0, 'currentColor', 0.0); ctx.shadowColor", "'rgba(18, 52, 86, 0.0)'");
+shouldBe("ctx.setStrokeColor('#f00'); ctx.strokeStyle", "'#ff0000'");
+shouldBe("ctx.setStrokeColor('currentColor'); ctx.strokeStyle", "'#123456'");
+shouldBe("ctx.setStrokeColor('#f00', 0.0); ctx.strokeStyle", "'rgba(255, 0, 0, 0.0)'");
+shouldBe("ctx.setStrokeColor('currentColor', 0.0); ctx.strokeStyle", "'rgba(18, 52, 86, 0.0)'");
+shouldBe("ctx.setFillColor('#f00'); ctx.fillStyle", "'#ff0000'");
+shouldBe("ctx.setFillColor('currentColor'); ctx.fillStyle", "'#123456'");
+shouldBe("ctx.setFillColor('#f00', 0.0); ctx.fillStyle", "'rgba(255, 0, 0, 0.0)'");
+shouldBe("ctx.setFillColor('currentColor', 0.0); ctx.fillStyle", "'rgba(18, 52, 86, 0.0)'");
+shouldBe("tryLinearGradientColor('#f00')", "'255,0,0,255'");
+shouldBe("tryLinearGradientColor('currentColor')", "'0,0,0,255'");
+shouldBe("tryRadialGradientColor('#f00')", "'255,0,0,255'");
+shouldBe("tryRadialGradientColor('currentColor')", "'0,0,0,255'");
+
+// Last but not least, verify that we're case insensitive
+shouldBe("ctx.shadowColor = '#f00'; ctx.shadowColor", "'#ff0000'");
+shouldBe("ctx.shadowColor = 'CURRENTCOLOR'; ctx.shadowColor", "'#123456'");
+
+var successfullyParsed = true;
index 20a7cd6e6923d6f27adf1d6ddbeabf19ad6f660d..08476688ccca97aaaf68f21dc51560e80ee67129 100644 (file)
@@ -5564,9 +5564,6 @@ canvas/philip/tests/2d.composite.uncovered.pattern.source-out.html
 canvas/philip/tests/2d.drawImage.broken.html
 canvas/philip/tests/2d.drawImage.incomplete.html
 canvas/philip/tests/2d.drawImage.null.html
-canvas/philip/tests/2d.fillStyle.parse.current.basic.html
-canvas/philip/tests/2d.fillStyle.parse.current.changed.html
-canvas/philip/tests/2d.fillStyle.parse.current.removed.html
 canvas/philip/tests/2d.fillStyle.parse.system.html
 canvas/philip/tests/2d.gradient.radial.cone.front.html
 canvas/philip/tests/2d.gradient.radial.cone.top.html
index 820d3bf489e8ec56e078ae906987e0e07cdce6a2..7ab6d576db3a5897a06e8b0397fe3bb06bd4c795 100644 (file)
@@ -169,9 +169,6 @@ canvas/philip/tests/2d.composite.uncovered.pattern.source-out.html
 canvas/philip/tests/2d.drawImage.broken.html
 canvas/philip/tests/2d.drawImage.incomplete.html
 canvas/philip/tests/2d.drawImage.null.html
-canvas/philip/tests/2d.fillStyle.parse.current.basic.html
-canvas/philip/tests/2d.fillStyle.parse.current.changed.html
-canvas/philip/tests/2d.fillStyle.parse.current.removed.html
 canvas/philip/tests/2d.fillStyle.parse.system.html
 canvas/philip/tests/2d.gradient.radial.cone.front.html
 canvas/philip/tests/2d.gradient.radial.cone.top.html
index 0429bc1c422e22346f3f0f07a31e4a50f8900a8f..321e551f411fc94658a9f298270ecff6e08d44db 100644 (file)
@@ -5178,9 +5178,6 @@ canvas/philip/tests/2d.composite.uncovered.pattern.source-out.html
 canvas/philip/tests/2d.drawImage.broken.html
 canvas/philip/tests/2d.drawImage.incomplete.html
 canvas/philip/tests/2d.drawImage.null.html
-canvas/philip/tests/2d.fillStyle.parse.current.basic.html
-canvas/philip/tests/2d.fillStyle.parse.current.changed.html
-canvas/philip/tests/2d.fillStyle.parse.current.removed.html
 canvas/philip/tests/2d.fillStyle.parse.system.html
 canvas/philip/tests/2d.gradient.radial.cone.behind.html
 canvas/philip/tests/2d.gradient.radial.cone.beside.html
index 31ba8b62e07f809c5ab36111cf86d7d74686aed0..9093498307c09fdb6c5654843b61351677ceb03c 100644 (file)
@@ -1,3 +1,43 @@
+2010-10-14  Andreas Kling  <kling@webkit.org>
+
+        Reviewed by Darin Adler.
+
+        Canvas: "currentColor" should inherit the canvas element's color
+        https://bugs.webkit.org/show_bug.cgi?id=40273
+
+        Add support for "currentColor" in CanvasRenderingContext2D APIs.
+        If the canvas is in-document, "currentColor" is replaced by canvas.style.color,
+        otherwise we use fully opaque black.
+
+        For gradient addColorStop(), "currentColor" always means fully opaque black.
+
+        Spec link:
+        http://www.whatwg.org/specs/web-apps/current-work/#2dcontext
+
+        Test: fast/canvas/canvas-currentColor.html
+
+        * html/canvas/CanvasGradient.cpp:
+        (WebCore::CanvasGradient::addColorStop):
+        * html/canvas/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::setStrokeStyle):
+        (WebCore::CanvasRenderingContext2D::setFillStyle):
+        (WebCore::CanvasRenderingContext2D::setShadowColor):
+        (WebCore::CanvasRenderingContext2D::setShadow):
+        * html/canvas/CanvasStyle.cpp:
+        (WebCore::parseColor):
+        (WebCore::currentColor):
+        (WebCore::parseColorOrCurrentColor):
+        (WebCore::CanvasStyle::CanvasStyle):
+        (WebCore::CanvasStyle::createFromString):
+        (WebCore::CanvasStyle::createFromStringWithOverrideAlpha):
+        (WebCore::CanvasStyle::isEquivalentColor):
+        (WebCore::CanvasStyle::applyStrokeColor):
+        (WebCore::CanvasStyle::applyFillColor):
+        * html/canvas/CanvasStyle.h:
+        (WebCore::CanvasStyle::isCurrentColor):
+        (WebCore::CanvasStyle::hasOverrideAlpha):
+        (WebCore::CanvasStyle::overrideAlpha):
+
 2010-10-08  Yury Semikhatsky  <yurys@chromium.org>
 
         Reviewed by Pavel Feldman.
index fd48194dcabf1f89e85b5d77f2640ee7b68ab41d..7c98a82b2ac569a1aa6c50271a7b30a926073e2a 100644 (file)
@@ -27,6 +27,8 @@
 #include "config.h"
 #include "CanvasGradient.h"
 
+#include "CanvasPattern.h"
+#include "CanvasStyle.h"
 #include "CSSParser.h"
 #include "ExceptionCode.h"
 
@@ -52,7 +54,7 @@ void CanvasGradient::addColorStop(float value, const String& color, ExceptionCod
     }
 
     RGBA32 rgba = 0;
-    if (!CSSParser::parseColor(rgba, color)) {
+    if (!parseColorOrCurrentColor(rgba, color, 0 /*canvas*/)) {
         if (!m_dashbardCompatibilityMode)
             ec = SYNTAX_ERR;
         return;
index be909301f694e22afddec53c3ee503bb3df24e25..9cffd926f55e08aa12d1765c3105406a1f587783 100644 (file)
@@ -249,7 +249,13 @@ void CanvasRenderingContext2D::setStrokeStyle(PassRefPtr<CanvasStyle> style)
     if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentColor(*style))
         return;
 
-    checkOrigin(style->canvasPattern());
+    if (style->isCurrentColor()) {
+        if (style->hasOverrideAlpha())
+            style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
+        else
+            style = CanvasStyle::createFromRGBA(currentColor(canvas()));
+    } else
+        checkOrigin(style->canvasPattern());
 
     state().m_strokeStyle = style;
     GraphicsContext* c = drawingContext();
@@ -272,7 +278,13 @@ void CanvasRenderingContext2D::setFillStyle(PassRefPtr<CanvasStyle> style)
     if (state().m_fillStyle && state().m_fillStyle->isEquivalentColor(*style))
         return;
 
-    checkOrigin(style->canvasPattern());
+    if (style->isCurrentColor()) {
+        if (style->hasOverrideAlpha())
+            style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
+        else
+            style = CanvasStyle::createFromRGBA(currentColor(canvas()));
+    } else
+        checkOrigin(style->canvasPattern());
 
     state().m_fillStyle = style;
     GraphicsContext* c = drawingContext();
@@ -394,7 +406,7 @@ String CanvasRenderingContext2D::shadowColor() const
 
 void CanvasRenderingContext2D::setShadowColor(const String& color)
 {
-    if (!CSSParser::parseColor(state().m_shadowColor, color))
+    if (!parseColorOrCurrentColor(state().m_shadowColor, color, canvas()))
         return;
 
     applyShadow();
@@ -982,7 +994,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur)
 
 void CanvasRenderingContext2D::setShadow(float width, float height, float blur, const String& color)
 {
-    if (!CSSParser::parseColor(state().m_shadowColor, color))
+    if (!parseColorOrCurrentColor(state().m_shadowColor, color, canvas()))
         return;
 
     state().m_shadowOffset = FloatSize(width, height);
@@ -1007,7 +1019,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
 {
     RGBA32 rgba;
 
-    if (!CSSParser::parseColor(rgba, color))
+    if (!parseColorOrCurrentColor(rgba, color, canvas()))
         return;
 
     state().m_shadowColor = colorWithOverrideAlpha(rgba, alpha);
index fd3c6e5a323c1b746e055ccaf77a1787ffb5a1a7..5a30f63082fb91805d5911fefea02fa94a7301fa 100644 (file)
 #include "CanvasStyle.h"
 
 #include "CSSParser.h"
+#include "CSSPropertyNames.h"
 #include "CanvasGradient.h"
 #include "CanvasPattern.h"
 #include "GraphicsContext.h"
+#include "HTMLCanvasElement.h"
 #include <wtf/Assertions.h>
 #include <wtf/PassRefPtr.h>
 
 
 namespace WebCore {
 
+enum ColorParseResult { ParsedRGBA, ParsedCurrentColor, ParseFailed };
+
+static ColorParseResult parseColor(RGBA32& parsedColor, const String& colorString)
+{
+    if (equalIgnoringCase(colorString, "currentcolor"))
+        return ParsedCurrentColor;
+    if (CSSParser::parseColor(parsedColor, colorString))
+        return ParsedRGBA;
+    return ParseFailed;
+}
+
+RGBA32 currentColor(HTMLCanvasElement* canvas)
+{
+    if (!canvas || !canvas->inDocument())
+        return Color::black;
+    RGBA32 rgba = Color::black;
+    CSSParser::parseColor(rgba, canvas->style()->getPropertyValue(CSSPropertyColor));
+    return rgba;
+}
+
+bool parseColorOrCurrentColor(RGBA32& parsedColor, const String& colorString, HTMLCanvasElement* canvas)
+{
+    ColorParseResult parseResult = parseColor(parsedColor, colorString);
+    switch (parseResult) {
+    case ParsedRGBA:
+        return true;
+    case ParsedCurrentColor:
+        parsedColor = currentColor(canvas);
+        return true;
+    case ParseFailed:
+        return false;
+    }
+}
+
+CanvasStyle::CanvasStyle(Type type, float overrideAlpha)
+    : m_type(type)
+    , m_overrideAlpha(overrideAlpha)
+{
+}
+
 CanvasStyle::CanvasStyle(RGBA32 rgba)
     : m_type(RGBA)
     , m_rgba(rgba)
@@ -89,17 +131,29 @@ CanvasStyle::CanvasStyle(PassRefPtr<CanvasPattern> pattern)
 PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color)
 {
     RGBA32 rgba;
-    if (!CSSParser::parseColor(rgba, color))
+    ColorParseResult parseResult = parseColor(rgba, color);
+    switch (parseResult) {
+    case ParsedRGBA:
+        return adoptRef(new CanvasStyle(rgba));
+    case ParsedCurrentColor:
+        return adoptRef(new CanvasStyle(CurrentColor));
+    case ParseFailed:
         return 0;
-    return adoptRef(new CanvasStyle(rgba));
+    }
 }
 
 PassRefPtr<CanvasStyle> CanvasStyle::createFromStringWithOverrideAlpha(const String& color, float alpha)
 {
     RGBA32 rgba;
-    if (!CSSParser::parseColor(rgba, color))
+    ColorParseResult parseResult = parseColor(rgba, color);
+    switch (parseResult) {
+    case ParsedRGBA:
+        return adoptRef(new CanvasStyle(colorWithOverrideAlpha(rgba, alpha)));
+    case ParsedCurrentColor:
+        return adoptRef(new CanvasStyle(CurrentColorWithOverrideAlpha, alpha));
+    case ParseFailed:
         return 0;
-    return adoptRef(new CanvasStyle(colorWithOverrideAlpha(rgba, alpha)));
+    }
 }
 
 PassRefPtr<CanvasStyle> CanvasStyle::createFromGradient(PassRefPtr<CanvasGradient> gradient)
@@ -121,16 +175,18 @@ bool CanvasStyle::isEquivalentColor(const CanvasStyle& other) const
         return false;
 
     switch (m_type) {
-    case CanvasStyle::RGBA:
+    case RGBA:
         return m_rgba == other.m_rgba;
-    case CanvasStyle::CMYKA:
+    case CMYKA:
         return m_cmyka.c == other.m_cmyka.c
             && m_cmyka.m == other.m_cmyka.m
             && m_cmyka.y == other.m_cmyka.y
             && m_cmyka.k == other.m_cmyka.k
             && m_cmyka.a == other.m_cmyka.a;
-    case CanvasStyle::Gradient:
-    case CanvasStyle::ImagePattern:
+    case Gradient:
+    case ImagePattern:
+    case CurrentColor:
+    case CurrentColorWithOverrideAlpha:
         return false;
     }
 
@@ -188,6 +244,10 @@ void CanvasStyle::applyStrokeColor(GraphicsContext* context)
     case ImagePattern:
         context->setStrokePattern(canvasPattern()->pattern());
         break;
+    case CurrentColor:
+    case CurrentColorWithOverrideAlpha:
+        ASSERT_NOT_REACHED();
+        break;
     }
 }
 
@@ -221,6 +281,10 @@ void CanvasStyle::applyFillColor(GraphicsContext* context)
     case ImagePattern:
         context->setFillPattern(canvasPattern()->pattern());
         break;
+    case CurrentColor:
+    case CurrentColorWithOverrideAlpha:
+        ASSERT_NOT_REACHED();
+        break;
     }
 }
 
index 3ca760a68d0afd52ba3d5e2d2698440d28150771..91dc9233cd06e34a3dac64a365303c00f8761784 100644 (file)
 
 #include "Color.h"
 #include "PlatformString.h"
+#include <wtf/Assertions.h>
 
 namespace WebCore {
 
     class CanvasGradient;
     class CanvasPattern;
     class GraphicsContext;
+    class HTMLCanvasElement;
 
     class CanvasStyle : public RefCounted<CanvasStyle> {
     public:
@@ -47,7 +49,11 @@ namespace WebCore {
         static PassRefPtr<CanvasStyle> createFromGradient(PassRefPtr<CanvasGradient>);
         static PassRefPtr<CanvasStyle> createFromPattern(PassRefPtr<CanvasPattern>);
 
-        String color() const { return Color(m_rgba).serialized(); }
+        bool isCurrentColor() const { return m_type == CurrentColor || m_type == CurrentColorWithOverrideAlpha; }
+        bool hasOverrideAlpha() const { return m_type == CurrentColorWithOverrideAlpha; }
+        float overrideAlpha() const { ASSERT(m_type == CurrentColorWithOverrideAlpha); return m_overrideAlpha; }
+
+        String color() const { ASSERT(m_type == RGBA || m_type == CMYKA); return Color(m_rgba).serialized(); }
         CanvasGradient* canvasGradient() const { return m_gradient.get(); }
         CanvasPattern* canvasPattern() const { return m_pattern.get(); }
 
@@ -59,6 +65,9 @@ namespace WebCore {
         bool isEquivalentCMYKA(float c, float m, float y, float k, float a) const;
 
     private:
+        enum Type { RGBA, CMYKA, Gradient, ImagePattern, CurrentColor, CurrentColorWithOverrideAlpha };
+
+        CanvasStyle(Type, float overrideAlpha = 0);
         CanvasStyle(RGBA32 rgba);
         CanvasStyle(float grayLevel, float alpha);
         CanvasStyle(float r, float g, float b, float a);
@@ -66,11 +75,12 @@ namespace WebCore {
         CanvasStyle(PassRefPtr<CanvasGradient>);
         CanvasStyle(PassRefPtr<CanvasPattern>);
 
-        enum Type { RGBA, CMYKA, Gradient, ImagePattern };
-
         Type m_type;
 
-        RGBA32 m_rgba;
+        union {
+            RGBA32 m_rgba;
+            float m_overrideAlpha;
+        };
 
         RefPtr<CanvasGradient> m_gradient;
         RefPtr<CanvasPattern> m_pattern;
@@ -86,6 +96,9 @@ namespace WebCore {
         } m_cmyka;
     };
 
+    RGBA32 currentColor(HTMLCanvasElement*);
+    bool parseColorOrCurrentColor(RGBA32& parsedColor, const String& colorString, HTMLCanvasElement*);
+
 } // namespace WebCore
 
 #endif