Added LoadIconImage member function to nsIDeviceContext, and added new

network context for doing sync load (used when loading icons)
This commit is contained in:
troy%netscape.com 1998-07-29 00:42:50 +00:00
parent 19661eba07
commit 223ec0aca4
13 changed files with 408 additions and 32 deletions

BIN
gfx/src/icon_0.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

BIN
gfx/src/icon_1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

View File

@ -30,7 +30,7 @@ CPPSRCS=nsColor.cpp nsColorNames.cpp nsColorNamesRGB.cpp nsFont.cpp \
nsImageGroup.cpp nsImageManager.cpp nsImageNetContextAsync.cpp \
nsImageRenderer.cpp nsImageRequest.cpp nsImageSystemServices.cpp \
nsImageURL.cpp nsRect.cpp nsTransform2D.cpp nsFontCache.cpp \
nsDeviceContext.cpp
nsDeviceContext.cpp nsImageNetContextSync.cpp
EXPORTS=nsColor.h nsColorNames.h nsCoord.h nsFont.h nsRect.h nsPoint.h \
nsSize.h nsMargin.h nsTransform2D.h nsIRenderingContext.h \
@ -45,7 +45,7 @@ CPP_OBJS=.\$(OBJDIR)\nsColor.obj .\$(OBJDIR)\nsColorNames.obj \
.\$(OBJDIR)\nsImageRequest.obj .\$(OBJDIR)\nsImageSystemServices.obj \
.\$(OBJDIR)\nsImageURL.obj .\$(OBJDIR)\nsRect.obj \
.\$(OBJDIR)\nsTransform2D.obj .\$(OBJDIR)\nsFontCache.obj \
.\$(OBJDIR)\nsDeviceContext.obj
.\$(OBJDIR)\nsDeviceContext.obj .\$(OBJDIR)\nsImageNetContextSync.obj
LINCS=-I$(PUBLIC)\util -I$(PUBLIC)\img \
-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor \
@ -61,6 +61,12 @@ include <$(DEPTH)\config\rules.mak>
libs:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
install::
$(MAKE_INSTALL) icon_0.gif $(DIST)\bin\res\gfx
$(MAKE_INSTALL) icon_1.gif $(DIST)\bin\res\gfx
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
rm -f $(PDBFILE).pdb
rm -f $(DIST)\bin\res\gfx\icon_0.gif
rm -f $(DIST)\bin\res\gfx\icon_1.gif

View File

@ -20,10 +20,17 @@
#include "nsIFontCache.h"
#include "nsIView.h"
#include "nsGfxCIID.h"
#include "nsImageNet.h"
#include "nsImageRequest.h"
#include "nsIImageGroup.h"
#include "il_util.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kDeviceContextIID, NS_IDEVICE_CONTEXT_IID);
NS_IMPL_QUERY_INTERFACE(DeviceContextImpl, kDeviceContextIID)
NS_IMPL_ADDREF(DeviceContextImpl)
NS_IMPL_RELEASE(DeviceContextImpl)
DeviceContextImpl :: DeviceContextImpl()
{
NS_INIT_REFCNT();
@ -33,6 +40,11 @@ DeviceContextImpl :: DeviceContextImpl()
mGammaValue = 1.0f;
mGammaTable = new PRUint8[256];
mZoom = 1.0f;
mWidget = nsnull;
mIconImageGroup = nsnull;
for (PRInt32 i = 0; i < NS_NUMBER_OF_ICONS; i++) {
mIcons[i] = nsnull;
}
}
DeviceContextImpl :: ~DeviceContextImpl()
@ -44,11 +56,13 @@ DeviceContextImpl :: ~DeviceContextImpl()
delete mGammaTable;
mGammaTable = nsnull;
}
}
NS_IMPL_QUERY_INTERFACE(DeviceContextImpl, kDeviceContextIID)
NS_IMPL_ADDREF(DeviceContextImpl)
NS_IMPL_RELEASE(DeviceContextImpl)
IL_DestroyGroupContext(mIconImageGroup);
for (PRInt32 i = 0; i < NS_NUMBER_OF_ICONS; i++) {
NS_IF_RELEASE(mIcons[i]);
}
}
nsresult DeviceContextImpl :: Init(nsNativeWidget aWidget)
{
@ -203,3 +217,111 @@ nsNativeWidget DeviceContextImpl :: GetNativeWidget(void)
return mWidget;
}
nsresult DeviceContextImpl::CreateImageGroupContext(nsIRenderingContext& aContext)
{
ilIImageRenderer* renderer;
nsresult result;
// Create an image renderer
result = NS_NewImageRenderer(&renderer);
if (NS_FAILED(result)) {
return result;
}
// Create an image group context. The image renderer code expects the
// display_context to be a pointer to a nsIRenderingContext
mIconImageGroup = IL_NewGroupContext((void*)(nsIRenderingContext*)&aContext,
renderer);
if (nsnull == mIconImageGroup) {
NS_RELEASE(renderer);
return NS_ERROR_OUT_OF_MEMORY;
}
// Initialize the image group context.
// XXX Hard coded tp 24-bits.
IL_RGBBits colorRGBBits;
IL_ColorSpace* colorSpace;
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);
if (nsnull == colorSpace) {
NS_RELEASE(renderer);
IL_DestroyGroupContext(mIconImageGroup);
return NS_ERROR_OUT_OF_MEMORY;
}
// This is all synchronous, so don't waste time with progressive display
IL_DisplayData displayData;
displayData.dither_mode = IL_Auto;
displayData.color_space = colorSpace;
displayData.progressive_display = PR_FALSE;
IL_SetDisplayMode(mIconImageGroup, IL_COLOR_SPACE | IL_DITHER_MODE, &displayData);
IL_ReleaseColorSpace(colorSpace);
return NS_OK;
}
NS_IMETHODIMP DeviceContextImpl::LoadIconImage(nsIRenderingContext& aContext,
PRInt32 aId,
nsIImage*& aImage)
{
nsresult result;
// Initialize out parameter
aImage = nsnull;
// Make sure the icon number is valid
if ((aId < 0) || (aId >= NS_NUMBER_OF_ICONS)) {
return NS_ERROR_ILLEGAL_VALUE;
}
// See if the icon is already loaded
if (nsnull != mIcons[aId]) {
aImage = mIcons[aId]->GetImage();
return NS_OK;
}
// Make sure we have an image group context
if (nsnull == mIconImageGroup) {
result = CreateImageGroupContext(aContext);
if (NS_FAILED(result)) {
return result;
}
}
// Build the URL string
char url[128];
sprintf(url, "resource://res/gfx/icon_%d.gif", aId);
// Use a sync net context
ilINetContext* netContext;
result = NS_NewImageNetContextSync(&netContext);
if (NS_FAILED(result)) {
return result;
}
// Create an image request object which will do the actual load
ImageRequestImpl* imageReq = new ImageRequestImpl();
if (nsnull == imageReq) {
result = NS_ERROR_OUT_OF_MEMORY;
} else {
// Load the image
result = imageReq->Init(mIconImageGroup, url, nsnull, nsnull, 0, 0,
nsImageLoadFlags_kHighPriority, netContext);
aImage = imageReq->GetImage();
// Keep the image request object around and avoid reloading the image
NS_ADDREF(imageReq);
mIcons[aId] = imageReq;
}
netContext->Release();
return result;
}

View File

@ -20,6 +20,8 @@
#define nsDeviceContext_h___
#include "nsIDeviceContext.h"
#include "libimg.h"
class nsIImageRequest;
class DeviceContextImpl : public nsIDeviceContext
{
@ -57,11 +59,16 @@ public:
virtual nsNativeWidget GetNativeWidget(void);
NS_IMETHOD LoadIconImage(nsIRenderingContext& aContext,
PRInt32 aId,
nsIImage*& aImage);
protected:
virtual ~DeviceContextImpl();
nsresult CreateFontCache();
void SetGammaTable(PRUint8 * aTable, float aCurrentGamma, float aNewGamma);
nsresult CreateImageGroupContext(nsIRenderingContext& aContext);
float mTwipsToPixels;
float mPixelsToTwips;
@ -72,6 +79,8 @@ protected:
float mGammaValue;
PRUint8 *mGammaTable;
nsNativeWidget mWidget;
IL_GroupContext* mIconImageGroup;
nsIImageRequest* mIcons[NS_NUMBER_OF_ICONS];
};
#endif /* nsDeviceContext_h___ */

