зеркало из https://github.com/mozilla/gecko-dev.git
fixing custom cursor crash bug 332713. r=biesi sr=vlad
This commit is contained in:
Родитель
af8d622530
Коммит
cf33d376df
|
@ -2777,6 +2777,88 @@ NS_IMETHODIMP nsWindow::SetCursor(imgIContainer* aCursor,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_CAIRO_GFX
|
||||||
|
nsCOMPtr<gfxIImageFrame> frame;
|
||||||
|
aCursor->GetFrameAt(0, getter_AddRefs(frame));
|
||||||
|
if (!frame)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
PRInt32 width, height;
|
||||||
|
PRUint32 bpr;
|
||||||
|
gfx_format format;
|
||||||
|
frame->GetWidth(&width);
|
||||||
|
frame->GetHeight(&height);
|
||||||
|
frame->GetImageBytesPerRow(&bpr);
|
||||||
|
frame->GetFormat(&format);
|
||||||
|
|
||||||
|
frame->LockImageData();
|
||||||
|
|
||||||
|
PRUint32 dataLen;
|
||||||
|
PRUint8 *data;
|
||||||
|
nsresult rv = frame->GetImageData(&data, &dataLen);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
frame->UnlockImageData();
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* flip the image so that it is stored bottom-up */
|
||||||
|
PRUint8 *bottomUpData = (PRUint8*)malloc(dataLen);
|
||||||
|
if (!bottomUpData) {
|
||||||
|
frame->UnlockImageData();
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == gfxIFormats::RGB_A8 || format == gfxIFormats::BGR_A8) {
|
||||||
|
for (PRInt32 i = 0; i < height; ++i) {
|
||||||
|
PRUint32 srcOffset = i * bpr;
|
||||||
|
PRUint32 dstOffset = dataLen - (bpr * (i + 1));
|
||||||
|
PRUint32 *srcRow = (PRUint32*)(data + srcOffset);
|
||||||
|
PRUint32 *dstRow = (PRUint32*)(bottomUpData + dstOffset);
|
||||||
|
memcpy(dstRow, srcRow, bpr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (PRInt32 i = 0; i < height; ++i) {
|
||||||
|
PRUint32 srcOffset = i * bpr;
|
||||||
|
PRUint32 dstOffset = dataLen - (bpr * (i + 1));
|
||||||
|
PRUint32 *srcRow = (PRUint32*)(data + srcOffset);
|
||||||
|
PRUint32 *dstRow = (PRUint32*)(bottomUpData + dstOffset);
|
||||||
|
for (PRInt32 x = 0; x < width; ++x) {
|
||||||
|
dstRow[x] = (srcRow[x] & 0xFFFFFF) | (0xFF << 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HBITMAP bmp = DataToBitmap(bottomUpData, width, height, 32);
|
||||||
|
|
||||||
|
free(bottomUpData);
|
||||||
|
|
||||||
|
frame->UnlockImageData();
|
||||||
|
|
||||||
|
ICONINFO info = {0};
|
||||||
|
info.fIcon = FALSE;
|
||||||
|
info.xHotspot = aHotspotX;
|
||||||
|
info.yHotspot = aHotspotY;
|
||||||
|
info.hbmMask = bmp;
|
||||||
|
info.hbmColor = bmp;
|
||||||
|
|
||||||
|
HCURSOR cursor = ::CreateIconIndirect(&info);
|
||||||
|
::DeleteObject(bmp);
|
||||||
|
if (cursor == NULL) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCursor = nsCursor(-1);
|
||||||
|
::SetCursor(cursor);
|
||||||
|
|
||||||
|
NS_IF_RELEASE(gCursorImgContainer);
|
||||||
|
gCursorImgContainer = aCursor;
|
||||||
|
NS_ADDREF(gCursorImgContainer);
|
||||||
|
|
||||||
|
if (gHCursor != NULL)
|
||||||
|
::DestroyIcon(gHCursor);
|
||||||
|
gHCursor = cursor;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
// Get the image data
|
// Get the image data
|
||||||
nsCOMPtr<gfxIImageFrame> frame;
|
nsCOMPtr<gfxIImageFrame> frame;
|
||||||
aCursor->GetFrameAt(0, getter_AddRefs(frame));
|
aCursor->GetFrameAt(0, getter_AddRefs(frame));
|
||||||
|
@ -2909,6 +2991,8 @@ NS_IMETHODIMP nsWindow::SetCursor(imgIContainer* aCursor,
|
||||||
::DestroyIcon(gHCursor);
|
::DestroyIcon(gHCursor);
|
||||||
gHCursor = cursor;
|
gHCursor = cursor;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче