Bug 245407 - Use Quartz for nsImageMac. r=sfraser, sr=tor.

This commit is contained in:
pedemont%us.ibm.com 2005-02-20 03:21:04 +00:00
Родитель 6308fe5e8d
Коммит 4e31dcd7d7
13 изменённых файлов: 775 добавлений и 1576 удалений

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

@ -66,7 +66,12 @@ typedef enum {
#define nsImageUpdateFlags_kColorMapChanged 0x1
#define nsImageUpdateFlags_kBitsChanged 0x2
// The following platforms store image data rows bottom-up.
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_MACOSX)
#define MOZ_PLATFORM_IMAGES_BOTTOM_TO_TOP
#endif
// IID for the nsIImage interface
#define NS_IIMAGE_IID \
{ 0xce91c93f, 0x532d, 0x470d, \

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

@ -135,7 +135,7 @@ CPPSRCS += \
$(NULL)
endif
ifneq (,$(filter gtk gtk2 xlib beos windows os2 mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
ifneq (,$(filter gtk gtk2 xlib beos windows os2,$(MOZ_WIDGET_TOOLKIT)))
CPPSRCS += imgScaler.cpp
endif

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

@ -91,6 +91,10 @@ CPPSRCS = \
nsNativeThemeMac.cpp \
$(NULL)
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
CMMSRCS = nsCocoaImageUtils.mm
endif
SHARED_LIBRARY_LIBS = $(DIST)/lib/$(LIB_PREFIX)gfxshared_s.$(LIB_SUFFIX)
EXTRA_DSO_LIBS = mozutil_s gkgfx
EXTRA_DEPS = $(DIST)/lib/$(LIB_PREFIX)mozutil_s.$(LIB_SUFFIX)
@ -113,3 +117,8 @@ include $(topsrcdir)/config/rules.mk
CXXFLAGS += $(TK_CFLAGS)
CFLAGS += $(TK_CFLAGS)
INCLUDES += $(TK_CFLAGS) -I$(srcdir)/..
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
LDFLAGS += -framework Cocoa
endif

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

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

@ -39,7 +39,14 @@
#include "nsDrawingSurfaceMac.h"
#include "nsGraphicState.h"
#include "nsRegionPool.h"
#ifdef MOZ_WIDGET_COCOA
// Helper functions to manipulate CGContextRef from a Cocoa NSQuickDrawView.
// Implemented in nsCocoaUtils.mm.
extern CGContextRef Cocoa_LockFocus(void* view);
extern void Cocoa_UnlockFocus(void* view);
#endif
static NS_DEFINE_IID(kIDrawingSurfaceIID, NS_IDRAWING_SURFACE_IID);
static NS_DEFINE_IID(kIDrawingSurfaceMacIID, NS_IDRAWING_SURFACE_MAC_IID);
@ -53,13 +60,15 @@ static NS_DEFINE_IID(kIDrawingSurfaceMacIID, NS_IDRAWING_SURFACE_MAC_IID);
nsDrawingSurfaceMac::nsDrawingSurfaceMac()
{
mPort = NULL;
mGS = sGraphicStatePool.GetNewGS(); //new nsGraphicState();
mGS = sGraphicStatePool.GetNewGS(); //new nsGraphicState();
mWidth = mHeight = 0;
mLockOffset = mLockHeight = 0;
mLockFlags = 0;
mIsOffscreen = PR_FALSE;
mIsLocked = PR_FALSE;
mIsOffscreen = PR_FALSE;
mIsLocked = PR_FALSE;
#ifdef MOZ_WIDGET_COCOA
mWidgetView = nsnull;
#endif
}
/** ---------------------------------------------------
@ -246,6 +255,9 @@ NS_IMETHODIMP nsDrawingSurfaceMac::Init(nsIWidget *aTheWidget)
// get our native graphics port from the widget
mPort = reinterpret_cast<CGrafPtr>(aTheWidget->GetNativeData(NS_NATIVE_GRAPHIC));
mGS->Init(aTheWidget);
#ifdef MOZ_WIDGET_COCOA
mWidgetView = aTheWidget->GetNativeData(NS_NATIVE_WIDGET);
#endif
return NS_OK;
}
@ -326,3 +338,69 @@ NS_IMETHODIMP nsDrawingSurfaceMac::Init(PRUint32 aDepth, PRUint32 aWidth, PRUint
return NS_OK;
}
// Takes a QD Rect and adds it to the path of the CG Context. This is used
// by QDRegionToRects in order to create a clipping path from a region.
static OSStatus
CreatePathFromRectsProc(UInt16 aMessage, RgnHandle aRegion, const Rect* aRect,
void* aData)
{
CGContextRef context = NS_STATIC_CAST(CGContextRef, aData);
if (aMessage == kQDRegionToRectsMsgParse)
{
CGRect rect = ::CGRectMake(aRect->left, aRect->top,
aRect->right - aRect->left,
aRect->bottom - aRect->top);
::CGContextAddRect(context, rect);
}
return noErr;
}
NS_IMETHODIMP_(CGContextRef)
nsDrawingSurfaceMac::StartQuartzDrawing()
{
CGContextRef context;
#ifdef MOZ_WIDGET_COCOA
// In Cocoa, we get the context directly from the NSQuickDrawView.
if (mWidgetView) {
context = Cocoa_LockFocus(mWidgetView);
} else
#endif
{
// Convert GrafPort to a CGContext
::QDBeginCGContext(mPort, &context);
// Translate to QuickDraw coordinate system
Rect portRect;
::GetPortBounds(mPort, &portRect);
::CGContextTranslateCTM(context, 0, (float)(portRect.bottom - portRect.top));
::CGContextScaleCTM(context, 1, -1);
}
// Construct a CG path from the QD region and clip to the path.
// NOTE: Ordinarily we would use ClipCGContextToRegion, but it seems to have
// some bugs, particulary when drawing interlaced PNGs.
StRegionFromPool currentClipRgn;
::GetPortClipRegion(mPort, currentClipRgn);
::QDRegionToRects(currentClipRgn, kQDParseRegionFromTopLeft,
CreatePathFromRectsProc, context);
::CGContextClip(context);
return context;
}
NS_IMETHODIMP_(void)
nsDrawingSurfaceMac::EndQuartzDrawing(CGContextRef aContext)
{
// Synchronize the context to QD port before closing it.
::CGContextSynchronize(aContext);
#ifdef MOZ_WIDGET_COCOA
if (mWidgetView)
Cocoa_UnlockFocus(mWidgetView);
else
#endif
::QDEndCGContext(mPort, &aContext);
}

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

@ -1,92 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsDrawingSurfaceMac_h___
#define nsDrawingSurfaceMac_h___
#include "nsIDrawingSurface.h"
#include "nsIDrawingSurfaceMac.h"
#include "nsGfxUtils.h"
#include "nsCarbonHelpers.h"
class nsGraphicState;
class nsDrawingSurfaceMac : public nsIDrawingSurface,
nsIDrawingSurfaceMac
{
public:
nsDrawingSurfaceMac();
virtual ~nsDrawingSurfaceMac();
NS_DECL_ISUPPORTS
//nsIDrawingSurface interface
NS_IMETHOD Lock(PRInt32 aX, PRInt32 aY, PRUint32 aWidth, PRUint32 aHeight,
void **aBits, PRInt32 *aStride, PRInt32 *aWidthBytes,
PRUint32 aFlags);
NS_IMETHOD Unlock(void);
NS_IMETHOD GetDimensions(PRUint32 *aWidth, PRUint32 *aHeight);
NS_IMETHOD IsOffscreen(PRBool *aOffScreen) { *aOffScreen = mIsOffscreen; return NS_OK; }
NS_IMETHOD IsPixelAddressable(PRBool *aAddressable);
NS_IMETHOD GetPixelFormat(nsPixelFormat *aFormat);
//nsIDrawingSurfaceMac interface
NS_IMETHOD Init(nsIDrawingSurface* aDS);
NS_IMETHOD Init(CGrafPtr aThePort);
NS_IMETHOD Init(nsIWidget *aTheWidget);
NS_IMETHOD Init(PRUint32 aDepth,PRUint32 aWidth, PRUint32 aHeight,PRUint32 aFlags);
NS_IMETHOD GetGrafPtr(CGrafPtr *aTheGrafPtr) { *aTheGrafPtr = mPort; return NS_OK; }
// locals
nsGraphicState* GetGS(void) {return mGS;}
private:
CGrafPtr mPort; // the onscreen or offscreen CGrafPtr;
PRUint32 mWidth;
PRUint32 mHeight;
PRInt32 mLockOffset;
PRInt32 mLockHeight;
PRUint32 mLockFlags;
PRBool mIsOffscreen;
PRBool mIsLocked;
nsGraphicState* mGS; // a graphics state for the surface
};
#endif

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

@ -408,4 +408,29 @@ protected:
};
/**
* Stack based utility class for releasing a Quartz color space.
* Use as follows:
* CGColorSpaceRef rgbSpace = ::CGColorSpaceCreateDeviceRGB();
* StColorSpaceReleaser csReleaser(rgbSpace);
*/
class StColorSpaceReleaser
{
public:
StColorSpaceReleaser(CGColorSpaceRef inColorSpace)
: mColorSpace(inColorSpace)
{
}
~StColorSpaceReleaser()
{
// No need to check for NULL, since CGColorSpaceCreateDeviceRGB(NULL)
// is a noop.
::CGColorSpaceRelease(mColorSpace);
}
private:
CGColorSpaceRef mColorSpace;
};
#endif // nsGfxUtils_h_

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

@ -48,12 +48,14 @@ class GraphicsState;
// windows specific drawing surface method set
#define NS_IDRAWING_SURFACE_MAC_IID \
{ 0x1ed958b0, 0xcab6, 0x11d2, \
{ 0xa8, 0x49, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
{ 0xd49598bb, 0x04ff, 0x4aba, \
{ 0xab, 0x90, 0x5b, 0xd0, 0xdd, 0x82, 0xba, 0xef } }
class nsIDrawingSurfaceMac : public nsISupports
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IDRAWING_SURFACE_MAC_IID)
/**
* Initialize a drawing surface using a Macintosh GrafPtr.
* aPort is not owned by this drawing surface, just used by it.
@ -95,6 +97,22 @@ public:
**/
NS_IMETHOD GetGrafPtr(CGrafPtr *aPort) = 0;
/**
* Quartz helper function. Constructs a Quartz context from the drawing
* surface's QuickDraw port. Must be balanced with a call to
* EndQuartzDrawing().
* @return Quartz drawing context
**/
NS_IMETHOD_(CGContextRef) StartQuartzDrawing() = 0;
/**
* Quartz helper function. Releases Quartz context and resets state of
* drawing surface for QuickDraw calls. Must be called when you are done
* drawing to the Quartz context.
* @param Quartz drawing context returned by StartQuartzDrawing()
**/
NS_IMETHOD_(void) EndQuartzDrawing(CGContextRef aContext) = 0;
};
#endif // nsIDrawingSurfaceMac_h___

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

@ -71,25 +71,6 @@ public:
// Convert from the os-native PICT format. Most likely
// used for clipboard.
NS_IMETHOD ConvertFromPICT ( PicHandle inPicture ) = 0;
// Get the PixMap for this image
NS_IMETHOD GetGWorldPtr ( GWorldPtr* aGWorld ) = 0;
//Convert to the os-native icon format. Most used to put icons
//onto windows and menus. The outIcon will be allocated, the caller
//is responsible for disposing the memory
NS_IMETHOD ConvertToIcon( const nsRect& aSrcRegion,
const PRInt16 aIconDepth,
const PRInt16 aIconSize,
Handle* aOutIcon,
OSType* aOutIconType) = 0;
//Companion method for ConvertToIcon, makes icon masks
//see nsImageMac.cpp for full details
NS_IMETHOD ConvertAlphaToIconMask( const nsRect& aSrcRegion,
const PRInt16 aMaskDepth,
const PRInt16 aMaskSize,
Handle* aOutMask,
OSType* aOutIconType) = 0;
}; // nsIImageMac

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -40,7 +40,6 @@
#include "nsIImage.h"
#include "nsIImageMac.h"
#include <QDOffscreen.h>
class nsImageMac : public nsIImage, public nsIImageMac
{
@ -60,15 +59,21 @@ public:
virtual PRInt32 GetWidth() { return mWidth; }
virtual PRInt32 GetHeight() { return mHeight; }
virtual PRUint8* GetBits();
virtual PRUint8* GetBits() { return mImageBits; }
virtual PRInt32 GetLineStride() { return mRowBytes; }
virtual PRBool GetHasAlphaMask() { return mMaskGWorld != nsnull; }
virtual PRBool GetHasAlphaMask() { return mAlphaBits != nsnull; }
virtual PRUint8* GetAlphaBits();
virtual PRUint8* GetAlphaBits() { return mAlphaBits; }
virtual PRInt32 GetAlphaLineStride() { return mAlphaRowBytes; }
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect);
// Called when an image decoder updates the image bits (mImageBits &
// mAlphaBits). 'aFlags' is ignored.
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags,
nsRect *aUpdateRect);
// Optimizes memory usage for object.
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual nsColorMap* GetColorMap() { return nsnull; }
NS_IMETHOD Draw(nsIRenderingContext &aContext, nsIDrawingSurface* aSurface,
@ -101,118 +106,69 @@ public:
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
NS_IMETHOD GetGWorldPtr(GWorldPtr* aGWorld);
// Convert to and from the os-native PICT format. Most likely
// used for clipboard.
NS_IMETHOD ConvertToPICT(PicHandle* outPicture);
NS_IMETHOD ConvertFromPICT(PicHandle inPicture);
//Convert to os-native icon format(s)
//exact format depends on the bit depth
NS_IMETHOD ConvertToIcon( const nsRect& aSrcRegion,
const PRInt16 aIconDepth,
const PRInt16 aIconSize,
Handle* aOutIcon,
OSType* aOutIconType);
NS_IMETHOD ConvertAlphaToIconMask( const nsRect& aSrcRegion,
const PRInt16 aMaskDepth,
const PRInt16 aMaskSize,
Handle* aOutMask,
OSType* aOutIconType);
protected:
nsresult SlowTile(nsIRenderingContext &aContext,
nsIDrawingSurface* aSurface,
PRInt32 aSXOffset, PRInt32 aSYOffset,
PRInt32 aPadX, PRInt32 aPadY,
const nsRect &aTileRect);
nsresult DrawTileQuickly(nsIRenderingContext &aContext,
nsIDrawingSurface* aSurface,
PRInt32 aSXOffset, PRInt32 aSYOffset,
const nsRect &aTileRect);
nsresult CopyPixMap( const Rect& aSrcRegion,
const Rect& aDestRegion,
const PRInt32 aDestDepth,
const PRBool aCopyMaskBits,
Handle *aDestData,
PRBool aAllow2Bytes = PR_FALSE);
static GDHandle GetCachedGDeviceForDepth(PRInt32 aDepth);
static OSType MakeIconType(PRInt32 aHeight, PRInt32 aDepth, PRBool aMask);
static OSErr CreateGWorld(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,
GWorldPtr* outGWorld, char** outBits, PRInt32* outRowBytes);
static PRInt32 CalculateRowBytes(PRUint32 aWidth, PRUint32 aDepth);
static PRUint32 GetPixelFormatForDepth(PRInt32 inDepth, PRInt32& outBitsPerPixel, CTabHandle* outDefaultColorTable = nsnull);
static void ClearGWorld(GWorldPtr);
static OSErr AllocateGWorld(PRInt16 depth, CTabHandle colorTable, const Rect& bounds, GWorldPtr *outGWorld);
inline static PRInt32 CalculateRowBytesInternal(PRUint32 aWidth,
PRUint32 aDepth,
PRBool aAllow2Bytes);
static nsresult ConcatBitsHandles( Handle srcData1,
Handle srcData2,
Handle *dstData);
static nsresult MakeOpaqueMask( const PRInt32 aWidth,
const PRInt32 aHeight,
const PRInt32 aDepth,
Handle *aMask);
static void CopyBitsWithMask(const BitMap* srcBits, const BitMap* maskBits, PRInt16 maskDepth, const BitMap* destBits,
const Rect& srcRect, const Rect& maskRect, const Rect& destRect, PRBool inDrawingToPort);
static PRBool RenderingToPrinter(nsIRenderingContext &aContext);
static OSErr CreateGWorldInternal( PRInt32 aWidth,
PRInt32 aHeight,
PRInt32 aDepth,
GWorldPtr* outGWorld,
char** outBits,
PRInt32* outRowBytes,
PRBool aAllow2Bytes);
// Recreate internal image structure from updated image bits.
void EnsureCachedImage();
static PRInt32 CalculateRowBytesInternal(PRUint32 aWidth,
PRUint32 aDepth,
PRBool aAllow2Bytes);
// Return alpha bit at position 'x' in the row pointed to by 'rowptr'.
inline PRUint8 GetBit(PRUint8* rowptr, PRUint32 x) {
return (rowptr[x >> 3] & (1 << (7 - x & 0x7)));
}
// Takes ownership of the given image and bitmap. The CGImageRef is retained.
void AdoptImage(CGImageRef aNewImage, PRUint8* aNewBitamp);
private:
GWorldPtr mImageGWorld;
char* mImageBits; // malloc'd block
PRUint8* mImageBits; // malloc'd block
CGImageRef mImage;
PRInt32 mWidth;
PRInt32 mHeight;
PRInt32 mRowBytes;
PRInt32 mBytesPerPixel;
// alpha layer members
GWorldPtr mMaskGWorld;
char* mMaskBits; // malloc'd block
PRInt16 mAlphaDepth; // alpha layer depth
PRUint8* mAlphaBits; // malloc'd block
PRInt32 mAlphaRowBytes; // alpha row bytes
PRInt8 mAlphaDepth; // alpha layer depth
PRPackedBool mPendingUpdate; // true when we need to recreate CGImageRef
PRBool mOptimized; // true when nsImage object has been
// optimized (see |Optimize()|)
PRInt32 mDecodedX1; // Keeps track of what part of image
PRInt32 mDecodedY1; // has been decoded.
PRInt32 mDecodedX2;
PRInt32 mDecodedY2;
//nsPoint mLocation; // alpha mask location
//PRInt8 mImageCache; // place to save off the old image for fast animation
PRInt32 mDecodedX2;
PRInt32 mDecodedY2;
};
#endif

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

@ -286,9 +286,8 @@ NS_IMETHODIMP gfxImageFrame::SetImageData(const PRUint8 *aData, PRUint32 aLength
PRInt32 imgLen = row_stride * mSize.height;
PRInt32 newOffset;
#if defined(XP_WIN) || defined(XP_OS2)
#ifdef MOZ_PLATFORM_IMAGES_BOTTOM_TO_TOP
// Adjust: We need offset to be top-down rows & LTR within each row
// On win32 & os/2, it's passed in as bottom-up rows & LTR within each row
PRUint32 yOffset = ((PRUint32)(aOffset / row_stride)) * row_stride;
newOffset = ((mSize.height - 1) * row_stride) - yOffset + (aOffset % row_stride);
#else
@ -385,9 +384,8 @@ NS_IMETHODIMP gfxImageFrame::SetAlphaData(const PRUint8 *aData, PRUint32 aLength
PRInt32 alphaLen = row_stride * mSize.height;
PRInt32 offset;
#if defined(XP_WIN) || defined(XP_OS2)
#ifdef MOZ_PLATFORM_IMAGES_BOTTOM_TO_TOP
// Adjust: We need offset to be top-down rows & LTR within each row
// On win32 & os/2, it's passed in as bottom-up rows & LTR within each row
PRUint32 yOffset = ((PRUint32)(aOffset / row_stride)) * row_stride;
offset = ((mSize.height - 1) * row_stride) - yOffset + (aOffset % row_stride);
#else

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

@ -751,15 +751,15 @@ void imgContainerGIF::BuildCompositeMask(gfxIImageFrame *aCompositingFrame,
const PRUint32 height = PR_MIN(heightOverlay,
heightComposite - overlayYOffset);
// Windows and OS/2 have the funky bottom up data storage we need to account for
#if defined(XP_WIN) || defined(XP_OS2)
#ifdef MOZ_PLATFORM_IMAGES_BOTTOM_TO_TOP
// Account for bottom-up storage
PRInt32 offset = ((heightComposite - 1) - overlayYOffset) * abprComposite;
#else
PRInt32 offset = overlayYOffset * abprComposite;
#endif
PRUint8* alphaLine = compositingAlphaData + offset + (overlayXOffset >> 3);
#if defined(XP_WIN) || defined(XP_OS2)
#ifdef MOZ_PLATFORM_IMAGES_BOTTOM_TO_TOP
offset = (heightOverlay - 1) * abprOverlay;
#else
offset = 0;
@ -820,7 +820,7 @@ void imgContainerGIF::BuildCompositeMask(gfxIImageFrame *aCompositingFrame,
}
}
#if defined(XP_WIN) || defined(XP_OS2)
#ifdef MOZ_PLATFORM_IMAGES_BOTTOM_TO_TOP
alphaLine -= abprComposite;
overlayLine -= abprOverlay;
#else
@ -877,8 +877,8 @@ void imgContainerGIF::SetMaskVisibility(gfxIImageFrame *aFrame,
PRUint32 abpr;
aFrame->GetAlphaBytesPerRow(&abpr);
// Windows and OS/2 have the funky bottom up data storage we need to account for
#if defined(XP_WIN) || defined(XP_OS2)
#ifdef MOZ_PLATFORM_IMAGES_BOTTOM_TO_TOP
// Account for bottom-up storage.
// Start at the bottom (top in memory), go to the top (bottom in memory)
PRUint8* alphaLine = alphaData + ((frameHeight - aY - height) * abpr) +
(aX >> 3);