Commit e1f01e9d authored by xidachen's avatar xidachen Committed by Commit bot

Implement createImageBitmap(SVG) of intrinsic size = 0

When we have a SVG image whose intrinsic size is 0, then
createImageBitmap
from the above SVG image should throw InvalidStateError. Also,
createImageBitmap with a cropRect should not throw. This CL adds a
layout to verify that.

BUG=604510

Review URL: https://codereview.chromium.org/1901153002

Cr-Commit-Position: refs/heads/master@{#389805}
parent 37954aac
Test createImageBitmap from a SVG image without intrinsic size.
Test createImageBitmap from a SVG image without intrinsic size and with zero size.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS createImageBitmap promise rejected: InvalidStateError: Failed to execute 'createImageBitmap' on 'Window': The image element contains an SVG image without intrinsic dimensions.
PASS createImageBitmap from a SVG without intrinsic size rejected: InvalidStateError: Failed to execute 'createImageBitmap' on 'Window': The image element contains an SVG image without intrinsic dimensions.
PASS createImageBitmap from a SVG with zero size rejected: InvalidStateError: Failed to execute 'createImageBitmap' on 'Window': The image element contains an SVG image without intrinsic dimensions.
PASS createImageBitmap from a zero size SVG with cropRect succeed
PASS d[0] is 0
PASS d[1] is 0
PASS d[2] is 0
PASS d[3] is 0
PASS d[0] is 0
PASS d[1] is 0
PASS d[2] is 0
PASS d[3] is 0
PASS d[0] is 0
PASS d[1] is 0
PASS d[2] is 0
PASS d[3] is 0
PASS d[0] is 0
PASS d[1] is 0
PASS d[2] is 0
PASS d[3] is 0
PASS successfullyParsed is true
TEST COMPLETE
......
......@@ -6,20 +6,72 @@
<body>
<script>
description("Test createImageBitmap from a SVG image without intrinsic size.");
description("Test createImageBitmap from a SVG image without intrinsic size and with zero size.");
window.jsTestIsAsync = true;
var image = new Image();
image.onload = function() {
createImageBitmap(image).then(function(imageBitmap) {
testFailed("createImageBitmap promise resolved, expected to be rejected");
finishJSTest();
}, function (e) {
testPassed("createImageBitmap promise rejected: " + e);
finishJSTest();
});
var image1Loaded = false;
var image2Loaded = false;
var image1 = new Image();
var image2 = new Image();
image1.onload = function() {
image1Loaded = true;
testCreateImageBitmap();
}
image1.src = '../../svg/hixie/intrinsic/resources/003.svg';
image2.onload = function() {
image2Loaded = true;
testCreateImageBitmap();
}
image2.src = 'resources/zeroSize.svg';
function testCreateImageBitmap()
{
if (image1Loaded && image2Loaded) {
createImageBitmap(image1).then(function(bitmap1) {
testFailed("createImageBitmap from a SVG without intrinsic size succeed, expected to be rejected");
finishJSTest();
}, function (e) {
testPassed("createImageBitmap from a SVG without intrinsic size rejected: " + e);
createImageBitmap(image2).then(function(bitmap2) {
testFailed("createImageBitmap from a SVG with zero size succeed, expected to be rejected");
finishJSTest();
}, function(e) {
testPassed("createImageBitmap from a SVG with zero size rejected: " + e);
createImageBitmap(image2, 0, 0, 100, 100).then(function(bitmap3) {
testPassed("createImageBitmap from a zero size SVG with cropRect succeed");
checkImageBitmap(bitmap3);
finishJSTest();
}, function(e) {
testFailed("createImageBitmap from a zero size SVG with cropRect rejected: " + e);
finishJSTest();
});
});
});
}
}
function shouldBeClear(ctx, x, y) {
// should be transparent black pixels
d = ctx.getImageData(x, y, 1, 1).data;
shouldBe("d[0]", "0");
shouldBe("d[1]", "0");
shouldBe("d[2]", "0");
shouldBe("d[3]", "0");
}
function checkImageBitmap(bitmap)
{
var canvas = document.createElement("canvas");
canvas.width = 100;
canvas.height = 100;
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, 100, 100);
ctx.drawImage(bitmap, 0, 0);
shouldBeClear(ctx, 0, 0);
shouldBeClear(ctx, 0, 99);
shouldBeClear(ctx, 99, 0);
shouldBeClear(ctx, 99, 99);
}
image.src = '../../svg/hixie/intrinsic/resources/003.svg';
</script>
</body>
......
<svg xmlns="http://www.w3.org/2000/svg">
<script>
onload = function() {
document.documentElement.setAttribute('width', '0');
document.documentElement.setAttribute('height', '0');
}
</script>
</svg>
......@@ -685,17 +685,6 @@ void HTMLImageElement::forceReload() const
ScriptPromise HTMLImageElement::createImageBitmap(ScriptState* scriptState, EventTarget& eventTarget, int sx, int sy, int sw, int sh, const ImageBitmapOptions& options, ExceptionState& exceptionState)
{
ASSERT(eventTarget.toLocalDOMWindow());
if (!cachedImage()) {
exceptionState.throwDOMException(InvalidStateError, "No image can be retrieved from the provided element.");
return ScriptPromise();
}
if (cachedImage()->getImage()->isSVGImage()) {
SVGImage* image = toSVGImage(cachedImage()->getImage());
if (!image->hasIntrinsicDimensions()) {
exceptionState.throwDOMException(InvalidStateError, "The image element contains an SVG image without intrinsic dimensions.");
return ScriptPromise();
}
}
if (!sw || !sh) {
exceptionState.throwDOMException(IndexSizeError, String::format("The source %s provided is 0.", sw ? "height" : "width"));
return ScriptPromise();
......
......@@ -41,6 +41,7 @@
#include "core/html/HTMLVideoElement.h"
#include "core/html/ImageData.h"
#include "core/imagebitmap/ImageBitmapOptions.h"
#include "core/svg/graphics/SVGImage.h"
#include "core/workers/WorkerGlobalScope.h"
#include "platform/SharedBuffer.h"
#include "platform/ThreadSafeFunctional.h"
......@@ -53,10 +54,23 @@
namespace blink {
static inline ImageBitmapSource* toImageBitmapSourceInternal(const ImageBitmapSourceUnion& value)
static inline ImageBitmapSource* toImageBitmapSourceInternal(const ImageBitmapSourceUnion& value, ExceptionState& exceptionState, bool hasCropRect)
{
if (value.isHTMLImageElement())
return value.getAsHTMLImageElement();
if (value.isHTMLImageElement()) {
HTMLImageElement* imageElement = value.getAsHTMLImageElement();
if (!imageElement || !imageElement->cachedImage()) {
exceptionState.throwDOMException(InvalidStateError, "No image can be retrieved from the provided element.");
return nullptr;
}
if (imageElement->cachedImage()->getImage()->isSVGImage()) {
SVGImage* image = toSVGImage(imageElement->cachedImage()->getImage());
if (!image->hasIntrinsicDimensions() && !hasCropRect) {
exceptionState.throwDOMException(InvalidStateError, "The image element contains an SVG image without intrinsic dimensions.");
return nullptr;
}
}
return imageElement;
}
if (value.isHTMLVideoElement())
return value.getAsHTMLVideoElement();
if (value.isHTMLCanvasElement())
......@@ -75,7 +89,9 @@ ScriptPromise ImageBitmapFactories::createImageBitmap(ScriptState* scriptState,
{
UseCounter::Feature feature = UseCounter::CreateImageBitmap;
UseCounter::count(scriptState->getExecutionContext(), feature);
ImageBitmapSource* bitmapSourceInternal = toImageBitmapSourceInternal(bitmapSource);
ImageBitmapSource* bitmapSourceInternal = toImageBitmapSourceInternal(bitmapSource, exceptionState, false);
if (!bitmapSourceInternal)
return ScriptPromise();
if (bitmapSourceInternal->isBlob()) {
Blob* blob = static_cast<Blob*>(bitmapSourceInternal);
ImageBitmapLoader* loader = ImageBitmapFactories::ImageBitmapLoader::create(from(eventTarget), IntRect(), options, scriptState);
......@@ -92,7 +108,9 @@ ScriptPromise ImageBitmapFactories::createImageBitmap(ScriptState* scriptState,
{
UseCounter::Feature feature = UseCounter::CreateImageBitmap;
UseCounter::count(scriptState->getExecutionContext(), feature);
ImageBitmapSource* bitmapSourceInternal = toImageBitmapSourceInternal(bitmapSource);
ImageBitmapSource* bitmapSourceInternal = toImageBitmapSourceInternal(bitmapSource, exceptionState, true);
if (!bitmapSourceInternal)
return ScriptPromise();
return createImageBitmap(scriptState, eventTarget, bitmapSourceInternal, sx, sy, sw, sh, options, exceptionState);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment