зеркало из https://github.com/mozilla/pjs.git
Fixes for Aurora custom icons.
This commit is contained in:
Родитель
4e92a95c04
Коммит
03dbdd68c6
|
@ -1149,7 +1149,7 @@ void CDCCX::FloodRect(LTRB& Rect, HBRUSH hColor)
|
|||
}
|
||||
BITMAPINFO* CDCCX::FillBitmapInfoHeader(NI_Pixmap* pImage)
|
||||
{
|
||||
BITMAPINFO *pBMInfo;
|
||||
BITMAPINFO *pBMInfo = NULL;
|
||||
|
||||
NI_PixmapHeader* imageHeader = &pImage->header;
|
||||
int pixmap_depth = imageHeader->color_space->pixmap_depth;
|
||||
|
|
|
@ -1,498 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; 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 "stdafx.h"
|
||||
#include "cxicon.h"
|
||||
#include "feimage.h"
|
||||
#include "winproto.h"
|
||||
#include "helper.h"
|
||||
|
||||
HBITMAP CRDFImage::m_hBadImageBitmap = NULL;
|
||||
int CRDFImage::refCount = 0;
|
||||
|
||||
CRDFImage::CRDFImage(const char * url)
|
||||
{
|
||||
m_nRefCount = 0;
|
||||
pUrl = _strdup( url);
|
||||
bmpInfo = NULL;
|
||||
m_bCompletelyLoaded = FALSE;
|
||||
m_bFrameLoaded = FALSE;
|
||||
bits = 0;
|
||||
maskbits = 0;
|
||||
|
||||
m_BadImage = FALSE;
|
||||
CRDFImage::refCount++;
|
||||
iconContext = NULL;
|
||||
pairCount = 0;
|
||||
}
|
||||
|
||||
CRDFImage::~CRDFImage()
|
||||
{
|
||||
// XP_FREE( bmpInfo);
|
||||
// CDCCX::HugeFree(bits);
|
||||
// CDCCX::HugeFree(maskbits);
|
||||
free(pUrl);
|
||||
|
||||
CRDFImage::refCount--;
|
||||
if (refCount == 0)
|
||||
{
|
||||
if (CRDFImage::m_hBadImageBitmap)
|
||||
VERIFY(::DeleteObject(CRDFImage::m_hBadImageBitmap));
|
||||
}
|
||||
}
|
||||
|
||||
void CRDFImage::AddListener(CCustomImageObject* pObject, HT_Resource r)
|
||||
{
|
||||
// We only want to have one copy of the same image in this list.
|
||||
for (POSITION pos = resourceList.GetHeadPosition();
|
||||
pos != NULL; )
|
||||
{
|
||||
// Enumerate over the list and call remove listener on each image.
|
||||
CIconCallbackInfo* pInfo = (CIconCallbackInfo*)resourceList.GetNext(pos);
|
||||
if (pInfo->pObject == pObject &&
|
||||
pInfo->pResource == r)
|
||||
return; // We're already listening for this resource.
|
||||
}
|
||||
|
||||
// Add a listener.
|
||||
CIconCallbackInfo* iconCallbackInfo = new CIconCallbackInfo(pObject, r);
|
||||
resourceList.AddHead(iconCallbackInfo);
|
||||
pObject->AddLoadingImage(this);
|
||||
m_nRefCount++;
|
||||
if (iconContext == NULL)
|
||||
{
|
||||
// Kick off the load.
|
||||
ProcessIcon();
|
||||
}
|
||||
}
|
||||
|
||||
void CRDFImage::RemoveListener(CCustomImageObject *pObject)
|
||||
{
|
||||
// Listener has been destroyed. Need to get all references to it out of the list.
|
||||
// Just do this by NULLing out the pObject field of the iconcallbackinfo structs.
|
||||
for (POSITION pos = resourceList.GetHeadPosition();
|
||||
pos != NULL; )
|
||||
{
|
||||
CIconCallbackInfo* pInfo = (CIconCallbackInfo*)resourceList.GetNext(pos);
|
||||
if (pInfo->pObject == pObject)
|
||||
{
|
||||
pInfo->pObject = NULL;
|
||||
m_nRefCount--;
|
||||
if (m_nRefCount == 0 && iconContext)
|
||||
{
|
||||
iconContext->Interrupt();
|
||||
DestroyContext();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CRDFImage::RemoveListenerForSpecificResource(CCustomImageObject *pObject, HT_Resource r)
|
||||
{
|
||||
// Listener has been destroyed. Need to get all references to it out of the list.
|
||||
// Just do this by NULLing out the pObject field of the iconcallbackinfo structs.
|
||||
for (POSITION pos = resourceList.GetHeadPosition();
|
||||
pos != NULL; )
|
||||
{
|
||||
CIconCallbackInfo* pInfo = (CIconCallbackInfo*)resourceList.GetNext(pos);
|
||||
if (pInfo->pObject == pObject && pInfo->pResource == r)
|
||||
{
|
||||
pInfo->pObject = NULL;
|
||||
m_nRefCount--;
|
||||
if (m_nRefCount == 0 && iconContext)
|
||||
{
|
||||
iconContext->Interrupt();
|
||||
DestroyContext();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CRDFImage::DestroyContext()
|
||||
{
|
||||
if (iconContext)
|
||||
{
|
||||
iconContext->DeleteContextDC();
|
||||
iconContext->NiceDestruction();
|
||||
iconContext = NULL;
|
||||
}
|
||||
|
||||
resourceList.RemoveAll();
|
||||
}
|
||||
|
||||
BOOL CRDFImage::FrameLoaded()
|
||||
{
|
||||
return (m_bFrameLoaded);
|
||||
}
|
||||
|
||||
BOOL CRDFImage::FrameSuccessfullyLoaded()
|
||||
{
|
||||
return (m_bFrameLoaded && bits);
|
||||
}
|
||||
|
||||
BOOL CRDFImage::CompletelyLoaded()
|
||||
{
|
||||
return m_bCompletelyLoaded;
|
||||
}
|
||||
|
||||
void Icon_GetUrlExitRoutine(URL_Struct *pUrl, int iStatus, MWContext *pContext)
|
||||
{
|
||||
// Report any errors.
|
||||
if(iStatus < 0 && pUrl->error_msg != NULL)
|
||||
{
|
||||
void* pData;
|
||||
CRDFImage* theImage = NULL;
|
||||
if (CHTFEData::m_CustomURLCache.Lookup(pUrl->address, pData))
|
||||
theImage = (CRDFImage*)pData;
|
||||
|
||||
if (theImage)
|
||||
{ // Since we cannot load this url, replace it with a bad image.
|
||||
theImage->m_BadImage = TRUE;
|
||||
theImage->bits = 0;
|
||||
theImage->maskbits = 0;
|
||||
theImage->bmpInfo = 0;
|
||||
if (!CRDFImage::m_hBadImageBitmap)
|
||||
CRDFImage::m_hBadImageBitmap = ::LoadBitmap(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_IMAGE_BAD));
|
||||
theImage->CompleteCallback();
|
||||
}
|
||||
}
|
||||
// standard free-a-URL-with-Windows-DDE-gunk mechanism:
|
||||
|
||||
if (NCAPIDATA(pUrl))
|
||||
NCAPIDATA(pUrl)->EndProgress();
|
||||
if (!NCAPIDATA(pUrl) || NCAPIDATA(pUrl)->CanFreeUrl()) {
|
||||
FEU_DeleteUrlData(pUrl, NULL);
|
||||
NET_FreeURLStruct(pUrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static BOOL IsImageMimeType(const CString& theFormat)
|
||||
{
|
||||
BOOL val = FALSE;
|
||||
if (theFormat.CompareNoCase(IMAGE_GIF) == 0)
|
||||
val = TRUE;
|
||||
else if (theFormat.CompareNoCase(IMAGE_JPG) == 0)
|
||||
val = TRUE;
|
||||
else if (theFormat.CompareNoCase(IMAGE_PJPG) == 0)
|
||||
val = TRUE;
|
||||
else if (theFormat.CompareNoCase(IMAGE_PPM) == 0)
|
||||
val = TRUE;
|
||||
else if (theFormat.CompareNoCase(IMAGE_PNG) == 0)
|
||||
val = TRUE;
|
||||
else if (theFormat.CompareNoCase(IMAGE_XBM) == 0)
|
||||
val = TRUE;
|
||||
else if (theFormat.CompareNoCase(IMAGE_XBM2) == 0)
|
||||
val = TRUE;
|
||||
else if (theFormat.CompareNoCase(IMAGE_XBM3) == 0)
|
||||
val = TRUE;
|
||||
return val;
|
||||
}
|
||||
|
||||
static BOOL ValidNSBitmapFormat(char* extension)
|
||||
{
|
||||
CPtrList* allHelpers = &(CHelperApp::m_cplHelpers);
|
||||
|
||||
for (POSITION pos = allHelpers->GetHeadPosition(); pos != NULL;)
|
||||
{
|
||||
CHelperApp* app = (CHelperApp*)allHelpers->GetNext(pos);
|
||||
CString helperMime(app->cd_item->ci.type);
|
||||
|
||||
if (IsImageMimeType(helperMime))
|
||||
{
|
||||
if (app->cd_item->num_exts > 0)
|
||||
{
|
||||
for (int i = 0; i < app->cd_item->num_exts; i++)
|
||||
{
|
||||
CString extString(app->cd_item->exts[i]);
|
||||
if (extString == &extension[1])
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CRDFImage::ProcessIcon()
|
||||
{
|
||||
char *ext = FE_FindFileExt(pUrl);
|
||||
if (!ext) return;
|
||||
if (ValidNSBitmapFormat(ext))
|
||||
{
|
||||
// If there is no context, create one for processing the image.
|
||||
hSubDC = ::CreateCompatibleDC(NULL);
|
||||
|
||||
if (iconContext == NULL)
|
||||
{
|
||||
iconContext = new CXIcon(this);
|
||||
iconContext->SubstituteDC(hSubDC);
|
||||
iconContext->Initialize(FALSE, NULL, FALSE);
|
||||
iconContext->SetUseDibPalColors(FALSE);
|
||||
}
|
||||
|
||||
// Temporary hack to disable loading RDF images for the layout integration
|
||||
// build.
|
||||
#ifndef MOZ_NGLAYOUT
|
||||
// Ask for this via client pull.
|
||||
// We may be in the call stack of the image lib, and doing
|
||||
// lots of fast small get urls causes it to barf due
|
||||
// to list management not being reentrant.
|
||||
FEU_ClientPull(iconContext->GetContext(), 0, NET_CreateURLStruct(pUrl, NET_DONT_RELOAD), FO_CACHE_AND_PRESENT, FALSE);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{ // handle window internal format BMP
|
||||
CString extension = ext;
|
||||
if (extension.CompareNoCase(".bmp"))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Error handling here, unknow bitmap format.
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CRDFImage::CompleteCallback()
|
||||
{
|
||||
m_bCompletelyLoaded = TRUE;
|
||||
m_bFrameLoaded = TRUE;
|
||||
while (!resourceList.IsEmpty())
|
||||
{
|
||||
CIconCallbackInfo* callback = (CIconCallbackInfo*)(resourceList.RemoveHead());
|
||||
if (callback->pObject)
|
||||
{
|
||||
callback->pObject->LoadComplete(callback->pResource);
|
||||
callback->pObject->RemoveLoadingImage(this);
|
||||
}
|
||||
delete callback;
|
||||
}
|
||||
|
||||
DestroyContext();
|
||||
}
|
||||
|
||||
void CRDFImage::CompleteFrameCallback()
|
||||
{
|
||||
m_bFrameLoaded = TRUE;
|
||||
for (POSITION pos = resourceList.GetHeadPosition(); pos != NULL; )
|
||||
{
|
||||
CIconCallbackInfo* callback = (CIconCallbackInfo*)(resourceList.GetNext(pos));
|
||||
if (callback->pObject)
|
||||
{
|
||||
callback->pObject->LoadComplete(callback->pResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CXIcon::CXIcon(CRDFImage* theImage)
|
||||
{
|
||||
MWContext *pContext = GetContext();
|
||||
m_cxType = IconCX;
|
||||
pContext->type = MWContextIcon;
|
||||
m_MM = MM_TEXT;
|
||||
m_hDC = 0;
|
||||
m_icon = theImage;
|
||||
m_image = NULL;
|
||||
m_mask = NULL;
|
||||
}
|
||||
|
||||
CXIcon::~CXIcon()
|
||||
{
|
||||
}
|
||||
|
||||
BITMAPINFO * CXIcon::NewPixmap(NI_Pixmap *pImage, BOOL isMask)
|
||||
{
|
||||
// remember which bitmap we have so we can get the bits later in imageComplete.
|
||||
if (isMask)
|
||||
m_mask = pImage;
|
||||
else m_image = pImage;
|
||||
|
||||
return CDCCX::NewPixmap(pImage, isMask);
|
||||
}
|
||||
|
||||
int CXIcon::DisplayPixmap(NI_Pixmap* image, NI_Pixmap* mask, int32 x, int32 y, int32 x_offset, int32 y_offset, int32 width, int32 height, int32 lScaleWidth, int32 lScaleHeight, LTRB& Rect)
|
||||
{
|
||||
/*
|
||||
if (m_image)
|
||||
{
|
||||
CDCCX::HugeFree(m_image->bits);
|
||||
m_image->bits = NULL;
|
||||
FEBitmapInfo *imageInfo = (FEBitmapInfo*)m_image->client_data;
|
||||
delete imageInfo;
|
||||
m_image->client_data = NULL;
|
||||
m_image = NULL;
|
||||
}
|
||||
|
||||
if (m_mask)
|
||||
{
|
||||
CDCCX::HugeFree(m_mask->bits);
|
||||
m_mask->bits = NULL;
|
||||
FEBitmapInfo *imageInfo = (FEBitmapInfo*)m_mask->client_data;
|
||||
delete imageInfo;
|
||||
m_mask->client_data = NULL;
|
||||
m_mask = NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
if (m_icon->bits)
|
||||
{
|
||||
// Free the old pixmap to make way for the new.
|
||||
CDCCX::HugeFree(m_icon->bits);
|
||||
m_icon->bits = NULL;
|
||||
}
|
||||
|
||||
if (m_icon->maskbits)
|
||||
{
|
||||
// Free the old mask to make way for the new.
|
||||
CDCCX::HugeFree(m_icon->maskbits);
|
||||
m_icon->maskbits = NULL;
|
||||
}
|
||||
|
||||
if (m_icon->bmpInfo)
|
||||
{
|
||||
XP_FREE(m_icon->bmpInfo);
|
||||
m_icon->bmpInfo = NULL;
|
||||
}
|
||||
|
||||
// Get the new pixmap.
|
||||
m_image = image;
|
||||
m_mask = mask;
|
||||
|
||||
// Fill in our header.
|
||||
m_icon->bmpInfo = FillBitmapInfoHeader(image);
|
||||
|
||||
// Copy our bits if we have any.
|
||||
if (m_image->bits)
|
||||
{
|
||||
FEBitmapInfo* imageInfo = (FEBitmapInfo*) m_image->client_data;
|
||||
BITMAPINFOHEADER* header = (BITMAPINFOHEADER*)imageInfo->bmpInfo;
|
||||
m_icon->bits = HugeAlloc(header->biSizeImage, 1);
|
||||
memcpy( m_icon->bits, m_image->bits, header->biSizeImage );
|
||||
}
|
||||
|
||||
if (mask && m_mask->bits)
|
||||
{
|
||||
FEBitmapInfo* imageInfo = (FEBitmapInfo*) m_mask->client_data;
|
||||
BITMAPINFOHEADER* header = (BITMAPINFOHEADER*)imageInfo->bmpInfo;
|
||||
m_icon->maskbits = HugeAlloc(header->biSizeImage, 1);
|
||||
memcpy( m_icon->maskbits, m_mask->bits, header->biSizeImage );
|
||||
}
|
||||
|
||||
m_icon->CompleteFrameCallback();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CXIcon::ImageComplete(NI_Pixmap* image)
|
||||
{
|
||||
// Will get a call for both the mask and for the image.
|
||||
if (m_image && m_mask)
|
||||
{
|
||||
m_icon->pairCount++;
|
||||
if (m_icon->pairCount == 2)
|
||||
m_icon->CompleteCallback();
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have no mask.
|
||||
m_icon->CompleteCallback();
|
||||
}
|
||||
}
|
||||
|
||||
// Don't display partial images.
|
||||
void CXIcon::AllConnectionsComplete(MWContext *pContext)
|
||||
{
|
||||
CDCCX::AllConnectionsComplete(pContext);
|
||||
}
|
||||
|
||||
void CXIcon::NiceDestruction()
|
||||
{
|
||||
m_bIdleDestroy = TRUE;
|
||||
FEU_RequestIdleProcessing(GetContext());
|
||||
}
|
||||
|
||||
// ========================= CCustomImageObject Helpers =============================
|
||||
|
||||
CRDFImage* CCustomImageObject::LookupImage(const char* url, HT_Resource r)
|
||||
{
|
||||
// Find the image.
|
||||
void* pData;
|
||||
CRDFImage* pImage = NULL;
|
||||
if (CHTFEData::m_CustomURLCache.Lookup(url, pData))
|
||||
{
|
||||
pImage = (CRDFImage*)pData;
|
||||
|
||||
// Add ourselves to the callback list if the image hasn't completely loaded.
|
||||
if (!pImage->CompletelyLoaded())
|
||||
{
|
||||
// The image is currently loading. Register ourselves with the image so that we will get called
|
||||
// when the image finishes loading.
|
||||
pImage->AddListener(this, r);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new NavCenter image.
|
||||
pImage = new CRDFImage(url);
|
||||
pImage->AddListener(this, r);
|
||||
CHTFEData::m_CustomURLCache.SetAt(url, pImage);
|
||||
}
|
||||
|
||||
return pImage;
|
||||
}
|
||||
|
||||
CCustomImageObject::~CCustomImageObject()
|
||||
{
|
||||
// The displayer of the image is being destroyed. It should be removed as a listener from all
|
||||
// images.
|
||||
for (POSITION pos = loadingImagesList.GetHeadPosition();
|
||||
pos != NULL; )
|
||||
{
|
||||
// Enumerate over the list and call remove listener on each image.
|
||||
CRDFImage* pImage = (CRDFImage*)loadingImagesList.GetNext(pos);
|
||||
pImage->RemoveListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
void CCustomImageObject::AddLoadingImage(CRDFImage* pImage)
|
||||
{
|
||||
// We only want to have one copy of the same image in this list.
|
||||
for (POSITION pos = loadingImagesList.GetHeadPosition();
|
||||
pos != NULL; )
|
||||
{
|
||||
// Enumerate over the list and call remove listener on each image.
|
||||
CRDFImage* pNavImage = (CRDFImage*)loadingImagesList.GetNext(pos);
|
||||
if (pNavImage == pImage)
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the image to the list.
|
||||
loadingImagesList.AddHead(pImage);
|
||||
}
|
||||
|
||||
void CCustomImageObject::RemoveLoadingImage(CRDFImage* pImage)
|
||||
{
|
||||
// Should only occur once in our list. Find and remove.
|
||||
POSITION pos = loadingImagesList.Find(pImage);
|
||||
if (pos)
|
||||
loadingImagesList.RemoveAt(pos);
|
||||
}
|
Загрузка…
Ссылка в новой задаче