Changed CreateILColorSpace() to GetILColorSpace() (device context now

owns the color space), and cleaned up image renderer code
This commit is contained in:
troy%netscape.com 1998-08-17 23:20:42 +00:00
parent 087f296c2c
commit 3590c4caed
9 changed files with 165 additions and 210 deletions

View File

@ -437,7 +437,7 @@ nsresult nsDeviceContextMac :: CheckFontExistence(const nsString& aFontName)
return NS_OK;
}
nsresult nsDeviceContextMac :: CreateILColorSpace(IL_ColorSpace*& aColorSpace)
nsresult nsDeviceContextMac :: GetILColorSpace(IL_ColorSpace*& aColorSpace)
{
return nsnull;
}

View File

@ -47,6 +47,7 @@ DeviceContextImpl :: DeviceContextImpl()
mIcons[i] = nsnull;
}
mFontAliasTable = nsnull;
mColorSpace = nsnull;
}
static PRBool DeleteValue(nsHashKey* aKey, void* aValue)
@ -76,6 +77,10 @@ DeviceContextImpl :: ~DeviceContextImpl()
mFontAliasTable->Enumerate(DeleteValue);
delete mFontAliasTable;
}
if (nsnull != mColorSpace) {
IL_ReleaseColorSpace(mColorSpace);
}
}
nsresult DeviceContextImpl :: Init(nsNativeWidget aWidget)
@ -258,7 +263,7 @@ nsresult DeviceContextImpl::CreateIconILGroupContext()
// Initialize the image group context.
IL_ColorSpace* colorSpace;
result = CreateILColorSpace(colorSpace);
result = GetILColorSpace(colorSpace);
if (NS_FAILED(result)) {
NS_RELEASE(renderer);
IL_DestroyGroupContext(mIconImageGroup);
@ -492,24 +497,29 @@ NS_IMETHODIMP DeviceContextImpl::GetLocalFontName(const nsString& aFaceName, nsS
return result;
}
NS_IMETHODIMP DeviceContextImpl::CreateILColorSpace(IL_ColorSpace*& aColorSpace)
NS_IMETHODIMP DeviceContextImpl::GetILColorSpace(IL_ColorSpace*& aColorSpace)
{
IL_RGBBits colorRGBBits;
// Default is to create a 24-bit color space
colorRGBBits.red_shift = 16;
colorRGBBits.red_bits = 8;
colorRGBBits.green_shift = 8;
colorRGBBits.green_bits = 8;
colorRGBBits.blue_shift = 0;
colorRGBBits.blue_bits = 8;
aColorSpace = IL_CreateTrueColorSpace(&colorRGBBits, 24);
if (nsnull == aColorSpace) {
return NS_ERROR_OUT_OF_MEMORY;
if (nsnull == mColorSpace) {
IL_RGBBits colorRGBBits;
// Default is to create a 24-bit color space
colorRGBBits.red_shift = 16;
colorRGBBits.red_bits = 8;
colorRGBBits.green_shift = 8;
colorRGBBits.green_bits = 8;
colorRGBBits.blue_shift = 0;
colorRGBBits.blue_bits = 8;
mColorSpace = IL_CreateTrueColorSpace(&colorRGBBits, 24);
if (nsnull == mColorSpace) {
aColorSpace = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
}
NS_POSTCONDITION(nsnull != mColorSpace, "null color space");
aColorSpace = mColorSpace;
IL_AddRefToColorSpace(aColorSpace);
return NS_OK;
}

View File

@ -70,7 +70,7 @@ public:
NS_IMETHOD GetDepth(PRUint32& aDepth);
NS_IMETHOD CreateILColorSpace(IL_ColorSpace*& aColorSpace);
NS_IMETHOD GetILColorSpace(IL_ColorSpace*& aColorSpace);
protected:
virtual ~DeviceContextImpl();
@ -95,6 +95,7 @@ protected:
IL_GroupContext* mIconImageGroup;
nsIImageRequest* mIcons[NS_NUMBER_OF_ICONS];
nsHashtable* mFontAliasTable;
IL_ColorSpace* mColorSpace;
};
#endif /* nsDeviceContext_h___ */

View File

@ -129,10 +129,12 @@ public:
NS_IMETHOD GetDepth(PRUint32& aDepth) = 0;
/**
* Create an image lib color space that's appropriate for this rendering
* context
* Return the image lib color space that's appropriate for this rendering
* context.
*
* You must call IL_ReleaseColorSpace() when you're done using the color space.
*/
NS_IMETHOD CreateILColorSpace(IL_ColorSpace*& aColorSpace) = 0;
NS_IMETHOD GetILColorSpace(IL_ColorSpace*& aColorSpace) = 0;
};
#endif /* nsIDeviceContext_h___ */

View File

@ -71,7 +71,6 @@ private:
IL_GroupContext *mGroupContext;
nsVoidArray *mObservers;
nsIDeviceContext *mDeviceContext;
IL_ColorSpace *mColorSpace;
ilINetContext* mNetContext;
};
@ -103,10 +102,6 @@ ImageGroupImpl::~ImageGroupImpl()
IL_DestroyGroupContext(mGroupContext);
}
if (mColorSpace != nsnull) {
IL_ReleaseColorSpace(mColorSpace);
}
NS_IF_RELEASE(mManager);
NS_IF_RELEASE(mNetContext);
}
@ -137,20 +132,22 @@ ImageGroupImpl::Init(nsIDeviceContext *aDeviceContext)
mDeviceContext = aDeviceContext;
NS_ADDREF(mDeviceContext);
// Ask the device context to create a color space.
// XXX We should ask the device context to get its color space
// rather than having it create a color space for us...
mDeviceContext->CreateILColorSpace(mColorSpace);
// Get color space to use for this device context.
IL_ColorSpace* colorSpace;
mDeviceContext->GetILColorSpace(colorSpace);
// Set the image group context display mode
IL_DisplayData displayData;
displayData.dither_mode = IL_Auto;
displayData.color_space = mColorSpace;
displayData.color_space = colorSpace;
displayData.progressive_display = PR_TRUE;
IL_SetDisplayMode(mGroupContext,
IL_COLOR_SPACE | IL_PROGRESSIVE_DISPLAY | IL_DITHER_MODE,
&displayData);
// Release the color space
IL_ReleaseColorSpace(colorSpace);
return NS_OK;
}

