+2008-02-22 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Sam W.
+
+ Bug 17486: Support HTML5 Canvas.getImageData API
+ Support Canvas.getImageData and Canvas.createImageData
+
+ Test cases for ImageData behaviour and getImageData correctness
+
+ * fast/canvas/canvas-ImageData-behaviour-expected.txt: Added.
+ * fast/canvas/canvas-ImageData-behaviour.html: Added.
+ * fast/canvas/canvas-ImageData-behaviour.js: Added.
+ * fast/canvas/canvas-getImageData-expected.txt: Added.
+ * fast/canvas/canvas-getImageData.html: Added.
+
2008-02-22 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
--- /dev/null
+Series of tests to ensure correct behaviour of the ImageData object
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS imageData.width is 2
+PASS imageData.height is 2
+PASS imageData.data.length is 16
+PASS imageData.data[0] is 0
+PASS imageData.data[1] is 0
+PASS imageData.data[2] is 0
+PASS imageData.data[3] is 0
+PASS imageData.data[4] is 0
+PASS imageData.data[5] is 0
+PASS imageData.data[6] is 0
+PASS imageData.data[7] is 0
+PASS imageData.data[8] is 0
+PASS imageData.data[9] is 0
+PASS imageData.data[10] is 0
+PASS imageData.data[11] is 0
+PASS imageData.data[12] is 0
+PASS imageData.data[13] is 0
+PASS imageData.data[14] is 0
+PASS imageData.data[15] is 0
+PASS imageData.data[0] = NaN, imageData.data[0] is 0
+PASS imageData.data[0] = true, imageData.data[0] is 1
+PASS imageData.data[0] = false, imageData.data[0] is 0
+PASS imageData.data[0] = "garbage", imageData.data[0] is 0
+PASS imageData.data[0] = -1, imageData.data[0] is 0
+PASS imageData.data[0] = "0", imageData.data[0] is 0
+PASS imageData.data[0] = "1", imageData.data[0] is 1
+PASS imageData.data[0] = "2", imageData.data[0] is 2
+PASS imageData.data[0] = Infinity, imageData.data[0] is 255
+PASS imageData.data[0] = -Infinity, imageData.data[0] is 0
+PASS imageData.data[0] = -5, imageData.data[0] is 0
+PASS imageData.data[0] = -0.5, imageData.data[0] is 0
+PASS imageData.data[0] = 0, imageData.data[0] is 0
+PASS imageData.data[0] = 0.5, imageData.data[0] is 1
+PASS imageData.data[0] = 5, imageData.data[0] is 5
+PASS imageData.data[0] = 5.4, imageData.data[0] is 5
+PASS imageData.data[0] = 255, imageData.data[0] is 255
+PASS imageData.data[0] = 256, imageData.data[0] is 255
+PASS imageData.data[0] = null, imageData.data[0] is 0
+PASS imageData.data[0] = undefined, imageData.data[0] is 0
+PASS imageData.data['foo']='garbage',imageData.data['foo'] is 'garbage'
+PASS imageData.data[-1]='garbage',imageData.data[-1] is 'garbage'
+PASS imageData.data[17]='garbage',imageData.data[17] is undefined
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!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>
+<canvas id="canvas"></canvas>
+<script src="canvas-ImageData-behaviour.js"></script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
--- /dev/null
+description("Series of tests to ensure correct behaviour of the ImageData object");
+
+imageData = document.getElementById("canvas").getContext("2d").getImageData(0,0,2,2);
+
+shouldBe("imageData.width", "2");
+shouldBe("imageData.height", "2");
+shouldBe("imageData.data.length", "16");
+for (var i = 0; i < imageData.data.length; i++)
+ shouldBe("imageData.data["+i+"]", "0");
+
+var testValues = [NaN, true, false, "\"garbage\"", "-1",
+ "\"0\"", "\"1\"", "\"2\"", Infinity, -Infinity,
+ -5, -0.5, 0, 0.5, 5,
+ 5.4, 255, 256, null, undefined];
+var testResults = [0, 1, 0, 0, 0,
+ 0, 1, 2, 255, 0,
+ 0, 0, 0, 1, 5,
+ 5, 255, 255, 0, 0];
+for (var i = 0; i < testValues.length; i++) {
+ shouldBe("imageData.data[0] = "+testValues[i]+", imageData.data[0]", ""+testResults[i]);
+}
+
+shouldBe("imageData.data['foo']='garbage',imageData.data['foo']", "'garbage'");
+shouldBe("imageData.data[-1]='garbage',imageData.data[-1]", "'garbage'");
+shouldBe("imageData.data[17]='garbage',imageData.data[17]", "undefined");
+
+var successfullyParsed = true;
--- /dev/null
+This test ensures that getImageData works correctly.
+PASS: pixel at (0,0) was [0,0,0,255]
+PASS: pixel at (4,0) was [0,11,0,255]
+PASS: pixel at (8,0) was [0,21,0,255]
+PASS: pixel at (12,0) was [0,32,0,255]
+PASS: pixel at (16,0) was [0,43,0,255]
+PASS: pixel at (20,0) was [0,53,0,255]
+PASS: pixel at (24,0) was [0,64,0,255]
+PASS: pixel at (28,0) was [0,74,0,255]
+PASS: pixel at (32,0) was [0,85,0,255]
+PASS: pixel at (36,0) was [0,96,0,255]
+PASS: pixel at (40,0) was [0,106,0,255]
+PASS: pixel at (44,0) was [0,117,0,255]
+PASS: pixel at (48,0) was [0,128,0,255]
+PASS: pixel at (52,0) was [0,138,0,255]
+PASS: pixel at (56,0) was [0,149,0,255]
+PASS: pixel at (60,0) was [0,159,0,255]
+PASS: pixel at (64,0) was [0,170,0,255]
+PASS: pixel at (68,0) was [0,181,0,255]
+PASS: pixel at (72,0) was [0,191,0,255]
+PASS: pixel at (76,0) was [0,202,0,255]
+PASS: pixel at (80,0) was [0,213,0,255]
+PASS: pixel at (84,0) was [0,223,0,255]
+PASS: pixel at (88,0) was [0,234,0,255]
+PASS: pixel at (92,0) was [0,244,0,255]
+PASS: pixel at (96,0) was [0,255,0,255]
+PASS: pixel at (5,5) was [64,128,191,255]
+PASS: Correct data for content outside canvas bounds
+PASS: pixel at (50,50) was [0,0,0,0]
+PASS: pixel at (50,54) was [0,0,0,1]
+PASS: pixel at (50,58) was [0,0,0,2]
+PASS: pixel at (50,62) was [0,0,0,16]
+PASS: pixel at (50,66) was [0,0,0,32]
+PASS: pixel at (50,70) was [0,0,0,64]
+PASS: pixel at (50,74) was [0,0,0,96]
+PASS: pixel at (50,78) was [0,0,0,128]
+PASS: pixel at (50,82) was [0,0,0,192]
+PASS: pixel at (50,86) was [0,0,0,254]
+PASS: pixel at (50,90) was [0,0,0,255]
+PASS: pixel at (54,50) was [0,0,0,0]
+PASS: pixel at (54,54) was [0,0,0,1]
+PASS: pixel at (54,58) was [0,0,0,2]
+PASS: pixel at (54,62) was [0,0,0,16]
+PASS: pixel at (54,66) was [0,0,0,32]
+PASS: pixel at (54,70) was [0,0,0,64]
+PASS: pixel at (54,74) was [0,0,0,96]
+PASS: pixel at (54,78) was [1,0,0,128]
+PASS: pixel at (54,82) was [1,0,0,192]
+PASS: pixel at (54,86) was [1,0,0,254]
+PASS: pixel at (54,90) was [1,0,0,255]
+PASS: pixel at (58,50) was [0,0,0,0]
+PASS: pixel at (58,54) was [0,0,0,1]
+PASS: pixel at (58,58) was [0,0,0,2]
+PASS: pixel at (58,62) was [0,0,0,16]
+PASS: pixel at (58,66) was [0,0,0,32]
+PASS: pixel at (58,70) was [3,0,0,64]
+PASS: pixel at (58,74) was [2,0,0,96]
+PASS: pixel at (58,78) was [1,0,0,128]
+PASS: pixel at (58,82) was [2,0,0,192]
+PASS: pixel at (58,86) was [2,0,0,254]
+PASS: pixel at (58,90) was [2,0,0,255]
+PASS: pixel at (62,50) was [0,0,0,0]
+PASS: pixel at (62,54) was [0,0,0,1]
+PASS: pixel at (62,58) was [0,0,0,2]
+PASS: pixel at (62,62) was [15,0,0,16]
+PASS: pixel at (62,66) was [15,0,0,32]
+PASS: pixel at (62,70) was [15,0,0,64]
+PASS: pixel at (62,74) was [15,0,0,96]
+PASS: pixel at (62,78) was [15,0,0,128]
+PASS: pixel at (62,82) was [15,0,0,192]
+PASS: pixel at (62,86) was [16,0,0,254]
+PASS: pixel at (62,90) was [16,0,0,255]
+PASS: pixel at (66,50) was [0,0,0,0]
+PASS: pixel at (66,54) was [0,0,0,1]
+PASS: pixel at (66,58) was [0,0,0,2]
+PASS: pixel at (66,62) was [31,0,0,16]
+PASS: pixel at (66,66) was [31,0,0,32]
+PASS: pixel at (66,70) was [31,0,0,64]
+PASS: pixel at (66,74) was [31,0,0,96]
+PASS: pixel at (66,78) was [31,0,0,128]
+PASS: pixel at (66,82) was [31,0,0,192]
+PASS: pixel at (66,86) was [32,0,0,254]
+PASS: pixel at (66,90) was [32,0,0,255]
+PASS: pixel at (70,50) was [0,0,0,0]
+PASS: pixel at (70,54) was [0,0,0,1]
+PASS: pixel at (70,58) was [127,0,0,2]
+PASS: pixel at (70,62) was [63,0,0,16]
+PASS: pixel at (70,66) was [63,0,0,32]
+PASS: pixel at (70,70) was [63,0,0,64]
+PASS: pixel at (70,74) was [63,0,0,96]
+PASS: pixel at (70,78) was [63,0,0,128]
+PASS: pixel at (70,82) was [63,0,0,192]
+PASS: pixel at (70,86) was [64,0,0,254]
+PASS: pixel at (70,90) was [64,0,0,255]
+PASS: pixel at (74,50) was [0,0,0,0]
+PASS: pixel at (74,54) was [0,0,0,1]
+PASS: pixel at (74,58) was [127,0,0,2]
+PASS: pixel at (74,62) was [95,0,0,16]
+PASS: pixel at (74,66) was [95,0,0,32]
+PASS: pixel at (74,70) was [95,0,0,64]
+PASS: pixel at (74,74) was [95,0,0,96]
+PASS: pixel at (74,78) was [95,0,0,128]
+PASS: pixel at (74,82) was [95,0,0,192]
+PASS: pixel at (74,86) was [96,0,0,254]
+PASS: pixel at (74,90) was [96,0,0,255]
+PASS: pixel at (78,50) was [0,0,0,0]
+PASS: pixel at (78,54) was [255,0,0,1]
+PASS: pixel at (78,58) was [127,0,0,2]
+PASS: pixel at (78,62) was [127,0,0,16]
+PASS: pixel at (78,66) was [127,0,0,32]
+PASS: pixel at (78,70) was [127,0,0,64]
+PASS: pixel at (78,74) was [127,0,0,96]
+PASS: pixel at (78,78) was [127,0,0,128]
+PASS: pixel at (78,82) was [127,0,0,192]
+PASS: pixel at (78,86) was [127,0,0,254]
+PASS: pixel at (78,90) was [128,0,0,255]
+PASS: pixel at (82,50) was [0,0,0,0]
+PASS: pixel at (82,54) was [255,0,0,1]
+PASS: pixel at (82,58) was [255,0,0,2]
+PASS: pixel at (82,62) was [191,0,0,16]
+PASS: pixel at (82,66) was [191,0,0,32]
+PASS: pixel at (82,70) was [191,0,0,64]
+PASS: pixel at (82,74) was [191,0,0,96]
+PASS: pixel at (82,78) was [191,0,0,128]
+PASS: pixel at (82,82) was [192,0,0,192]
+PASS: pixel at (82,86) was [191,0,0,254]
+PASS: pixel at (82,90) was [192,0,0,255]
+PASS: pixel at (86,50) was [0,0,0,0]
+PASS: pixel at (86,54) was [255,0,0,1]
+PASS: pixel at (86,58) was [255,0,0,2]
+PASS: pixel at (86,62) was [255,0,0,16]
+PASS: pixel at (86,66) was [255,0,0,32]
+PASS: pixel at (86,70) was [255,0,0,64]
+PASS: pixel at (86,74) was [255,0,0,96]
+PASS: pixel at (86,78) was [253,0,0,128]
+PASS: pixel at (86,82) was [253,0,0,192]
+PASS: pixel at (86,86) was [253,0,0,254]
+PASS: pixel at (86,90) was [254,0,0,255]
+PASS: pixel at (90,50) was [0,0,0,0]
+PASS: pixel at (90,54) was [255,0,0,1]
+PASS: pixel at (90,58) was [255,0,0,2]
+PASS: pixel at (90,62) was [255,0,0,16]
+PASS: pixel at (90,66) was [255,0,0,32]
+PASS: pixel at (90,70) was [255,0,0,64]
+PASS: pixel at (90,74) was [255,0,0,96]
+PASS: pixel at (90,78) was [255,0,0,128]
+PASS: pixel at (90,82) was [255,0,0,192]
+PASS: pixel at (90,86) was [255,0,0,254]
+PASS: pixel at (90,90) was [255,0,0,255]
+
--- /dev/null
+This test ensures that getImageData works correctly.
+<div id="log"></div>
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+var canvas = document.createElement("canvas");
+canvas.width = 200;
+canvas.height = 200;
+var context = canvas.getContext("2d");
+
+function log(msg){
+ document.getElementById("log").innerHTML += msg + "<br/>";
+}
+
+function dataToArray(data) {
+ var result = new Array(data.length)
+ for (var i = 0; i < data.length; i++)
+ result[i] = data[i];
+ return result;
+}
+
+function getPixel(ctx, x, y) {
+ var data = ctx.getImageData(x,y,1,1);
+ if (!data) // getImageData failed, which should never happen
+ return [-1,-1,-1,-1];
+ return dataToArray(data.data);
+}
+
+function pixelShouldBe(ctx, x, y, colour) {
+ var ctxColour = getPixel(ctx, x, y);
+ var correct = true;
+ for (var i = 0; i < 4; i++)
+ if (colour[i] != ctxColour[i]) {
+ correct = false;
+ break;
+ }
+ if (correct)
+ log("PASS: pixel at ("+[x,y]+") was ["+colour+"]");
+ else
+ log("FAIL: pixel at ("+[x,y]+") was ["+ctxColour+"], expected ["+colour+"]");
+}
+
+if (!context.setFillColor)
+ context.setFillColor = function(r,g,b,a) {
+ this.fillStyle = "rgba("+[Math.round(r*255),Math.round(g*255),Math.round(b*255),Math.round(a*255)]+")"
+ }
+
+// Check that getImageData is return the data for the right portion of the image
+for(var x = 0; x < 100; x+=4) {
+ context.setFillColor(0, x/96, 0, 1);
+ context.fillRect(x,0,1,1);
+ pixelShouldBe(context, x, 0, [0, Math.round(255*x/96), 0, 255]);
+}
+
+// Check rgba ordering
+context.clearRect(0,0,100,100);
+context.setFillColor(0.25, 0.5, 0.75, 1);
+context.fillRect(5,5,1,1);
+pixelShouldBe(context, 5, 5, [Math.round(0.25*255), Math.round(0.5*255), Math.round(0.75*255), 255]);
+
+// Check that we return transparent black for regions outside the canvas proper
+context.fillStyle = "rgba(255,255,255,255)";
+context.fillRect(198, 5, 4, 1); // final 2 pixels horizontally should be clipped
+var content = dataToArray(context.getImageData(198, 5, 4, 1).data);
+var expected = [255,255,255,255,255,255,255,255,
+ 0,0,0,0,0,0,0,0];
+var matched = true;
+for (var i = 0; i < 16; i++)
+ if (content[i] != expected[i]) {
+ matched = false;
+ break;
+ }
+if (matched)
+ log("PASS: Correct data for content outside canvas bounds");
+else
+ log("FAIL: Did not get correct data for content outside canvas bounds: "+content);
+
+// Ensure returned values are not premultiplied
+var values = [0,1,2,16,32,64,96,128,192,254,255];
+
+// this function simply accounts for truncation due to premultiplication in the canvas implementation
+function premult(value, alpha) {
+ return alpha ? Math.floor(Math.round(value*alpha/255)*255/alpha) : 0;
+}
+
+for (var i = 0; i < values.length; i++) {
+ for (var a = 0; a < values.length; a++) {
+ context.fillStyle = "rgba(" + [values[i], 0, 0, values[a]/255] +")";
+ context.fillRect(50+i*4,50+a*4,2,2);
+ pixelShouldBe(context, 50+i*4, 50+a*4, [premult(values[i], values[a]), 0, 0, values[a]]);
+ }
+}
+
+</script>
+2008-02-22 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Sam W.
+
+ Support Canvas.getImageData and Canvas.createImageData
+
+ This patch adds support for all the pixel reading portions
+ of the HTML5 Canvas spec. There are two new types ImageData
+ and CanvasPixelArray which are used to provide the HTML5
+ ImageData object, and the required semantics for assignment
+ to the ImageData data array.
+
+ We only implement the CG version of ImageBuffer::getImageData,
+ but the logic is null safe, so this will not introduce any
+ crashes into other platforms, unfortunately it will result in
+ JS Object detection "lying" on non-CG platforms.
+
+ Tests: fast/canvas/canvas-ImageData-behaviour.html
+ fast/canvas/canvas-getImageData.html
+
+ * DerivedSources.make:
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/JSCanvasPixelArrayCustom.cpp: Added.
+ (WebCore::JSCanvasPixelArray::indexGetter):
+ (WebCore::JSCanvasPixelArray::indexSetter):
+ (WebCore::toJS):
+ * bindings/js/JSCanvasRenderingContext2DCustom.cpp:
+ * bindings/scripts/CodeGeneratorJS.pm:
+ * html/CanvasPixelArray.cpp: Added.
+ (WebCore::CanvasPixelArray::create):
+ * html/CanvasPixelArray.h: Added.
+ (WebCore::CanvasPixelArray::data):
+ (WebCore::CanvasPixelArray::length):
+ (WebCore::CanvasPixelArray::set):
+ (WebCore::CanvasPixelArray::get):
+ * html/CanvasPixelArray.idl: Added.
+ * html/CanvasRenderingContext2D.cpp:
+ (WebCore::createEmptyImageData):
+ (WebCore::CanvasRenderingContext2D::createImageData):
+ (WebCore::CanvasRenderingContext2D::getImageData):
+ * html/CanvasRenderingContext2D.h:
+ * html/CanvasRenderingContext2D.idl:
+ * html/HTMLCanvasElement.cpp:
+ (WebCore::HTMLCanvasElement::convertLogicalToDevice):
+ (WebCore::HTMLCanvasElement::createImageBuffer):
+ * html/HTMLCanvasElement.h:
+ * html/ImageData.cpp: Added.
+ (WebCore::ImageData::create):
+ (WebCore::ImageData::ImageData):
+ * html/ImageData.h: Added.
+ (WebCore::ImageData::width):
+ (WebCore::ImageData::height):
+ (WebCore::ImageData::data):
+ * html/ImageData.idl: Added.
+ * platform/graphics/ImageBuffer.h:
+ * platform/graphics/cairo/ImageBufferCairo.cpp:
+ (WebCore::ImageBuffer::getImageData):
+ * platform/graphics/cg/ImageBufferCG.cpp:
+ (WebCore::ImageBuffer::getImageData):
+ * platform/graphics/qt/ImageBufferQt.cpp:
+ (WebCore::ImageBuffer::getImageData):
+ * platform/graphics/wx/ImageBufferWx.cpp:
+ (WebCore::ImageBuffer::getImageData):
+
2008-02-22 Sam Weinig <sam@webkit.org>
Rubber-stamped by Adam Roben.
JSCSSValueList.h \
JSCanvasGradient.h \
JSCanvasPattern.h \
+ JSCanvasPixelArray.h \
JSCanvasRenderingContext2D.h \
JSCharacterData.h \
JSComment.h \
JSHTMLUListElement.h \
JSHTMLVideoElement.h \
JSHistory.h \
+ JSImageData.h \
JSKeyboardEvent.h \
JSLocation.lut.h \
JSMediaError.h \
DerivedSources/JSCSSValueList.h \
DerivedSources/JSCanvasGradient.h \
DerivedSources/JSCanvasPattern.h \
+ DerivedSources/JSCanvasPixelArray.h \
DerivedSources/JSCanvasRenderingContext2D.h \
DerivedSources/JSCharacterData.h \
DerivedSources/JSComment.h \
DerivedSources/JSHTMLTitleElement.h \
DerivedSources/JSHTMLUListElement.h \
DerivedSources/JSHistory.h \
+ DerivedSources/JSImageData.h \
DerivedSources/JSKeyboardEvent.h \
DerivedSources/JSMediaList.h \
DerivedSources/JSMouseEvent.h \
DerivedSources/JSCSSValueList.cpp \
DerivedSources/JSCanvasGradient.cpp \
DerivedSources/JSCanvasPattern.cpp \
+ DerivedSources/JSCanvasPixelArray.cpp \
DerivedSources/JSCanvasRenderingContext2D.cpp \
DerivedSources/JSCharacterData.cpp \
DerivedSources/JSComment.cpp \
DerivedSources/JSHTMLTitleElement.cpp \
DerivedSources/JSHTMLUListElement.cpp \
DerivedSources/JSHistory.cpp \
+ DerivedSources/JSImageData.cpp \
DerivedSources/JSKeyboardEvent.cpp \
DerivedSources/JSMediaList.cpp \
DerivedSources/JSMouseEvent.cpp \
webcore_sources += \
WebCore/bindings/js/GCController.cpp \
WebCore/bindings/js/JSAttrCustom.cpp \
+ WebCore/bindings/js/JSCanvasPixelArrayCustom.cpp \
WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp \
WebCore/bindings/js/JSCSSRuleCustom.cpp \
WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp \
WebCore/history/PageCache.cpp \
WebCore/html/CanvasGradient.cpp \
WebCore/html/CanvasPattern.cpp \
+ WebCore/html/CanvasPixelArray.cpp \
WebCore/html/CanvasRenderingContext2D.cpp \
WebCore/html/CanvasStyle.cpp \
WebCore/html/FormDataList.cpp \
WebCore/html/HTMLTokenizer.cpp \
WebCore/html/HTMLUListElement.cpp \
WebCore/html/HTMLViewSourceDocument.cpp \
+ WebCore/html/ImageData.cpp \
WebCore/loader/Cache.cpp \
WebCore/loader/CachedCSSStyleSheet.cpp \
WebCore/loader/CachedFont.cpp \
dom/WheelEvent.idl \
html/CanvasGradient.idl \
html/CanvasPattern.idl \
+ html/CanvasPixelArray.idl \
html/CanvasRenderingContext2D.idl \
html/HTMLAnchorElement.idl \
html/HTMLAppletElement.idl \
html/HTMLTextAreaElement.idl \
html/HTMLTitleElement.idl \
html/HTMLUListElement.idl \
+ html/ImageData.idl \
page/BarInfo.idl \
page/Console.idl \
page/DOMSelection.idl \
SOURCES += \
bindings/js/GCController.cpp \
bindings/js/JSAttrCustom.cpp \
+ bindings/js/JSCanvasPixelArrayCustom.cpp \
bindings/js/JSCanvasRenderingContext2DCustom.cpp \
bindings/js/JSCSSRuleCustom.cpp \
bindings/js/JSCSSStyleDeclarationCustom.cpp \
history/PageCache.cpp \
html/CanvasGradient.cpp \
html/CanvasPattern.cpp \
+ html/CanvasPixelArray.cpp \
html/CanvasRenderingContext2D.cpp \
html/CanvasStyle.cpp \
html/FormDataList.cpp \
html/HTMLTokenizer.cpp \
html/HTMLUListElement.cpp \
html/HTMLViewSourceDocument.cpp \
+ html/ImageData.cpp \
loader/Cache.cpp \
loader/CachedCSSStyleSheet.cpp \
loader/CachedFont.cpp \
>\r
</File>\r
<File\r
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSCanvasPixelArray.cpp"\r
+ >\r
+ <File\r
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSCanvasPixelArray.h"\r
+ >\r
+ <File\r
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSCanvasRenderingContext2D.cpp"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSImageData.cpp"\r
+ >\r
+ <File\r
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSImageData.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSKeyboardEvent.cpp"\r
>\r
</File>\r
<File\r
RelativePath="..\html\CanvasPattern.h"\r
>\r
+ <File\r
+ RelativePath="..\html\CanvasPixelArray.cpp"\r
+ >\r
+ <File\r
+ RelativePath="..\html\CanvasPixelArray.h"\r
+ >\r
</File>\r
<File\r
RelativePath="..\html\CanvasRenderingContext2D.cpp"\r
>\r
</File>\r
<File\r
+ RelativePath="..\html\ImageData.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\html\ImageData.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath="..\html\MediaError.h"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath="..\bindings\js\JSCanvasPixelArrayCustom.cpp"\r
+ >\r
+ <File\r
RelativePath="..\bindings\js\JSLocation.cpp"\r
>\r
</File>\r
A71878900B2D04AC00A16ECE /* DragControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = A718788F0B2D04AC00A16ECE /* DragControllerMac.mm */; };
A7352C190B1BB89D00A986D0 /* RenderSVGBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7352C170B1BB89D00A986D0 /* RenderSVGBlock.cpp */; };
A7352C1A0B1BB89D00A986D0 /* RenderSVGBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = A7352C180B1BB89D00A986D0 /* RenderSVGBlock.h */; };
+ A766F3530D6BDE3500ABDDB3 /* JSCanvasPixelArrayCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A766F3520D6BDE3500ABDDB3 /* JSCanvasPixelArrayCustom.cpp */; };
+ A77979160D6B9D0C003851B9 /* CanvasPixelArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A77979100D6B9D0C003851B9 /* CanvasPixelArray.cpp */; };
+ A77979170D6B9D0C003851B9 /* CanvasPixelArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A77979110D6B9D0C003851B9 /* CanvasPixelArray.h */; };
+ A77979180D6B9D0C003851B9 /* CanvasPixelArray.idl in Resources */ = {isa = PBXBuildFile; fileRef = A77979120D6B9D0C003851B9 /* CanvasPixelArray.idl */; };
+ A77979190D6B9D0C003851B9 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A77979130D6B9D0C003851B9 /* ImageData.cpp */; };
+ A779791A0D6B9D0C003851B9 /* ImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = A77979140D6B9D0C003851B9 /* ImageData.h */; };
+ A779791B0D6B9D0C003851B9 /* ImageData.idl in Resources */ = {isa = PBXBuildFile; fileRef = A77979150D6B9D0C003851B9 /* ImageData.idl */; };
+ A77979260D6B9E64003851B9 /* JSCanvasPixelArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A77979220D6B9E64003851B9 /* JSCanvasPixelArray.cpp */; };
+ A77979270D6B9E64003851B9 /* JSCanvasPixelArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A77979230D6B9E64003851B9 /* JSCanvasPixelArray.h */; };
+ A77979280D6B9E64003851B9 /* JSImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A77979240D6B9E64003851B9 /* JSImageData.cpp */; };
+ A77979290D6B9E64003851B9 /* JSImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = A77979250D6B9E64003851B9 /* JSImageData.h */; };
A784941B0B5FE507001E237A /* Clipboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A784941A0B5FE507001E237A /* Clipboard.cpp */; };
A795463E0B5C4C80007B438F /* DragDataMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = A795463D0B5C4C80007B438F /* DragDataMac.mm */; };
A79546430B5C4CB4007B438F /* DragData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A79546420B5C4CB4007B438F /* DragData.cpp */; };
A718788F0B2D04AC00A16ECE /* DragControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DragControllerMac.mm; sourceTree = "<group>"; };
A7352C170B1BB89D00A986D0 /* RenderSVGBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGBlock.cpp; sourceTree = "<group>"; };
A7352C180B1BB89D00A986D0 /* RenderSVGBlock.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderSVGBlock.h; sourceTree = "<group>"; };
+ A766F3520D6BDE3500ABDDB3 /* JSCanvasPixelArrayCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCanvasPixelArrayCustom.cpp; sourceTree = "<group>"; };
+ A77979100D6B9D0C003851B9 /* CanvasPixelArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CanvasPixelArray.cpp; sourceTree = "<group>"; };
+ A77979110D6B9D0C003851B9 /* CanvasPixelArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CanvasPixelArray.h; sourceTree = "<group>"; };
+ A77979120D6B9D0C003851B9 /* CanvasPixelArray.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CanvasPixelArray.idl; sourceTree = "<group>"; };
+ A77979130D6B9D0C003851B9 /* ImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = "<group>"; };
+ A77979140D6B9D0C003851B9 /* ImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = "<group>"; };
+ A77979150D6B9D0C003851B9 /* ImageData.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ImageData.idl; sourceTree = "<group>"; };
+ A77979220D6B9E64003851B9 /* JSCanvasPixelArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCanvasPixelArray.cpp; sourceTree = "<group>"; };
+ A77979230D6B9E64003851B9 /* JSCanvasPixelArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCanvasPixelArray.h; sourceTree = "<group>"; };
+ A77979240D6B9E64003851B9 /* JSImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSImageData.cpp; sourceTree = "<group>"; };
+ A77979250D6B9E64003851B9 /* JSImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSImageData.h; sourceTree = "<group>"; };
A784941A0B5FE507001E237A /* Clipboard.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Clipboard.cpp; sourceTree = "<group>"; };
A795463D0B5C4C80007B438F /* DragDataMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = DragDataMac.mm; sourceTree = "<group>"; };
A79546420B5C4CB4007B438F /* DragData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DragData.cpp; sourceTree = "<group>"; };
93EEC1EC09C2877700C515D1 /* html */ = {
isa = PBXGroup;
children = (
+ A77979100D6B9D0C003851B9 /* CanvasPixelArray.cpp */,
+ A77979110D6B9D0C003851B9 /* CanvasPixelArray.h */,
+ A77979120D6B9D0C003851B9 /* CanvasPixelArray.idl */,
+ A77979130D6B9D0C003851B9 /* ImageData.cpp */,
+ A77979140D6B9D0C003851B9 /* ImageData.h */,
+ A77979150D6B9D0C003851B9 /* ImageData.idl */,
93EEC1F009C2877700C515D1 /* CanvasGradient.cpp */,
93EEC1F109C2877700C515D1 /* CanvasGradient.h */,
930CAB8809C49EFA00229C04 /* CanvasGradient.idl */,
A83B79080CCAFF2B000B0825 /* HTML */ = {
isa = PBXGroup;
children = (
+ A77979220D6B9E64003851B9 /* JSCanvasPixelArray.cpp */,
+ A77979230D6B9E64003851B9 /* JSCanvasPixelArray.h */,
+ A77979240D6B9E64003851B9 /* JSImageData.cpp */,
+ A77979250D6B9E64003851B9 /* JSImageData.h */,
65DF323309D1DE65000BE325 /* JSCanvasGradient.cpp */,
65DF323409D1DE65000BE325 /* JSCanvasGradient.h */,
65DF323509D1DE65000BE325 /* JSCanvasPattern.cpp */,
BC4EDEF70C08F414007EDD49 /* Custom */ = {
isa = PBXGroup;
children = (
+ A766F3520D6BDE3500ABDDB3 /* JSCanvasPixelArrayCustom.cpp */,
BC2ED6BB0C6BD2F000920BFF /* JSAttrCustom.cpp */,
1A9EF4560A1B957D00332B63 /* JSCanvasRenderingContext2DCustom.cpp */,
BC46C1ED0C0DDBDF0020CFC3 /* JSCSSRuleCustom.cpp */,
BCC573350D695BBE006EF517 /* DOMProgressEvent.h in Headers */,
BCC573380D695BD7006EF517 /* DOMProgressEventInternal.h in Headers */,
BCC5733A0D695BF1006EF517 /* DOMTextPrivate.h in Headers */,
+ A77979170D6B9D0C003851B9 /* CanvasPixelArray.h in Headers */,
+ A779791A0D6B9D0C003851B9 /* ImageData.h in Headers */,
+ A77979270D6B9E64003851B9 /* JSCanvasPixelArray.h in Headers */,
+ A77979290D6B9E64003851B9 /* JSImageData.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
85136CA80AED665900F90A3D /* westResizeCursor.png in Resources */,
1AB1AE7A0C051FDE00139F4F /* zoomInCursor.png in Resources */,
1AB1AE7B0C051FDE00139F4F /* zoomOutCursor.png in Resources */,
+ A77979180D6B9D0C003851B9 /* CanvasPixelArray.idl in Resources */,
+ A779791B0D6B9D0C003851B9 /* ImageData.idl in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
C0294DF30D5A6FD800CC7D6B /* UserStyleSheetLoader.cpp in Sources */,
37F818FE0D657606005E1F05 /* WebCoreURLResponse.mm in Sources */,
BCC573360D695BBE006EF517 /* DOMProgressEvent.mm in Sources */,
+ A77979160D6B9D0C003851B9 /* CanvasPixelArray.cpp in Sources */,
+ A77979190D6B9D0C003851B9 /* ImageData.cpp in Sources */,
+ A77979260D6B9E64003851B9 /* JSCanvasPixelArray.cpp in Sources */,
+ A77979280D6B9E64003851B9 /* JSImageData.cpp in Sources */,
+ A766F3530D6BDE3500ABDDB3 /* JSCanvasPixelArrayCustom.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSCanvasPixelArray.h"
+
+#include "CanvasPixelArray.h"
+
+using namespace KJS;
+
+namespace WebCore {
+
+JSValue* JSCanvasPixelArray::indexGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
+{
+ CanvasPixelArray* array = static_cast<JSCanvasPixelArray*>(slot.slotBase())->impl();
+ unsigned index = slot.index();
+ unsigned char result;
+ if (array->get(index, result))
+ return jsNumber(result);
+ return jsUndefined();
+}
+
+void JSCanvasPixelArray::indexSetter(ExecState* exec, unsigned index, JSValue* value, int)
+{
+ if (index >= m_impl->length())
+ return;
+ double pixelValue = value->toNumber(exec);
+ if (exec->hadException())
+ return;
+ m_impl->set(index, pixelValue);
+}
+
+JSValue* toJS(ExecState* exec, CanvasPixelArray* pixels)
+{
+ if (!pixels)
+ return jsNull();
+
+ DOMObject* ret = ScriptInterpreter::getDOMObject(pixels);
+ if (ret)
+ return ret;
+
+ ret = new JSCanvasPixelArray(JSCanvasPixelArrayPrototype::self(exec), pixels);
+
+ Collector::reportExtraMemoryCost(pixels->length());
+
+ ScriptInterpreter::putDOMObject(pixels, ret);
+
+ return ret;
+}
+
+} // namespace WebCore
return 0;
}
+JSValue* JSCanvasRenderingContext2D::putImageData(ExecState* exec, const List& args)
+{
+ return jsUndefined();
+}
+
} // namespace WebCore
{
my $type = shift;
- return 1 if $type eq "Node" or $type eq "Document" or $type eq "HTMLCollection" or $type eq "SVGPathSeg" or $type eq "StyleSheet" or $type eq "CSSRule" or $type eq "CSSValue" or $type eq "Event";
+ return 1 if $type eq "Node" or $type eq "Document" or $type eq "HTMLCollection" or $type eq "SVGPathSeg" or $type eq "StyleSheet" or $type eq "CSSRule" or $type eq "CSSValue" or $type eq "Event" or $type eq "CanvasPixelArray";
return 0;
}
# Destructor
push(@headerContent, " virtual ~$className();\n") if (!$hasParent or $interfaceName eq "Document");
+ my $hasGetter = $numAttributes > 0
+ || $dataNode->extendedAttributes->{"GenerateConstructor"}
+ || $dataNode->extendedAttributes->{"HasIndexGetter"}
+ || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}
+ || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}
+ || $dataNode->extendedAttributes->{"HasNameGetter"}
+ || $dataNode->extendedAttributes->{"HasOverridingNameGetter"};
+
# Getters
- if ($numAttributes > 0 || $dataNode->extendedAttributes->{"GenerateConstructor"}) {
+ if ($hasGetter) {
push(@headerContent, " virtual bool getOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&);\n");
- push(@headerContent, " KJS::JSValue* getValueProperty(KJS::ExecState*, int token) const;\n");
+ push(@headerContent, " KJS::JSValue* getValueProperty(KJS::ExecState*, int token) const;\n") if $numAttributes > 0 || $dataNode->extendedAttributes->{"GenerateConstructor"};
push(@headerContent, " bool customGetOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&);\n") if $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
}
}
}
- push(@headerContent, " virtual void put(KJS::ExecState*, const KJS::Identifier&, KJS::JSValue*, int attr = KJS::None);\n") if ($hasReadWriteProperties || $dataNode->extendedAttributes->{"CustomPutFunction"});
- push(@headerContent, " void putValueProperty(KJS::ExecState*, int, KJS::JSValue*, int attr);\n") if $hasReadWriteProperties;
- push(@headerContent, " bool customPut(KJS::ExecState*, const KJS::Identifier&, KJS::JSValue*, int attr);\n") if $dataNode->extendedAttributes->{"CustomPutFunction"};
+ my $hasSetter = $hasReadWriteProperties
+ || $dataNode->extendedAttributes->{"CustomPutFunction"}
+ || $dataNode->extendedAttributes->{"HasCustomIndexSetter"};
+
+ # Getters
+ if ($hasSetter) {
+ push(@headerContent, " virtual void put(KJS::ExecState*, const KJS::Identifier&, KJS::JSValue*, int attr = KJS::None);\n");
+ push(@headerContent, " void putValueProperty(KJS::ExecState*, int, KJS::JSValue*, int attr);\n") if $hasReadWriteProperties;
+ push(@headerContent, " bool customPut(KJS::ExecState*, const KJS::Identifier&, KJS::JSValue*, int attr);\n") if $dataNode->extendedAttributes->{"CustomPutFunction"};
+ }
# Class info
push(@headerContent, " virtual const KJS::ClassInfo* classInfo() const { return &info; }\n");
push(@headerContent, " virtual bool deleteProperty(KJS::ExecState*, const KJS::Identifier&);\n") if $dataNode->extendedAttributes->{"CustomDeleteProperty"};
# Custom getPropertyNames function
- push(@headerContent, " virtual void getPropertyNames(KJS::ExecState*, KJS::PropertyNameArray&);\n") if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"} || $dataNode->extendedAttributes->{"HasIndexGetter"});
+ push(@headerContent, " virtual void getPropertyNames(KJS::ExecState*, KJS::PropertyNameArray&);\n") if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"} || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"});
push(@headerContent, " bool customGetPropertyNames(KJS::ExecState*, KJS::PropertyNameArray&);\n") if $dataNode->extendedAttributes->{"CustomGetPropertyNames"};
# Constructor object getter
}
}
- # Index setter
- if ($dataNode->extendedAttributes->{"HasCustomIndexSetter"}) {
- push(@headerContent, " void indexSetter(KJS::ExecState*, unsigned index, KJS::JSValue*, int attr);\n");
- }
if (!$hasParent) {
if ($podType) {
}
# Index getter
- if ($dataNode->extendedAttributes->{"HasIndexGetter"}) {
- push(@headerContent, "private:\n");
+ if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) {
push(@headerContent, " static KJS::JSValue* indexGetter(KJS::ExecState*, KJS::JSObject*, const KJS::Identifier&, const KJS::PropertySlot&);\n");
}
+
+ # Index setter
+ if ($dataNode->extendedAttributes->{"HasCustomIndexSetter"}) {
+ push(@headerContent, " void indexSetter(KJS::ExecState*, unsigned index, KJS::JSValue*, int attr);\n");
+ }
# Name getter
if ($dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"}) {
push(@headerContent, "private:\n");
push(@implContentHeader, "#include \"$className.h\"\n\n");
push(@implContentHeader, "#include <wtf/GetPtr.h>\n\n");
- push(@implContentHeader, "#include <kjs/PropertyNameArray.h>\n") if $dataNode->extendedAttributes->{"HasIndexGetter"};
+ push(@implContentHeader, "#include <kjs/PropertyNameArray.h>\n") if $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"};
AddIncludesForType($interfaceName);
push(@implContent, "{\n ScriptInterpreter::forgetDOMObject(static_cast<${implClassName}*>(impl()));\n}\n\n");
}
+ my $hasGetter = $numAttributes > 0
+ || $dataNode->extendedAttributes->{"GenerateConstructor"}
+ || $dataNode->extendedAttributes->{"HasIndexGetter"}
+ || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}
+ || $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}
+ || $dataNode->extendedAttributes->{"HasNameGetter"}
+ || $dataNode->extendedAttributes->{"HasOverridingNameGetter"};
+
# Attributes
- if ($numAttributes ne 0) {
+ if ($hasGetter) {
push(@implContent, "bool ${className}::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)\n");
push(@implContent, "{\n");
&$hasNameGetterGeneration();
}
- my $requiresManualLookup = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasNameGetter"};
+ my $requiresManualLookup = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"};
if ($requiresManualLookup) {
push(@implContent, " const HashEntry* entry = Lookup::findEntry(&${className}Table, propertyName);\n");
push(@implContent, " if (entry) {\n");
push(@implContent, " }\n");
}
- if ($dataNode->extendedAttributes->{"HasIndexGetter"}) {
+ if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) {
push(@implContent, " bool ok;\n");
push(@implContent, " unsigned index = propertyName.toUInt32(&ok, false);\n");
push(@implContent, " if (ok && index < static_cast<$implClassName*>(impl())->length()) {\n");
push(@implContent, " return true;\n");
}
- if ($requiresManualLookup) {
- push(@implContent, " return Base::getOwnPropertySlot(exec, propertyName, slot);\n");
- } else {
+ if ($numAttributes > 0) {
push(@implContent, " return getStaticValueSlot<$className, Base>(exec, &${className}Table, this, propertyName, slot);\n");
+ } else {
+ push(@implContent, " return Base::getOwnPropertySlot(exec, propertyName, slot);\n");
}
push(@implContent, "}\n\n");
- push(@implContent, "JSValue* ${className}::getValueProperty(ExecState* exec, int token) const\n{\n");
+ if ($numAttributes > 0) {
+ push(@implContent, "JSValue* ${className}::getValueProperty(ExecState* exec, int token) const\n");
+ push(@implContent, "{\n");
- push(@implContent, " switch (token) {\n");
+ push(@implContent, " switch (token) {\n");
- foreach my $attribute (@{$dataNode->attributes}) {
- my $getterFunctionName = $codeGenerator->WK_lcfirst($attribute->signature->name);
+ foreach my $attribute (@{$dataNode->attributes}) {
+ my $getterFunctionName = $codeGenerator->WK_lcfirst($attribute->signature->name);
- my $implClassNameForValueConversion = "";
- if (!$podType and ($codeGenerator->IsSVGAnimatedType($implClassName) or $attribute->type !~ /^readonly/)) {
- $implClassNameForValueConversion = $implClassName;
- }
+ my $implClassNameForValueConversion = "";
+ if (!$podType and ($codeGenerator->IsSVGAnimatedType($implClassName) or $attribute->type !~ /^readonly/)) {
+ $implClassNameForValueConversion = $implClassName;
+ }
- push(@implContent, " case " . $codeGenerator->WK_ucfirst($attribute->signature->name)
- . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : "")
- . "AttrNum: {\n");
+ push(@implContent, " case " . $codeGenerator->WK_ucfirst($attribute->signature->name)
+ . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : "")
+ . "AttrNum: {\n");
- if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} &&
- !$attribute->signature->extendedAttributes->{"DoNotCheckDomainSecurity"} &&
- !$attribute->signature->extendedAttributes->{"DoNotCheckDomainSecurityOnGet"}) {
- push(@implContent, " if (!allowsAccessFrom(exec))\n");
- push(@implContent, " return jsUndefined();\n");
- }
+ if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} &&
+ !$attribute->signature->extendedAttributes->{"DoNotCheckDomainSecurity"} &&
+ !$attribute->signature->extendedAttributes->{"DoNotCheckDomainSecurityOnGet"}) {
+ push(@implContent, " if (!allowsAccessFrom(exec))\n");
+ push(@implContent, " return jsUndefined();\n");
+ }
- if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"CustomGetter"}) {
- push(@implContent, " return $getterFunctionName(exec);\n");
- } elsif ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
- $implIncludes{"kjs_dom.h"} = 1;
- push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(impl());\n");
- push(@implContent, " return checkNodeSecurity(exec, imp->$getterFunctionName()) ? " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$getterFunctionName()") . " : jsUndefined();\n");
- } elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) {
- $implIncludes{"Document.h"} = 1;
- $implIncludes{"kjs_dom.h"} = 1;
- push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(impl());\n");
- push(@implContent, " return checkNodeSecurity(exec, imp->contentDocument()) ? " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$getterFunctionName()") . " : jsUndefined();\n");
- } elsif ($attribute->signature->type =~ /Constructor$/) {
- my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
- $constructorType =~ s/Constructor$//;
- push(@implContent, " return JS" . $constructorType . "::getConstructor(exec);\n");
- } elsif (!@{$attribute->getterExceptions}) {
- if ($podType) {
- push(@implContent, " $podType imp(*impl());\n");
- if ($podType eq "float") { # Special case for JSSVGNumber
- push(@implContent, " return " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp") . ";\n");
+ if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"CustomGetter"}) {
+ push(@implContent, " return $getterFunctionName(exec);\n");
+ } elsif ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
+ $implIncludes{"kjs_dom.h"} = 1;
+ push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(impl());\n");
+ push(@implContent, " return checkNodeSecurity(exec, imp->$getterFunctionName()) ? " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$getterFunctionName()") . " : jsUndefined();\n");
+ } elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) {
+ $implIncludes{"Document.h"} = 1;
+ $implIncludes{"kjs_dom.h"} = 1;
+ push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(impl());\n");
+ push(@implContent, " return checkNodeSecurity(exec, imp->contentDocument()) ? " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$getterFunctionName()") . " : jsUndefined();\n");
+ } elsif ($attribute->signature->type =~ /Constructor$/) {
+ my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
+ $constructorType =~ s/Constructor$//;
+ push(@implContent, " return JS" . $constructorType . "::getConstructor(exec);\n");
+ } elsif (!@{$attribute->getterExceptions}) {
+ if ($podType) {
+ push(@implContent, " $podType imp(*impl());\n");
+ if ($podType eq "float") { # Special case for JSSVGNumber
+ push(@implContent, " return " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp") . ";\n");
+ } else {
+ push(@implContent, " return " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp.$getterFunctionName()") . ";\n");
+ }
} else {
- push(@implContent, " return " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp.$getterFunctionName()") . ";\n");
+ push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(impl());\n");
+ my $type = $codeGenerator->StripModule($attribute->signature->type);
+ my $jsType = NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$getterFunctionName()");
+ if ($codeGenerator->IsSVGAnimatedType($type)) {
+ push(@implContent, " RefPtr<$type> obj = $jsType;\n");
+ push(@implContent, " return toJS(exec, obj.get(), imp);\n");
+ } else {
+ push(@implContent, " return $jsType;\n");
+ }
}
} else {
- push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(impl());\n");
- my $type = $codeGenerator->StripModule($attribute->signature->type);
- my $jsType = NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$getterFunctionName()");
- if ($codeGenerator->IsSVGAnimatedType($type)) {
- push(@implContent, " RefPtr<$type> obj = $jsType;\n");
- push(@implContent, " return toJS(exec, obj.get(), imp);\n");
+ push(@implContent, " ExceptionCode ec = 0;\n");
+
+ if ($podType) {
+ push(@implContent, " $podType imp(*impl());\n");
+ push(@implContent, " KJS::JSValue* result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp.$getterFunctionName(ec)") . ";\n");
} else {
- push(@implContent, " return $jsType;\n");
+ push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(impl());\n");
+ push(@implContent, " KJS::JSValue* result = " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$getterFunctionName(ec)") . ";\n");
}
- }
- } else {
- push(@implContent, " ExceptionCode ec = 0;\n");
- if ($podType) {
- push(@implContent, " $podType imp(*impl());\n");
- push(@implContent, " KJS::JSValue* result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp.$getterFunctionName(ec)") . ";\n");
- } else {
- push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(impl());\n");
- push(@implContent, " KJS::JSValue* result = " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$getterFunctionName(ec)") . ";\n");
+ push(@implContent, " setDOMException(exec, ec);\n");
+ push(@implContent, " return result;\n");
}
+ push(@implContent, " }\n");
+ }
- push(@implContent, " setDOMException(exec, ec);\n");
- push(@implContent, " return result;\n");
+ if ($dataNode->extendedAttributes->{"GenerateConstructor"}) {
+ push(@implContent, " case ConstructorAttrNum:\n");
+ push(@implContent, " return getConstructor(exec);\n");
}
- push(@implContent, " }\n");
- }
- if ($dataNode->extendedAttributes->{"GenerateConstructor"}) {
- push(@implContent, " case ConstructorAttrNum:\n");
- push(@implContent, " return getConstructor(exec);\n");
+ push(@implContent, " }\n");
+ push(@implContent, " return 0;\n");
+ push(@implContent, "}\n\n");
}
- push(@implContent, " }\n");
- push(@implContent, " return 0;\n}\n\n");
-
# Check if we have any writable attributes
my $hasReadWriteProperties = 0;
foreach my $attribute (@{$dataNode->attributes}) {
$hasReadWriteProperties = 1 if $attribute->type !~ /^readonly/;
}
- if ($hasReadWriteProperties || $dataNode->extendedAttributes->{"CustomPutFunction"}) {
+
+ my $hasSetter = $hasReadWriteProperties
+ || $dataNode->extendedAttributes->{"CustomPutFunction"}
+ || $dataNode->extendedAttributes->{"HasCustomIndexSetter"};
+
+ if ($hasSetter) {
push(@implContent, "void ${className}::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)\n");
push(@implContent, "{\n");
if ($dataNode->extendedAttributes->{"HasCustomIndexSetter"}) {
push(@implContent, " if (customPut(exec, propertyName, value, attr))\n");
push(@implContent, " return;\n");
}
+
if ($hasReadWriteProperties) {
push(@implContent, " lookupPut<$className, Base>(exec, propertyName, value, attr, &${className}Table, this);\n");
} else {
}
}
- if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"} || $dataNode->extendedAttributes->{"HasIndexGetter"}) {
+ if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"} || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) {
push(@implContent, "void ${className}::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)\n");
push(@implContent, "{\n");
if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"}) {
push(@implContent, " if (customGetPropertyNames(exec, propertyNames))\n");
push(@implContent, " return;\n");
}
- if ($dataNode->extendedAttributes->{"HasIndexGetter"}) {
+ if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) {
push(@implContent, " for (unsigned i = 0; i < static_cast<${implClassName}*>(impl())->length(); ++i)\n");
push(@implContent, " propertyNames.add(Identifier::from(i));\n");
}
close($IMPL);
undef($IMPL);
- @implHeaderContent = ();
+ @implContentHeader = ();
@implContent = ();
%implIncludes = ();
}
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CanvasPixelArray.h"
+
+namespace WebCore {
+
+PassRefPtr<CanvasPixelArray> CanvasPixelArray::create(unsigned size)
+{
+ return adoptRef(new CanvasPixelArray(size));
+}
+
+CanvasPixelArray::CanvasPixelArray(unsigned size)
+ : m_data(size)
+{
+}
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CanvasPixelArray_h
+#define CanvasPixelArray_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class CanvasPixelArray : public RefCounted<CanvasPixelArray> {
+ public:
+ static PassRefPtr<CanvasPixelArray> create(unsigned size);
+ Vector<unsigned char>& data() { return m_data; }
+ unsigned length() const { return m_data.size(); }
+ void set(unsigned index, double value)
+ {
+ if (!(value > 0)) // Clamp NaN to 0
+ value = 0;
+ else if (value > 255)
+ value = 255;
+ m_data[index] = static_cast<unsigned char>(round(value));
+ }
+
+ bool get(unsigned index, unsigned char& result) const
+ {
+ if (index >= m_data.size())
+ return false;
+ result = m_data[index];
+ return true;
+ }
+
+ private:
+ CanvasPixelArray(unsigned size);
+ Vector<unsigned char> m_data;
+ };
+
+} // namespace WebCore
+
+#endif // CanvasPixelArray_h
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+
+ interface [
+ HasCustomIndexGetter,
+ HasCustomIndexSetter,
+ GenerateToJS
+ ] CanvasPixelArray {
+ readonly attribute long length;
+ };
+
+}
#include "CachedImage.h"
#include "CanvasGradient.h"
#include "CanvasPattern.h"
+#include "CanvasPixelArray.h"
#include "CanvasStyle.h"
#include "Document.h"
#include "ExceptionCode.h"
#include "HTMLCanvasElement.h"
#include "HTMLImageElement.h"
#include "HTMLNames.h"
+#include "ImageBuffer.h"
+#include "ImageData.h"
#include "NotImplemented.h"
#include "RenderHTMLCanvas.h"
#include "Settings.h"
state().m_appliedFillPattern = true;
}
+static PassRefPtr<ImageData> createEmptyImageData(const IntSize& size)
+{
+ PassRefPtr<ImageData> data = ImageData::create(size.width(), size.height());
+ memset(data->data()->data().data(), 0, data->data()->length());
+ return data;
+}
+
+PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh) const
+{
+ FloatSize unscaledSize(sw, sh);
+ IntSize scaledSize;
+ if (m_canvas)
+ scaledSize = m_canvas->convertLogicalToDevice(unscaledSize);
+ else
+ scaledSize = IntSize(ceilf(sw), ceilf(sh));
+ if (scaledSize.width() < 1)
+ scaledSize.setWidth(1);
+ if (scaledSize.height() < 1)
+ scaledSize.setHeight(1);
+
+ return createEmptyImageData(scaledSize);
+}
+
+PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh) const
+{
+ FloatRect unscaledRect(sx, sy, sw, sh);
+ IntRect scaledRect = m_canvas ? m_canvas->convertLogicalToDevice(unscaledRect) : enclosingIntRect(unscaledRect);
+ if (scaledRect.width() < 1)
+ scaledRect.setWidth(1);
+ if (scaledRect.height() < 1)
+ scaledRect.setHeight(1);
+ ImageBuffer* buffer = m_canvas ? m_canvas->buffer() : 0;
+ if (!buffer)
+ return createEmptyImageData(scaledRect.size());
+ return buffer->getImageData(scaledRect);
+}
+
} // namespace WebCore
class GraphicsContext;
class HTMLCanvasElement;
class HTMLImageElement;
+ class ImageData;
typedef int ExceptionCode;
PassRefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1);
PassRefPtr<CanvasPattern> createPattern(HTMLImageElement*, const String& repetitionType, ExceptionCode&);
PassRefPtr<CanvasPattern> createPattern(HTMLCanvasElement*, const String& repetitionType, ExceptionCode&);
-
+
+ PassRefPtr<ImageData> createImageData(float width, float height) const;
+ PassRefPtr<ImageData> getImageData(float sx, float sy, float sw, float sh) const;
+
void reset();
void detachCanvas() { m_canvas = 0; }
[Custom] void createPattern(/* 2 */);
attribute [Custom] custom strokeStyle;
- attribute [Custom] custom fillStyle;
+ attribute [Custom] custom fillStyle;
+
+ // pixel manipulation
+ ImageData createImageData(in float sw, in float sh);
+ ImageData getImageData(in float sx, in float sy, in float sw, in float sh);
+ [Custom] void putImageData(/* in ImageData imagedata, in float dx, in float dy [, in float dirtyX, in float dirtyY, in float dirtyWidth, in float dirtyHeight] */);
};
}
// Firefox limits width/height to 32767 pixels, but slows down dramatically before it
// reaches that limit. We limit by area instead, giving us larger maximum dimensions,
// in exchange for a smaller maximum canvas size.
-static const float maxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels
+const float HTMLCanvasElement::MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels
HTMLCanvasElement::HTMLCanvasElement(Document* doc)
: HTMLElement(canvasTag, doc)
p->paintBuffer(m_imageBuffer.get(), r);
}
-void HTMLCanvasElement::createImageBuffer() const
+IntRect HTMLCanvasElement::convertLogicalToDevice(const FloatRect& logicalRect) const
{
- ASSERT(!m_createdImageBuffer);
- ASSERT(!m_imageBuffer);
-
- m_createdImageBuffer = true;
+ return IntRect(convertLogicalToDevice(logicalRect.location()), convertLogicalToDevice(logicalRect.size()));
+}
- float unscaledWidth = width();
- float unscaledHeight = height();
+IntSize HTMLCanvasElement::convertLogicalToDevice(const FloatSize& logicalSize) const
+{
float pageScaleFactor = document()->frame() ? document()->frame()->page()->chrome()->scaleFactor() : 1.0f;
- float wf = ceilf(unscaledWidth * pageScaleFactor);
- float hf = ceilf(unscaledHeight * pageScaleFactor);
+ float wf = ceilf(logicalSize.width() * pageScaleFactor);
+ float hf = ceilf(logicalSize.height() * pageScaleFactor);
+
+ if (!(wf >= 1 && hf >= 1 && wf * hf <= MaxCanvasArea))
+ return IntSize();
- if (!(wf >= 1 && hf >= 1 && wf * hf <= maxCanvasArea))
- return;
+ return IntSize(static_cast<unsigned>(wf), static_cast<unsigned>(hf));
+}
+
+IntPoint HTMLCanvasElement::convertLogicalToDevice(const FloatPoint& logicalPos) const
+{
+ float pageScaleFactor = document()->frame() ? document()->frame()->page()->chrome()->scaleFactor() : 1.0f;
+ float xf = logicalPos.x() * pageScaleFactor;
+ float yf = logicalPos.y() * pageScaleFactor;
+
+ return IntPoint(static_cast<unsigned>(xf), static_cast<unsigned>(yf));
+}
- IntSize size(static_cast<unsigned>(wf), static_cast<unsigned>(hf));
+void HTMLCanvasElement::createImageBuffer() const
+{
+ ASSERT(!m_imageBuffer);
+ m_createdImageBuffer = true;
+
+ FloatSize unscaledSize(width(), height());
+ IntSize size = convertLogicalToDevice(unscaledSize);
+ if (!size.width() || !size.height())
+ return;
m_imageBuffer.set(ImageBuffer::create(size, false).release());
}
class CanvasRenderingContext2D;
typedef CanvasRenderingContext2D CanvasRenderingContext;
+class FloatPoint;
class FloatRect;
+class FloatSize;
class GraphicsContext;
class ImageBuffer;
+class IntPoint;
+class InttRect;
+class IntSize;
class HTMLCanvasElement : public HTMLElement {
public:
#elif PLATFORM(CAIRO)
cairo_surface_t* createPlatformImage() const;
#endif
-
+
+ IntRect convertLogicalToDevice(const FloatRect&) const;
+ IntSize convertLogicalToDevice(const FloatSize&) const;
+ IntPoint convertLogicalToDevice(const FloatPoint&) const;
+ static const float MaxCanvasArea;
private:
void createImageBuffer() const;
void reset();
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ImageData.h"
+
+#include "CanvasPixelArray.h"
+
+namespace WebCore {
+
+PassRefPtr<ImageData> ImageData::create(unsigned width, unsigned height)
+{
+ return adoptRef(new ImageData(width, height));
+}
+
+ImageData::ImageData(unsigned width, unsigned height)
+ : m_width(width)
+ , m_height(height)
+ , m_data(CanvasPixelArray::create(width * height * 4))
+{
+}
+
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ImageData_h
+#define ImageData_h
+
+#include "CanvasPixelArray.h"
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class ImageData : public RefCounted<ImageData> {
+ public:
+ static PassRefPtr<ImageData> create(unsigned width, unsigned height);
+
+ unsigned width() const { return m_width; }
+ unsigned height() const { return m_height; }
+ CanvasPixelArray* data() const { return m_data.get(); }
+
+ private:
+ ImageData(unsigned width, unsigned height);
+ unsigned m_width;
+ unsigned m_height;
+ RefPtr<CanvasPixelArray> m_data;
+ };
+
+} // namespace WebCore
+
+#endif // ImageData_h
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+
+ interface [
+ GenerateConstructor
+ ] ImageData {
+ readonly attribute long width;
+ readonly attribute long height;
+ readonly attribute CanvasPixelArray data;
+ };
+
+}
#include "IntSize.h"
#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
#include <memory>
#if PLATFORM(CG)
namespace WebCore {
class GraphicsContext;
+ class ImageData;
+ class IntRect;
class RenderObject;
class ImageBuffer : Noncopyable {
cairo_surface_t* surface() const;
#endif
+ PassRefPtr<ImageData> getImageData(const IntRect& rect) const;
private:
void* m_data;
IntSize m_size;
return m_surface;
}
+PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect&) const
+{
+ notImplemented();
+ return 0;
+}
}
/*
* Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2008 Apple, Inc
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "ImageBuffer.h"
#include "GraphicsContext.h"
+#include "ImageData.h"
#include <ApplicationServices/ApplicationServices.h>
#include <wtf/Assertions.h>
return m_cgImage;
}
+PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
+{
+ if (!m_data)
+ return 0;
+
+ PassRefPtr<ImageData> result = ImageData::create(rect.width(), rect.height());
+ unsigned char* data = result->data()->data().data();
+
+ if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height())
+ memset(data, 0, result->data()->length());
+
+ int originx = rect.x();
+ int destx = 0;
+ if (originx < 0) {
+ destx = -originx;
+ originx = 0;
+ }
+ int endx = rect.x() + rect.width();
+ if (endx > m_size.width())
+ endx = m_size.width();
+ int numColumns = endx - originx;
+
+ int originy = rect.y();
+ int desty = 0;
+ if (originy < 0) {
+ desty = -originy;
+ originy = 0;
+ }
+ int endy = rect.y() + rect.height();
+ if (endy > m_size.height())
+ endy = m_size.height();
+ int numRows = endy - originy;
+
+ unsigned srcBytesPerRow = 4 * m_size.width();
+ unsigned destBytesPerRow = 4 * rect.width();
+
+ // -originy to handle the accursed flipped y axis
+ unsigned char* srcRows = reinterpret_cast<unsigned char*>(m_data) + (m_size.height() - originy - 1) * srcBytesPerRow + originx * 4;
+ unsigned char* destRows = data + desty * destBytesPerRow + destx * 4;
+ for (int y = 0; y < numRows; ++y) {
+ for (int x = 0; x < numColumns; x++) {
+ if (unsigned char alpha = srcRows[3]) {
+ destRows[0] = (srcRows[0] * 255) / alpha;
+ destRows[1] = (srcRows[1] * 255) / alpha;
+ destRows[2] = (srcRows[2] * 255) / alpha;
+ destRows[3] = alpha;
+ } else {
+ reinterpret_cast<uint32_t*>(destRows)[0] = reinterpret_cast<uint32_t*>(srcRows)[0];
+ }
+ destRows += 4;
+ }
+ srcRows -= srcBytesPerRow;
+ }
+ return result;
+}
+
}
#include "ImageBuffer.h"
#include "GraphicsContext.h"
+#include "NotImplemented.h"
#include <QPainter>
#include <QPixmap>
return &m_pixmap;
}
+PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect&) const
+{
+ notImplemented();
+ return 0;
+}
+
}
#include "config.h"
#include "ImageBuffer.h"
#include "GraphicsContext.h"
+#include "NotImplemented.h"
namespace WebCore {
return 0;
}
+PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect&) const
+{
+ notImplemented();
+ return 0;
+}
+
}