Bug 1768593. Allow createImageBitmap to work on img elements whose src is an svg with no specified size of resizeWidth/Height is specified. r=lsalzman

Just need to pass the resizeWidth/Height down into SurfaceFromElement for html image elements so we can ask for a frame of the right size from the image.

We have to annotate the new test that I add as failing, just like all of the existing tests, because we don't yet support the resizeQuality option, so we fail that part of the test and pass all of the rest of it. The part that we are fixing here passes.

Differential Revision: https://phabricator.services.mozilla.com/D147739
This commit is contained in:
Timothy Nikkel 2022-06-02 03:31:43 +00:00
Родитель ff71e7aae1
Коммит 4a902a6a3e
6 изменённых файлов: 80 добавлений и 10 удалений

Просмотреть файл

@ -595,8 +595,23 @@ static already_AddRefed<SourceSurface> GetSurfaceFromElement(
flags |= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION;
}
SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(&aElement, flags);
Maybe<int32_t> resizeWidth, resizeHeight;
if (aOptions.mResizeWidth.WasPassed()) {
if (!CheckedInt32(aOptions.mResizeWidth.Value()).isValid()) {
aRv.ThrowInvalidStateError("resizeWidth is too large");
return nullptr;
}
resizeWidth.emplace(aOptions.mResizeWidth.Value());
}
if (aOptions.mResizeHeight.WasPassed()) {
if (!CheckedInt32(aOptions.mResizeHeight.Value()).isValid()) {
aRv.ThrowInvalidStateError("resizeHeight is too large");
return nullptr;
}
resizeHeight.emplace(aOptions.mResizeHeight.Value());
}
SurfaceFromElementResult res = nsLayoutUtils::SurfaceFromElement(
&aElement, resizeWidth, resizeHeight, flags);
RefPtr<SourceSurface> surface = res.GetSourceSurface();
if (NS_WARN_IF(!surface)) {

Просмотреть файл

@ -7120,7 +7120,8 @@ static RefPtr<SourceSurface> ScaleSourceSurface(SourceSurface& aSurface,
}
SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement(
nsIImageLoadingContent* aElement, uint32_t aSurfaceFlags,
nsIImageLoadingContent* aElement, const Maybe<int32_t>& aResizeWidth,
const Maybe<int32_t>& aResizeHeight, uint32_t aSurfaceFlags,
RefPtr<DrawTarget>& aTarget) {
SurfaceFromElementResult result;
nsresult rv;
@ -7199,10 +7200,22 @@ SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement(
imgWidth = MOZ_KnownLive(element)->Width();
imgHeight = MOZ_KnownLive(element)->Height();
} else {
auto res = imgContainer->GetResolution();
rv = imgContainer->GetWidth(&imgWidth);
if (NS_SUCCEEDED(rv)) {
res.ApplyXTo(imgWidth);
} else if (aResizeWidth.isSome()) {
imgWidth = *aResizeWidth;
rv = NS_OK;
}
nsresult rv2 = imgContainer->GetHeight(&imgHeight);
if (NS_SUCCEEDED(rv2)) {
res.ApplyYTo(imgHeight);
} else if (aResizeHeight.isSome()) {
imgHeight = *aResizeHeight;
rv2 = NS_OK;
}
if (NS_FAILED(rv) || NS_FAILED(rv2)) return result;
imgContainer->GetResolution().ApplyTo(imgWidth, imgHeight);
}
result.mSize = result.mIntrinsicSize = IntSize(imgWidth, imgHeight);
@ -7266,7 +7279,7 @@ SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement(
HTMLImageElement* aElement, uint32_t aSurfaceFlags,
RefPtr<DrawTarget>& aTarget) {
return SurfaceFromElement(static_cast<nsIImageLoadingContent*>(aElement),
aSurfaceFlags, aTarget);
Nothing(), Nothing(), aSurfaceFlags, aTarget);
}
SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement(
@ -7373,7 +7386,8 @@ SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement(
}
SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement(
dom::Element* aElement, uint32_t aSurfaceFlags,
dom::Element* aElement, const Maybe<int32_t>& aResizeWidth,
const Maybe<int32_t>& aResizeHeight, uint32_t aSurfaceFlags,
RefPtr<DrawTarget>& aTarget) {
// If it's a <canvas>, we may be able to just grab its internal surface
if (HTMLCanvasElement* canvas = HTMLCanvasElement::FromNodeOrNull(aElement)) {
@ -7392,7 +7406,8 @@ SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement(
return SurfaceFromElementResult();
}
return SurfaceFromElement(imageLoader, aSurfaceFlags, aTarget);
return SurfaceFromElement(imageLoader, aResizeWidth, aResizeHeight,
aSurfaceFlags, aTarget);
}
/* static */

Просмотреть файл

@ -2219,18 +2219,38 @@ class nsLayoutUtils {
}
static mozilla::SurfaceFromElementResult SurfaceFromElement(
mozilla::dom::Element* aElement, uint32_t aSurfaceFlags,
mozilla::dom::Element* aElement,
const mozilla::Maybe<int32_t>& aResizeWidth,
const mozilla::Maybe<int32_t>& aResizeHeight, uint32_t aSurfaceFlags,
RefPtr<DrawTarget>& aTarget);
static mozilla::SurfaceFromElementResult SurfaceFromElement(
mozilla::dom::Element* aElement, uint32_t aSurfaceFlags = 0) {
RefPtr<DrawTarget> target = nullptr;
return SurfaceFromElement(aElement, aSurfaceFlags, target);
return SurfaceFromElement(aElement, mozilla::Nothing(), mozilla::Nothing(),
aSurfaceFlags, target);
}
static mozilla::SurfaceFromElementResult SurfaceFromElement(
mozilla::dom::Element* aElement, uint32_t aSurfaceFlags,
RefPtr<DrawTarget>& aTarget) {
return SurfaceFromElement(aElement, mozilla::Nothing(), mozilla::Nothing(),
aSurfaceFlags, aTarget);
}
static mozilla::SurfaceFromElementResult SurfaceFromElement(
mozilla::dom::Element* aElement,
const mozilla::Maybe<int32_t>& aResizeWidth,
const mozilla::Maybe<int32_t>& aResizeHeight,
uint32_t aSurfaceFlags = 0) {
RefPtr<DrawTarget> target = nullptr;
return SurfaceFromElement(aElement, aResizeWidth, aResizeHeight,
aSurfaceFlags, target);
}
// There are a bunch of callers of SurfaceFromElement. Just mark it as
MOZ_CAN_RUN_SCRIPT_BOUNDARY
static mozilla::SurfaceFromElementResult SurfaceFromElement(
nsIImageLoadingContent* aElement, uint32_t aSurfaceFlags,
nsIImageLoadingContent* aElement,
const mozilla::Maybe<int32_t>& aResizeWidth,
const mozilla::Maybe<int32_t>& aResizeHeight, uint32_t aSurfaceFlags,
RefPtr<DrawTarget>& aTarget);
// Need an HTMLImageElement overload, because otherwise the
// nsIImageLoadingContent and mozilla::dom::Element overloads are ambiguous

Просмотреть файл

@ -5,6 +5,9 @@
[createImageBitmap from a HTMLImageElement with resize option.]
expected: FAIL
[createImageBitmap from a HTMLImageElement of svg with no specified size with resize option.]
expected: FAIL
[createImageBitmap from a HTMLCanvasElement with resize option.]
expected: FAIL

Просмотреть файл

@ -143,6 +143,17 @@ promise_test(function() {
}).then(testImageBitmap);
}, 'createImageBitmap from a HTMLImageElement with resize option.');
// HTMLImageElement of svg with no specified size
promise_test(function() {
return new Promise((resolve, reject) => {
var image = new Image();
image.onload = function() {
resolve(image);
}
image.src = '/images/pattern-nosize.svg'
}).then(testImageBitmap);
}, 'createImageBitmap from a HTMLImageElement of svg with no specified size with resize option.');
// ImageBitmap
promise_test(function() {
var testCanvas = initializeTestCanvas();

Просмотреть файл

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<rect x="00" y="00" width="10" height="10" fill="#ff0000"/>
<rect x="10" y="00" width="10" height="10" fill="#00ff00"/>
<rect x="00" y="10" width="10" height="10" fill="#0000ff"/>
<rect x="10" y="10" width="10" height="10" fill="#000000"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 316 B