View File

@ -29,234 +29,172 @@ static NS_DEFINE_IID(kIImageRendererIID, IL_IIMAGERENDERER_IID);
class ImageRendererImpl : public ilIImageRenderer {
public:
static IL_ColorSpace *sPseudoColorSpace;
ImageRendererImpl();
~ImageRendererImpl();
NS_DECL_ISUPPORTS
virtual void NewPixmap(void* aDisplayContext,
PRInt32 aWidth, PRInt32 aHeight,
IL_Pixmap* aImage, IL_Pixmap* aMask);
PRInt32 aWidth, PRInt32 aHeight,
IL_Pixmap* aImage, IL_Pixmap* aMask);
virtual void UpdatePixmap(void* aDisplayContext,
IL_Pixmap* aImage,
PRInt32 aXOffset, PRInt32 aYOffset,
PRInt32 aWidth, PRInt32 aHeight);
IL_Pixmap* aImage,
PRInt32 aXOffset, PRInt32 aYOffset,
PRInt32 aWidth, PRInt32 aHeight);
virtual void ControlPixmapBits(void* aDisplayContext,
IL_Pixmap* aImage, PRUint32 aControlMsg);
IL_Pixmap* aImage, PRUint32 aControlMsg);
virtual void DestroyPixmap(void* aDisplayContext, IL_Pixmap* aImage);
virtual void DisplayPixmap(void* aDisplayContext,
IL_Pixmap* aImage, IL_Pixmap* aMask,
PRInt32 aX, PRInt32 aY,
PRInt32 aXOffset, PRInt32 aYOffset,
PRInt32 aWidth, PRInt32 aHeight);
IL_Pixmap* aImage, IL_Pixmap* aMask,
PRInt32 aX, PRInt32 aY,
PRInt32 aXOffset, PRInt32 aYOffset,
PRInt32 aWidth, PRInt32 aHeight);
virtual void DisplayIcon(void* aDisplayContext,
PRInt32 aX, PRInt32 aY, PRUint32 aIconNumber);
PRInt32 aX, PRInt32 aY, PRUint32 aIconNumber);
virtual void GetIconDimensions(void* aDisplayContext,
PRInt32 *aWidthPtr, PRInt32 *aHeightPtr,
PRUint32 aIconNumber);
PRInt32 *aWidthPtr, PRInt32 *aHeightPtr,
PRUint32 aIconNumber);
};
IL_ColorSpace *ImageRendererImpl::sPseudoColorSpace = nsnull;
ImageRendererImpl::ImageRendererImpl()
{
NS_INIT_REFCNT();
}
ImageRendererImpl::~ImageRendererImpl()
{
}
NS_IMPL_ISUPPORTS(ImageRendererImpl, kIImageRendererIID)
void
ImageRendererImpl::NewPixmap(void* aDisplayContext,
PRInt32 aWidth, PRInt32 aHeight,
IL_Pixmap* aImage, IL_Pixmap* aMask)
PRInt32 aWidth, PRInt32 aHeight,
IL_Pixmap* aImage, IL_Pixmap* aMask)
{
nsIDeviceContext *dc = (nsIDeviceContext *)aDisplayContext;
nsIImage *img;
nsresult rv;
nsIDeviceContext *dc = (nsIDeviceContext *)aDisplayContext;
nsIImage *img;
nsresult rv;
static NS_DEFINE_IID(kImageCID, NS_IMAGE_CID);
static NS_DEFINE_IID(kImageIID, NS_IIMAGE_IID);
static NS_DEFINE_IID(kImageCID, NS_IMAGE_CID);
static NS_DEFINE_IID(kImageIID, NS_IIMAGE_IID);
rv = NSRepository::CreateInstance(kImageCID, nsnull, kImageIID, (void **)&img);
if (NS_OK != rv)
return;
PRInt32 depth;
if (aImage->header.color_space->pixmap_depth == 8) {
depth = 8;
}
else {
depth = 24;
}
// XXX When the other platforms implement GetDepth() then remove the
// XP_WIN ifdef
#ifdef XP_WIN
PRUint32 deviceDepth;
dc->GetDepth(deviceDepth);
if ((8 == depth) && (deviceDepth > (PRUint32)depth)) {
// Don't force dithering to the color cube...
depth = 24;
// Create a new image object
rv = NSRepository::CreateInstance(kImageCID, nsnull, kImageIID, (void **)&img);
if (NS_OK != rv) {
// XXX What about error handling?
return;
}
#endif
img->Init(aWidth, aHeight, depth,
(aMask == nsnull) ? nsMaskRequirements_kNoMask :
nsMaskRequirements_kNeeds1Bit);
// Have the image match the depth and color space associated with the
// device.
// XXX We probably don't want to do that for monomchrome images (e.g., XBM)
// or one-bit deep GIF images.
PRInt32 depth;
IL_ColorSpace *colorSpace;
aImage->bits = img->GetBits();
aImage->client_data = img;
// We don't need to add a reference here, because we're already holding
// a reference, because of the call above to the repository to create the
// nsIImage*
aImage->header.width = aWidth;
aImage->header.height = aHeight;
aImage->header.widthBytes = img->GetLineStride();
dc->GetILColorSpace(colorSpace);
depth = colorSpace->pixmap_depth;
if (aMask) {
aMask->bits = img->GetAlphaBits();
aMask->client_data = img;
// Make sure you add another reference here, because when the mask's
// pixmap is destroyed the reference will be released
NS_ADDREF(img);
aMask->header.width = aWidth;
aMask->header.height = aHeight;
// Initialize the image object
img->Init(aWidth, aHeight, depth, (aMask == nsnull) ? nsMaskRequirements_kNoMask :
nsMaskRequirements_kNeeds1Bit);
// Update the pixmap image and mask information
aImage->bits = img->GetBits();
aImage->client_data = img; // we don't need to add a ref here, because there's
// already one from the call to create the image object
aImage->header.width = aWidth;
aImage->header.height = aHeight;
aImage->header.widthBytes = img->GetLineStride();
if (aMask) {
aMask->bits = img->GetAlphaBits();
aMask->client_data = img;
// We must add another reference here, because when the mask's pixmap is
// destroyed it will release a reference
NS_ADDREF(img);
aMask->header.width = aWidth;
aMask->header.height = aHeight;
}
// Replace the existing color space with the color space associated
// with the device.
IL_ReleaseColorSpace(aImage->header.color_space);
aImage->header.color_space = colorSpace;
// XXX Why do we do this on a per-image basis?
if (8 == depth) {
IL_ColorMap *cmap = &colorSpace->cmap;
nsColorMap *nscmap = img->GetColorMap();
PRUint8 *mapptr = nscmap->Index;
int i;
for (i=0; i < cmap->num_colors; i++) {
*mapptr++ = cmap->map[i].red;
*mapptr++ = cmap->map[i].green;
*mapptr++ = cmap->map[i].blue;
}
if (8 == depth) {
IL_ColorMap *cmap;
if (sPseudoColorSpace == nsnull) {
#ifdef XP_WIN
// This needs to match the logical palette
// XXX Clean this up to use the one and only color space
// the device manager should hold...
IL_RGB reserved[10];
memset(reserved, 0, sizeof(reserved));
cmap = IL_NewCubeColorMap(reserved, 10, 216 + 10);
#else
cmap = IL_NewCubeColorMap(nsnull, 0, 216);
#endif
if (cmap != nsnull) {
sPseudoColorSpace = IL_CreatePseudoColorSpace(cmap, 8, 8);
img->ImageUpdated(dc, nsImageUpdateFlags_kColorMapChanged, nsnull);
if (sPseudoColorSpace == nsnull) {
IL_DestroyColorMap(cmap);
// XXX We should do something here
return;
}
}
else {
// XXX We should do something here
return;
}
}
IL_AddRefToColorSpace(sPseudoColorSpace);
IL_ReleaseColorSpace(aImage->header.color_space);
aImage->header.color_space = sPseudoColorSpace;
cmap = &sPseudoColorSpace->cmap;
nsColorMap *nscmap = img->GetColorMap();
PRUint8 *mapptr = nscmap->Index;
int i;
for (i=0; i < cmap->num_colors; i++) {
*mapptr++ = cmap->map[i].red;
*mapptr++ = cmap->map[i].green;
*mapptr++ = cmap->map[i].blue;
}
img->ImageUpdated(dc, nsImageUpdateFlags_kColorMapChanged, nsnull);
if (aImage->header.transparent_pixel) {
PRUint8 red, green, blue;
PRUint8 *lookup_table = (PRUint8 *)aImage->header.color_space->cmap.table;
red = aImage->header.transparent_pixel->red;
green = aImage->header.transparent_pixel->green;
blue = aImage->header.transparent_pixel->blue;
aImage->header.transparent_pixel->index =
lookup_table[((red >> 3) << 10) |
((green >> 3) << 5) |
(blue >> 3)];
}
}
else {
IL_RGBBits colorRGBBits;
IL_ColorSpace *colorSpace;
// XXX We shouldn't be creating a new color space for pixmap. Change it
// to ask the device context for its color space
colorRGBBits.red_shift = 16;
colorRGBBits.red_bits = 8;
colorRGBBits.green_shift = 8;
colorRGBBits.green_bits = 8;
colorRGBBits.blue_shift = 0;
colorRGBBits.blue_bits = 8;
colorSpace = IL_CreateTrueColorSpace(&colorRGBBits, 24);
IL_ReleaseColorSpace(aImage->header.color_space);
aImage->header.color_space = colorSpace;
if (aImage->header.transparent_pixel) {
PRUint8 red, green, blue;
PRUint8 *lookup_table = (PRUint8 *)aImage->header.color_space->cmap.table;
red = aImage->header.transparent_pixel->red;
green = aImage->header.transparent_pixel->green;
blue = aImage->header.transparent_pixel->blue;
aImage->header.transparent_pixel->index = lookup_table[((red >> 3) << 10) |
((green >> 3) << 5) |
(blue >> 3)];
}
}
}
void
ImageRendererImpl::UpdatePixmap(void* aDisplayContext,
IL_Pixmap* aImage,
PRInt32 aXOffset, PRInt32 aYOffset,
PRInt32 aWidth, PRInt32 aHeight)
IL_Pixmap* aImage,
PRInt32 aXOffset, PRInt32 aYOffset,
PRInt32 aWidth, PRInt32 aHeight)
{
nsIDeviceContext *dc = (nsIDeviceContext *)aDisplayContext;
nsIImage *img = (nsIImage *)aImage->client_data;
nsRect drect(aXOffset, aYOffset, aWidth, aHeight);
nsIDeviceContext *dc = (nsIDeviceContext *)aDisplayContext;
nsIImage *img = (nsIImage *)aImage->client_data;
nsRect drect(aXOffset, aYOffset, aWidth, aHeight);
img->ImageUpdated(dc, nsImageUpdateFlags_kBitsChanged, &drect);
img->ImageUpdated(dc, nsImageUpdateFlags_kBitsChanged, &drect);
}
void
ImageRendererImpl::ControlPixmapBits(void* aDisplayContext,
IL_Pixmap* aImage, PRUint32 aControlMsg)
IL_Pixmap* aImage, PRUint32 aControlMsg)
{
nsIDeviceContext *dc = (nsIDeviceContext *)aDisplayContext;
nsIImage *img = (nsIImage *)aImage->client_data;
nsIDeviceContext *dc = (nsIDeviceContext *)aDisplayContext;
nsIImage *img = (nsIImage *)aImage->client_data;
if (aControlMsg == IL_RELEASE_BITS) {
img->Optimize(dc);
}
if (aControlMsg == IL_RELEASE_BITS) {
img->Optimize(dc);
}
}
void
ImageRendererImpl::DestroyPixmap(void* aDisplayContext, IL_Pixmap* aImage)
{
nsIDeviceContext *dc = (nsIDeviceContext *)aDisplayContext;
nsIImage *img = (nsIImage *)aImage->client_data;
nsIDeviceContext *dc = (nsIDeviceContext *)aDisplayContext;
nsIImage *img = (nsIImage *)aImage->client_data;
aImage->client_data = nsnull;
if (img) {
NS_RELEASE(img);
}
aImage->client_data = nsnull;
if (img) {
NS_RELEASE(img);
}
}
void
ImageRendererImpl::DisplayPixmap(void* aDisplayContext,
IL_Pixmap* aImage, IL_Pixmap* aMask,
PRInt32 aX, PRInt32 aY,
PRInt32 aXOffset, PRInt32 aYOffset,
PRInt32 aWidth, PRInt32 aHeight)
IL_Pixmap* aImage, IL_Pixmap* aMask,
PRInt32 aX, PRInt32 aY,
PRInt32 aXOffset, PRInt32 aYOffset,
PRInt32 aWidth, PRInt32 aHeight)
{
// Image library doesn't drive the display process.
// XXX Why is this part of the API?
@ -264,15 +202,15 @@ ImageRendererImpl::DisplayPixmap(void* aDisplayContext,
void
ImageRendererImpl::DisplayIcon(void* aDisplayContext,
PRInt32 aX, PRInt32 aY, PRUint32 aIconNumber)
PRInt32 aX, PRInt32 aY, PRUint32 aIconNumber)
{
// XXX Why is this part of the API?
}
void
ImageRendererImpl::GetIconDimensions(void* aDisplayContext,
PRInt32 *aWidthPtr, PRInt32 *aHeightPtr,
PRUint32 aIconNumber)
PRInt32 *aWidthPtr, PRInt32 *aHeightPtr,
PRUint32 aIconNumber)
{
// XXX Why is this part of the API?
}
@ -287,9 +225,8 @@ NS_NewImageRenderer(ilIImageRenderer **aInstancePtrResult)
ilIImageRenderer *renderer = new ImageRendererImpl();
if (renderer == nsnull) {
return NS_ERROR_OUT_OF_MEMORY;
return NS_ERROR_OUT_OF_MEMORY;
}
return renderer->QueryInterface(kIImageRendererIID,
(void **) aInstancePtrResult);
return renderer->QueryInterface(kIImageRendererIID, (void **)aInstancePtrResult);
}

