Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Implement resizing options for ImageBitmap rendering
https://bugs.webkit.org/show_bug.cgi?id=178687 <rdar://problem/35135417> Reviewed by Sam Weinig. Source/WebCore: Implement many of the sizing options for createImageBitmap. Test: http/wpt/2dcontext/imagebitmap/createImageBitmap-sizing.html * html/ImageBitmap.cpp: (WebCore::croppedSourceRectangleWithFormatting): Implement the first bit of the algorithm from the HTML specification. (WebCore::outputSizeForSourceRectangle): ... and then the second bit. Leave the rest in comments for now. (WebCore::interpolationQualityForResizeQuality): Helper function to map ImageBitmapOptions to GraphicsContext. (WebCore::ImageBitmap::createPromise): Implement more of the sizing algorithm. * html/ImageBitmap.h: Origin tainting is defined to be false by default. LayoutTests: More ImageBitmap tests, this time focusing on sizing. * http/wpt/2dcontext/imagebitmap/common.js: (createCanvasOfSize): (create9x9CanvasWith2dContext): (create18x18CanvasWith2dContext): Helper functions. * http/wpt/2dcontext/imagebitmap/createImageBitmap-sizing-expected.txt: Added. * http/wpt/2dcontext/imagebitmap/createImageBitmap-sizing.html: Added. * http/wpt/2dcontext/imagebitmap/drawImage-ImageBitmap.html: * http/wpt/2dcontext/imagebitmap/resources/target-blue-dot-no-intrinsic.svg: Added. * http/wpt/2dcontext/imagebitmap/resources/target-blue-dot.png: Renamed from LayoutTests/http/wpt/2dcontext/imagebitmap/target-blue-dot.png. * http/wpt/2dcontext/imagebitmap/resources/target-blue-dot.svg: Added. Canonical link: https://commits.webkit.org/194921@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223925 268f45cc-cd09-0410-ab3c-d52691b4dbfc
- Loading branch information
Showing
12 changed files
with
454 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,11 @@ | ||
|
||
PASS createImageBitmap rejects with TypeError if resizeWidth is negative | ||
PASS createImageBitmap rejects with TypeError if resizeHeight is negative | ||
PASS createImageBitmap with cropped source | ||
PASS createImageBitmap with a cropping rectangle that is bigger than the source | ||
PASS createImageBitmap with resizeWidth and resizeHeight | ||
PASS createImageBitmap with only resizeHeight should calculate resizeWidth | ||
PASS createImageBitmap with only resizeWidth should calculate resizeHeight | ||
PASS createImageBitmap with an SVG uses intrinsic size | ||
PASS createImageBitmap with an SVG that has no intrinsic size uses resize parameters | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,189 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<title>createImageBitmap with sizing test</title> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="/common/canvas-tests.js"></script> | ||
<script src="common.js"></script> | ||
<link rel="stylesheet" href="/common/canvas-tests.css"> | ||
<body> | ||
<script> | ||
(function() { | ||
|
||
// The ImageBitmap part of the HTML specification says this should be an InvalidStateError, but | ||
// the IDL requires an unsigned value, so the TypeError will hit first. | ||
promise_test(function(t) { | ||
return promise_rejects(t, new TypeError, createImageBitmap(new Image(), 0, 0, 10, 10, { resizeWidth: -10, resizeHeight: 10 })); | ||
}, "createImageBitmap rejects with TypeError if resizeWidth is negative"); | ||
|
||
promise_test(function(t) { | ||
return promise_rejects(t, new TypeError, createImageBitmap(new Image(), 0, 0, 10, 10, { resizeWidth: 10, resizeHeight: -10 })); | ||
}, "createImageBitmap rejects with TypeError if resizeHeight is negative"); | ||
|
||
promise_test(function() { | ||
return new Promise(function(resolve, reject) { | ||
let img = new Image(); | ||
img.onload = function() { resolve(img); }; | ||
img.src = "resources/target-blue-dot.png"; | ||
}).then(function(img) { | ||
// Crop the 9x9 image into 5x5. | ||
return createImageBitmap(img, 0, 0, 5, 5); | ||
}).then(function(imageBitmap) { | ||
assert_equals(imageBitmap.width, 5, "ImageBitmap width should be 5"); | ||
assert_equals(imageBitmap.height, 5, "ImageBitmap height should be 5"); | ||
|
||
let [canvas, ctx] = create9x9CanvasWith2dContext(); | ||
ctx.drawImage(imageBitmap, 0, 0); | ||
_assertPixel(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255"); | ||
_assertPixel(canvas, 4,3, 0,255,0,255, "4,3", "0,255,0,255"); | ||
_assertPixel(canvas, 3,4, 0,255,0,255, "3,4", "0,255,0,255"); | ||
_assertPixel(canvas, 4,4, 0,0,255,255, "4,4", "0,0,255,255"); // Target blue dot. | ||
_assertPixel(canvas, 5,4, 0,0,0,0, "5,4", "0,0,0,0"); // Outside source rectangle so transparent. | ||
_assertPixel(canvas, 4,5, 0,0,0,0, "4,5", "0,0,0,0"); // Outside source rectangle so transparent. | ||
}); | ||
}, "createImageBitmap with cropped source"); | ||
|
||
promise_test(function() { | ||
return new Promise(function(resolve, reject) { | ||
let img = new Image(); | ||
img.onload = function() { resolve(img); }; | ||
img.src = "resources/target-blue-dot.png"; | ||
}).then(function(img) { | ||
// Source is only 9x9, so the 100x100 will be clamped. | ||
return createImageBitmap(img, 0, 0, 100, 100); | ||
}).then(function(imageBitmap) { | ||
assert_equals(imageBitmap.width, 9, "ImageBitmap width should be 9"); | ||
assert_equals(imageBitmap.height, 9, "ImageBitmap height should be 9"); | ||
|
||
let [canvas, ctx] = create9x9CanvasWith2dContext(); | ||
ctx.drawImage(imageBitmap, 0, 0); | ||
_assertPixel(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255"); | ||
_assertPixel(canvas, 4,3, 0,255,0,255, "4,3", "0,255,0,255"); | ||
_assertPixel(canvas, 3,4, 0,255,0,255, "3,4", "0,255,0,255"); | ||
_assertPixel(canvas, 4,4, 0,0,255,255, "4,4", "0,0,255,255"); // Target blue dot. | ||
_assertPixel(canvas, 5,4, 0,255,0,255, "5,4", "0,255,0,255"); | ||
_assertPixel(canvas, 4,5, 0,255,0,255, "4,5", "0,255,0,255"); | ||
}); | ||
}, "createImageBitmap with a cropping rectangle that is bigger than the source"); | ||
|
||
promise_test(function() { | ||
return new Promise(function(resolve, reject) { | ||
let img = new Image(); | ||
img.onload = function() { resolve(img); }; | ||
img.src = "resources/target-blue-dot.png"; | ||
}).then(function(img) { | ||
// Resize the 9x9 into 18x18, but without interpolation so that | ||
// we can still do accurate pixel tests. | ||
return createImageBitmap(img, 0, 0, 9, 9, { resizeWidth: 18, resizeHeight: 18, resizeQuality: "pixelated" }); | ||
}).then(function(imageBitmap) { | ||
assert_equals(imageBitmap.width, 18, "ImageBitmap width should be 18"); | ||
assert_equals(imageBitmap.height, 18, "ImageBitmap height should be 18"); | ||
|
||
let [canvas, ctx] = create18x18CanvasWith2dContext(); | ||
ctx.drawImage(imageBitmap, 0, 0); | ||
// All the target points are now 2x what they would be normally. | ||
_assertPixel(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255"); | ||
_assertPixel(canvas, 8,6, 0,255,0,255, "8,6", "0,255,0,255"); | ||
_assertPixel(canvas, 6,8, 0,255,0,255, "6,8", "0,255,0,255"); | ||
_assertPixel(canvas, 8,8, 0,0,255,255, "8,8", "0,0,255,255"); // Target blue dot. | ||
_assertPixel(canvas, 9,9, 0,0,255,255, "9,9", "0,0,255,255"); // Target blue dot. | ||
_assertPixel(canvas, 10,8, 0,255,0,255, "10,8", "0,255,0,255"); | ||
_assertPixel(canvas, 8,10, 0,255,0,255, "8,10", "0,255,0,255"); | ||
|
||
}); | ||
}, "createImageBitmap with resizeWidth and resizeHeight"); | ||
|
||
promise_test(function() { | ||
return new Promise(function(resolve, reject) { | ||
let img = new Image(); | ||
img.onload = function() { resolve(img); }; | ||
img.src = "resources/target-blue-dot.png"; | ||
}).then(function(img) { | ||
// Only provide resizeHeight. | ||
return createImageBitmap(img, 0, 0, 9, 9, { resizeHeight: 18, resizeQuality: "pixelated" }); | ||
}).then(function(imageBitmap) { | ||
assert_equals(imageBitmap.width, 18, "ImageBitmap width should be 18"); | ||
assert_equals(imageBitmap.height, 18, "ImageBitmap height should be 18"); | ||
|
||
let [canvas, ctx] = create18x18CanvasWith2dContext(); | ||
ctx.drawImage(imageBitmap, 0, 0); | ||
// All the target points are now 2x what they would be normally. | ||
_assertPixel(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255"); | ||
_assertPixel(canvas, 8,6, 0,255,0,255, "8,6", "0,255,0,255"); | ||
_assertPixel(canvas, 6,8, 0,255,0,255, "6,8", "0,255,0,255"); | ||
_assertPixel(canvas, 8,8, 0,0,255,255, "8,8", "0,0,255,255"); // Target blue dot. | ||
_assertPixel(canvas, 9,9, 0,0,255,255, "9,9", "0,0,255,255"); // Target blue dot. | ||
_assertPixel(canvas, 10,8, 0,255,0,255, "10,8", "0,255,0,255"); | ||
_assertPixel(canvas, 8,10, 0,255,0,255, "8,10", "0,255,0,255"); | ||
|
||
}); | ||
}, "createImageBitmap with only resizeHeight should calculate resizeWidth"); | ||
|
||
promise_test(function() { | ||
return new Promise(function(resolve, reject) { | ||
let img = new Image(); | ||
img.onload = function() { resolve(img); }; | ||
img.src = "resources/target-blue-dot.png"; | ||
}).then(function(img) { | ||
// Only provide resizeWidth. | ||
return createImageBitmap(img, 0, 0, 9, 9, { resizeWidth: 18, resizeQuality: "pixelated" }); | ||
}).then(function(imageBitmap) { | ||
assert_equals(imageBitmap.width, 18, "ImageBitmap width should be 18"); | ||
assert_equals(imageBitmap.height, 18, "ImageBitmap height should be 18"); | ||
|
||
let [canvas, ctx] = create18x18CanvasWith2dContext(); | ||
ctx.drawImage(imageBitmap, 0, 0); | ||
// All the target points are now 2x what they would be normally. | ||
_assertPixel(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255"); | ||
_assertPixel(canvas, 8,6, 0,255,0,255, "8,6", "0,255,0,255"); | ||
_assertPixel(canvas, 6,8, 0,255,0,255, "6,8", "0,255,0,255"); | ||
_assertPixel(canvas, 8,8, 0,0,255,255, "8,8", "0,0,255,255"); // Target blue dot. | ||
_assertPixel(canvas, 9,9, 0,0,255,255, "9,9", "0,0,255,255"); // Target blue dot. | ||
_assertPixel(canvas, 10,8, 0,255,0,255, "10,8", "0,255,0,255"); | ||
_assertPixel(canvas, 8,10, 0,255,0,255, "8,10", "0,255,0,255"); | ||
|
||
}); | ||
}, "createImageBitmap with only resizeWidth should calculate resizeHeight"); | ||
|
||
promise_test(function() { | ||
return new Promise(function(resolve, reject) { | ||
let img = new Image(); | ||
img.onload = function() { resolve(img); }; | ||
img.src = "resources/target-blue-dot.svg"; | ||
}).then(function(img) { | ||
return createImageBitmap(img); | ||
}).then(function(imageBitmap) { | ||
let [canvas, ctx] = create9x9CanvasWith2dContext(); | ||
ctx.drawImage(imageBitmap, 0, 0); | ||
_assertPixel(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255"); | ||
_assertPixel(canvas, 4,3, 0,255,0,255, "4,3", "0,255,0,255"); | ||
_assertPixel(canvas, 3,4, 0,255,0,255, "3,4", "0,255,0,255"); | ||
_assertPixel(canvas, 4,4, 0,0,255,255, "4,4", "0,0,255,255"); // Target blue dot. | ||
_assertPixel(canvas, 5,4, 0,255,0,255, "5,4", "0,255,0,255"); | ||
_assertPixel(canvas, 4,5, 0,255,0,255, "4,5", "0,255,0,255"); | ||
}); | ||
}, "createImageBitmap with an SVG uses intrinsic size"); | ||
|
||
promise_test(function() { | ||
return new Promise(function(resolve, reject) { | ||
let img = new Image(); | ||
img.onload = function() { resolve(img); }; | ||
img.src = "resources/target-blue-dot-no-intrinsic.svg"; | ||
}).then(function(img) { | ||
return createImageBitmap(img, { resizeWidth: 9, resizeHeight: 9 }); | ||
}).then(function(imageBitmap) { | ||
let [canvas, ctx] = create9x9CanvasWith2dContext(); | ||
ctx.drawImage(imageBitmap, 0, 0); | ||
_assertPixel(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255"); | ||
_assertPixel(canvas, 4,3, 0,255,0,255, "4,3", "0,255,0,255"); | ||
_assertPixel(canvas, 3,4, 0,255,0,255, "3,4", "0,255,0,255"); | ||
_assertPixel(canvas, 4,4, 0,0,255,255, "4,4", "0,0,255,255"); // Target blue dot. | ||
_assertPixel(canvas, 5,4, 0,255,0,255, "5,4", "0,255,0,255"); | ||
_assertPixel(canvas, 4,5, 0,255,0,255, "4,5", "0,255,0,255"); | ||
}); | ||
}, "createImageBitmap with an SVG that has no intrinsic size uses resize parameters"); | ||
|
||
})(); | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.