|
|
|
@ -172,34 +172,17 @@ void CFavIconList::LoadDefaultIcon()
|
|
|
|
|
{ |
|
|
|
|
CString szFullPath; |
|
|
|
|
|
|
|
|
|
HICON defaultIcon = NULL; |
|
|
|
|
if (theApp.FindSkinFile(szFullPath, _T("default.ico"))) |
|
|
|
|
{ |
|
|
|
|
FILE *fp = _tfopen(szFullPath, _T("r")); |
|
|
|
|
if (fp) { |
|
|
|
|
fclose(fp); |
|
|
|
|
defaultIcon = (HICON)LoadImage(NULL, szFullPath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE); |
|
|
|
|
if (defaultIcon) { |
|
|
|
|
m_iDefaultIcon = Add(defaultIcon); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
HICON defaultIcon = theApp.skin.GetIconDefault(); |
|
|
|
|
if (defaultIcon) m_iDefaultIcon = Add(defaultIcon); |
|
|
|
|
|
|
|
|
|
// Add can return 0 even if it fails...
|
|
|
|
|
if (GetImageCount()==0) |
|
|
|
|
m_iDefaultIcon = Add(theApp.GetDefaultIcon()); |
|
|
|
|
|
|
|
|
|
if (theApp.FindSkinFile(szFullPath, _T("loading.ico"))) |
|
|
|
|
{ |
|
|
|
|
FILE *fp = _tfopen(szFullPath, _T("r")); |
|
|
|
|
if (fp) { |
|
|
|
|
fclose(fp); |
|
|
|
|
HICON loadingIcon = (HICON)LoadImage(NULL, szFullPath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE); |
|
|
|
|
if (loadingIcon) { |
|
|
|
|
m_iLoadingIcon = Add(loadingIcon); |
|
|
|
|
DestroyIcon(loadingIcon); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
HICON loadingIcon = theApp.skin.GetIconLoading(); |
|
|
|
|
if (loadingIcon) { |
|
|
|
|
m_iLoadingIcon = Add(loadingIcon); |
|
|
|
|
DestroyIcon(loadingIcon); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (GetImageCount()==1) { |
|
|
|
@ -220,14 +203,13 @@ BOOL CFavIconList::Create(int cx, int cy, UINT nFlags, int nInitial, int nGrow)
|
|
|
|
|
if (!CImageList::Create(cx,cy,nFlags,nInitial,nGrow)) |
|
|
|
|
return FALSE; |
|
|
|
|
|
|
|
|
|
mWidth = cx, |
|
|
|
|
mHeight = cy; |
|
|
|
|
LoadDefaultIcon(); |
|
|
|
|
LoadCache(); |
|
|
|
|
return TRUE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
extern nsresult NewURI(nsIURI **result, const nsAString &spec); |
|
|
|
|
extern nsresult NewURI(nsIURI **result, const nsACString &spec); |
|
|
|
|
|
|
|
|
|
void CFavIconList::AddMap(const char *uri, int index, const char* pageUri) |
|
|
|
|
{ |
|
|
|
|
// This function is called from another thread
|
|
|
|
@ -275,29 +257,6 @@ int CFavIconList::AddIcon(const char* uri, CBitmap* icon, CBitmap* mask, const c
|
|
|
|
|
return index; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int CFavIconList::AddIcon(const char* uri, HICON icon, const char* pageUri) |
|
|
|
|
{ |
|
|
|
|
int index = Add(icon); |
|
|
|
|
AddMap(uri, index, pageUri); |
|
|
|
|
return index; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int CFavIconList::AddDownloadedIcon(char* uri, TCHAR* file, nsresult aStatus) |
|
|
|
|
{ |
|
|
|
|
int index = GetDefaultIcon(); |
|
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(aStatus)) |
|
|
|
|
{ |
|
|
|
|
HICON favicon = (HICON)LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE); |
|
|
|
|
if (favicon){ |
|
|
|
|
index = AddIcon(uri, favicon); |
|
|
|
|
DestroyIcon(favicon); |
|
|
|
|
}
|
|
|
|
|
} |
|
|
|
|
DeleteFile(file); |
|
|
|
|
return index; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int CFavIconList::GetIcon(const TCHAR* aUrl) |
|
|
|
|
{ |
|
|
|
|
int index = GetDefaultIcon(); |
|
|
|
@ -398,384 +357,67 @@ void CFavIconList::ResetCache()
|
|
|
|
|
theApp.BroadcastMessage(UWM_NEWSITEICON, 0, -1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
BOOL CFavIconList::DwnFavIcon(nsIURI* iconURI, nsIURI* pageURI) |
|
|
|
|
{ |
|
|
|
|
#ifndef PNG_SUPPORT |
|
|
|
|
// Borked way to get the favicon.
|
|
|
|
|
imgIRequest* request = nullptr; |
|
|
|
|
|
|
|
|
|
IconObserver* observer = new IconObserver(this); |
|
|
|
|
if (NS_FAILED(observer->LoadIcon(iconURI, pageURI))) { |
|
|
|
|
delete observer; |
|
|
|
|
return FALSE; |
|
|
|
|
} |
|
|
|
|
return TRUE; |
|
|
|
|
|
|
|
|
|
//if (NS_FAILED(mIconObserver->LoadIcon(iconURI, pageURI))) {
|
|
|
|
|
// return FALSE;
|
|
|
|
|
// }
|
|
|
|
|
#else |
|
|
|
|
class iconObserver: public IImageObserver { |
|
|
|
|
public: |
|
|
|
|
iconObserver(CFavIconList* favList, nsIURI* icon, nsIURI* page) :
|
|
|
|
|
mFavList(favList), mIconURI(icon), mPageURI(page) {} |
|
|
|
|
|
|
|
|
|
// Currently the favicon is downloaded like any other file
|
|
|
|
|
// which is bad. A nsStreamListener have to be
|
|
|
|
|
// implemented.
|
|
|
|
|
nsCOMPtr<nsIWebBrowserPersist> persist(do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID)); |
|
|
|
|
if(!persist) return FALSE; |
|
|
|
|
|
|
|
|
|
TCHAR tempPath[MAX_PATH]; |
|
|
|
|
GetTempPath(MAX_PATH, tempPath); |
|
|
|
|
GetTempFileName(tempPath, _T("kme"), 0, tempPath);
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsILocalFile> file; |
|
|
|
|
#ifdef _UNICODE |
|
|
|
|
NS_NewLocalFile(nsDependentString(tempPath), TRUE, getter_AddRefs(file)); |
|
|
|
|
#else |
|
|
|
|
NS_NewNativeLocalFile(nsDependentCString(tempPath), TRUE, getter_AddRefs(file)); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
CProgressDialog *progress = new CProgressDialog(FALSE); |
|
|
|
|
//persist->SetProgressListener(progress);
|
|
|
|
|
progress->InitPersist(iconURI, file, persist, FALSE);
|
|
|
|
|
progress->SetCallBack(CFavIconList::DwnCall, this); |
|
|
|
|
persist->SetPersistFlags( |
|
|
|
|
nsIWebBrowserPersist::PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION| |
|
|
|
|
nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES); |
|
|
|
|
nsresult rv = persist->SaveURI(iconURI, nullptr, nullptr, nullptr, nullptr, file); |
|
|
|
|
if (NS_FAILED(rv)) { |
|
|
|
|
persist->SetProgressListener(nullptr); |
|
|
|
|
return FALSE; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
return TRUE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CFavIconList::DwnCall(char* uri, TCHAR* file, nsresult status, void* param) |
|
|
|
|
{ |
|
|
|
|
((CFavIconList*)param)->AddDownloadedIcon(uri,file,status); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(IconObserver, imgINotificationObserver) |
|
|
|
|
NS_IMETHODIMP IconObserver::Notify(imgIRequest *aProxy, int32_t aType, const nsIntRect *aRect) |
|
|
|
|
{ |
|
|
|
|
if (aType == imgINotificationObserver::LOAD_COMPLETE) |
|
|
|
|
{
|
|
|
|
|
if (!NS_SUCCEEDED(aProxy->StartDecoding())) |
|
|
|
|
aProxy->Cancel(NS_OK); |
|
|
|
|
} |
|
|
|
|
else if (aType == imgINotificationObserver::DECODE_COMPLETE) |
|
|
|
|
void ImageLoaded(HBITMAP hBitmap)
|
|
|
|
|
{ |
|
|
|
|
CreateDIB(aProxy); |
|
|
|
|
aProxy->Cancel(NS_OK); |
|
|
|
|
//mRequest = nullptr;
|
|
|
|
|
//NS_RELEASE_THIS();
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return NS_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct ALPHABITMAPINFO { |
|
|
|
|
BITMAPINFOHEADER bmiHeader; |
|
|
|
|
RGBQUAD bmiColors[256]; |
|
|
|
|
BITMAP info; |
|
|
|
|
::GetObject(hBitmap, sizeof(BITMAP), &info); |
|
|
|
|
int w,h; |
|
|
|
|
ImageList_GetIconSize(mFavList->GetSafeHandle(), &w, &h); |
|
|
|
|
if (info.bmWidth!=w && info.bmHeight!=h) {
|
|
|
|
|
HDC hDC = GetDC(NULL); |
|
|
|
|
HBITMAP hbmSized = ResizeIcon32(hDC, hBitmap, w, h); |
|
|
|
|
if (!hbmSized) hbmSized = ResizeIcon(hDC, hBitmap, w, h); |
|
|
|
|
if (hbmSized) { |
|
|
|
|
DeleteObject(hBitmap); |
|
|
|
|
hBitmap = hbmSized; |
|
|
|
|
} |
|
|
|
|
ReleaseDC(NULL, hDC); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
CBitmap bitmap; |
|
|
|
|
bitmap.Attach(hBitmap); |
|
|
|
|
|
|
|
|
|
nsCString nsuri; |
|
|
|
|
mIconURI->GetSpec(nsuri); |
|
|
|
|
nsCString nsPageuri; |
|
|
|
|
if (mPageURI) mPageURI->GetSpec(nsPageuri); |
|
|
|
|
|
|
|
|
|
ALPHABITMAPINFO(LONG aWidth, LONG aHeight, WORD depth) |
|
|
|
|
{ |
|
|
|
|
memset(&bmiHeader, 0, sizeof(bmiHeader)); |
|
|
|
|
bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
|
|
|
|
bmiHeader.biWidth = aWidth; |
|
|
|
|
bmiHeader.biHeight = aHeight; |
|
|
|
|
bmiHeader.biPlanes = 1; |
|
|
|
|
bmiHeader.biBitCount = depth; |
|
|
|
|
mFavList->AddIcon(nsuri.get(),&bitmap, (CBitmap*)NULL, nsPageuri.get()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* fill in gray scale palette */ |
|
|
|
|
int i, npal=1<<depth; // 2^depth
|
|
|
|
|
BYTE fact = 255/(npal-1);
|
|
|
|
|
for(i=0; i < npal; i++){ |
|
|
|
|
BYTE color = 255-i*fact; |
|
|
|
|
bmiColors[i].rgbBlue = color; |
|
|
|
|
bmiColors[i].rgbGreen = color; |
|
|
|
|
bmiColors[i].rgbRed = color; |
|
|
|
|
bmiColors[i].rgbReserved = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
protected: |
|
|
|
|
nsCOMPtr<nsIURI> mIconURI; |
|
|
|
|
nsCOMPtr<nsIURI> mPageURI; |
|
|
|
|
CFavIconList* mFavList; |
|
|
|
|
}; |
|
|
|
|
static HBITMAP DataToBitmap(PRUint8* aImageData, |
|
|
|
|
PRUint32 aWidth, |
|
|
|
|
PRUint32 aHeight, |
|
|
|
|
PRUint32 aDepth) |
|
|
|
|
{ |
|
|
|
|
HDC dc = ::GetDC(NULL); |
|
|
|
|
|
|
|
|
|
if (aDepth == 32) { |
|
|
|
|
// Alpha channel. We need the new header.
|
|
|
|
|
BITMAPV4HEADER head = { 0 }; |
|
|
|
|
head.bV4Size = sizeof(head); |
|
|
|
|
head.bV4Width = aWidth; |
|
|
|
|
head.bV4Height = aHeight; |
|
|
|
|
head.bV4Planes = 1; |
|
|
|
|
head.bV4BitCount = aDepth; |
|
|
|
|
head.bV4V4Compression = BI_BITFIELDS; |
|
|
|
|
head.bV4SizeImage = 0; // Uncompressed
|
|
|
|
|
head.bV4XPelsPerMeter = 0; |
|
|
|
|
head.bV4YPelsPerMeter = 0; |
|
|
|
|
head.bV4ClrUsed = 0; |
|
|
|
|
head.bV4ClrImportant = 0; |
|
|
|
|
|
|
|
|
|
head.bV4RedMask = 0x00FF0000; |
|
|
|
|
head.bV4GreenMask = 0x0000FF00; |
|
|
|
|
head.bV4BlueMask = 0x000000FF; |
|
|
|
|
head.bV4AlphaMask = 0xFF000000; |
|
|
|
|
|
|
|
|
|
HBITMAP bmp = ::CreateDIBitmap(dc, |
|
|
|
|
reinterpret_cast<CONST BITMAPINFOHEADER*>(&head), |
|
|
|
|
CBM_INIT, |
|
|
|
|
aImageData, |
|
|
|
|
reinterpret_cast<CONST BITMAPINFO*>(&head), |
|
|
|
|
DIB_RGB_COLORS); |
|
|
|
|
::ReleaseDC(NULL, dc); |
|
|
|
|
return bmp; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char reserved_space[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 2]; |
|
|
|
|
BITMAPINFOHEADER& head = *(BITMAPINFOHEADER*)reserved_space; |
|
|
|
|
|
|
|
|
|
head.biSize = sizeof(BITMAPINFOHEADER); |
|
|
|
|
head.biWidth = aWidth; |
|
|
|
|
head.biHeight = aHeight; |
|
|
|
|
head.biPlanes = 1; |
|
|
|
|
head.biBitCount = (WORD)aDepth; |
|
|
|
|
head.biCompression = BI_RGB; |
|
|
|
|
head.biSizeImage = 0; // Uncompressed
|
|
|
|
|
head.biXPelsPerMeter = 0; |
|
|
|
|
head.biYPelsPerMeter = 0; |
|
|
|
|
head.biClrUsed = 0; |
|
|
|
|
head.biClrImportant = 0; |
|
|
|
|
|
|
|
|
|
BITMAPINFO& bi = *(BITMAPINFO*)reserved_space; |
|
|
|
|
|
|
|
|
|
if (aDepth == 1) { |
|
|
|
|
RGBQUAD black = { 0, 0, 0, 0 }; |
|
|
|
|
RGBQUAD white = { 255, 255, 255, 0 }; |
|
|
|
|
|
|
|
|
|
bi.bmiColors[0] = white; |
|
|
|
|
bi.bmiColors[1] = black; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
HBITMAP bmp = ::CreateDIBitmap(dc, &head, CBM_INIT, aImageData, &bi, DIB_RGB_COLORS); |
|
|
|
|
::ReleaseDC(NULL, dc); |
|
|
|
|
return bmp; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
ConvertBGRXToBGRA(uint8_t* aData, const IntSize &aSize, int32_t aStride) |
|
|
|
|
{ |
|
|
|
|
uint32_t* pixel = reinterpret_cast<uint32_t*>(aData); |
|
|
|
|
|
|
|
|
|
for (int row = 0; row < aSize.height; ++row) { |
|
|
|
|
for (int column = 0; column < aSize.width; ++column) { |
|
|
|
|
#ifdef IS_BIG_ENDIAN |
|
|
|
|
pixel[column] |= 0x000000FF; |
|
|
|
|
#else |
|
|
|
|
pixel[column] |= 0xFF000000; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
pixel += (aStride/4); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
CopySurfaceDataToPackedArray(uint8_t* aSrc, uint8_t* aDst, IntSize aSrcSize, |
|
|
|
|
int32_t aSrcStride, int32_t aBytesPerPixel) |
|
|
|
|
{ |
|
|
|
|
MOZ_ASSERT(aBytesPerPixel > 0, |
|
|
|
|
"Negative stride for aDst not currently supported"); |
|
|
|
|
|
|
|
|
|
int packedStride = aSrcSize.width * aBytesPerPixel; |
|
|
|
|
|
|
|
|
|
if (aSrcStride == packedStride) { |
|
|
|
|
// aSrc is already packed, so we can copy with a single memcpy.
|
|
|
|
|
memcpy(aDst, aSrc, packedStride * aSrcSize.height); |
|
|
|
|
} else { |
|
|
|
|
// memcpy one row at a time.
|
|
|
|
|
for (int row = 0; row < aSrcSize.height; ++row) { |
|
|
|
|
memcpy(aDst, aSrc, packedStride); |
|
|
|
|
aSrc += aSrcStride; |
|
|
|
|
aDst += packedStride; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static uint8_t* SurfaceToPackedBGRA(DataSourceSurface *aSurface) |
|
|
|
|
{ |
|
|
|
|
SurfaceFormat format = aSurface->GetFormat(); |
|
|
|
|
if (format != SurfaceFormat::B8G8R8A8 && format != SurfaceFormat::B8G8R8X8) { |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
IntSize size = aSurface->GetSize(); |
|
|
|
|
|
|
|
|
|
uint8_t* imageBuffer = new (std::nothrow) uint8_t[size.width * size.height * sizeof(uint32_t)]; |
|
|
|
|
if (!imageBuffer) { |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
DataSourceSurface::MappedSurface map; |
|
|
|
|
if (!aSurface->Map(DataSourceSurface::READ, &map)) { |
|
|
|
|
delete [] imageBuffer; |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
CopySurfaceDataToPackedArray(map.mData, imageBuffer, size, |
|
|
|
|
map.mStride, 4 * sizeof(uint8_t)); |
|
|
|
|
|
|
|
|
|
aSurface->Unmap(); |
|
|
|
|
|
|
|
|
|
if (format == SurfaceFormat::B8G8R8X8) { |
|
|
|
|
// Convert BGRX to BGRA by setting a to 255.
|
|
|
|
|
ConvertBGRXToBGRA(reinterpret_cast<uint8_t *>(imageBuffer), size, size.width * sizeof(uint32_t)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return imageBuffer; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint8_t* Data32BitTo1Bit(uint8_t* aImageData, |
|
|
|
|
uint32_t aWidth, uint32_t aHeight) |
|
|
|
|
{ |
|
|
|
|
// We need (aWidth + 7) / 8 bytes plus zero-padding up to a multiple of
|
|
|
|
|
// 4 bytes for each row (HBITMAP requirement). Bug 353553.
|
|
|
|
|
uint32_t outBpr = ((aWidth + 31) / 8) & ~3; |
|
|
|
|
|
|
|
|
|
// Allocate and clear mask buffer
|
|
|
|
|
|
|
|
|
|
uint8_t* outData = (uint8_t*)calloc(outBpr, aHeight); |
|
|
|
|
if (!outData) |
|
|
|
|
return nullptr; |
|
|
|
|
|
|
|
|
|
int32_t *imageRow = (int32_t*)aImageData; |
|
|
|
|
for (uint32_t curRow = 0; curRow < aHeight; curRow++) { |
|
|
|
|
uint8_t *outRow = outData + curRow * outBpr; |
|
|
|
|
uint8_t mask = 0x80; |
|
|
|
|
for (uint32_t curCol = 0; curCol < aWidth; curCol++) { |
|
|
|
|
// Use sign bit to test for transparency, as alpha byte is highest byte
|
|
|
|
|
if (*imageRow++ < 0) |
|
|
|
|
*outRow |= mask; |
|
|
|
|
|
|
|
|
|
mask >>= 1; |
|
|
|
|
if (!mask) { |
|
|
|
|
outRow ++; |
|
|
|
|
mask = 0x80; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return outData; |
|
|
|
|
} |
|
|
|
|
NS_IMETHODIMP IconObserver::CreateDIB(imgIRequest *aRequest) |
|
|
|
|
BOOL CFavIconList::DwnFavIcon(nsIURI* iconURI, nsIURI* pageURI) |
|
|
|
|
{ |
|
|
|
|
nsresult rv; |
|
|
|
|
nsCOMPtr<imgIContainer> container; |
|
|
|
|
rv = aRequest->GetImage(getter_AddRefs(container)); |
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv); |
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG |
|
|
|
|
// There is a problem with the linking in debug
|
|
|
|
|
return NS_ERROR_FAILURE; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
// Get the image data
|
|
|
|
|
mozilla::RefPtr<SourceSurface> surface; |
|
|
|
|
iconObserver* io = new iconObserver(this, iconURI, pageURI); |
|
|
|
|
|
|
|
|
|
// Add fragment for wanted size
|
|
|
|
|
nsCString spec; |
|
|
|
|
iconURI->GetSpec(spec); |
|
|
|
|
spec.Append("#-moz-resolution="); |
|
|
|
|
char tmp[34]; |
|
|
|
|
itoa(mWidth, tmp, 10); |
|
|
|
|
spec.Append(tmp); |
|
|
|
|
spec.Append(","); |
|
|
|
|
itoa(mHeight, tmp, 10); |
|
|
|
|
spec.Append(tmp); |
|
|
|
|
|
|
|
|
|
surface = container->GetFrame(imgIContainer::FRAME_CURRENT, |
|
|
|
|
imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_WANT_DATA_SURFACE ); |
|
|
|
|
NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE); |
|
|
|
|
surface->GetFormat(); |
|
|
|
|
//surface->GetDataSurface();
|
|
|
|
|
|
|
|
|
|
mozilla::RefPtr<DataSourceSurface> dataSurface; |
|
|
|
|
DataSourceSurface::MappedSurface map; |
|
|
|
|
bool mappedOK; |
|
|
|
|
if (surface->GetFormat() != mozilla::gfx::SurfaceFormat::B8G8R8A8) { |
|
|
|
|
// Convert format to SurfaceFormat::B8G8R8A8
|
|
|
|
|
//dataSurface = gfxUtils::CopySurfaceToDataSourceSurfaceWithFormat(surface, SurfaceFormat::B8G8R8A8);
|
|
|
|
|
//NS_ENSURE_TRUE(dataSurface, NULL);
|
|
|
|
|
//mappedOK = dataSurface->Map(mozilla::gfx::DataSourceSurface::MapType::READ, &map);
|
|
|
|
|
} else { |
|
|
|
|
dataSurface = surface->GetDataSurface(); |
|
|
|
|
NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE); |
|
|
|
|
mappedOK = dataSurface->Map(mozilla::gfx::DataSourceSurface::READ, &map); |
|
|
|
|
} |
|
|
|
|
NS_ENSURE_TRUE(dataSurface && mappedOK, NS_ERROR_FAILURE); |
|
|
|
|
//MOZ_ASSERT(dataSurface->GetFormat() == mozilla::gfx::SurfaceFormat::B8G8R8A8);
|
|
|
|
|
|
|
|
|
|
IntSize frameSize = surface->GetSize(); |
|
|
|
|
if (frameSize.IsEmpty()) { |
|
|
|
|
return NS_ERROR_FAILURE; |
|
|
|
|
} |
|
|
|
|
nsCOMPtr<nsIURI> uri; |
|
|
|
|
NewURI(getter_AddRefs(uri), spec); |
|
|
|
|
|
|
|
|
|
uint8_t* data = nullptr; |
|
|
|
|
nsAutoArrayPtr<uint8_t> autoDeleteArray; |
|
|
|
|
if (map.mStride == BytesPerPixel(dataSurface->GetFormat()) * frameSize.width) { |
|
|
|
|
// Mapped data is already packed
|
|
|
|
|
data = map.mData; |
|
|
|
|
} else { |
|
|
|
|
// We can't use map.mData since the pixels are not packed (as required by
|
|
|
|
|
// CreateDIBitmap, which is called under the DataToBitmap call below).
|
|
|
|
|
//
|
|
|
|
|
// We must unmap before calling SurfaceToPackedBGRA because it needs access
|
|
|
|
|
// to the pixel data.
|
|
|
|
|
dataSurface->Unmap(); |
|
|
|
|
map.mData = nullptr; |
|
|
|
|
|
|
|
|
|
data = autoDeleteArray = SurfaceToPackedBGRA(dataSurface); |
|
|
|
|
NS_ENSURE_TRUE(data, NS_ERROR_FAILURE); |
|
|
|
|
if (!nsImageObserver::LoadImage(io, uri)) { |
|
|
|
|
delete io; |
|
|
|
|
return FALSE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
HBITMAP hBitmap = DataToBitmap(data, frameSize.width, -frameSize.height, 32); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int32_t w = frameSize.width;
|
|
|
|
|
int32_t h = frameSize.height;
|
|
|
|
|
|
|
|
|
|
if (w!=16 && h!=16) {
|
|
|
|
|
HDC hDC = GetDC(NULL); |
|
|
|
|
HBITMAP hbmSized = ResizeIcon32(hDC, hBitmap, w, h); |
|
|
|
|
if (!hbmSized) hbmSized = ResizeIcon(hDC, hBitmap, w, h); |
|
|
|
|
if (hbmSized) { |
|
|
|
|
DeleteObject(hBitmap); |
|
|
|
|
hBitmap = hbmSized; |
|
|
|
|
} |
|
|
|
|
ReleaseDC(NULL, hDC); |
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CBitmap bitmap; |
|
|
|
|
bitmap.Attach(hBitmap); |
|
|
|
|
|
|
|
|
|
CString uri; |
|
|
|
|
nsCOMPtr<nsIURI> URI; |
|
|
|
|
nsEmbedCString nsuri; |
|
|
|
|
rv = aRequest->GetURI(getter_AddRefs(URI)); |
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv); |
|
|
|
|
URI->GetSpec(nsuri); |
|
|
|
|
|
|
|
|
|
nsEmbedCString nsPageuri; |
|
|
|
|
if (mPageUri) mPageUri->GetSpec(nsPageuri); |
|
|
|
|
mFavList->AddIcon(nsuri.get(),&bitmap, (CBitmap*)NULL, nsPageuri.get()); |
|
|
|
|
return NS_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP IconObserver::LoadIcon(nsIURI *iconUri, nsIURI* pageUri) |
|
|
|
|
{ |
|
|
|
|
nsresult rv; |
|
|
|
|
nsCOMPtr<imgILoader> loader = do_GetService("@mozilla.org/image/loader;1", &rv); |
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv); |
|
|
|
|
mPageUri = pageUri; |
|
|
|
|
|
|
|
|
|
return loader->LoadImageXPCOM(iconUri, pageUri, nullptr,
|
|
|
|
|
nullptr, nullptr, this, this, nsIRequest::LOAD_BYPASS_CACHE,
|
|
|
|
|
nullptr, nullptr, getter_AddRefs(mRequest)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return TRUE; |
|
|
|
|
} |