View File

@ -106,8 +106,14 @@ NS_IMETHODIMP nsDeviceContextWin::GetDepth(PRUint32& aDepth)
return NS_OK;
}
NS_IMETHODIMP nsDeviceContextWin::CreateILColorSpace(IL_ColorSpace*& aColorSpace)
NS_IMETHODIMP nsDeviceContextWin::GetILColorSpace(IL_ColorSpace*& aColorSpace)
{
if (nsnull != mColorSpace) {
aColorSpace = mColorSpace;
IL_AddRefToColorSpace(aColorSpace);
return NS_OK;
}
HWND hwnd = (HWND)GetNativeWidget();
HDC hdc = ::GetDC(hwnd);
nsresult result = NS_OK;
@ -168,14 +174,16 @@ NS_IMETHODIMP nsDeviceContextWin::CreateILColorSpace(IL_ColorSpace*& aColorSpace
}
// Create an IL pseudo color space
aColorSpace = IL_CreatePseudoColorSpace(colorMap, 8, 8);
mColorSpace = IL_CreatePseudoColorSpace(colorMap, 8, 8);
if (nsnull == aColorSpace) {
return NS_ERROR_OUT_OF_MEMORY;
}
aColorSpace = mColorSpace;
IL_AddRefToColorSpace(aColorSpace);
} else {
// Create a default color space.
result = DeviceContextImpl::CreateILColorSpace(aColorSpace);
// Get the default color space.
result = DeviceContextImpl::GetILColorSpace(aColorSpace);
}
return result;

View File

@ -42,7 +42,7 @@ public:
NS_IMETHOD GetDepth(PRUint32& aDepth);
NS_IMETHOD CreateILColorSpace(IL_ColorSpace*& aColorSpace);
NS_IMETHOD GetILColorSpace(IL_ColorSpace*& aColorSpace);
protected:
virtual ~nsDeviceContextWin();

View File

@ -437,7 +437,7 @@ nsresult nsDeviceContextMac :: CheckFontExistence(const nsString& aFontName)
return NS_OK;
}
nsresult nsDeviceContextMac :: CreateILColorSpace(IL_ColorSpace*& aColorSpace)
nsresult nsDeviceContextMac :: GetILColorSpace(IL_ColorSpace*& aColorSpace)
{
return nsnull;
}