зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1367251 - add bindings for options to createImageBitmap and support flipY r=bzbarsky,aosmond
implementation of imageOrientation: none|flipY. Differential Revision: https://phabricator.services.mozilla.com/D29562 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
d98231a231
Коммит
730d95aa10
|
@ -6967,15 +6967,17 @@ void nsGlobalWindowInner::FireOnNewGlobalObject() {
|
|||
#endif
|
||||
|
||||
already_AddRefed<Promise> nsGlobalWindowInner::CreateImageBitmap(
|
||||
JSContext* aCx, const ImageBitmapSource& aImage, ErrorResult& aRv) {
|
||||
return ImageBitmap::Create(this, aImage, Nothing(), aRv);
|
||||
JSContext* aCx, const ImageBitmapSource& aImage,
|
||||
const ImageBitmapOptions& aOptions, ErrorResult& aRv) {
|
||||
return ImageBitmap::Create(this, aImage, Nothing(), aOptions, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise> nsGlobalWindowInner::CreateImageBitmap(
|
||||
JSContext* aCx, const ImageBitmapSource& aImage, int32_t aSx, int32_t aSy,
|
||||
int32_t aSw, int32_t aSh, ErrorResult& aRv) {
|
||||
return ImageBitmap::Create(this, aImage,
|
||||
Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aRv);
|
||||
int32_t aSw, int32_t aSh, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv) {
|
||||
return ImageBitmap::Create(
|
||||
this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aOptions, aRv);
|
||||
}
|
||||
|
||||
mozilla::dom::TabGroup* nsGlobalWindowInner::TabGroupInner() {
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsSize.h"
|
||||
#include "nsCheapSets.h"
|
||||
#include "mozilla/dom/ImageBitmapBinding.h"
|
||||
#include "mozilla/dom/ImageBitmapSource.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsRefreshDriver.h"
|
||||
|
@ -883,11 +884,13 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||
|
||||
already_AddRefed<mozilla::dom::Promise> CreateImageBitmap(
|
||||
JSContext* aCx, const mozilla::dom::ImageBitmapSource& aImage,
|
||||
const mozilla::dom::ImageBitmapOptions& aOptions,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<mozilla::dom::Promise> CreateImageBitmap(
|
||||
JSContext* aCx, const mozilla::dom::ImageBitmapSource& aImage,
|
||||
int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
|
||||
const mozilla::dom::ImageBitmapOptions& aOptions,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
// ChromeWindow bits. Do NOT call these unless your window is in
|
||||
|
@ -1441,6 +1444,7 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||
|
||||
NS_IMETHOD Run() override {
|
||||
if (mInner) {
|
||||
;
|
||||
RefPtr<nsIRunnable> inner = std::move(mInner);
|
||||
inner->Run();
|
||||
}
|
||||
|
|
|
@ -257,6 +257,32 @@ static already_AddRefed<DataSourceSurface> CropAndCopyDataSourceSurface(
|
|||
return dstDataSurface.forget();
|
||||
}
|
||||
|
||||
static DataSourceSurface* FlipYDataSourceSurface(DataSourceSurface* aSurface) {
|
||||
MOZ_ASSERT(aSurface);
|
||||
|
||||
// Invert in y direction.
|
||||
DataSourceSurface::ScopedMap srcMap(aSurface, DataSourceSurface::READ_WRITE);
|
||||
if (NS_WARN_IF(!srcMap.IsMapped())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const IntSize srcSize = aSurface->GetSize();
|
||||
uint8_t* srcBufferPtr = srcMap.GetData();
|
||||
const uint32_t stride = srcMap.GetStride();
|
||||
|
||||
CheckedInt<uint32_t> copiedBytesPerRaw = CheckedInt<uint32_t>(stride);
|
||||
if (!copiedBytesPerRaw.isValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (int i = 0; i < srcSize.height / 2; ++i) {
|
||||
std::swap_ranges(srcBufferPtr + stride * i, srcBufferPtr + stride * (i + 1),
|
||||
srcBufferPtr + stride * (srcSize.height - 1 - i));
|
||||
}
|
||||
|
||||
return aSurface;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encapsulate the given _aSurface_ into a layers::SourceSurfaceImage.
|
||||
*/
|
||||
|
@ -275,7 +301,8 @@ static already_AddRefed<layers::Image> CreateImageFromSurface(
|
|||
*/
|
||||
static already_AddRefed<SourceSurface> CreateSurfaceFromRawData(
|
||||
const gfx::IntSize& aSize, uint32_t aStride, gfx::SurfaceFormat aFormat,
|
||||
uint8_t* aBuffer, uint32_t aBufferLength, const Maybe<IntRect>& aCropRect) {
|
||||
uint8_t* aBuffer, uint32_t aBufferLength, const Maybe<IntRect>& aCropRect,
|
||||
const ImageBitmapOptions& aOptions) {
|
||||
MOZ_ASSERT(!aSize.IsEmpty());
|
||||
MOZ_ASSERT(aBuffer);
|
||||
|
||||
|
@ -301,17 +328,26 @@ static already_AddRefed<SourceSurface> CreateSurfaceFromRawData(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (aOptions.mImageOrientation == ImageOrientation::FlipY) {
|
||||
result = FlipYDataSourceSurface(result);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!result)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
static already_AddRefed<layers::Image> CreateImageFromRawData(
|
||||
const gfx::IntSize& aSize, uint32_t aStride, gfx::SurfaceFormat aFormat,
|
||||
uint8_t* aBuffer, uint32_t aBufferLength, const Maybe<IntRect>& aCropRect) {
|
||||
uint8_t* aBuffer, uint32_t aBufferLength, const Maybe<IntRect>& aCropRect,
|
||||
const ImageBitmapOptions& aOptions) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Copy and crop the source buffer into a SourceSurface.
|
||||
RefPtr<SourceSurface> rgbaSurface = CreateSurfaceFromRawData(
|
||||
aSize, aStride, aFormat, aBuffer, aBufferLength, aCropRect);
|
||||
aSize, aStride, aFormat, aBuffer, aBufferLength, aCropRect, aOptions);
|
||||
|
||||
if (NS_WARN_IF(!rgbaSurface)) {
|
||||
return nullptr;
|
||||
|
@ -370,7 +406,8 @@ class CreateImageFromRawDataInMainThreadSyncTask final
|
|||
CreateImageFromRawDataInMainThreadSyncTask(
|
||||
uint8_t* aBuffer, uint32_t aBufferLength, uint32_t aStride,
|
||||
gfx::SurfaceFormat aFormat, const gfx::IntSize& aSize,
|
||||
const Maybe<IntRect>& aCropRect, layers::Image** aImage)
|
||||
const Maybe<IntRect>& aCropRect, layers::Image** aImage,
|
||||
const ImageBitmapOptions& aOptions)
|
||||
: WorkerMainThreadRunnable(
|
||||
GetCurrentThreadWorkerPrivate(),
|
||||
NS_LITERAL_CSTRING("ImageBitmap :: Create Image from Raw Data")),
|
||||
|
@ -380,7 +417,8 @@ class CreateImageFromRawDataInMainThreadSyncTask final
|
|||
mStride(aStride),
|
||||
mFormat(aFormat),
|
||||
mSize(aSize),
|
||||
mCropRect(aCropRect) {
|
||||
mCropRect(aCropRect),
|
||||
mOptions(aOptions) {
|
||||
MOZ_ASSERT(!(*aImage),
|
||||
"Don't pass an existing Image into "
|
||||
"CreateImageFromRawDataInMainThreadSyncTask.");
|
||||
|
@ -388,7 +426,7 @@ class CreateImageFromRawDataInMainThreadSyncTask final
|
|||
|
||||
bool MainThreadRun() override {
|
||||
RefPtr<layers::Image> image = CreateImageFromRawData(
|
||||
mSize, mStride, mFormat, mBuffer, mBufferLength, mCropRect);
|
||||
mSize, mStride, mFormat, mBuffer, mBufferLength, mCropRect, mOptions);
|
||||
|
||||
if (NS_WARN_IF(!image)) {
|
||||
return false;
|
||||
|
@ -407,6 +445,7 @@ class CreateImageFromRawDataInMainThreadSyncTask final
|
|||
gfx::SurfaceFormat mFormat;
|
||||
gfx::IntSize mSize;
|
||||
const Maybe<IntRect>& mCropRect;
|
||||
const ImageBitmapOptions mOptions;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -674,10 +713,79 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateFromOffscreenCanvas(
|
|||
return ret.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<ImageBitmap> ImageBitmap::CreateImageBitmapInternal(
|
||||
nsIGlobalObject* aGlobal, gfx::SourceSurface* aSurface,
|
||||
const Maybe<IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
const bool aWriteOnly, const bool aAllocatedImageData, const bool aMustCopy,
|
||||
ErrorResult& aRv) {
|
||||
bool needToReportMemoryAllocation = aAllocatedImageData;
|
||||
const IntSize srcSize = aSurface->GetSize();
|
||||
IntRect cropRect =
|
||||
aCropRect.valueOr(IntRect(0, 0, srcSize.width, srcSize.height));
|
||||
|
||||
RefPtr<SourceSurface> surface = aSurface;
|
||||
RefPtr<DataSourceSurface> dataSurface;
|
||||
|
||||
/*
|
||||
* if we don't own the data and need to create a new buffer to flip Y.
|
||||
* or
|
||||
* we need to crop and flip, where crop must come first.
|
||||
* or
|
||||
* Or the caller demands a copy (WebGL contexts).
|
||||
*/
|
||||
if ((aOptions.mImageOrientation == ImageOrientation::FlipY &&
|
||||
(!aAllocatedImageData || aCropRect.isSome())) ||
|
||||
aMustCopy) {
|
||||
dataSurface = surface->GetDataSurface();
|
||||
|
||||
dataSurface = CropAndCopyDataSourceSurface(dataSurface, cropRect);
|
||||
if (NS_WARN_IF(!dataSurface)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
surface = dataSurface;
|
||||
cropRect.MoveTo(0, 0);
|
||||
needToReportMemoryAllocation = true;
|
||||
}
|
||||
|
||||
// flip image in Y direction
|
||||
if (aOptions.mImageOrientation == ImageOrientation::FlipY) {
|
||||
if (!dataSurface) {
|
||||
dataSurface = surface->GetDataSurface();
|
||||
};
|
||||
|
||||
surface = FlipYDataSourceSurface(dataSurface);
|
||||
if (NS_WARN_IF(!surface)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Create an Image from the SourceSurface.
|
||||
RefPtr<layers::Image> data = CreateImageFromSurface(surface);
|
||||
|
||||
if (NS_WARN_IF(!data)) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aWriteOnly);
|
||||
|
||||
if (needToReportMemoryAllocation) {
|
||||
ret->mAllocatedImageData = true;
|
||||
}
|
||||
|
||||
// Set the picture rectangle.
|
||||
ret->SetPictureRect(cropRect, aRv);
|
||||
|
||||
return ret.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
||||
nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl,
|
||||
const Maybe<IntRect>& aCropRect, ErrorResult& aRv) {
|
||||
const Maybe<IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv) {
|
||||
// Check if the image element is completely available or not.
|
||||
if (!aImageEl.Complete()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
|
@ -695,28 +803,18 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Create ImageBitmap.
|
||||
RefPtr<layers::Image> data = CreateImageFromSurface(surface);
|
||||
bool needToReportMemoryAllocation = false;
|
||||
|
||||
if (NS_WARN_IF(!data)) {
|
||||
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
// Set the picture rectangle.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
ret->SetPictureRect(aCropRect.ref(), aRv);
|
||||
}
|
||||
|
||||
return ret.forget();
|
||||
return CreateImageBitmapInternal(aGlobal, surface, aCropRect, aOptions,
|
||||
writeOnly, needToReportMemoryAllocation,
|
||||
false, aRv);
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
||||
nsIGlobalObject* aGlobal, SVGImageElement& aImageEl,
|
||||
const Maybe<IntRect>& aCropRect, ErrorResult& aRv) {
|
||||
const Maybe<IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv) {
|
||||
bool writeOnly = true;
|
||||
|
||||
// Get the SourceSurface out from the image element and then do security
|
||||
|
@ -728,28 +826,18 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Create ImageBitmap.
|
||||
RefPtr<layers::Image> data = CreateImageFromSurface(surface);
|
||||
bool needToReportMemoryAllocation = false;
|
||||
|
||||
if (NS_WARN_IF(!data)) {
|
||||
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
// Set the picture rectangle.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
ret->SetPictureRect(aCropRect.ref(), aRv);
|
||||
}
|
||||
|
||||
return ret.forget();
|
||||
return CreateImageBitmapInternal(aGlobal, surface, aCropRect, aOptions,
|
||||
writeOnly, needToReportMemoryAllocation,
|
||||
false, aRv);
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
||||
nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl,
|
||||
const Maybe<IntRect>& aCropRect, ErrorResult& aRv) {
|
||||
const Maybe<IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv) {
|
||||
aVideoEl.MarkAsContentSource(
|
||||
mozilla::dom::HTMLVideoElement::CallerAPI::CREATE_IMAGEBITMAP);
|
||||
|
||||
|
@ -780,20 +868,21 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
|||
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
// Set the picture rectangle.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
ret->SetPictureRect(aCropRect.ref(), aRv);
|
||||
}
|
||||
RefPtr<SourceSurface> surface = data->GetAsSourceSurface();
|
||||
|
||||
return ret.forget();
|
||||
bool needToReportMemoryAllocation = false;
|
||||
|
||||
return CreateImageBitmapInternal(aGlobal, surface, aCropRect, aOptions,
|
||||
writeOnly, needToReportMemoryAllocation,
|
||||
false, aRv);
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
||||
nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvasEl,
|
||||
const Maybe<IntRect>& aCropRect, ErrorResult& aRv) {
|
||||
const Maybe<IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv) {
|
||||
if (aCanvasEl.Width() == 0 || aCanvasEl.Height() == 0) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
|
@ -811,56 +900,28 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
|||
writeOnly = aCanvasEl.IsWriteOnly();
|
||||
}
|
||||
|
||||
// Crop the source surface if needed.
|
||||
RefPtr<SourceSurface> croppedSurface;
|
||||
IntRect cropRect = aCropRect.valueOr(IntRect());
|
||||
|
||||
// If the HTMLCanvasElement's rendering context is WebGL, then the snapshot
|
||||
// we got from the HTMLCanvasElement is a DataSourceSurface which is a copy
|
||||
// of the rendering context. We handle cropping in this case.
|
||||
bool needToReportMemoryAllocation = false;
|
||||
bool mustCopy = false;
|
||||
|
||||
if ((aCanvasEl.GetCurrentContextType() == CanvasContextType::WebGL1 ||
|
||||
aCanvasEl.GetCurrentContextType() == CanvasContextType::WebGL2) &&
|
||||
aCropRect.isSome()) {
|
||||
RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
|
||||
croppedSurface = CropAndCopyDataSourceSurface(dataSurface, cropRect);
|
||||
cropRect.MoveTo(0, 0);
|
||||
needToReportMemoryAllocation = true;
|
||||
} else {
|
||||
croppedSurface = surface;
|
||||
mustCopy = true;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!croppedSurface)) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create an Image from the SourceSurface.
|
||||
RefPtr<layers::Image> data = CreateImageFromSurface(croppedSurface);
|
||||
|
||||
if (NS_WARN_IF(!data)) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
if (needToReportMemoryAllocation) {
|
||||
ret->mAllocatedImageData = true;
|
||||
}
|
||||
|
||||
// Set the picture rectangle.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
ret->SetPictureRect(cropRect, aRv);
|
||||
}
|
||||
|
||||
return ret.forget();
|
||||
return CreateImageBitmapInternal(aGlobal, surface, aCropRect, aOptions,
|
||||
writeOnly, needToReportMemoryAllocation,
|
||||
mustCopy, aRv);
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
||||
nsIGlobalObject* aGlobal, ImageData& aImageData,
|
||||
const Maybe<IntRect>& aCropRect, ErrorResult& aRv) {
|
||||
const Maybe<IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv) {
|
||||
// Copy data into SourceSurface.
|
||||
dom::Uint8ClampedArray array;
|
||||
DebugOnly<bool> inited = array.Init(aImageData.GetDataObject());
|
||||
|
@ -888,12 +949,12 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
|||
RefPtr<layers::Image> data;
|
||||
if (NS_IsMainThread()) {
|
||||
data = CreateImageFromRawData(imageSize, imageStride, FORMAT, array.Data(),
|
||||
dataLength, aCropRect);
|
||||
dataLength, aCropRect, aOptions);
|
||||
} else {
|
||||
RefPtr<CreateImageFromRawDataInMainThreadSyncTask> task =
|
||||
new CreateImageFromRawDataInMainThreadSyncTask(
|
||||
array.Data(), dataLength, imageStride, FORMAT, imageSize, aCropRect,
|
||||
getter_AddRefs(data));
|
||||
getter_AddRefs(data), aOptions);
|
||||
task->Dispatch(Canceling, aRv);
|
||||
}
|
||||
|
||||
|
@ -917,7 +978,8 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
|||
/* static */
|
||||
already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
||||
nsIGlobalObject* aGlobal, CanvasRenderingContext2D& aCanvasCtx,
|
||||
const Maybe<IntRect>& aCropRect, ErrorResult& aRv) {
|
||||
const Maybe<IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv) {
|
||||
nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(aGlobal);
|
||||
nsGlobalWindowInner* window = nsGlobalWindowInner::Cast(win);
|
||||
if (NS_WARN_IF(!window) || !window->GetExtantDoc()) {
|
||||
|
@ -945,44 +1007,32 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<layers::Image> data = CreateImageFromSurface(surface);
|
||||
bool needToReportMemoryAllocation = true;
|
||||
|
||||
if (NS_WARN_IF(!data)) {
|
||||
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
ret->mAllocatedImageData = true;
|
||||
|
||||
// Set the picture rectangle.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
ret->SetPictureRect(aCropRect.ref(), aRv);
|
||||
}
|
||||
|
||||
return ret.forget();
|
||||
return CreateImageBitmapInternal(aGlobal, surface, aCropRect, aOptions,
|
||||
writeOnly, needToReportMemoryAllocation,
|
||||
false, aRv);
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
||||
nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap,
|
||||
const Maybe<IntRect>& aCropRect, ErrorResult& aRv) {
|
||||
const Maybe<IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv) {
|
||||
if (!aImageBitmap.mData) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<layers::Image> data = aImageBitmap.mData;
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(
|
||||
aGlobal, data, aImageBitmap.mWriteOnly, aImageBitmap.mAlphaType);
|
||||
|
||||
// Set the picture rectangle.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
ret->SetPictureRect(aCropRect.ref(), aRv);
|
||||
}
|
||||
RefPtr<SourceSurface> surface = data->GetAsSourceSurface();
|
||||
|
||||
return ret.forget();
|
||||
bool needToReportMemoryAllocation = false;
|
||||
|
||||
return CreateImageBitmapInternal(aGlobal, surface, aCropRect, aOptions,
|
||||
aImageBitmap.mWriteOnly,
|
||||
needToReportMemoryAllocation, false, aRv);
|
||||
}
|
||||
|
||||
class FulfillImageBitmapPromise {
|
||||
|
@ -1054,7 +1104,8 @@ class CreateImageBitmapFromBlob final : public CancelableRunnable,
|
|||
|
||||
static already_AddRefed<CreateImageBitmapFromBlob> Create(
|
||||
Promise* aPromise, nsIGlobalObject* aGlobal, Blob& aBlob,
|
||||
const Maybe<IntRect>& aCropRect, nsIEventTarget* aMainThreadEventTarget);
|
||||
const Maybe<IntRect>& aCropRect, nsIEventTarget* aMainThreadEventTarget,
|
||||
const ImageBitmapOptions& aOptions);
|
||||
|
||||
NS_IMETHOD Run() override {
|
||||
MOZ_ASSERT(IsCurrentThread());
|
||||
|
@ -1074,7 +1125,8 @@ class CreateImageBitmapFromBlob final : public CancelableRunnable,
|
|||
CreateImageBitmapFromBlob(Promise* aPromise, nsIGlobalObject* aGlobal,
|
||||
already_AddRefed<nsIInputStream> aInputStream,
|
||||
const Maybe<IntRect>& aCropRect,
|
||||
nsIEventTarget* aMainThreadEventTarget)
|
||||
nsIEventTarget* aMainThreadEventTarget,
|
||||
const ImageBitmapOptions& aOptions)
|
||||
: CancelableRunnable("dom::CreateImageBitmapFromBlob"),
|
||||
mMutex("dom::CreateImageBitmapFromBlob::mMutex"),
|
||||
mPromise(aPromise),
|
||||
|
@ -1083,6 +1135,7 @@ class CreateImageBitmapFromBlob final : public CancelableRunnable,
|
|||
mCropRect(aCropRect),
|
||||
mOriginalCropRect(aCropRect),
|
||||
mMainThreadEventTarget(aMainThreadEventTarget),
|
||||
mFlipY(aOptions.mImageOrientation == ImageOrientation::FlipY),
|
||||
mThread(GetCurrentVirtualThread()) {}
|
||||
|
||||
virtual ~CreateImageBitmapFromBlob() {}
|
||||
|
@ -1130,8 +1183,8 @@ class CreateImageBitmapFromBlob final : public CancelableRunnable,
|
|||
Maybe<IntRect> mCropRect;
|
||||
Maybe<IntRect> mOriginalCropRect;
|
||||
IntSize mSourceSize;
|
||||
|
||||
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
|
||||
const bool mFlipY;
|
||||
void* mThread;
|
||||
};
|
||||
|
||||
|
@ -1163,7 +1216,8 @@ class CreateImageBitmapFromBlobRunnable : public WorkerRunnable {
|
|||
static void AsyncCreateImageBitmapFromBlob(Promise* aPromise,
|
||||
nsIGlobalObject* aGlobal,
|
||||
Blob& aBlob,
|
||||
const Maybe<IntRect>& aCropRect) {
|
||||
const Maybe<IntRect>& aCropRect,
|
||||
const ImageBitmapOptions& aOptions) {
|
||||
// Let's identify the main-thread event target.
|
||||
nsCOMPtr<nsIEventTarget> mainThreadEventTarget;
|
||||
if (NS_IsMainThread()) {
|
||||
|
@ -1175,7 +1229,7 @@ static void AsyncCreateImageBitmapFromBlob(Promise* aPromise,
|
|||
}
|
||||
|
||||
RefPtr<CreateImageBitmapFromBlob> task = CreateImageBitmapFromBlob::Create(
|
||||
aPromise, aGlobal, aBlob, aCropRect, mainThreadEventTarget);
|
||||
aPromise, aGlobal, aBlob, aCropRect, mainThreadEventTarget, aOptions);
|
||||
if (NS_WARN_IF(!task)) {
|
||||
aPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
|
@ -1187,7 +1241,8 @@ static void AsyncCreateImageBitmapFromBlob(Promise* aPromise,
|
|||
/* static */
|
||||
already_AddRefed<Promise> ImageBitmap::Create(
|
||||
nsIGlobalObject* aGlobal, const ImageBitmapSource& aSrc,
|
||||
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv) {
|
||||
const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv) {
|
||||
MOZ_ASSERT(aGlobal);
|
||||
|
||||
RefPtr<Promise> promise = Promise::Create(aGlobal, aRv);
|
||||
|
@ -1216,41 +1271,41 @@ already_AddRefed<Promise> ImageBitmap::Create(
|
|||
MOZ_ASSERT(
|
||||
NS_IsMainThread(),
|
||||
"Creating ImageBitmap from HTMLImageElement off the main thread.");
|
||||
imageBitmap =
|
||||
CreateInternal(aGlobal, aSrc.GetAsHTMLImageElement(), aCropRect, aRv);
|
||||
imageBitmap = CreateInternal(aGlobal, aSrc.GetAsHTMLImageElement(),
|
||||
aCropRect, aOptions, aRv);
|
||||
} else if (aSrc.IsSVGImageElement()) {
|
||||
MOZ_ASSERT(
|
||||
NS_IsMainThread(),
|
||||
"Creating ImageBitmap from SVGImageElement off the main thread.");
|
||||
imageBitmap =
|
||||
CreateInternal(aGlobal, aSrc.GetAsSVGImageElement(), aCropRect, aRv);
|
||||
imageBitmap = CreateInternal(aGlobal, aSrc.GetAsSVGImageElement(),
|
||||
aCropRect, aOptions, aRv);
|
||||
} else if (aSrc.IsHTMLVideoElement()) {
|
||||
MOZ_ASSERT(
|
||||
NS_IsMainThread(),
|
||||
"Creating ImageBitmap from HTMLVideoElement off the main thread.");
|
||||
imageBitmap =
|
||||
CreateInternal(aGlobal, aSrc.GetAsHTMLVideoElement(), aCropRect, aRv);
|
||||
imageBitmap = CreateInternal(aGlobal, aSrc.GetAsHTMLVideoElement(),
|
||||
aCropRect, aOptions, aRv);
|
||||
} else if (aSrc.IsHTMLCanvasElement()) {
|
||||
MOZ_ASSERT(
|
||||
NS_IsMainThread(),
|
||||
"Creating ImageBitmap from HTMLCanvasElement off the main thread.");
|
||||
imageBitmap =
|
||||
CreateInternal(aGlobal, aSrc.GetAsHTMLCanvasElement(), aCropRect, aRv);
|
||||
imageBitmap = CreateInternal(aGlobal, aSrc.GetAsHTMLCanvasElement(),
|
||||
aCropRect, aOptions, aRv);
|
||||
} else if (aSrc.IsImageData()) {
|
||||
imageBitmap =
|
||||
CreateInternal(aGlobal, aSrc.GetAsImageData(), aCropRect, aRv);
|
||||
imageBitmap = CreateInternal(aGlobal, aSrc.GetAsImageData(), aCropRect,
|
||||
aOptions, aRv);
|
||||
} else if (aSrc.IsCanvasRenderingContext2D()) {
|
||||
MOZ_ASSERT(NS_IsMainThread(),
|
||||
"Creating ImageBitmap from CanvasRenderingContext2D off the "
|
||||
"main thread.");
|
||||
imageBitmap = CreateInternal(aGlobal, aSrc.GetAsCanvasRenderingContext2D(),
|
||||
aCropRect, aRv);
|
||||
aCropRect, aOptions, aRv);
|
||||
} else if (aSrc.IsImageBitmap()) {
|
||||
imageBitmap =
|
||||
CreateInternal(aGlobal, aSrc.GetAsImageBitmap(), aCropRect, aRv);
|
||||
imageBitmap = CreateInternal(aGlobal, aSrc.GetAsImageBitmap(), aCropRect,
|
||||
aOptions, aRv);
|
||||
} else if (aSrc.IsBlob()) {
|
||||
AsyncCreateImageBitmapFromBlob(promise, aGlobal, aSrc.GetAsBlob(),
|
||||
aCropRect);
|
||||
aCropRect, aOptions);
|
||||
return promise.forget();
|
||||
} else {
|
||||
MOZ_CRASH("Unsupported type!");
|
||||
|
@ -1407,7 +1462,8 @@ size_t BindingJSObjectMallocBytes(ImageBitmap* aBitmap) {
|
|||
/* static */
|
||||
already_AddRefed<CreateImageBitmapFromBlob> CreateImageBitmapFromBlob::Create(
|
||||
Promise* aPromise, nsIGlobalObject* aGlobal, Blob& aBlob,
|
||||
const Maybe<IntRect>& aCropRect, nsIEventTarget* aMainThreadEventTarget) {
|
||||
const Maybe<IntRect>& aCropRect, nsIEventTarget* aMainThreadEventTarget,
|
||||
const ImageBitmapOptions& aOptions) {
|
||||
// Get the internal stream of the blob.
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
ErrorResult error;
|
||||
|
@ -1428,7 +1484,8 @@ already_AddRefed<CreateImageBitmapFromBlob> CreateImageBitmapFromBlob::Create(
|
|||
}
|
||||
|
||||
RefPtr<CreateImageBitmapFromBlob> task = new CreateImageBitmapFromBlob(
|
||||
aPromise, aGlobal, stream.forget(), aCropRect, aMainThreadEventTarget);
|
||||
aPromise, aGlobal, stream.forget(), aCropRect, aMainThreadEventTarget,
|
||||
aOptions);
|
||||
|
||||
// Nothing to do for the main-thread.
|
||||
if (NS_IsMainThread()) {
|
||||
|
@ -1576,6 +1633,7 @@ CreateImageBitmapFromBlob::OnImageReady(imgIContainer* aImgContainer,
|
|||
|
||||
// Crop the source surface if needed.
|
||||
RefPtr<SourceSurface> croppedSurface = surface;
|
||||
RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
|
||||
|
||||
if (mCropRect.isSome()) {
|
||||
// The blob is just decoded into a RasterImage and not optimized yet, so the
|
||||
|
@ -1590,11 +1648,22 @@ CreateImageBitmapFromBlob::OnImageReady(imgIContainer* aImgContainer,
|
|||
// TODO: Bug1189632 is going to refactor this create-from-blob part to
|
||||
// decode the blob off the main thread. Re-check if we should do
|
||||
// cropping at this moment again there.
|
||||
RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
|
||||
|
||||
croppedSurface = CropAndCopyDataSourceSurface(dataSurface, mCropRect.ref());
|
||||
if (NS_WARN_IF(!croppedSurface)) {
|
||||
MimeTypeAndDecodeAndCropBlobCompletedMainThread(
|
||||
nullptr, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
dataSurface = croppedSurface->GetDataSurface();
|
||||
mCropRect->MoveTo(0, 0);
|
||||
}
|
||||
|
||||
if (mFlipY) {
|
||||
croppedSurface = FlipYDataSourceSurface(dataSurface);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!croppedSurface)) {
|
||||
MimeTypeAndDecodeAndCropBlobCompletedMainThread(
|
||||
nullptr, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define mozilla_dom_ImageBitmap_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/ImageBitmapBinding.h"
|
||||
#include "mozilla/dom/ImageBitmapSource.h"
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
|
@ -119,6 +120,7 @@ class ImageBitmap final : public nsISupports, public nsWrapperCache {
|
|||
static already_AddRefed<Promise> Create(nsIGlobalObject* aGlobal,
|
||||
const ImageBitmapSource& aSrc,
|
||||
const Maybe<gfx::IntRect>& aCropRect,
|
||||
const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static JSObject* ReadStructuredClone(
|
||||
|
@ -169,33 +171,46 @@ class ImageBitmap final : public nsISupports, public nsWrapperCache {
|
|||
|
||||
void SetPictureRect(const gfx::IntRect& aRect, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<ImageBitmap> CreateImageBitmapInternal(
|
||||
nsIGlobalObject* aGlobal, gfx::SourceSurface* aSurface,
|
||||
const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
const bool aWriteOnly, const bool aAllocatedImageData,
|
||||
const bool aMustCopy, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<ImageBitmap> CreateInternal(
|
||||
nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl,
|
||||
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
||||
const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<ImageBitmap> CreateInternal(
|
||||
nsIGlobalObject* aGlobal, SVGImageElement& aImageEl,
|
||||
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
||||
const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<ImageBitmap> CreateInternal(
|
||||
nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl,
|
||||
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
||||
const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<ImageBitmap> CreateInternal(
|
||||
nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvasEl,
|
||||
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
||||
const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<ImageBitmap> CreateInternal(
|
||||
nsIGlobalObject* aGlobal, ImageData& aImageData,
|
||||
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
||||
const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<ImageBitmap> CreateInternal(
|
||||
nsIGlobalObject* aGlobal, CanvasRenderingContext2D& aCanvasCtx,
|
||||
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
||||
const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<ImageBitmap> CreateInternal(
|
||||
nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap,
|
||||
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
||||
const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> mParent;
|
||||
|
||||
|
|
|
@ -386,3 +386,18 @@ dictionary ChannelPixelLayout {
|
|||
};
|
||||
|
||||
typedef sequence<ChannelPixelLayout> ImagePixelLayout;
|
||||
|
||||
enum ImageOrientation { "none", "flipY" };
|
||||
//enum PremultiplyAlpha { "none", "premultiply", "default" };
|
||||
//enum ColorSpaceConversion { "none", "default" };
|
||||
//enum ResizeQuality { "pixelated", "low", "medium", "high" };
|
||||
|
||||
dictionary ImageBitmapOptions {
|
||||
ImageOrientation imageOrientation = "none";
|
||||
// options to be added bugs: 1363861
|
||||
//PremultiplyAlpha premultiplyAlpha = "default";
|
||||
//ColorSpaceConversion colorSpaceConversion = "default";
|
||||
//[EnforceRange] unsigned long resizeWidth;
|
||||
//[EnforceRange] unsigned long resizeHeight;
|
||||
//ResizeQuality resizeQuality = "low";
|
||||
};
|
||||
|
|
|
@ -40,9 +40,9 @@ interface mixin WindowOrWorkerGlobalScope {
|
|||
|
||||
// ImageBitmap
|
||||
[Throws]
|
||||
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource aImage);
|
||||
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource aImage, optional ImageBitmapOptions aOptions = {});
|
||||
[Throws]
|
||||
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource aImage, long aSx, long aSy, long aSw, long aSh);
|
||||
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource aImage, long aSx, long aSy, long aSw, long aSh, optional ImageBitmapOptions aOptions = {});
|
||||
};
|
||||
|
||||
// https://fetch.spec.whatwg.org/#fetch-method
|
||||
|
|
|
@ -491,15 +491,17 @@ already_AddRefed<IDBFactory> WorkerGlobalScope::GetIndexedDB(
|
|||
}
|
||||
|
||||
already_AddRefed<Promise> WorkerGlobalScope::CreateImageBitmap(
|
||||
JSContext* aCx, const ImageBitmapSource& aImage, ErrorResult& aRv) {
|
||||
return ImageBitmap::Create(this, aImage, Nothing(), aRv);
|
||||
JSContext* aCx, const ImageBitmapSource& aImage,
|
||||
const ImageBitmapOptions& aOptions, ErrorResult& aRv) {
|
||||
return ImageBitmap::Create(this, aImage, Nothing(), aOptions, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise> WorkerGlobalScope::CreateImageBitmap(
|
||||
JSContext* aCx, const ImageBitmapSource& aImage, int32_t aSx, int32_t aSy,
|
||||
int32_t aSw, int32_t aSh, ErrorResult& aRv) {
|
||||
return ImageBitmap::Create(this, aImage,
|
||||
Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aRv);
|
||||
int32_t aSw, int32_t aSh, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv) {
|
||||
return ImageBitmap::Create(
|
||||
this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aOptions, aRv);
|
||||
}
|
||||
|
||||
nsresult WorkerGlobalScope::Dispatch(
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "mozilla/dom/Headers.h"
|
||||
#include "mozilla/dom/RequestBinding.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "mozilla/dom/ImageBitmapBinding.h"
|
||||
#include "mozilla/dom/ImageBitmapSource.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
@ -172,15 +173,14 @@ class WorkerGlobalScope : public DOMEventTargetHelper,
|
|||
|
||||
bool IsSecureContext() const;
|
||||
|
||||
already_AddRefed<Promise> CreateImageBitmap(JSContext* aCx,
|
||||
const ImageBitmapSource& aImage,
|
||||
ErrorResult& aRv);
|
||||
already_AddRefed<Promise> CreateImageBitmap(
|
||||
JSContext* aCx, const ImageBitmapSource& aImage,
|
||||
const ImageBitmapOptions& aOptions, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise> CreateImageBitmap(JSContext* aCx,
|
||||
const ImageBitmapSource& aImage,
|
||||
int32_t aSx, int32_t aSy,
|
||||
int32_t aSw, int32_t aSh,
|
||||
ErrorResult& aRv);
|
||||
already_AddRefed<Promise> CreateImageBitmap(
|
||||
JSContext* aCx, const ImageBitmapSource& aImage, int32_t aSx, int32_t aSy,
|
||||
int32_t aSw, int32_t aSh, const ImageBitmapOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
bool WindowInteractionAllowed() const {
|
||||
return mWindowInteractionsAllowed > 0;
|
||||
|
|
|
@ -1,67 +1,7 @@
|
|||
[createImageBitmap-flipY.html]
|
||||
[createImageBitmap from a vector SVGImageElement imageOrientation: "none", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a vector SVGImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an HTMLCanvasElement imageOrientation: "none", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageData imageOrientation: "none", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an HTMLVideoElement from a data URL imageOrientation: "flipY", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an OffscreenCanvas imageOrientation: "flipY", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a vector HTMLImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an HTMLVideoElement imageOrientation: "flipY", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a Blob imageOrientation: "flipY", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an HTMLCanvasElement imageOrientation: "flipY", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an HTMLVideoElement imageOrientation: "none", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageData imageOrientation: "flipY", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a bitmap HTMLImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an OffscreenCanvas imageOrientation: "none", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageBitmap imageOrientation: "flipY", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a vector HTMLImageElement imageOrientation: "none", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a Blob imageOrientation: "none", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an HTMLVideoElement from a data URL imageOrientation: "none", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from an ImageBitmap imageOrientation: "none", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a bitmap HTMLImageElement imageOrientation: "none", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a bitmap SVGImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap from a bitmap SVGImageElement imageOrientation: "none", and drawImage on the created ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче