Reworked load image support and provided content changed calls to the shell when image sizes arrive

This commit is contained in:
kipp 1998-05-09 03:22:01 +00:00
Родитель 2cc285c48b
Коммит d2e721ddd9
2 изменённых файлов: 370 добавлений и 182 удалений

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

@ -17,6 +17,7 @@
*/
#include "nsPresContext.h"
#include "nsIPresShell.h"
#include "nsIContent.h"
#include "nsILinkHandler.h"
#include "nsIStyleContext.h"
#include "nsIStyleSet.h"
@ -34,24 +35,9 @@
#include "nsIURL.h"
#include "nsString.h"
static NS_DEFINE_IID(kIPresContextIID, NS_IPRESCONTEXT_IID);
#define NOISY
#if 0
// XXX this code needs to move far away from here
static nsIImageManager* gImageManager = nsnull;
static void InitImageLibrary()
{
// Initialize image library
if (NS_OK == NS_NewImageManager(&gImageManager)) {
if (NS_OK == gImageManager->Init()) {
gImageManager->SetCacheSize(1024*1024);
return;
}
}
printf("can't initialize image library\n");
}
// XXX end code with no home...
#endif
static NS_DEFINE_IID(kIPresContextIID, NS_IPRESCONTEXT_IID);
class ImageLoader : public nsIImageRequestObserver {
public:
@ -70,13 +56,25 @@ public:
return mImage;
}
PRInt32 FrameCount();
PRBool GetImageSize(nsSize& aSize) {
if ((mSize.width > 0) && (mSize.height > 0)) {
aSize = mSize;
return PR_TRUE;
}
return PR_FALSE;
}
PRInt32 FrameCount() const {
return mFrames.Count();
}
PRBool RemoveFrame(nsIFrame* aFrame);
void AddFrame(nsIFrame* aFrame);
void UpdateFrames();
void DamageRepairFrames();
void ReflowFrames();
virtual void Notify(nsIImageRequest *aImageRequest,
nsIImage *aImage,
@ -93,20 +91,19 @@ public:
nsIImage* mImage;
nsIImageRequest* mImageRequest;
nsIImageGroup* mImageGroup;
PRInt32 mWidth, mHeight; // in pixels
nsSize mSize; // Note: in pixels
nsImageError mError;
};
ImageLoader::ImageLoader(nsPresContext* aCX, nsIImageGroup* aGroup,
nsIFrame* aFrame)
: mSize(-1, -1)
{
mCX = aCX;
AddFrame(aFrame);
mImage = nsnull;
mImageRequest = nsnull;
mImageGroup = aGroup; NS_ADDREF(aGroup);
mWidth = -1;
mHeight = -1;
}
ImageLoader::~ImageLoader()
@ -117,7 +114,8 @@ ImageLoader::~ImageLoader()
}
}
void ImageLoader::LoadImage(const nsString& aURL)
void
ImageLoader::LoadImage(const nsString& aURL)
{
if (nsnull == mImage) {
// Save url
@ -137,19 +135,21 @@ static NS_DEFINE_IID(kIImageRequestObserver, NS_IIMAGEREQUESTOBSERVER_IID);
NS_IMPL_ISUPPORTS(ImageLoader, kIImageRequestObserver);
static PRBool gXXXInstalledColorMap;
void ImageLoader::Notify(nsIImageRequest *aImageRequest,
nsIImage *aImage,
nsImageNotification aNotificationType,
PRInt32 aParam1, PRInt32 aParam2,
void *aParam3)
void
ImageLoader::Notify(nsIImageRequest *aImageRequest,
nsIImage *aImage,
nsImageNotification aNotificationType,
PRInt32 aParam1, PRInt32 aParam2,
void *aParam3)
{
switch (aNotificationType) {
case nsImageNotification_kDimensions:
#ifdef NOISY
printf("Image:%d x %d\n", aParam1, aParam2);
#endif
mWidth = aParam1;
mHeight = aParam2;
mSize.width = aParam1;
mSize.height = aParam2;
ReflowFrames();
break;
case nsImageNotification_kPixmapUpdate:
@ -159,21 +159,27 @@ void ImageLoader::Notify(nsIImageRequest *aImageRequest,
mImage = aImage;
NS_ADDREF(aImage);
}
UpdateFrames();
DamageRepairFrames();
break;
}
}
PRInt32 ImageLoader::FrameCount()
void
ImageLoader::NotifyError(nsIImageRequest *aImageRequest,
nsImageError aErrorType)
{
return mFrames.Count();
mError = aErrorType;
DamageRepairFrames();
}
PRBool ImageLoader::RemoveFrame(nsIFrame* aFrame)
PRBool
ImageLoader::RemoveFrame(nsIFrame* aFrame)
{
return mFrames.RemoveElement(aFrame);
}
void ImageLoader::AddFrame(nsIFrame* aFrame)
void
ImageLoader::AddFrame(nsIFrame* aFrame)
{
PRInt32 i, n = mFrames.Count();
for (i = 0; i < n; i++) {
@ -185,15 +191,18 @@ void ImageLoader::AddFrame(nsIFrame* aFrame)
mFrames.AppendElement(aFrame);
}
void ImageLoader::UpdateFrames()
void
ImageLoader::DamageRepairFrames()
{
PRInt32 i, n = mFrames.Count();
for (i = 0; i < n; i++) {
nsIFrame* frame = (nsIFrame*) mFrames.ElementAt(i);
// XXX installed colormap should be presentation-context/window state
// XXX this should be done somewhere else, like when the window
// is created or something???
// XXX maybe there should be a seperate notification service for
// colormap events?
nsIWidget* window;
frame->GetWindow(window);
if (!gXXXInstalledColorMap && mImage) {
nsColorMap* cmap = mImage->GetColorMap();
@ -206,9 +215,8 @@ void ImageLoader::UpdateFrames()
// Determine damaged area and tell view manager to redraw it
nsPoint offset;
nsRect bounds;
frame->GetRect(bounds);
nsIView* view;
frame->GetRect(bounds);
frame->GetOffsetFromView(offset, view);
nsIViewManager* vm = view->GetViewManager();
bounds.x = offset.x;
@ -219,10 +227,16 @@ void ImageLoader::UpdateFrames()
}
}
void ImageLoader::NotifyError(nsIImageRequest *aImageRequest,
nsImageError aErrorType)
void
ImageLoader::ReflowFrames()
{
printf("XXX image error: %d\n", aErrorType);
PRInt32 i, n = mFrames.Count();
mCX->BeginLoadImageUpdate();
for (i = 0; i < n; i++) {
nsIFrame* frame = (nsIFrame*) mFrames.ElementAt(i);
mCX->ImageUpdate(frame);
}
mCX->EndLoadImageUpdate();
}
//----------------------------------------------------------------------
@ -241,6 +255,7 @@ nsPresContext::nsPresContext()
mImageGroup = nsnull;
mLinkHandler = nsnull;
mContainer = nsnull;
mImageUpdates = 0;
}
nsPresContext::~nsPresContext()
@ -269,12 +284,14 @@ nsPresContext::~nsPresContext()
NS_IF_RELEASE(mContainer);
}
nsrefcnt nsPresContext::AddRef(void)
nsrefcnt
nsPresContext::AddRef(void)
{
return ++mRefCnt;
}
nsrefcnt nsPresContext::Release(void)
nsrefcnt
nsPresContext::Release(void)
{
NS_PRECONDITION(0 != mRefCnt, "bad refcnt");
if (--mRefCnt == 0) {
@ -288,16 +305,16 @@ NS_IMPL_QUERY_INTERFACE(nsPresContext, kIPresContextIID);
// Note: We don't hold a reference on the shell; it has a reference to
// us
void nsPresContext::SetShell(nsIPresShell* aShell)
void
nsPresContext::SetShell(nsIPresShell* aShell)
{
mShell = aShell;
}
nsIPresShell* nsPresContext::GetShell()
nsIPresShell*
nsPresContext::GetShell()
{
if (nsnull != mShell) {
NS_ADDREF(mShell);
}
NS_IF_ADDREF(mShell);
return mShell;
}
@ -316,70 +333,85 @@ nsPresContext::ResolveStyleContextFor(nsIContent* aContent,
return result;
}
nsIFontMetrics* nsPresContext::GetMetricsFor(const nsFont& aFont)
nsIFontMetrics*
nsPresContext::GetMetricsFor(const nsFont& aFont)
{
if (nsnull != mDeviceContext)
return mDeviceContext->GetMetricsFor(aFont);
return nsnull;
}
const nsFont& nsPresContext::GetDefaultFont(void)
const nsFont&
nsPresContext::GetDefaultFont(void)
{
return mDefaultFont;
}
nsRect nsPresContext::GetVisibleArea()
nsRect
nsPresContext::GetVisibleArea()
{
return mVisibleArea;
}
void nsPresContext::SetVisibleArea(const nsRect& r)
void
nsPresContext::SetVisibleArea(const nsRect& r)
{
mVisibleArea = r;
}
float nsPresContext::GetPixelsToTwips() const
float
nsPresContext::GetPixelsToTwips() const
{
if (nsnull != mDeviceContext)
if (nsnull != mDeviceContext) {
return mDeviceContext->GetDevUnitsToAppUnits();
}
return 1.0f;
}
float nsPresContext::GetTwipsToPixels() const
float
nsPresContext::GetTwipsToPixels() const
{
if (nsnull != mDeviceContext)
if (nsnull != mDeviceContext) {
return mDeviceContext->GetAppUnitsToDevUnits();
}
return 1.0f;
}
nsIDeviceContext * nsPresContext::GetDeviceContext() const
nsIDeviceContext*
nsPresContext::GetDeviceContext() const
{
NS_IF_ADDREF(mDeviceContext);
return mDeviceContext;
}
nsIImage* nsPresContext::LoadImage(const nsString& aURL, nsIFrame* aForFrame)
NS_METHOD
nsPresContext::LoadImage(const nsString& aURL,
nsIFrame* aForFrame,
PRInt32& aLoadImageStatus,
nsImageError& aError,
nsSize& aImageSize,
nsIImage*& aImage)
{
aLoadImageStatus = 0;
nsresult rv;
if (nsnull == mImageGroup) {
// XXX this is bad; if we allow for subwindows that have different
// rendering context's this won't work
// Create image group
rv = NS_NewImageGroup(&mImageGroup);
if (NS_OK != rv) {
return rv;
}
// Initialize the image group
nsIWidget* window;
aForFrame->GetWindow(window);
nsIRenderingContext* drawCtx = window->GetRenderingContext();
drawCtx->Scale(mDeviceContext->GetAppUnitsToDevUnits(),
mDeviceContext->GetAppUnitsToDevUnits());
if ((NS_OK != NS_NewImageGroup(&mImageGroup)) ||
(NS_OK != mImageGroup->Init(drawCtx))) {
// XXX what to do?
printf("XXX: can't get image group created\n");
NS_RELEASE(drawCtx);
return nsnull;
}
rv = mImageGroup->Init(drawCtx);
NS_RELEASE(drawCtx);
if (NS_OK != rv) {
return rv;
}
}
// Get absolute version of the url
@ -387,38 +419,54 @@ nsIImage* nsPresContext::LoadImage(const nsString& aURL, nsIFrame* aForFrame)
nsIURL* docURL = doc->GetDocumentURL();
char* spec = aURL.ToNewCString();
nsIURL* url;
nsresult rv = NS_NewURL(&url, docURL, spec);
rv = NS_NewURL(&url, docURL, spec);
delete spec;
NS_RELEASE(docURL);
NS_RELEASE(doc);
if (NS_OK != rv) {
// XXX lost error
return nsnull;
return rv;
}
nsAutoString absURL;
url->ToString(absURL);
NS_RELEASE(url);
PRInt32 n = mImageLoaders.Count();
for (PRInt32 i = 0; i < n; i++) {
ImageLoader* loader = (ImageLoader*) mImageLoaders.ElementAt(i);
// Lookup image request in our loaders array
PRInt32 i, n = mImageLoaders.Count();
ImageLoader* loader;
for (i = 0; i < n; i++) {
loader = (ImageLoader*) mImageLoaders.ElementAt(i);
if (absURL.Equals(loader->GetURL())) {
loader->AddFrame(aForFrame);
return loader->GetImage();
goto done;
}
}
ImageLoader* loader = new ImageLoader(this, mImageGroup, aForFrame);
// We haven't seen that image before. Create a new loader and
// start it going.
loader = new ImageLoader(this, mImageGroup, aForFrame);
if (nsnull == loader) {
return NS_ERROR_OUT_OF_MEMORY;
}
mImageLoaders.AppendElement(loader);
loader->LoadImage(absURL);
return loader->GetImage();
done:
aLoadImageStatus = 0;
if (loader->GetImageSize(aImageSize)) {
aLoadImageStatus |= NS_LOAD_IMAGE_STATUS_SIZE;
}
aImage = loader->GetImage();
if (nsnull != aImage) {
aLoadImageStatus |= NS_LOAD_IMAGE_STATUS_BITS;
}
return NS_OK;
}
void nsPresContext::StopLoadImage(nsIFrame* aForFrame)
NS_METHOD
nsPresContext::StopLoadImage(nsIFrame* aForFrame)
{
PRInt32 n = mImageLoaders.Count();
for (PRInt32 i = 0; i < n;) {
PRInt32 i, n = mImageLoaders.Count();
for (i = 0; i < n;) {
ImageLoader* loader = (ImageLoader*) mImageLoaders.ElementAt(i);
if (loader->RemoveFrame(aForFrame)) {
if (0 == loader->FrameCount()) {
@ -430,9 +478,52 @@ void nsPresContext::StopLoadImage(nsIFrame* aForFrame)
}
i++;
}
return NS_OK;
}
NS_IMETHODIMP nsPresContext::SetLinkHandler(nsILinkHandler* aHandler)
void
nsPresContext::BeginLoadImageUpdate()
{
++mImageUpdates;
}
void
nsPresContext::ImageUpdate(nsIFrame* aFrame)
{
nsIContent* content;
aFrame->GetContent(content);
mPendingImageUpdates.AppendElement(content);
if (0 == mImageUpdates) {
ProcessLoadImageUpdates();
}
}
void
nsPresContext::EndLoadImageUpdate()
{
if (--mImageUpdates == 0) {
ProcessLoadImageUpdates();
}
}
void
nsPresContext::ProcessLoadImageUpdates()
{
PRInt32 i, n = mPendingImageUpdates.Count();
mShell->EnterReflowLock();
mShell->BeginUpdate();
for (i = 0; i < n; i++) {
nsIContent* content = (nsIContent*) mPendingImageUpdates.ElementAt(i);
mShell->ContentChanged(content, nsnull);
NS_RELEASE(content);
}
mPendingImageUpdates.Clear();
mShell->EndUpdate();
mShell->ExitReflowLock();
}
NS_IMETHODIMP
nsPresContext::SetLinkHandler(nsILinkHandler* aHandler)
{ // XXX should probably be a WEAK reference
NS_IF_RELEASE(mLinkHandler);
mLinkHandler = aHandler;
@ -440,7 +531,8 @@ NS_IMETHODIMP nsPresContext::SetLinkHandler(nsILinkHandler* aHandler)
return NS_OK;
}
NS_IMETHODIMP nsPresContext::GetLinkHandler(nsILinkHandler** aResult)
NS_IMETHODIMP
nsPresContext::GetLinkHandler(nsILinkHandler** aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
@ -451,7 +543,8 @@ NS_IMETHODIMP nsPresContext::GetLinkHandler(nsILinkHandler** aResult)
return NS_OK;
}
NS_IMETHODIMP nsPresContext::SetContainer(nsISupports* aHandler)
NS_IMETHODIMP
nsPresContext::SetContainer(nsISupports* aHandler)
{ // XXX should most likely be a WEAK reference
NS_IF_RELEASE(mContainer);
mContainer = aHandler;
@ -459,7 +552,8 @@ NS_IMETHODIMP nsPresContext::SetContainer(nsISupports* aHandler)
return NS_OK;
}
NS_IMETHODIMP nsPresContext::GetContainer(nsISupports** aResult)
NS_IMETHODIMP
nsPresContext::GetContainer(nsISupports** aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {

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

@ -17,6 +17,7 @@
*/
#include "nsPresContext.h"
#include "nsIPresShell.h"
#include "nsIContent.h"
#include "nsILinkHandler.h"
#include "nsIStyleContext.h"
#include "nsIStyleSet.h"
@ -34,24 +35,9 @@
#include "nsIURL.h"
#include "nsString.h"
static NS_DEFINE_IID(kIPresContextIID, NS_IPRESCONTEXT_IID);
#define NOISY
#if 0
// XXX this code needs to move far away from here
static nsIImageManager* gImageManager = nsnull;
static void InitImageLibrary()
{
// Initialize image library
if (NS_OK == NS_NewImageManager(&gImageManager)) {
if (NS_OK == gImageManager->Init()) {
gImageManager->SetCacheSize(1024*1024);
return;
}
}
printf("can't initialize image library\n");
}
// XXX end code with no home...
#endif
static NS_DEFINE_IID(kIPresContextIID, NS_IPRESCONTEXT_IID);
class ImageLoader : public nsIImageRequestObserver {
public:
@ -70,13 +56,25 @@ public:
return mImage;
}
PRInt32 FrameCount();
PRBool GetImageSize(nsSize& aSize) {
if ((mSize.width > 0) && (mSize.height > 0)) {
aSize = mSize;
return PR_TRUE;
}
return PR_FALSE;
}
PRInt32 FrameCount() const {
return mFrames.Count();
}
PRBool RemoveFrame(nsIFrame* aFrame);
void AddFrame(nsIFrame* aFrame);
void UpdateFrames();
void DamageRepairFrames();
void ReflowFrames();
virtual void Notify(nsIImageRequest *aImageRequest,
nsIImage *aImage,
@ -93,20 +91,19 @@ public:
nsIImage* mImage;
nsIImageRequest* mImageRequest;
nsIImageGroup* mImageGroup;
PRInt32 mWidth, mHeight; // in pixels
nsSize mSize; // Note: in pixels
nsImageError mError;
};
ImageLoader::ImageLoader(nsPresContext* aCX, nsIImageGroup* aGroup,
nsIFrame* aFrame)
: mSize(-1, -1)
{
mCX = aCX;
AddFrame(aFrame);
mImage = nsnull;
mImageRequest = nsnull;
mImageGroup = aGroup; NS_ADDREF(aGroup);
mWidth = -1;
mHeight = -1;
}
ImageLoader::~ImageLoader()
@ -117,7 +114,8 @@ ImageLoader::~ImageLoader()
}
}
void ImageLoader::LoadImage(const nsString& aURL)
void
ImageLoader::LoadImage(const nsString& aURL)
{
if (nsnull == mImage) {
// Save url
@ -137,19 +135,21 @@ static NS_DEFINE_IID(kIImageRequestObserver, NS_IIMAGEREQUESTOBSERVER_IID);
NS_IMPL_ISUPPORTS(ImageLoader, kIImageRequestObserver);
static PRBool gXXXInstalledColorMap;
void ImageLoader::Notify(nsIImageRequest *aImageRequest,
nsIImage *aImage,
nsImageNotification aNotificationType,
PRInt32 aParam1, PRInt32 aParam2,
void *aParam3)
void
ImageLoader::Notify(nsIImageRequest *aImageRequest,
nsIImage *aImage,
nsImageNotification aNotificationType,
PRInt32 aParam1, PRInt32 aParam2,
void *aParam3)
{
switch (aNotificationType) {
case nsImageNotification_kDimensions:
#ifdef NOISY
printf("Image:%d x %d\n", aParam1, aParam2);
#endif
mWidth = aParam1;
mHeight = aParam2;
mSize.width = aParam1;
mSize.height = aParam2;
ReflowFrames();
break;
case nsImageNotification_kPixmapUpdate:
@ -159,21 +159,27 @@ void ImageLoader::Notify(nsIImageRequest *aImageRequest,
mImage = aImage;
NS_ADDREF(aImage);
}
UpdateFrames();
DamageRepairFrames();
break;
}
}
PRInt32 ImageLoader::FrameCount()
void
ImageLoader::NotifyError(nsIImageRequest *aImageRequest,
nsImageError aErrorType)
{
return mFrames.Count();
mError = aErrorType;
DamageRepairFrames();
}
PRBool ImageLoader::RemoveFrame(nsIFrame* aFrame)
PRBool
ImageLoader::RemoveFrame(nsIFrame* aFrame)
{
return mFrames.RemoveElement(aFrame);
}
void ImageLoader::AddFrame(nsIFrame* aFrame)
void
ImageLoader::AddFrame(nsIFrame* aFrame)
{
PRInt32 i, n = mFrames.Count();
for (i = 0; i < n; i++) {
@ -185,15 +191,18 @@ void ImageLoader::AddFrame(nsIFrame* aFrame)
mFrames.AppendElement(aFrame);
}
void ImageLoader::UpdateFrames()
void
ImageLoader::DamageRepairFrames()
{
PRInt32 i, n = mFrames.Count();
for (i = 0; i < n; i++) {
nsIFrame* frame = (nsIFrame*) mFrames.ElementAt(i);
// XXX installed colormap should be presentation-context/window state
// XXX this should be done somewhere else, like when the window
// is created or something???
// XXX maybe there should be a seperate notification service for
// colormap events?
nsIWidget* window;
frame->GetWindow(window);
if (!gXXXInstalledColorMap && mImage) {
nsColorMap* cmap = mImage->GetColorMap();
@ -206,9 +215,8 @@ void ImageLoader::UpdateFrames()
// Determine damaged area and tell view manager to redraw it
nsPoint offset;
nsRect bounds;
frame->GetRect(bounds);
nsIView* view;
frame->GetRect(bounds);
frame->GetOffsetFromView(offset, view);
nsIViewManager* vm = view->GetViewManager();
bounds.x = offset.x;
@ -219,10 +227,16 @@ void ImageLoader::UpdateFrames()
}
}
void ImageLoader::NotifyError(nsIImageRequest *aImageRequest,
nsImageError aErrorType)
void
ImageLoader::ReflowFrames()
{
printf("XXX image error: %d\n", aErrorType);
PRInt32 i, n = mFrames.Count();
mCX->BeginLoadImageUpdate();
for (i = 0; i < n; i++) {
nsIFrame* frame = (nsIFrame*) mFrames.ElementAt(i);
mCX->ImageUpdate(frame);
}
mCX->EndLoadImageUpdate();
}
//----------------------------------------------------------------------
@ -241,6 +255,7 @@ nsPresContext::nsPresContext()
mImageGroup = nsnull;
mLinkHandler = nsnull;
mContainer = nsnull;
mImageUpdates = 0;
}
nsPresContext::~nsPresContext()
@ -269,12 +284,14 @@ nsPresContext::~nsPresContext()
NS_IF_RELEASE(mContainer);
}
nsrefcnt nsPresContext::AddRef(void)
nsrefcnt
nsPresContext::AddRef(void)
{
return ++mRefCnt;
}
nsrefcnt nsPresContext::Release(void)
nsrefcnt
nsPresContext::Release(void)
{
NS_PRECONDITION(0 != mRefCnt, "bad refcnt");
if (--mRefCnt == 0) {
@ -288,16 +305,16 @@ NS_IMPL_QUERY_INTERFACE(nsPresContext, kIPresContextIID);
// Note: We don't hold a reference on the shell; it has a reference to
// us
void nsPresContext::SetShell(nsIPresShell* aShell)
void
nsPresContext::SetShell(nsIPresShell* aShell)
{
mShell = aShell;
}
nsIPresShell* nsPresContext::GetShell()
nsIPresShell*
nsPresContext::GetShell()
{
if (nsnull != mShell) {
NS_ADDREF(mShell);
}
NS_IF_ADDREF(mShell);
return mShell;
}
@ -316,70 +333,85 @@ nsPresContext::ResolveStyleContextFor(nsIContent* aContent,
return result;
}
nsIFontMetrics* nsPresContext::GetMetricsFor(const nsFont& aFont)
nsIFontMetrics*
nsPresContext::GetMetricsFor(const nsFont& aFont)
{
if (nsnull != mDeviceContext)
return mDeviceContext->GetMetricsFor(aFont);
return nsnull;
}
const nsFont& nsPresContext::GetDefaultFont(void)
const nsFont&
nsPresContext::GetDefaultFont(void)
{
return mDefaultFont;
}
nsRect nsPresContext::GetVisibleArea()
nsRect
nsPresContext::GetVisibleArea()
{
return mVisibleArea;
}
void nsPresContext::SetVisibleArea(const nsRect& r)
void
nsPresContext::SetVisibleArea(const nsRect& r)
{
mVisibleArea = r;
}
float nsPresContext::GetPixelsToTwips() const
float
nsPresContext::GetPixelsToTwips() const
{
if (nsnull != mDeviceContext)
if (nsnull != mDeviceContext) {
return mDeviceContext->GetDevUnitsToAppUnits();
}
return 1.0f;
}
float nsPresContext::GetTwipsToPixels() const
float
nsPresContext::GetTwipsToPixels() const
{
if (nsnull != mDeviceContext)
if (nsnull != mDeviceContext) {
return mDeviceContext->GetAppUnitsToDevUnits();
}
return 1.0f;
}
nsIDeviceContext * nsPresContext::GetDeviceContext() const
nsIDeviceContext*
nsPresContext::GetDeviceContext() const
{
NS_IF_ADDREF(mDeviceContext);
return mDeviceContext;
}
nsIImage* nsPresContext::LoadImage(const nsString& aURL, nsIFrame* aForFrame)
NS_METHOD
nsPresContext::LoadImage(const nsString& aURL,
nsIFrame* aForFrame,
PRInt32& aLoadImageStatus,
nsImageError& aError,
nsSize& aImageSize,
nsIImage*& aImage)
{
aLoadImageStatus = 0;
nsresult rv;
if (nsnull == mImageGroup) {
// XXX this is bad; if we allow for subwindows that have different
// rendering context's this won't work
// Create image group
rv = NS_NewImageGroup(&mImageGroup);
if (NS_OK != rv) {
return rv;
}
// Initialize the image group
nsIWidget* window;
aForFrame->GetWindow(window);
nsIRenderingContext* drawCtx = window->GetRenderingContext();
drawCtx->Scale(mDeviceContext->GetAppUnitsToDevUnits(),
mDeviceContext->GetAppUnitsToDevUnits());
if ((NS_OK != NS_NewImageGroup(&mImageGroup)) ||
(NS_OK != mImageGroup->Init(drawCtx))) {
// XXX what to do?
printf("XXX: can't get image group created\n");
NS_RELEASE(drawCtx);
return nsnull;
}
rv = mImageGroup->Init(drawCtx);
NS_RELEASE(drawCtx);
if (NS_OK != rv) {
return rv;
}
}
// Get absolute version of the url
@ -387,38 +419,54 @@ nsIImage* nsPresContext::LoadImage(const nsString& aURL, nsIFrame* aForFrame)
nsIURL* docURL = doc->GetDocumentURL();
char* spec = aURL.ToNewCString();
nsIURL* url;
nsresult rv = NS_NewURL(&url, docURL, spec);
rv = NS_NewURL(&url, docURL, spec);
delete spec;
NS_RELEASE(docURL);
NS_RELEASE(doc);
if (NS_OK != rv) {
// XXX lost error
return nsnull;
return rv;
}
nsAutoString absURL;
url->ToString(absURL);
NS_RELEASE(url);
PRInt32 n = mImageLoaders.Count();
for (PRInt32 i = 0; i < n; i++) {
ImageLoader* loader = (ImageLoader*) mImageLoaders.ElementAt(i);
// Lookup image request in our loaders array
PRInt32 i, n = mImageLoaders.Count();
ImageLoader* loader;
for (i = 0; i < n; i++) {
loader = (ImageLoader*) mImageLoaders.ElementAt(i);
if (absURL.Equals(loader->GetURL())) {
loader->AddFrame(aForFrame);
return loader->GetImage();
goto done;
}
}
ImageLoader* loader = new ImageLoader(this, mImageGroup, aForFrame);
// We haven't seen that image before. Create a new loader and
// start it going.
loader = new ImageLoader(this, mImageGroup, aForFrame);
if (nsnull == loader) {
return NS_ERROR_OUT_OF_MEMORY;
}
mImageLoaders.AppendElement(loader);
loader->LoadImage(absURL);
return loader->GetImage();
done:
aLoadImageStatus = 0;
if (loader->GetImageSize(aImageSize)) {
aLoadImageStatus |= NS_LOAD_IMAGE_STATUS_SIZE;
}
aImage = loader->GetImage();
if (nsnull != aImage) {
aLoadImageStatus |= NS_LOAD_IMAGE_STATUS_BITS;
}
return NS_OK;
}
void nsPresContext::StopLoadImage(nsIFrame* aForFrame)
NS_METHOD
nsPresContext::StopLoadImage(nsIFrame* aForFrame)
{
PRInt32 n = mImageLoaders.Count();
for (PRInt32 i = 0; i < n;) {
PRInt32 i, n = mImageLoaders.Count();
for (i = 0; i < n;) {
ImageLoader* loader = (ImageLoader*) mImageLoaders.ElementAt(i);
if (loader->RemoveFrame(aForFrame)) {
if (0 == loader->FrameCount()) {
@ -430,9 +478,52 @@ void nsPresContext::StopLoadImage(nsIFrame* aForFrame)
}
i++;
}
return NS_OK;
}
NS_IMETHODIMP nsPresContext::SetLinkHandler(nsILinkHandler* aHandler)
void
nsPresContext::BeginLoadImageUpdate()
{
++mImageUpdates;
}
void
nsPresContext::ImageUpdate(nsIFrame* aFrame)
{
nsIContent* content;
aFrame->GetContent(content);
mPendingImageUpdates.AppendElement(content);
if (0 == mImageUpdates) {
ProcessLoadImageUpdates();
}
}
void
nsPresContext::EndLoadImageUpdate()
{
if (--mImageUpdates == 0) {
ProcessLoadImageUpdates();
}
}
void
nsPresContext::ProcessLoadImageUpdates()
{
PRInt32 i, n = mPendingImageUpdates.Count();
mShell->EnterReflowLock();
mShell->BeginUpdate();
for (i = 0; i < n; i++) {
nsIContent* content = (nsIContent*) mPendingImageUpdates.ElementAt(i);
mShell->ContentChanged(content, nsnull);
NS_RELEASE(content);
}
mPendingImageUpdates.Clear();
mShell->EndUpdate();
mShell->ExitReflowLock();
}
NS_IMETHODIMP
nsPresContext::SetLinkHandler(nsILinkHandler* aHandler)
{ // XXX should probably be a WEAK reference
NS_IF_RELEASE(mLinkHandler);
mLinkHandler = aHandler;
@ -440,7 +531,8 @@ NS_IMETHODIMP nsPresContext::SetLinkHandler(nsILinkHandler* aHandler)
return NS_OK;
}
NS_IMETHODIMP nsPresContext::GetLinkHandler(nsILinkHandler** aResult)
NS_IMETHODIMP
nsPresContext::GetLinkHandler(nsILinkHandler** aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
@ -451,7 +543,8 @@ NS_IMETHODIMP nsPresContext::GetLinkHandler(nsILinkHandler** aResult)
return NS_OK;
}
NS_IMETHODIMP nsPresContext::SetContainer(nsISupports* aHandler)
NS_IMETHODIMP
nsPresContext::SetContainer(nsISupports* aHandler)
{ // XXX should most likely be a WEAK reference
NS_IF_RELEASE(mContainer);
mContainer = aHandler;
@ -459,7 +552,8 @@ NS_IMETHODIMP nsPresContext::SetContainer(nsISupports* aHandler)
return NS_OK;
}
NS_IMETHODIMP nsPresContext::GetContainer(nsISupports** aResult)
NS_IMETHODIMP
nsPresContext::GetContainer(nsISupports** aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {