Add support for CanvasPattern.setTransform()
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Nov 2017 21:33:44 +0000 (21:33 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Nov 2017 21:33:44 +0000 (21:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=179935

Reviewed by Sam Weinig.

Source/WebCore:

Add support for setTransform() on CanvasPattern, per
<https://html.spec.whatwg.org/multipage/canvas.html#dom-canvaspattern-settransform>
It uses [MayThrowException] since the "validate and fixup" steps for DOMMatrix can throw
an exception.

Under the hood, the transform is just pushed onto Pattern as the patternSpaceTransform().

Minor cleanup in Pattern.

Test: fast/canvas/canvas-pattern-with-transform.html

* html/canvas/CanvasPattern.cpp:
(WebCore::CanvasPattern::setTransform):
* html/canvas/CanvasPattern.h:
* html/canvas/CanvasPattern.idl:
* platform/graphics/Pattern.h:

LayoutTests:

Moved the test previously known as canvas-pattern-transform.html to canvas-pattern-with-transform.html
and added a new test.

* fast/canvas/canvas-pattern-transform-expected.txt:
* fast/canvas/canvas-pattern-transform.html:
* fast/canvas/canvas-pattern-with-transform-expected.txt: Copied from LayoutTests/fast/canvas/canvas-pattern-transform-expected.txt.
* fast/canvas/canvas-pattern-with-transform.html: Copied from LayoutTests/fast/canvas/canvas-pattern-transform.html.
* fast/canvas/canvas-pattern-with-transform.js: Renamed from LayoutTests/fast/canvas/canvas-pattern-transform.js.

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

12 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/canvas/canvas-pattern-transform-expected.txt
LayoutTests/fast/canvas/canvas-pattern-transform.html
LayoutTests/fast/canvas/canvas-pattern-with-transform-expected.txt [new file with mode: 0644]
LayoutTests/fast/canvas/canvas-pattern-with-transform.html [new file with mode: 0644]
LayoutTests/fast/canvas/canvas-pattern-with-transform.js [moved from LayoutTests/fast/canvas/canvas-pattern-transform.js with 100% similarity]
Source/WebCore/ChangeLog
Source/WebCore/html/canvas/CanvasPattern.cpp
Source/WebCore/html/canvas/CanvasPattern.h
Source/WebCore/html/canvas/CanvasPattern.idl
Source/WebCore/platform/graphics/Pattern.h
Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp

index 8090714..72f335f 100644 (file)
@@ -1,3 +1,19 @@
+2017-11-23  Simon Fraser  <simon.fraser@apple.com>
+
+        Add support for CanvasPattern.setTransform()
+        https://bugs.webkit.org/show_bug.cgi?id=179935
+
+        Reviewed by Sam Weinig.
+        
+        Moved the test previously known as canvas-pattern-transform.html to canvas-pattern-with-transform.html
+        and added a new test.
+
+        * fast/canvas/canvas-pattern-transform-expected.txt:
+        * fast/canvas/canvas-pattern-transform.html:
+        * fast/canvas/canvas-pattern-with-transform-expected.txt: Copied from LayoutTests/fast/canvas/canvas-pattern-transform-expected.txt.
+        * fast/canvas/canvas-pattern-with-transform.html: Copied from LayoutTests/fast/canvas/canvas-pattern-transform.html.
+        * fast/canvas/canvas-pattern-with-transform.js: Renamed from LayoutTests/fast/canvas/canvas-pattern-transform.js.
+
 2017-11-23  Ms2ger  <Ms2ger@igalia.com>
 
         [WPE] Mark media/media-source/media-source-paint-to-canvas.html as passing.
index 91e4343..6c63f40 100644 (file)
-Series of tests to ensure correct behaviour on transform of a pattern
+PASS successfullyParsed is true
 
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+TEST COMPLETE
+PASS function () {
+                ctx.setTransform({a: 1, m11: 11, b: 2, m12: 12, c: 3, m21: 21, d: 4, m22: 22, e: 5, m41: 41, f: 6, m42: 42});
+            } threw exception TypeError: init.a and init.m11 do not match.
 
+Testing canvas repeat transform  pattern transform 
+Checking point 4 4
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 124 124
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 64 32
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 64 96
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 32 64
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 96 64
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 32 32
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 96 32
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 96 32
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 96 96
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
 
-PASS imgdata[4] is 0
-PASS imgdata[5] is 255
-PASS imgdata[6] is 0
-PASS imgdata[4] is 255
-PASS imgdata[5] is 0
-PASS imgdata[6] is 0
-PASS imgdata[4] is 0
-PASS imgdata[5] is 255
-PASS imgdata[6] is 0
-PASS successfullyParsed is true
+Testing canvas no-repeat transform  pattern transform scale(0.5)
+Checking point 2 2
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 31 31
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 6 6
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 16 16
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 64 64
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 96 96
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
 
-TEST COMPLETE
+Testing canvas repeat transform  pattern transform rotate(45deg)
+Checking point 2 2
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 42 2
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 42 64
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 32 32
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 96 96
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+
+Testing canvas repeat transform  pattern transform translate(32px, 0)
+Checking point 4 4
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 124 124
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 64 32
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 2 96
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+
+Testing canvas repeat transform  pattern transform translate(32px, 32px) rotate(45deg) scale(0.5)
+Checking point 24 24
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 104 104
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 22 64
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 90 112
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 16 32
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 82 58
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+
+Testing canvas repeat transform scale(0.5) pattern transform rotate(45deg)
+Checking point 4 4
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 62 62
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 2 24
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 24 2
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 24 2
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 32 48
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 66 4
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 4 66
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
+Checking point 104 104
+PASS imgdata[0] is expectedRed
+PASS imgdata[1] is expectedGreen
+PASS imgdata[2] is expectedBlue
 
index fb8d0f9..07f923b 100644 (file)
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<!DOCTYPE HTML>
 <html>
-<head>
-<script src="../../resources/js-test-pre.js"></script>
-</head>
-<body>
-<script src="canvas-pattern-transform.js"></script>
-<script src="../../resources/js-test-post.js"></script>
-</body>
-</html>
+  <head>
+    <style>
+        canvas {
+            border: 1px solid black;
+            margin: 10px;
+        }
+    </style>
+    <script src="../../resources/js-test-pre.js"></script>
+    <script>
+        var patternCanvas;
+        function drawOneCanvas(canvas, repeat, transform, patternTransform)
+        {
+            var context = canvas.getContext('2d');
+
+            context.fillStyle = 'black';
+            context.fillRect(0, 0, canvas.width, canvas.height);
+
+            var pattern = context.createPattern(patternCanvas, repeat);
+
+            var patternMatrix = new DOMMatrix;
+            if (patternTransform)
+                patternMatrix.setMatrixValue(patternTransform);
+            if ('setTransform' in pattern)
+                pattern.setTransform(patternMatrix);
+
+            if (transform) {
+                var matrix = new DOMMatrix;
+                matrix.setMatrixValue(transform);
+                context.setTransform(matrix);
+            }
+
+            context.fillStyle = pattern;
+            context.fillRect(0, 0, canvas.width, canvas.height);
+        }
+
+        function createPatternCanvas()
+        {
+            patternCanvas = document.createElement('canvas');
+            patternCanvas.height = 64;
+            patternCanvas.width = 64;
+
+            var context = patternCanvas.getContext('2d');
+
+            context.fillStyle = 'blue';
+            context.fillRect(0, 0, patternCanvas.width, patternCanvas.height);
+
+            context.fillStyle = 'green';
+            const borderWidth = 8;
+            context.fillRect(borderWidth, borderWidth, patternCanvas.width - 2 * borderWidth, patternCanvas.height - 2 * borderWidth);
+        }
+        
+        function setupCanvas(data)
+        {
+            var canvas = document.createElement('canvas');
+            canvas.height = 128;
+            canvas.width = 128;
+
+            drawOneCanvas(canvas, data.repeat, data.transform, data.patternTransform);
+            
+            debug('');
+            debug('Testing canvas ' + data.repeat + ' transform ' + data.transform + ' pattern transform ' + data.patternTransform);
+            return canvas;
+        }
+        
+        function testCanvas(canvas, testData)
+        {
+            var test;
+            for (test of testData)
+                checkPixel(canvas, test.x, test.y, test.r, test.g, test.b);
+        }
+
+        var imgdata;
+        var expectedRed;
+        var expectedGreen;
+        var expectedBlue;
+        function checkPixel(canvas, x, y, r, g, b)
+        {
+            var context = canvas.getContext('2d');
+            var imageData = context.getImageData(x, y, 1, 1);
+            imgdata = imageData.data;
+            
+            debug('Checking point ' + x + ' ' + y);
+            expectedRed = r;
+            expectedGreen = g;
+            expectedBlue = b;
+            shouldBe("imgdata[0]", "expectedRed");
+            shouldBe("imgdata[1]", "expectedGreen");
+            shouldBe("imgdata[2]", "expectedBlue");
+        }
+        
+        function testInvalidMatrix()
+        {
+            var testCanvas = document.createElement('canvas');
+            testCanvas.height = 64;
+            testCanvas.width = 64;
+
+            var ctx = testCanvas.getContext('2d');
+
+            shouldThrowErrorName(function() {
+                ctx.setTransform({a: 1, m11: 11, b: 2, m12: 12, c: 3, m21: 21, d: 4, m22: 22, e: 5, m41: 41, f: 6, m42: 42});
+            }, "TypeError");
+        }
+
+        function doTest()
+        {
+            testInvalidMatrix();
+            createPatternCanvas();
+
+            const tests = [
+                {
+                    repeat : 'repeat',
+                    transform : '',
+                    patternTransform : '',
+                    test : [
+                        // Check two corners for blue.
+                        { x : 4, y : 4, r : 0, g : 0, b : 255 },
+                        { x : 124, y : 124, r : 0, g : 0, b : 255 },
+                        // Check for blue cross in the middle.
+                        { x : 64, y : 32, r : 0, g : 0, b : 255 },
+                        { x : 64, y : 96, r : 0, g : 0, b : 255 },
+                        { x : 32, y : 64, r : 0, g : 0, b : 255 },
+                        { x : 96, y : 64, r : 0, g : 0, b : 255 },
+                        // Four fields of green.
+                        { x : 32, y : 32, r : 0, g : 128, b : 0 },
+                        { x : 96, y : 32, r : 0, g : 128, b : 0 },
+                        { x : 96, y : 32, r : 0, g : 128, b : 0 },
+                        { x : 96, y : 96, r : 0, g : 128, b : 0 },
+                    ],
+                },
+                {
+                    repeat : 'no-repeat',
+                    transform : '',
+                    patternTransform : 'scale(0.5)',
+                    test : [
+                        // Check two corners for blue.
+                        { x : 2, y : 2, r : 0, g : 0, b : 255 },
+                        { x : 31, y : 31, r : 0, g : 0, b : 255 },
+                        // Green near corner and middle.
+                        { x : 6, y : 6, r : 0, g : 128, b : 0 },
+                        { x : 16, y : 16, r : 0, g : 128, b : 0 },
+                        // Mostly black
+                        { x : 64, y : 64, r : 0, g : 0, b : 0 },
+                        { x : 96, y : 96, r : 0, g : 0, b : 0 },
+                    ],
+                },
+                {
+                    repeat: 'repeat',
+                    transform: '',
+                    patternTransform: 'rotate(45deg)',
+                    test : [
+                        // Check two corners for blue.
+                        { x : 2, y : 2, r : 0, g : 0, b : 255 },
+                        // Green at top edge due to rotation.
+                        { x : 42, y : 2, r : 0, g : 128, b : 0 },
+                        { x : 42, y : 64, r : 0, g : 128, b : 0 },
+                        // Blue diagonal.
+                        { x : 32, y : 32, r : 0, g : 0, b : 255 },
+                        { x : 96, y : 96, r : 0, g : 0, b : 255 },
+                    ],
+                },
+                {
+                    repeat: 'repeat',
+                    transform: '',
+                    patternTransform: 'translate(32px, 0)',
+                    test : [
+                        // Check two corners for blue.
+                        { x : 4, y : 4, r : 0, g : 0, b : 255 },
+                        { x : 124, y : 124, r : 0, g : 0, b : 255 },
+                        // Green is offset half pattern width.
+                        { x : 64, y : 32, r : 0, g : 128, b : 0 },
+                        { x : 2, y : 96, r : 0, g : 128, b : 0 },
+                    ],
+                },
+                {
+                    repeat: 'repeat',
+                    transform: '',
+                    patternTransform: 'translate(32px, 32px) rotate(45deg) scale(0.5)',
+                    test : [
+                        // Blue diagonals
+                        { x : 24, y : 24, r : 0, g : 0, b : 255 },
+                        { x : 104, y : 104, r : 0, g : 0, b : 255 },
+                        { x : 22, y : 64, r : 0, g : 0, b : 255 },
+                        { x : 90, y : 112, r : 0, g : 0, b : 255 },
+                        // Green centers.
+                        { x : 16, y : 32, r : 0, g : 128, b : 0 },
+                        { x : 82, y : 58, r : 0, g : 128, b : 0 },
+                    ],
+                },
+                {
+                    repeat: 'repeat',
+                    transform: 'scale(0.5)',
+                    patternTransform: 'rotate(45deg)',
+                    test : [
+                        // Blue diagonals
+                        { x : 4, y : 4, r : 0, g : 0, b : 255 },
+                        { x : 62, y : 62, r : 0, g : 0, b : 255 },
+
+                        // Green centers.
+                        { x : 2, y : 24, r : 0, g : 128, b : 0 },
+                        { x : 24, y : 2, r : 0, g : 128, b : 0 },
+                        { x : 24, y : 2, r : 0, g : 128, b : 0 },
+                        { x : 32, y : 48, r : 0, g : 128, b : 0 },
+
+                        // Mostly black
+                        { x : 66, y : 4, r : 0, g : 0, b : 0 },
+                        { x : 4, y : 66, r : 0, g : 0, b : 0 },
+                        { x : 104, y : 104, r : 0, g : 0, b : 0 },
+                    ],
+                },
+            ];
+
+            var testData;
+            for (testData of tests) {
+                var canvas = setupCanvas(testData);
+                testCanvas(canvas, testData.test);
+            }
+        }
+      
+      window.addEventListener('load', doTest, false);
+    </script>
+  </head>
+  <body>
+  </body>
+  <script src="../../resources/js-test-post.js"></script>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/fast/canvas/canvas-pattern-with-transform-expected.txt b/LayoutTests/fast/canvas/canvas-pattern-with-transform-expected.txt
new file mode 100644 (file)
index 0000000..91e4343
--- /dev/null
@@ -0,0 +1,18 @@
+Series of tests to ensure correct behaviour on transform of a pattern
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS imgdata[4] is 0
+PASS imgdata[5] is 255
+PASS imgdata[6] is 0
+PASS imgdata[4] is 255
+PASS imgdata[5] is 0
+PASS imgdata[6] is 0
+PASS imgdata[4] is 0
+PASS imgdata[5] is 255
+PASS imgdata[6] is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/canvas-pattern-with-transform.html b/LayoutTests/fast/canvas/canvas-pattern-with-transform.html
new file mode 100644 (file)
index 0000000..f8e724f
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="canvas-pattern-with-transform.js"></script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
index 3e401f6..fc9c6e4 100644 (file)
@@ -1,3 +1,27 @@
+2017-11-23  Simon Fraser  <simon.fraser@apple.com>
+
+        Add support for CanvasPattern.setTransform()
+        https://bugs.webkit.org/show_bug.cgi?id=179935
+
+        Reviewed by Sam Weinig.
+        
+        Add support for setTransform() on CanvasPattern, per
+        <https://html.spec.whatwg.org/multipage/canvas.html#dom-canvaspattern-settransform>
+        It uses [MayThrowException] since the "validate and fixup" steps for DOMMatrix can throw
+        an exception.
+        
+        Under the hood, the transform is just pushed onto Pattern as the patternSpaceTransform().
+        
+        Minor cleanup in Pattern.
+
+        Test: fast/canvas/canvas-pattern-with-transform.html
+
+        * html/canvas/CanvasPattern.cpp:
+        (WebCore::CanvasPattern::setTransform):
+        * html/canvas/CanvasPattern.h:
+        * html/canvas/CanvasPattern.idl:
+        * platform/graphics/Pattern.h:
+
 2017-11-23  Sam Weinig  <sam@webkit.org>
 
         Remove unneeded ScriptController::processingUserGesture() forwarding functions
index 143336a..9a9de9a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2008, 2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,6 +26,8 @@
 #include "config.h"
 #include "CanvasPattern.h"
 
+#include "DOMMatrix2DInit.h"
+#include "DOMMatrixReadOnly.h"
 #include "Image.h"
 #include "Pattern.h"
 #include <wtf/text/WTFString.h>
@@ -70,4 +72,14 @@ bool CanvasPattern::parseRepetitionType(const String& type, bool& repeatX, bool&
     return false;
 }
 
+ExceptionOr<void> CanvasPattern::setTransform(DOMMatrix2DInit&& matrixInit)
+{
+    auto checkValid = DOMMatrixReadOnly::validateAndFixup(matrixInit);
+    if (checkValid.hasException())
+        return checkValid.releaseException();
+
+    m_pattern->setPatternSpaceTransform({ matrixInit.a.value_or(1), matrixInit.b.value_or(0), matrixInit.c.value_or(0), matrixInit.d.value_or(1), matrixInit.e.value_or(0), matrixInit.f.value_or(0) });
+    return { };
+}
+
 } // namespace WebCore
index b8faaab..c8a9e3c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2008, 2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "ExceptionOr.h"
 #include <wtf/Forward.h>
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
@@ -33,6 +34,7 @@ namespace WebCore {
 
 class Image;
 class Pattern;
+struct DOMMatrix2DInit;
 
 class CanvasPattern : public RefCounted<CanvasPattern> {
 public:
@@ -45,6 +47,8 @@ public:
     const Pattern& pattern() const { return m_pattern; }
 
     bool originClean() const { return m_originClean; }
+    
+    ExceptionOr<void> setTransform(DOMMatrix2DInit&&);
 
 private:
     CanvasPattern(Ref<Image>&&, bool repeatX, bool repeatY, bool originClean);
index 3c9ab34..3d1b29d 100644 (file)
@@ -28,6 +28,5 @@
     ImplementationLacksVTable
 ] interface CanvasPattern {
     // opaque object
-    // FIXME: Implement setTransform.
-    // void setTransform(optional DOMMatrix2DInit transform);
+    [MayThrowException] void setTransform(optional DOMMatrix2DInit transform);
 };
index 1cef98e..f467a0f 100644 (file)
@@ -25,8 +25,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef Pattern_h
-#define Pattern_h
+#pragma once
 
 #include "AffineTransform.h"
 
@@ -66,7 +65,7 @@ public:
     PlatformPatternPtr createPlatformPattern(const GraphicsContext&, float alpha, const AffineTransform& userSpaceTransformation) const;
 #endif
     void setPatternSpaceTransform(const AffineTransform& patternSpaceTransformation);
-    const AffineTransform& getPatternSpaceTransform() { return m_patternSpaceTransformation; };
+    const AffineTransform& patternSpaceTransform() { return m_patternSpaceTransformation; };
     bool repeatX() const { return m_repeatX; }
     bool repeatY() const { return m_repeatY; }
 
@@ -74,11 +73,10 @@ private:
     Pattern(Ref<Image>&&, bool repeatX, bool repeatY);
 
     Ref<Image> m_tileImage;
+    AffineTransform m_patternSpaceTransformation;
     bool m_repeatX;
     bool m_repeatY;
-    AffineTransform m_patternSpaceTransformation;
 };
 
 } //namespace
 
-#endif
index c828174..d424414 100644 (file)
@@ -318,7 +318,7 @@ void PlatformContextCairo::clipForPatternFilling(const GraphicsContextState& sta
     FloatRect clipRect(x1, y1, x2 - x1, y2 - y1);
 
     auto& patternImage = state.fillPattern->tileImage();
-    const AffineTransform& patternTransform = state.fillPattern->getPatternSpaceTransform();
+    const AffineTransform& patternTransform = state.fillPattern->patternSpaceTransform();
     FloatRect patternRect = patternTransform.mapRect(FloatRect(0, 0, patternImage.width(), patternImage.height()));
 
     bool repeatX = state.fillPattern->repeatX();