View File

@ -26,7 +26,6 @@
#include "nsIWidget.h"
class nsIView;
class nsIRenderingContext;
class nsIFontCache;
class nsIFontMetrics;
class nsIWidget;
@ -45,6 +44,7 @@ typedef void * nsNativeDeviceContext;
*/
#define NS_ICON_LOADING_IMAGE 0
#define NS_ICON_BROKEN_IMAGE 1
#define NS_NUMBER_OF_ICONS 2
class nsIDeviceContext : public nsISupports
{
@ -102,8 +102,12 @@ public:
virtual nsNativeWidget GetNativeWidget(void) = 0;
//load the specified icon. this is a blocking call that does not return
//until the icon is loaded
// NS_IMETHOD LoadIcon(PRInt32 aId, nsIImage*&) = 0;
//until the icon is loaded.
//release the image when you're done
NS_IMETHOD LoadIconImage(nsIRenderingContext& aContext,
PRInt32 aId,
nsIImage*& aImage) = 0;
};
#endif /* nsIDeviceContext_h___ */

View File

@ -210,11 +210,15 @@ ImageGroupImpl::GetImage(const char* aUrl,
ImageRequestImpl *image_req = new ImageRequestImpl();
if (image_req != nsnull) {
if (image_req->Init(mGroupContext, aUrl, aObserver, aBackgroundColor,
aWidth, aHeight, aFlags) == NS_OK) {
ilINetContext* net_cx;
// Create an async net context, and ask the image request object
// to get the image
if (NS_SUCCEEDED(NS_NewImageNetContext(&net_cx)) &&
NS_SUCCEEDED(image_req->Init(mGroupContext, aUrl, aObserver, aBackgroundColor,
aWidth, aHeight, aFlags, net_cx))) {
NS_ADDREF(image_req);
}
else {
} else {
delete image_req;
image_req = nsnull;
}

View File

@ -28,3 +28,6 @@ extern "C" NS_GFX_(nsresult) NS_NewImageURL(ilIURL **aInstancePtrResult, const
extern "C" NS_GFX_(nsresult) NS_NewImageRenderer(ilIImageRenderer **aInstancePtrResult);
extern "C" NS_GFX_(nsresult) NS_NewImageSystemServices(ilISystemServices **aInstancePtrResult);
// Internal net context used for synchronously loading icons
nsresult NS_NewImageNetContextSync(ilINetContext** aInstancePtrResult);

View File

@ -0,0 +1,235 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "libimg.h"
#include "nsImageNet.h"
#include "ilINetContext.h"
#include "ilIURL.h"
#include "ilINetReader.h"
#include "nsIInputStream.h"
#include "nsIURL.h"
#include "prmem.h"
#include "plstr.h"
#include "il_strm.h"
#include "nsINetService.h"
static NS_DEFINE_IID(kIImageNetContextIID, IL_INETCONTEXT_IID);
static NS_DEFINE_IID(kIURLIID, NS_IURL_IID);
class ImageNetContextSyncImpl : public ilINetContext {
public:
ImageNetContextSyncImpl(NET_ReloadMethod aReloadPolicy);
~ImageNetContextSyncImpl();
NS_DECL_ISUPPORTS
virtual ilINetContext* Clone();
virtual NET_ReloadMethod GetReloadPolicy();
virtual void AddReferer(ilIURL* aUrl);
virtual void Interrupt();
virtual ilIURL* CreateURL(const char* aUrl,
NET_ReloadMethod aReloadMethod);
virtual PRBool IsLocalFileURL(char* aAddress);
virtual PRBool IsURLInMemCache(ilIURL* aUrl);
virtual PRBool IsURLInDiskCache(ilIURL* aUrl);
virtual int GetURL(ilIURL* aUrl,
NET_ReloadMethod aLoadMethod,
ilINetReader* aReader);
NET_ReloadMethod mReloadPolicy;
};
ImageNetContextSyncImpl::ImageNetContextSyncImpl(NET_ReloadMethod aReloadPolicy)
{
NS_INIT_REFCNT();
mReloadPolicy = aReloadPolicy;
}
ImageNetContextSyncImpl::~ImageNetContextSyncImpl()
{
}
NS_IMPL_ISUPPORTS(ImageNetContextSyncImpl, kIImageNetContextIID)
ilINetContext*
ImageNetContextSyncImpl::Clone()
{
ilINetContext *cx;
if (NS_NewImageNetContextSync(&cx) == NS_OK) {
return cx;
}
return nsnull;
}
NET_ReloadMethod
ImageNetContextSyncImpl::GetReloadPolicy()
{
return mReloadPolicy;
}
void
ImageNetContextSyncImpl::AddReferer(ilIURL *aUrl)
{
}
void
ImageNetContextSyncImpl::Interrupt()
{
}
ilIURL*
ImageNetContextSyncImpl::CreateURL(const char* aURL,
NET_ReloadMethod aReloadMethod)
{
ilIURL *url;
if (NS_NewImageURL(&url, aURL) == NS_OK) {
return url;
}
return nsnull;
}
PRBool
ImageNetContextSyncImpl::IsLocalFileURL(char *aAddress)
{
if (PL_strncasecmp(aAddress, "file:", 5) == 0) {
return PR_TRUE;
} else {
return PR_FALSE;
}
}
PRBool
ImageNetContextSyncImpl::IsURLInMemCache(ilIURL *aUrl)
{
return PR_FALSE;
}
PRBool
ImageNetContextSyncImpl::IsURLInDiskCache(ilIURL *aUrl)
{
return PR_FALSE;
}
int
ImageNetContextSyncImpl::GetURL(ilIURL* aURL,
NET_ReloadMethod aLoadMethod,
ilINetReader* aReader)
{
NS_PRECONDITION(nsnull != aURL, "null URL");
NS_PRECONDITION(nsnull != aReader, "null reader");
if (aURL == nsnull || aReader == nsnull) {
return -1;
}
aURL->SetReader(aReader);
PRInt32 status = 0;
// Get a nsIURL interface
nsIURL* url;
aURL->QueryInterface(kIURLIID, (void **)&url);
// Get a network service interface which we'll use to create a stream
nsINetService *service;
if (NS_SUCCEEDED(NS_NewINetService(&service, nsnull))) {
nsIInputStream* stream = nsnull;
// Initiate a synchronous URL load
if (NS_SUCCEEDED(service->OpenBlockingStream(url, nsnull, &stream)) &&
(aReader->StreamCreated(aURL, IL_UNKNOWN) == PR_TRUE)) {
// Read the URL data
char buf[2048];
PRInt32 count;
nsresult result;
PRBool first = PR_TRUE;
result = stream->Read(buf, 0, sizeof(buf), &count);
while (NS_SUCCEEDED(result) && (count > 0)) {
if (first == PR_TRUE) {
PRInt32 ilErr;
ilErr = aReader->FirstWrite((const unsigned char *)buf, count);
first = PR_FALSE;
// If FirstWrite fails then the image type cannot be determined
if (ilErr != 0) {
result = NS_ERROR_ABORT;
break;
}
}
aReader->Write((const unsigned char *)buf, count);
// Get the next block
result = stream->Read(buf, 0, sizeof(buf), &count);
}
if (NS_FAILED(result)) {
aReader->StreamAbort(-1);
status = -1;
} else {
NS_ASSERTION(0 == count, "expected EOF");
aReader->StreamComplete(PR_FALSE);
}
} else {
aReader->StreamAbort(-1);
status = -1;
}
NS_IF_RELEASE(stream);
NS_RELEASE(service);
} else {
aReader->StreamAbort(-1);
status = -1;
}
aReader->NetRequestDone(aURL, status);
return 0;
}
nsresult NS_NewImageNetContextSync(ilINetContext **aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
ilINetContext *cx = new ImageNetContextSyncImpl(NET_NORMAL_RELOAD);
if (cx == nsnull) {
return NS_ERROR_OUT_OF_MEMORY;
}
return cx->QueryInterface(kIImageNetContextIID, (void **) aInstancePtrResult);
}

View File

@ -22,7 +22,6 @@
#include "nsIImage.h"
#include "nsVoidArray.h"
#include "nsRect.h"
#include "ilINetContext.h"
#include "nsImageNet.h"
static NS_DEFINE_IID(kIImageRequestIID, NS_IIMAGEREQUEST_IID);
@ -47,7 +46,8 @@ ImageRequestImpl::Init(IL_GroupContext *aGroupContext,
nsIImageRequestObserver *aObserver,
const nscolor* aBackgroundColor,
PRUint32 aWidth, PRUint32 aHeight,
PRUint32 aFlags)
PRUint32 aFlags,
ilINetContext* aNetContext)
{
NS_PRECONDITION(nsnull != aGroupContext, "null group context");
NS_PRECONDITION(nsnull != aUrl, "null URL");
@ -55,12 +55,13 @@ ImageRequestImpl::Init(IL_GroupContext *aGroupContext,
NS_Error status;
IL_IRGB bgcolor;
PRUint32 flags;
nsresult result;
mGroupContext = aGroupContext;
if (AddObserver(aObserver) == PR_FALSE) {
return NS_ERROR_OUT_OF_MEMORY;
if (nsnull != aObserver) {
if (AddObserver(aObserver) == PR_FALSE) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
status = XP_NewObserverList(NULL, &mXPObserver);
@ -87,17 +88,9 @@ ImageRequestImpl::Init(IL_GroupContext *aGroupContext,
((aFlags & IL_BYPASS_CACHE) ? nsImageLoadFlags_kBypassCache : 0) |
((aFlags & IL_ONLY_FROM_CACHE) ? nsImageLoadFlags_kOnlyFromCache : 0);
ilINetContext *net_cx;
if ((result = NS_NewImageNetContext(&net_cx)) != NS_OK) {
XP_DisposeObserverList(mXPObserver);
mXPObserver = nsnull;
return result;
}
mImageReq = IL_GetImage(aUrl, aGroupContext, mXPObserver,
nsnull == aBackgroundColor ? nsnull : &bgcolor,
aWidth, aHeight, flags, (void *)net_cx);
aWidth, aHeight, flags, (void *)aNetContext);
if (mImageReq == nsnull) {
XP_DisposeObserverList(mXPObserver);

View File

@ -26,6 +26,7 @@
class nsVoidArray;
class nsIImageRequestObserver;
class ilINetContext;
class ImageRequestImpl : public nsIImageRequest {
public:
@ -36,7 +37,8 @@ public:
nsIImageRequestObserver *aObserver,
const nscolor* aBackgroundColor,
PRUint32 aWidth, PRUint32 aHeight,
PRUint32 aFlags);
PRUint32 aFlags,
ilINetContext* aNetContext);
void* operator new(size_t sz) {
void* rv = new char[sz];

View File

@ -22,8 +22,6 @@
nsDeviceContextWin :: nsDeviceContextWin()
: DeviceContextImpl()
{
NS_INIT_REFCNT();
HDC hdc = ::GetDC(NULL);
mTwipsToPixels = ((float)::GetDeviceCaps(hdc, LOGPIXELSX)) / NS_POINTS_TO_TWIPS_FLOAT(72.0f);

View File

@ -37,7 +37,7 @@ public:
virtual nsDrawingSurface GetDrawingSurface(nsIRenderingContext &aContext);
protected:
~nsDeviceContextWin();
virtual ~nsDeviceContextWin();
HDC mSurface;
};