From 4b64c371e1f6124f383eb4224a84d9f100b122c9 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Tue, 4 Mar 2014 16:56:44 +0000 Subject: [PATCH] Bug 950368 - Make nsWindowsShellService's WriteBitmap act on a Moz2D SourceSurface instead of a Thebes gfxASurface. r=mattwoodrow --- .../shell/src/nsWindowsShellService.cpp | 43 ++++++++++++------- gfx/thebes/gfxImageSurface.h | 3 +- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/browser/components/shell/src/nsWindowsShellService.cpp b/browser/components/shell/src/nsWindowsShellService.cpp index 680c126c9888..0d48251bef32 100644 --- a/browser/components/shell/src/nsWindowsShellService.cpp +++ b/browser/components/shell/src/nsWindowsShellService.cpp @@ -5,6 +5,8 @@ #include "imgIContainer.h" #include "imgIRequest.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/RefPtr.h" #include "nsIDOMElement.h" #include "nsIDOMHTMLImageElement.h" #include "nsIImageLoadingContent.h" @@ -55,6 +57,8 @@ #define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1" using mozilla::IsWin8OrLater; +using namespace mozilla; +using namespace mozilla::gfx; NS_IMPL_ISUPPORTS2(nsWindowsShellService, nsIWindowsShellService, nsIShellService) @@ -749,21 +753,30 @@ WriteBitmap(nsIFile* aFile, imgIContainer* aImage) { nsresult rv; - nsRefPtr surface = + nsRefPtr thebesSurface = aImage->GetFrame(imgIContainer::FRAME_FIRST, imgIContainer::FLAG_SYNC_DECODE); - NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(thebesSurface, NS_ERROR_FAILURE); - nsRefPtr image(surface->GetAsReadableARGB32ImageSurface()); - NS_ENSURE_TRUE(image, NS_ERROR_FAILURE); + nsRefPtr thebesImageSurface = + thebesSurface->GetAsReadableARGB32ImageSurface(); + NS_ENSURE_TRUE(thebesImageSurface, NS_ERROR_FAILURE); - int32_t width = image->Width(); - int32_t height = image->Height(); + RefPtr dataSurface = + thebesImageSurface->CopyToB8G8R8A8DataSourceSurface(); + NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE); - uint8_t* bits = image->Data(); - uint32_t length = image->GetDataSize(); - uint32_t bpr = uint32_t(image->Stride()); - int32_t bitCount = bpr/width; + DataSourceSurface::MappedSurface map; + dataSurface->Map(DataSourceSurface::MapType::READ, &map); + if (!map.mData) { + return NS_ERROR_FAILURE; + } + + int32_t width = dataSurface->GetSize().width; + int32_t height = dataSurface->GetSize().height; + int32_t bytesPerPixel = 4 * sizeof(uint8_t); + uint32_t bytesPerRow = bytesPerPixel * width; + uint32_t length = map.mStride * height; // initialize these bitmap structs which we will later // serialize directly to the head of the bitmap file @@ -772,9 +785,9 @@ WriteBitmap(nsIFile* aFile, imgIContainer* aImage) bmi.biWidth = width; bmi.biHeight = height; bmi.biPlanes = 1; - bmi.biBitCount = (WORD)bitCount*8; + bmi.biBitCount = (WORD)bytesPerPixel*8; bmi.biCompression = BI_RGB; - bmi.biSizeImage = length; + bmi.biSizeImage = bytesPerRow * height; bmi.biXPelsPerMeter = 0; bmi.biYPelsPerMeter = 0; bmi.biClrUsed = 0; @@ -804,9 +817,9 @@ WriteBitmap(nsIFile* aFile, imgIContainer* aImage) // show bitmaps with negative heights for top-to-bottom uint32_t i = length; do { - i -= bpr; - stream->Write(((const char*)bits) + i, bpr, &written); - if (written == bpr) { + i -= map.mStride; + stream->Write(((const char*)map.mData) + i, bytesPerRow, &written); + if (written == bytesPerRow) { rv = NS_OK; } else { rv = NS_ERROR_FAILURE; diff --git a/gfx/thebes/gfxImageSurface.h b/gfx/thebes/gfxImageSurface.h index 983cf6754327..2c86dd7f5646 100644 --- a/gfx/thebes/gfxImageSurface.h +++ b/gfx/thebes/gfxImageSurface.h @@ -112,8 +112,9 @@ public: /** * Copy to a Moz2D DataSourceSurface. + * Marked as virtual so that browsercomps can access this method. */ - mozilla::TemporaryRef CopyToB8G8R8A8DataSourceSurface(); + virtual mozilla::TemporaryRef CopyToB8G8R8A8DataSourceSurface(); /* return new Subimage with pointing to original image starting from aRect.pos * and size of aRect.size. New subimage keeping current image reference