int WIN32Window::internalLoadMouseCursor(const ImagePtr& image, const Point& hotSpot) { int width = image->getWidth(); int height = image->getHeight(); int numbits = width * height; int numbytes = (width * height)/8; std::vector<uchar> andMask(numbytes, 0); std::vector<uchar> xorMask(numbytes, 0); for(int i=0;i<numbits;++i) { uint32 rgba = stdext::readULE32(image->getPixelData() + i*4); if(rgba == 0xffffffff) { //white HSB_BIT_SET(xorMask, i); } else if(rgba == 0x00000000) { //alpha HSB_BIT_SET(andMask, i); } // otherwise 0xff000000 => black } HCURSOR cursor = CreateCursor(m_instance, hotSpot.x, hotSpot.y, width, height, &andMask[0], &xorMask[0]); m_cursors.push_back(cursor); return m_cursors.size()-1; }
static PassRefPtr<SharedCursor> createSharedCursor(Image* img, const IntPoint& hotSpot) { RefPtr<SharedCursor> impl; IntPoint effectiveHotSpot = determineHotSpot(img, hotSpot); static bool doAlpha = supportsAlphaCursors(); BitmapInfo cursorImage = BitmapInfo::create(IntSize(img->width(), img->height())); HDC dc = GetDC(0); HDC workingDC = CreateCompatibleDC(dc); if (doAlpha) { OwnPtr<HBITMAP> hCursor(CreateDIBSection(dc, (BITMAPINFO *)&cursorImage, DIB_RGB_COLORS, 0, 0, 0)); ASSERT(hCursor); img->getHBITMAP(hCursor.get()); HBITMAP hOldBitmap = (HBITMAP)SelectObject(workingDC, hCursor.get()); SetBkMode(workingDC, TRANSPARENT); SelectObject(workingDC, hOldBitmap); Vector<unsigned char, 128> maskBits; maskBits.fill(0xff, (img->width() + 7) / 8 * img->height()); OwnPtr<HBITMAP> hMask(CreateBitmap(img->width(), img->height(), 1, 1, maskBits.data())); ICONINFO ii; ii.fIcon = FALSE; ii.xHotspot = effectiveHotSpot.x(); ii.yHotspot = effectiveHotSpot.y(); ii.hbmMask = hMask.get(); ii.hbmColor = hCursor.get(); impl = SharedCursor::create(CreateIconIndirect(&ii)); } else { // Platform doesn't support alpha blended cursors, so we need // to create the mask manually HDC andMaskDC = CreateCompatibleDC(dc); HDC xorMaskDC = CreateCompatibleDC(dc); OwnPtr<HBITMAP> hCursor(CreateDIBSection(dc, &cursorImage, DIB_RGB_COLORS, 0, 0, 0)); ASSERT(hCursor); img->getHBITMAP(hCursor.get()); BITMAP cursor; GetObject(hCursor.get(), sizeof(BITMAP), &cursor); OwnPtr<HBITMAP> andMask(CreateBitmap(cursor.bmWidth, cursor.bmHeight, 1, 1, NULL)); OwnPtr<HBITMAP> xorMask(CreateCompatibleBitmap(dc, cursor.bmWidth, cursor.bmHeight)); HBITMAP oldCursor = (HBITMAP)SelectObject(workingDC, hCursor.get()); HBITMAP oldAndMask = (HBITMAP)SelectObject(andMaskDC, andMask.get()); HBITMAP oldXorMask = (HBITMAP)SelectObject(xorMaskDC, xorMask.get()); SetBkColor(workingDC, RGB(0,0,0)); BitBlt(andMaskDC, 0, 0, cursor.bmWidth, cursor.bmHeight, workingDC, 0, 0, SRCCOPY); SetBkColor(xorMaskDC, RGB(255, 255, 255)); SetTextColor(xorMaskDC, RGB(255, 255, 255)); BitBlt(xorMaskDC, 0, 0, cursor.bmWidth, cursor.bmHeight, andMaskDC, 0, 0, SRCCOPY); BitBlt(xorMaskDC, 0, 0, cursor.bmWidth, cursor.bmHeight, workingDC, 0,0, SRCAND); SelectObject(workingDC, oldCursor); SelectObject(andMaskDC, oldAndMask); SelectObject(xorMaskDC, oldXorMask); ICONINFO icon = {0}; icon.fIcon = FALSE; icon.xHotspot = effectiveHotSpot.x(); icon.yHotspot = effectiveHotSpot.y(); icon.hbmMask = andMask.get(); icon.hbmColor = xorMask.get(); impl = SharedCursor::create(CreateIconIndirect(&icon)); DeleteDC(xorMaskDC); DeleteDC(andMaskDC); } DeleteDC(workingDC); ReleaseDC(0, dc); return impl.release(); }
static HCURSOR qt_createPixmapCursor( const QCursor &cursor, const QPixmap &pixmap, const QPoint &hotspot ) { QSize size; /* calculate size of cursor */ QPoint pt = hotspot - cursor.hotSpot(); QPoint pixmap_point( 0, 0 ); QPoint cursor_point( 0, 0 ); if ( qWinVersion() <= Qt::WV_95 ) { /* Win95 can only fixed size */ size.setWidth( GetSystemMetrics ( SM_CXCURSOR ) ); size.setHeight ( GetSystemMetrics ( SM_CYCURSOR ) ); } else { /* calculate size (enlarge if needed) */ const QBitmap *tmp = cursor.bitmap(); /* Only bitmap cursors allowed... */ if ( tmp ) { QPoint point; // curent size size = pixmap.size(); // calc position of lower right cursor pos point.setX( pt.x() + tmp->size().width() ); point.setY( pt.y() + tmp->size().height() ); // resize when cursor to large if ( point.x() > pixmap.width() ) size.setWidth( point.x() ); if ( point.y() > pixmap.height() ) size.setHeight( point.y() ); // calc upper left corner where both pixmaps have to be drawn if ( pt.x() >= 0 ) { cursor_point.setX( pt.x() ); } else { pixmap_point.setX( -pt.x() ); // negative position -> resize size.setWidth( size.width() - pt.x() ); } if ( pt.y() >= 0 ) { cursor_point.setX( pt.x() ); } else { pixmap_point.setY( -pt.y() ); // negative position -> resize size.setHeight( size.height() - pt.y() ); } } } /* Mask */ QBitmap andMask( size ); BitBlt( andMask.handle(), 0, 0, size.width(), size.height(), NULL, 0, 0, WHITENESS ); if ( pixmap.mask() ) BitBlt( andMask.handle(), pixmap_point.x(), pixmap_point.y(), pixmap.width(), pixmap.height(), pixmap.mask() ->handle(), 0, 0, SRCAND ); else BitBlt( andMask.handle(), pixmap_point.x(), pixmap_point.y(), pixmap.width(), pixmap.height(), NULL, 0, 0, BLACKNESS ); const QBitmap *curMsk = cursor.mask(); if ( curMsk ) BitBlt( andMask.handle(), cursor_point.x(), cursor_point.y(), curMsk->width(), curMsk->height(), curMsk->handle(), 0, 0, SRCAND ); /* create Pixmap */ QPixmap xorMask( size ); xorMask.fill ( Qt::color1 ); QPainter paint2( &xorMask ); paint2.drawPixmap( pixmap_point, pixmap ); QPixmap pm; pm.convertFromImage( cursor.bitmap() ->convertToImage().convertDepth( 8 ) ); pm.setMask( *cursor.mask() ); paint2.drawPixmap ( cursor_point, pm ); paint2.end(); #ifdef DEBUG_QDND_SRC andMask.save ( "pand.png", "PNG" ); xorMask.save ( "pxor.png", "PNG" ); #endif HCURSOR cur = qt_createPixmapCursor ( qt_display_dc(), xorMask, andMask, hotspot, size ); if ( !cur ) { qWarning( "Error creating cursor: %d", GetLastError() ); } return cur; }
Cursor::Cursor(Image* img, const IntPoint& hotspot) { static bool doAlpha = supportsAlphaCursors(); BITMAPINFO cursorImage = {0}; cursorImage.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); cursorImage.bmiHeader.biWidth = img->width(); cursorImage.bmiHeader.biHeight = img->height(); cursorImage.bmiHeader.biPlanes = 1; cursorImage.bmiHeader.biBitCount = 32; cursorImage.bmiHeader.biCompression = BI_RGB; HDC dc = GetDC(0); HDC workingDC = CreateCompatibleDC(dc); if (doAlpha) { OwnPtr<HBITMAP> hCursor(CreateDIBSection(dc, (BITMAPINFO *)&cursorImage, DIB_RGB_COLORS, 0, 0, 0)); ASSERT(hCursor); img->getHBITMAP(hCursor.get()); HBITMAP hOldBitmap = (HBITMAP)SelectObject(workingDC, hCursor.get()); SetBkMode(workingDC, TRANSPARENT); SelectObject(workingDC, hOldBitmap); OwnPtr<HBITMAP> hMask(CreateBitmap(img->width(), img->height(), 1, 1, NULL)); ICONINFO ii; ii.fIcon = FALSE; ii.xHotspot = hotspot.x(); ii.yHotspot = hotspot.y(); ii.hbmMask = hMask.get(); ii.hbmColor = hCursor.get(); m_impl = new SharedCursor(CreateIconIndirect(&ii)); } else { // Platform doesn't support alpha blended cursors, so we need // to create the mask manually HDC andMaskDC = CreateCompatibleDC(dc); HDC xorMaskDC = CreateCompatibleDC(dc); OwnPtr<HBITMAP> hCursor(CreateDIBSection(dc, &cursorImage, DIB_RGB_COLORS, 0, 0, 0)); ASSERT(hCursor); img->getHBITMAP(hCursor.get()); BITMAP cursor; GetObject(hCursor.get(), sizeof(BITMAP), &cursor); OwnPtr<HBITMAP> andMask(CreateBitmap(cursor.bmWidth, cursor.bmHeight, 1, 1, NULL)); OwnPtr<HBITMAP> xorMask(CreateCompatibleBitmap(dc, cursor.bmWidth, cursor.bmHeight)); HBITMAP oldCursor = (HBITMAP)SelectObject(workingDC, hCursor.get()); HBITMAP oldAndMask = (HBITMAP)SelectObject(andMaskDC, andMask.get()); HBITMAP oldXorMask = (HBITMAP)SelectObject(xorMaskDC, xorMask.get()); SetBkColor(workingDC, RGB(0,0,0)); BitBlt(andMaskDC, 0, 0, cursor.bmWidth, cursor.bmHeight, workingDC, 0, 0, SRCCOPY); SetBkColor(xorMaskDC, RGB(255, 255, 255)); SetTextColor(xorMaskDC, RGB(255, 255, 255)); BitBlt(xorMaskDC, 0, 0, cursor.bmWidth, cursor.bmHeight, andMaskDC, 0, 0, SRCCOPY); BitBlt(xorMaskDC, 0, 0, cursor.bmWidth, cursor.bmHeight, workingDC, 0,0, SRCAND); SelectObject(workingDC, oldCursor); SelectObject(andMaskDC, oldAndMask); SelectObject(xorMaskDC, oldXorMask); ICONINFO icon = {0}; icon.fIcon = FALSE; icon.xHotspot = hotspot.x(); icon.yHotspot = hotspot.y(); icon.hbmMask = andMask.get(); icon.hbmColor = xorMask.get(); m_impl = new SharedCursor(CreateIconIndirect(&icon)); DeleteDC(xorMaskDC); DeleteDC(andMaskDC); } DeleteDC(workingDC); ReleaseDC(0, dc); }