зеркало из https://github.com/mozilla/gecko-dev.git
Remove duplicate image conversion code from nsMenuItemIconX and nsClipboard. b=544704 r=josh
This commit is contained in:
Родитель
d97c21160c
Коммит
9f07732e64
|
@ -50,6 +50,7 @@
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "nsObjCExceptions.h"
|
#include "nsObjCExceptions.h"
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
|
#include "nsCocoaUtils.h"
|
||||||
|
|
||||||
// Screenshots use the (undocumented) png pasteboard type.
|
// Screenshots use the (undocumented) png pasteboard type.
|
||||||
#define IMAGE_PASTEBOARD_TYPES NSTIFFPboardType, @"Apple PNG pasteboard type", nil
|
#define IMAGE_PASTEBOARD_TYPES NSTIFFPboardType, @"Apple PNG pasteboard type", nil
|
||||||
|
@ -450,40 +451,12 @@ nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<gfxImageSurface> currentFrame;
|
CGImageRef imageRef = NULL;
|
||||||
if (NS_FAILED(image->CopyFrame(imgIContainer::FRAME_CURRENT,
|
nsresult rv = nsCocoaUtils::CreateCGImageFromImageContainer(image, imgIContainer::FRAME_CURRENT, &imageRef);
|
||||||
imgIContainer::FLAG_SYNC_DECODE,
|
if (NS_FAILED(rv) || !imageRef) {
|
||||||
getter_AddRefs(currentFrame))))
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
PRInt32 height = currentFrame->Height();
|
|
||||||
PRInt32 stride = currentFrame->Stride();
|
|
||||||
PRInt32 width = currentFrame->Width();
|
|
||||||
if ((stride % 4 != 0) || (height < 1) || (width < 1))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Create a CGImageRef with the bits from the image, taking into account
|
|
||||||
// the alpha ordering and endianness of the machine so we don't have to
|
|
||||||
// touch the bits ourselves.
|
|
||||||
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL,
|
|
||||||
currentFrame->Data(),
|
|
||||||
stride * height,
|
|
||||||
NULL);
|
|
||||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
|
||||||
CGImageRef imageRef = CGImageCreate(width,
|
|
||||||
height,
|
|
||||||
8,
|
|
||||||
32,
|
|
||||||
stride,
|
|
||||||
colorSpace,
|
|
||||||
kCGBitmapByteOrder32Host | kCGImageAlphaFirst,
|
|
||||||
dataProvider,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
kCGRenderingIntentDefault);
|
|
||||||
CGColorSpaceRelease(colorSpace);
|
|
||||||
CGDataProviderRelease(dataProvider);
|
|
||||||
|
|
||||||
// Convert the CGImageRef to TIFF data.
|
// Convert the CGImageRef to TIFF data.
|
||||||
CFMutableDataRef tiffData = CFDataCreateMutable(kCFAllocatorDefault, 0);
|
CFMutableDataRef tiffData = CFDataCreateMutable(kCFAllocatorDefault, 0);
|
||||||
CGImageDestinationRef destRef = CGImageDestinationCreateWithData(tiffData,
|
CGImageDestinationRef destRef = CGImageDestinationCreateWithData(tiffData,
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
#include "nsMenuItemX.h"
|
#include "nsMenuItemX.h"
|
||||||
#include "gfxImageSurface.h"
|
#include "gfxImageSurface.h"
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
|
#include "nsCocoaUtils.h"
|
||||||
|
|
||||||
static const PRUint32 kIconWidth = 16;
|
static const PRUint32 kIconWidth = 16;
|
||||||
static const PRUint32 kIconHeight = 16;
|
static const PRUint32 kIconHeight = 16;
|
||||||
|
@ -426,23 +427,10 @@ nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest,
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<gfxImageSurface> image;
|
PRInt32 origWidth = 0, origHeight = 0;
|
||||||
nsresult rv = imageContainer->CopyFrame(imgIContainer::FRAME_CURRENT,
|
imageContainer->GetWidth(&origWidth);
|
||||||
imgIContainer::FLAG_NONE,
|
imageContainer->GetHeight(&origHeight);
|
||||||
getter_AddRefs(image));
|
|
||||||
if (NS_FAILED(rv) || !image) {
|
|
||||||
[mNativeMenuItem setImage:nil];
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32 origHeight = image->Height();
|
|
||||||
PRInt32 origStride = image->Stride();
|
|
||||||
PRInt32 origWidth = image->Width();
|
|
||||||
if ((origStride % 4 != 0) || (origHeight < 1) || (origWidth < 1)) {
|
|
||||||
[mNativeMenuItem setImage:nil];
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the image region is invalid, don't draw the image to almost match
|
// If the image region is invalid, don't draw the image to almost match
|
||||||
// the behavior of other platforms.
|
// the behavior of other platforms.
|
||||||
if (!mImageRegionRect.IsEmpty() &&
|
if (!mImageRegionRect.IsEmpty() &&
|
||||||
|
@ -455,106 +443,72 @@ nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest,
|
||||||
if (mImageRegionRect.IsEmpty()) {
|
if (mImageRegionRect.IsEmpty()) {
|
||||||
mImageRegionRect.SetRect(0, 0, origWidth, origHeight);
|
mImageRegionRect.SetRect(0, 0, origWidth, origHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRInt32 newStride = mImageRegionRect.width * sizeof(PRUint32);
|
CGImageRef origImage = NULL;
|
||||||
PRInt32 imageLength = mImageRegionRect.height * mImageRegionRect.width;
|
nsresult rv = nsCocoaUtils::CreateCGImageFromImageContainer(imageContainer,
|
||||||
|
imgIContainer::FRAME_CURRENT,
|
||||||
PRUint32* origImageData = (PRUint32*)image->Data();
|
&origImage);
|
||||||
PRUint32* imageData = origImageData;
|
if (NS_FAILED(rv) || !origImage) {
|
||||||
|
|
||||||
PRBool createSubImage = !(mImageRegionRect.x == 0 && mImageRegionRect.y == 0 &&
|
|
||||||
mImageRegionRect.width == origWidth && mImageRegionRect.height == origHeight);
|
|
||||||
if (createSubImage) {
|
|
||||||
imageData = (PRUint32*)malloc(imageLength * sizeof(PRUint32));
|
|
||||||
if (!imageData) {
|
|
||||||
[mNativeMenuItem setImage:nil];
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (PRInt32 y = 0; y < mImageRegionRect.height; y++) {
|
|
||||||
PRInt32 srcLine = (mImageRegionRect.y + y) * (origStride / 4);
|
|
||||||
PRInt32 dstLine = y * mImageRegionRect.width;
|
|
||||||
for (PRInt32 x = 0; x < mImageRegionRect.width; x++) {
|
|
||||||
imageData[dstLine + x] = origImageData[srcLine + x + mImageRegionRect.x];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CGDataProviderRef provider = ::CGDataProviderCreateWithData(NULL, imageData, imageLength,
|
|
||||||
createSubImage ? PRAllocCGFree : NULL);
|
|
||||||
if (!provider) {
|
|
||||||
if (createSubImage)
|
|
||||||
free(imageData);
|
|
||||||
[mNativeMenuItem setImage:nil];
|
[mNativeMenuItem setImage:nil];
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
CGColorSpaceRef colorSpace = ::CGColorSpaceCreateDeviceRGB();
|
|
||||||
uint32_t byteFormat = (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);
|
|
||||||
CGImageRef cgImage = ::CGImageCreate(mImageRegionRect.width, mImageRegionRect.height,
|
|
||||||
8, 32, newStride, colorSpace, byteFormat,
|
|
||||||
provider, NULL, true, kCGRenderingIntentDefault);
|
|
||||||
::CGDataProviderRelease(provider);
|
|
||||||
|
|
||||||
|
PRBool createSubImage = !(mImageRegionRect.x == 0 && mImageRegionRect.y == 0 &&
|
||||||
|
mImageRegionRect.width == origWidth && mImageRegionRect.height == origHeight);
|
||||||
|
|
||||||
|
CGImageRef finalImage = NULL;
|
||||||
|
if (createSubImage) {
|
||||||
|
// if mImageRegionRect is set using CSS, we need to slice a piece out of the overall
|
||||||
|
// image to use as the icon
|
||||||
|
finalImage = ::CGImageCreateWithImageInRect(origImage,
|
||||||
|
::CGRectMake(mImageRegionRect.x,
|
||||||
|
mImageRegionRect.y,
|
||||||
|
mImageRegionRect.width,
|
||||||
|
mImageRegionRect.height));
|
||||||
|
::CGImageRelease(origImage);
|
||||||
|
if (!finalImage) {
|
||||||
|
[mNativeMenuItem setImage:nil];
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
finalImage = origImage;
|
||||||
|
}
|
||||||
// The image may not be the right size for a menu icon (16x16).
|
// The image may not be the right size for a menu icon (16x16).
|
||||||
// Create a new CGImage for the menu item.
|
// Create a new CGImage for the menu item.
|
||||||
PRUint8* bitmap = (PRUint8*)malloc(kIconBytes);
|
PRUint8* bitmap = (PRUint8*)malloc(kIconBytes);
|
||||||
|
|
||||||
CGImageAlphaInfo alphaInfo = ::CGImageGetAlphaInfo(cgImage);
|
CGColorSpaceRef colorSpace = ::CGColorSpaceCreateDeviceRGB();
|
||||||
|
|
||||||
CGContextRef bitmapContext;
|
CGContextRef bitmapContext = ::CGBitmapContextCreate(bitmap, kIconWidth, kIconHeight,
|
||||||
bitmapContext = ::CGBitmapContextCreate(bitmap, kIconWidth, kIconHeight,
|
kIconBitsPerComponent,
|
||||||
kIconBitsPerComponent,
|
kIconBytesPerRow,
|
||||||
kIconBytesPerRow,
|
colorSpace,
|
||||||
colorSpace,
|
kCGImageAlphaPremultipliedLast);
|
||||||
alphaInfo);
|
|
||||||
if (!bitmapContext) {
|
|
||||||
::CGImageRelease(cgImage);
|
|
||||||
free(bitmap);
|
|
||||||
::CGColorSpaceRelease(colorSpace);
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
CGRect iconRect = ::CGRectMake(0, 0, kIconWidth, kIconHeight);
|
|
||||||
::CGContextClearRect(bitmapContext, iconRect);
|
|
||||||
::CGContextDrawImage(bitmapContext, iconRect, cgImage);
|
|
||||||
::CGImageRelease(cgImage);
|
|
||||||
::CGContextRelease(bitmapContext);
|
|
||||||
|
|
||||||
provider = ::CGDataProviderCreateWithData(NULL, bitmap, kIconBytes,
|
|
||||||
PRAllocCGFree);
|
|
||||||
if (!provider) {
|
|
||||||
free(bitmap);
|
|
||||||
::CGColorSpaceRelease(colorSpace);
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
CGImageRef iconImage =
|
|
||||||
::CGImageCreate(kIconWidth, kIconHeight, kIconBitsPerComponent,
|
|
||||||
kIconBitsPerPixel, kIconBytesPerRow, colorSpace, alphaInfo,
|
|
||||||
provider, NULL, TRUE, kCGRenderingIntentDefault);
|
|
||||||
::CGColorSpaceRelease(colorSpace);
|
::CGColorSpaceRelease(colorSpace);
|
||||||
::CGDataProviderRelease(provider);
|
if (!bitmapContext) {
|
||||||
|
::CGImageRelease(finalImage);
|
||||||
|
free(bitmap);
|
||||||
|
::CGColorSpaceRelease(colorSpace);
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
CGRect iconRect = ::CGRectMake(0, 0, kIconWidth, kIconHeight);
|
||||||
|
::CGContextDrawImage(bitmapContext, iconRect, finalImage);
|
||||||
|
|
||||||
|
CGImageRef iconImage = ::CGBitmapContextCreateImage(bitmapContext);
|
||||||
|
|
||||||
|
::CGImageRelease(finalImage);
|
||||||
|
::CGContextRelease(bitmapContext);
|
||||||
|
free(bitmap);
|
||||||
|
|
||||||
if (!iconImage) return NS_ERROR_FAILURE;
|
if (!iconImage) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
NSRect imageRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
|
NSImage *newImage = nil;
|
||||||
CGContextRef imageContext = nil;
|
rv = nsCocoaUtils::CreateNSImageFromCGImage(iconImage, &newImage);
|
||||||
|
if (NS_FAILED(rv) || !newImage) {
|
||||||
// Get the image dimensions.
|
[mNativeMenuItem setImage:nil];
|
||||||
imageRect.size.width = kIconWidth;
|
::CGImageRelease(iconImage);
|
||||||
imageRect.size.height = kIconHeight;
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
// Create a new image to receive the Quartz image data.
|
|
||||||
NSImage* newImage = [[NSImage alloc] initWithSize:imageRect.size];
|
|
||||||
|
|
||||||
[newImage lockFocus];
|
|
||||||
|
|
||||||
// Get the Quartz context and draw.
|
|
||||||
imageContext = (CGContextRef)[[NSGraphicsContext currentContext]
|
|
||||||
graphicsPort];
|
|
||||||
CGContextDrawImage(imageContext, *(CGRect*)&imageRect, iconImage);
|
|
||||||
[newImage unlockFocus];
|
|
||||||
|
|
||||||
if (!mNativeMenuItem) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
[mNativeMenuItem setImage:newImage];
|
[mNativeMenuItem setImage:newImage];
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче