- Timestamp:
- Jul 27, 2016 12:34:50 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
r62493 r62588 1753 1753 # else /* QT_VERSION >= 0x050000 */ 1754 1754 /* Create a ARGB image out of the shape data: */ 1755 QImage image(uWidth, uHeight, QImage::Format_ARGB32); 1756 memcpy(image.bits(), srcShapePtr, uHeight * uWidth * 4); 1755 1756 /* 1757 * Qt5 QCursor recommends 32 x 32 cursor, therefore the original data is copied to 1758 * a larger QImage if necessary. Cursors like 10x16 did not work correctly (Solaris 10 guest). 1759 */ 1760 uint uCursorWidth = uWidth >= 32? uWidth: 32; 1761 uint uCursorHeight = uHeight >= 32? uHeight: 32; 1762 uint x, y; 1757 1763 1758 1764 if (fHasAlpha) 1765 { 1766 QImage image(uCursorWidth, uCursorHeight, QImage::Format_ARGB32); 1767 memset(image.bits(), 0, image.byteCount()); 1768 1769 const uint32_t *pu32SrcShapeScanline = (uint32_t *)srcShapePtr; 1770 for (y = 0; y < uHeight; ++y, pu32SrcShapeScanline += uWidth) 1771 memcpy(image.scanLine(y), pu32SrcShapeScanline, uWidth * sizeof(uint32_t)); 1772 1759 1773 m_cursor = QCursor(QPixmap::fromImage(image), uXHot, uYHot); 1774 } 1760 1775 else 1761 1776 { … … 1764 1779 /* Incoming data consist of 32 bit BGR XOR mask and 1 bit AND mask. 1765 1780 * XOR pixels contain either 0x00000000 or 0x00FFFFFF. 1766 * image.convertToFormat(QImage::Format_Mono) converts them:1767 * 0x00000000 -> 1, 0x00FFFFFF -> 0.1768 1781 * 1769 * XOR AND originally intended result (F denotes 0x00FFFFFF): 1782 * Originally intended result (F denotes 0x00FFFFFF): 1783 * XOR AND 1770 1784 * 0 0 black 1771 1785 * F 0 white … … 1773 1787 * F 1 xor'd 1774 1788 * 1775 * XOR AND converted bitmap intended result: 1776 * 1 0 black 1777 * 0 0 white 1778 * 1 1 transparent 1779 * 0 1 xor'd 1789 * Actual Qt5 result for color table 0:0xFF000000, 1:0xFFFFFFFF 1790 * (tested on Windows 7 and 10 64 bit hosts): 1791 * Bitmap Mask 1792 * 0 0 black 1793 * 1 0 white 1794 * 0 1 xor 1795 * 1 1 transparent 1780 1796 * 1781 * Bitmap Mask actual Qt5 result (tested on Windows 7 64 bit host):1782 * 1 0 black1783 * 0 0 white1784 * 0 1 transparent1785 * 1 1 xor'd1786 *1787 * Converted bitmap to the Qt5 mask and bitmap:1788 * Mask = AND;1789 * Bitmap = ConvBitmap ^ Mask;1790 1797 */ 1791 QImage bitmap = image.convertToFormat(QImage::Format_Mono); 1792 QImage mask(uWidth, uHeight, QImage::Format_Mono); 1793 memcpy(mask.bits(), srcAndMaskPtr, uHeight * ((uWidth + 7) / 8)); 1794 1795 const uint8_t *pu8Mask = mask.bits(); 1796 uint8_t *pu8Bitmap = bitmap.bits(); 1797 uint i; 1798 for (i = 0; i < uHeight * ((uWidth + 7) / 8); ++i) 1799 pu8Bitmap[i] ^= pu8Mask[i]; 1800 1801 m_cursor = QCursor(QBitmap::fromImage(bitmap), QBitmap::fromImage(mask), uXHot, uYHot); 1802 } 1803 else 1804 { 1805 /* Assign alpha channel values according to the AND mask: 1 -> 0x00, 0 -> 0xFF: */ 1806 const uint8_t *pu8And = srcAndMaskPtr; 1807 uint32_t *pu32Pixel = (uint32_t *)image.bits(); 1808 uint y; 1798 1799 QVector<QRgb> colors(2); 1800 colors[0] = UINT32_C(0xFF000000); 1801 colors[1] = UINT32_C(0xFFFFFFFF); 1802 1803 QImage bitmap(uCursorWidth, uCursorHeight, QImage::Format_Mono); 1804 bitmap.setColorTable(colors); 1805 memset(bitmap.bits(), 0xFF, bitmap.byteCount()); 1806 1807 QImage mask(uCursorWidth, uCursorHeight, QImage::Format_Mono); 1808 mask.setColorTable(colors); 1809 memset(mask.bits(), 0xFF, mask.byteCount()); 1810 1811 const uint8_t *pu8SrcAndScanline = srcAndMaskPtr; 1812 const uint32_t *pu32SrcShapeScanline = (uint32_t *)srcShapePtr; 1809 1813 for (y = 0; y < uHeight; ++y) 1810 1814 { 1811 uint x; 1812 for (x = 0; x < (uWidth + 7) / 8; ++x) 1815 for (x = 0; x < uWidth; ++x) 1813 1816 { 1814 const uint8_t b = *pu8And; 1815 uint k; 1816 for (k = 0; k < 8; ++k) 1817 const uint8_t u8Bit = (uint8_t)(1 << (7 - x % 8)); 1818 1819 const uint8_t u8SrcMaskByte = pu8SrcAndScanline[x / 8]; 1820 const uint8_t u8SrcMaskBit = u8SrcMaskByte & u8Bit; 1821 const uint32_t u32SrcPixel = pu32SrcShapeScanline[x] & UINT32_C(0xFFFFFF); 1822 1823 uint8_t *pu8DstMaskByte = &mask.scanLine(y)[x / 8]; 1824 uint8_t *pu8DstBitmapByte = &bitmap.scanLine(y)[x / 8]; 1825 1826 if (u8SrcMaskBit == 0) 1817 1827 { 1818 if (b & (1 << (7 - k))) 1819 *pu32Pixel &= UINT32_C(0x00FFFFFF); 1828 if (u32SrcPixel == 0) 1829 { 1830 /* Black: Qt Bitmap = 0, Mask = 0 */ 1831 *pu8DstMaskByte &= ~u8Bit; 1832 *pu8DstBitmapByte &= ~u8Bit; 1833 } 1820 1834 else 1821 *pu32Pixel |= UINT32_C(0xFF000000); 1822 ++pu32Pixel; 1835 { 1836 /* White: Qt Bitmap = 1, Mask = 0 */ 1837 *pu8DstMaskByte &= ~u8Bit; 1838 *pu8DstBitmapByte |= u8Bit; 1839 } 1823 1840 } 1824 1825 ++pu8And; 1841 else 1842 { 1843 if (u32SrcPixel == 0) 1844 { 1845 /* Transparent: Qt Bitmap = 1, Mask = 1 */ 1846 *pu8DstMaskByte |= u8Bit; 1847 *pu8DstBitmapByte |= u8Bit; 1848 } 1849 else 1850 { 1851 /* Xor'ed: Qt Bitmap = 0, Mask = 1 */ 1852 *pu8DstMaskByte |= u8Bit; 1853 *pu8DstBitmapByte &= ~u8Bit; 1854 } 1855 } 1826 1856 } 1857 1858 pu8SrcAndScanline += (uWidth + 7) / 8; 1859 pu32SrcShapeScanline += uWidth; 1860 } 1861 1862 m_cursor = QCursor(QBitmap::fromImage(bitmap), QBitmap::fromImage(mask), uXHot, uYHot); 1863 } 1864 else 1865 { 1866 /* Assign alpha channel values according to the AND mask: 1 -> 0x00, 0 -> 0xFF: */ 1867 QImage image(uCursorWidth, uCursorHeight, QImage::Format_ARGB32); 1868 memset(image.bits(), 0, image.byteCount()); 1869 1870 const uint8_t *pu8SrcAndScanline = srcAndMaskPtr; 1871 const uint32_t *pu32SrcShapeScanline = (uint32_t *)srcShapePtr; 1872 1873 for (y = 0; y < uHeight; ++y) 1874 { 1875 uint32_t *pu32DstPixel = (uint32_t *)image.scanLine(y); 1876 1877 for (x = 0; x < uWidth; ++x) 1878 { 1879 const uint8_t u8Bit = (uint8_t)(1 << (7 - x % 8)); 1880 const uint8_t u8SrcMaskByte = pu8SrcAndScanline[x / 8]; 1881 1882 if (u8SrcMaskByte & u8Bit) 1883 *pu32DstPixel++ = pu32SrcShapeScanline[x] & UINT32_C(0x00FFFFFF); 1884 else 1885 *pu32DstPixel++ = pu32SrcShapeScanline[x] | UINT32_C(0xFF000000); 1886 } 1887 1888 pu32SrcShapeScanline += uWidth; 1889 pu8SrcAndScanline += (uWidth + 7) / 8; 1827 1890 } 1828 1891
Note:
See TracChangeset
for help on using the changeset viewer.