From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- dom/canvas/ImageBitmapRenderingContext.cpp | 314 +++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 dom/canvas/ImageBitmapRenderingContext.cpp (limited to 'dom/canvas/ImageBitmapRenderingContext.cpp') diff --git a/dom/canvas/ImageBitmapRenderingContext.cpp b/dom/canvas/ImageBitmapRenderingContext.cpp new file mode 100644 index 000000000..8f5074554 --- /dev/null +++ b/dom/canvas/ImageBitmapRenderingContext.cpp @@ -0,0 +1,314 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ImageBitmapRenderingContext.h" +#include "mozilla/dom/ImageBitmapRenderingContextBinding.h" +#include "ImageContainer.h" +#include "ImageLayers.h" + +namespace mozilla { +namespace dom { + +ImageBitmapRenderingContext::ImageBitmapRenderingContext() + : mWidth(0) + , mHeight(0) +{ +} + +ImageBitmapRenderingContext::~ImageBitmapRenderingContext() +{ + RemovePostRefreshObserver(); +} + +JSObject* +ImageBitmapRenderingContext::WrapObject(JSContext* aCx, JS::Handle aGivenProto) +{ + return ImageBitmapRenderingContextBinding::Wrap(aCx, this, aGivenProto); +} + +already_AddRefed +ImageBitmapRenderingContext::ClipToIntrinsicSize() +{ + if (!mImage) { + return nullptr; + } + + // If image is larger than canvas intrinsic size, clip it to the intrinsic size. + RefPtr surface; + RefPtr result; + if (mWidth < mImage->GetSize().width || + mHeight < mImage->GetSize().height) { + surface = MatchWithIntrinsicSize(); + } else { + surface = mImage->GetAsSourceSurface(); + } + result = new layers::SourceSurfaceImage(gfx::IntSize(mWidth, mHeight), surface); + return result.forget(); +} + +void +ImageBitmapRenderingContext::TransferImageBitmap(ImageBitmap& aImageBitmap) +{ + TransferFromImageBitmap(aImageBitmap); +} + +void +ImageBitmapRenderingContext::TransferFromImageBitmap(ImageBitmap& aImageBitmap) +{ + Reset(); + mImage = aImageBitmap.TransferAsImage(); + + if (!mImage) { + return; + } + + Redraw(gfxRect(0, 0, mWidth, mHeight)); +} + +int32_t +ImageBitmapRenderingContext::GetWidth() const +{ + return mWidth; +} + +int32_t +ImageBitmapRenderingContext::GetHeight() const +{ + return mHeight; +} + +NS_IMETHODIMP +ImageBitmapRenderingContext::SetDimensions(int32_t aWidth, int32_t aHeight) +{ + mWidth = aWidth; + mHeight = aHeight; + return NS_OK; +} + +NS_IMETHODIMP +ImageBitmapRenderingContext::InitializeWithDrawTarget(nsIDocShell* aDocShell, + NotNull aTarget) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +already_AddRefed +ImageBitmapRenderingContext::MatchWithIntrinsicSize() +{ + RefPtr surface = mImage->GetAsSourceSurface(); + RefPtr temp = + Factory::CreateDataSourceSurface(IntSize(mWidth, mHeight), surface->GetFormat()); + if (!temp) { + return nullptr; + } + + DataSourceSurface::ScopedMap map(temp, DataSourceSurface::READ_WRITE); + if (!map.IsMapped()) { + return nullptr; + } + + RefPtr dt = + Factory::CreateDrawTargetForData(BackendType::CAIRO, + map.GetData(), + temp->GetSize(), + map.GetStride(), + temp->GetFormat()); + if (!dt || !dt->IsValid()) { + gfxWarning() << "ImageBitmapRenderingContext::MatchWithIntrinsicSize failed"; + return nullptr; + } + + + dt->ClearRect(Rect(0, 0, mWidth, mHeight)); + dt->CopySurface(surface, + IntRect(0, 0, surface->GetSize().width, + surface->GetSize().height), + IntPoint(0, 0)); + + return temp.forget(); +} + +mozilla::UniquePtr +ImageBitmapRenderingContext::GetImageBuffer(int32_t* aFormat) +{ + *aFormat = 0; + + if (!mImage) { + return nullptr; + } + + RefPtr surface = mImage->GetAsSourceSurface(); + RefPtr data = surface->GetDataSurface(); + if (!data) { + return nullptr; + } + + if (data->GetSize() != IntSize(mWidth, mHeight)) { + data = MatchWithIntrinsicSize(); + } + + *aFormat = imgIEncoder::INPUT_FORMAT_HOSTARGB; + return SurfaceToPackedBGRA(data); +} + +NS_IMETHODIMP +ImageBitmapRenderingContext::GetInputStream(const char* aMimeType, + const char16_t* aEncoderOptions, + nsIInputStream** aStream) +{ + nsCString enccid("@mozilla.org/image/encoder;2?type="); + enccid += aMimeType; + nsCOMPtr encoder = do_CreateInstance(enccid.get()); + if (!encoder) { + return NS_ERROR_FAILURE; + } + + int32_t format = 0; + UniquePtr imageBuffer = GetImageBuffer(&format); + if (!imageBuffer) { + return NS_ERROR_FAILURE; + } + + return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer.get(), format, + encoder, aEncoderOptions, aStream); +} + +already_AddRefed +ImageBitmapRenderingContext::GetSurfaceSnapshot(bool* aPremultAlpha) +{ + if (!mImage) { + return nullptr; + } + + if (aPremultAlpha) { + *aPremultAlpha = true; + } + + RefPtr surface = mImage->GetAsSourceSurface(); + if (surface->GetSize() != IntSize(mWidth, mHeight)) { + return MatchWithIntrinsicSize(); + } + + return surface.forget(); +} + +NS_IMETHODIMP +ImageBitmapRenderingContext::SetIsOpaque(bool aIsOpaque) +{ + return NS_OK; +} + +bool +ImageBitmapRenderingContext::GetIsOpaque() +{ + return false; +} + +NS_IMETHODIMP +ImageBitmapRenderingContext::Reset() +{ + if (mCanvasElement) { + mCanvasElement->InvalidateCanvas(); + } + + mImage = nullptr; + + return NS_OK; +} + +already_AddRefed +ImageBitmapRenderingContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder, + Layer* aOldLayer, + LayerManager* aManager, + bool aMirror /* = false */) +{ + if (aMirror) { + // Not supported for ImageBitmapRenderingContext + return nullptr; + } + + if (!mImage) { + // No DidTransactionCallback will be received, so mark the context clean + // now so future invalidations will be dispatched. + MarkContextClean(); + return nullptr; + } + + RefPtr imageLayer; + + if (aOldLayer) { + imageLayer = static_cast(aOldLayer); + } else { + imageLayer = aManager->CreateImageLayer(); + } + + RefPtr imageContainer = imageLayer->GetContainer(); + if (!imageContainer) { + imageContainer = aManager->CreateImageContainer(); + imageLayer->SetContainer(imageContainer); + } + + AutoTArray imageList; + RefPtr image = ClipToIntrinsicSize(); + imageList.AppendElement(ImageContainer::NonOwningImage(image)); + imageContainer->SetCurrentImages(imageList); + + return imageLayer.forget(); +} + +void +ImageBitmapRenderingContext::MarkContextClean() +{ +} + +NS_IMETHODIMP +ImageBitmapRenderingContext::Redraw(const gfxRect& aDirty) +{ + if (!mCanvasElement) { + return NS_OK; + } + + mozilla::gfx::Rect rect = ToRect(aDirty); + mCanvasElement->InvalidateCanvasContent(&rect); + return NS_OK; +} + +NS_IMETHODIMP +ImageBitmapRenderingContext::SetIsIPC(bool aIsIPC) +{ + return NS_OK; +} + +void +ImageBitmapRenderingContext::DidRefresh() +{ +} + +void +ImageBitmapRenderingContext::MarkContextCleanForFrameCapture() +{ +} + +bool +ImageBitmapRenderingContext::IsContextCleanForFrameCapture() +{ + return true; +} + +NS_IMPL_CYCLE_COLLECTING_ADDREF(ImageBitmapRenderingContext) +NS_IMPL_CYCLE_COLLECTING_RELEASE(ImageBitmapRenderingContext) + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ImageBitmapRenderingContext, + mCanvasElement, + mOffscreenCanvas) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImageBitmapRenderingContext) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal) + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +} +} -- cgit v1.2.3