- Timestamp:
- Nov 9, 2009, 1:03:42 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/plugins/org.eclipse.swt/Eclipse SWT/pm/org/eclipse/swt/graphics/Image.java
r14 r218 3 3 /* 4 4 * OS/2 version. 5 * Copyright (c) 2002, 200 4EclipseOS2 Team.5 * Copyright (c) 2002, 2009 EclipseOS2 Team. 6 6 */ 7 7 … … 737 737 for (int y = 0; y < mask.height; y++) { 738 738 mask.getPixels(0, y, mask.width, maskPixels, 0); 739 // System.out.println(getBits(maskPixels[0]) + getBits(maskPixels[1]) + getBits(maskPixels[2]) + getBits(maskPixels[3])); 739 740 newMask.setPixels(0, y, newMask.width, maskPixels, 0); 740 741 } … … 1430 1431 if (i.depth == 2) { 1431 1432 ImageData img = new ImageData(i.width, i.height, 4, i.palette); 1432 ImageData.blit(ImageData.BLIT_SRC, 1433 i.data, i.depth, i.bytesPerLine, i.getByteOrder(), 1434 0, 0, i.width, i.height, null, null, null, 1433 ImageData.blit(ImageData.BLIT_SRC, i.data, i.depth, i.bytesPerLine, i.getByteOrder(), 1434 0, 0, i.width, i.height, null, null, null, 1435 1435 ImageData.ALPHA_OPAQUE, null, 0, 1436 1436 img.data, img.depth, img.bytesPerLine, i.getByteOrder(), 1437 1437 0, 0, img.width, img.height, null, null, null, 1438 1438 false, false); 1439 1439 img.transparentPixel = i.transparentPixel; … … 1446 1446 if (i.palette.isDirect) { 1447 1447 final PaletteData palette = i.palette; 1448 boolean convert = false; 1449 1450 switch (i.depth) { 1451 case 24: 1452 if ( 1453 palette.redMask == 0xFF && 1454 palette.greenMask == 0xFF00 && 1455 palette.blueMask == 0xFF0000 1456 ) { 1457 break; 1458 } 1459 case 8: 1460 case 16: 1461 case 32: 1462 convert = true; 1463 break; 1464 default: 1465 SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); 1466 } 1467 1468 if (convert || i.getByteOrder() != ImageData.MSB_FIRST) { 1469 PaletteData newPalette = new PaletteData (0xFF, 0xFF00, 0xFF0000); 1470 ImageData img = new ImageData (i.width, i.height, 24, newPalette); 1448 boolean convert = false; 1449 switch (i.depth) { 1450 case 24: 1451 if (palette.redMask == 0xFF && 1452 palette.greenMask == 0xFF00 && 1453 palette.blueMask == 0xFF0000) 1454 { 1455 break; 1456 } 1457 case 8: 1458 case 16: 1459 case 32: 1460 convert = true; 1461 break; 1462 default: 1463 SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); 1464 } 1465 1466 if (convert || i.getByteOrder() != ImageData.MSB_FIRST) { 1467 PaletteData newPalette = new PaletteData (0xFF, 0xFF00, 0xFF0000); 1468 ImageData img = new ImageData (i.width, i.height, 24, newPalette); 1471 1469 ImageData.blit (ImageData.BLIT_SRC, 1472 1473 1474 1475 1476 1477 1478 1479 1470 i.data, i.depth, i.bytesPerLine, i.getByteOrder(), 1471 0, 0, i.width, i.height, 1472 palette.redMask, palette.greenMask, palette.blueMask, 1473 ImageData.ALPHA_OPAQUE, null, 0, 1474 img.data, img.depth, img.bytesPerLine, ImageData.MSB_FIRST, 1475 0, 0, img.width, img.height, 1476 newPalette.redMask, newPalette.greenMask, newPalette.blueMask, 1477 false, false); 1480 1478 if (i.transparentPixel != -1) { 1481 img.transparentPixel = 1482 newPalette.getPixel(palette.getRGB(i.transparentPixel)); 1479 img.transparentPixel = newPalette.getPixel(palette.getRGB(i.transparentPixel)); 1483 1480 } 1484 1481 img.maskPad = i.maskPad; … … 1487 1484 img.alphaData = i.alphaData; 1488 1485 i = img; 1489 1486 } 1490 1487 } 1491 1488 1492 1489 /* Construct bitmap info header by hand */ 1493 RGB[] rgbs = i.palette.getRGBs(); 1494 int[] bmi = new int [BITMAPINFOHEADER2.int_sizeof + 1495 (i.palette.isDirect ? 0 : rgbs.length)]; 1490 RGB[] rgbs = i.palette.getRGBs(); 1491 int[] bmi = new int [BITMAPINFOHEADER2.int_sizeof +(i.palette.isDirect ? 0 : rgbs.length)]; 1496 1492 // cbFix 1497 1493 bmi [0] = BITMAPINFOHEADER2.sizeof; … … 1527 1523 bmi [15] = 0; 1528 1524 1529 1525 /* Set the rgb colors into the bitmap info */ 1530 1526 int offset = BITMAPINFOHEADER2.int_sizeof; 1531 1527 if (!i.palette.isDirect) { 1532 1528 for (int j = 0; j < rgbs.length; j++) { 1533 1529 bmi[offset] = (rgbs[j].red << 16) | (rgbs[j].green << 8) | rgbs[j].blue; 1534 1535 1530 offset++; 1531 } 1536 1532 } 1537 1533 … … 1542 1538 */ 1543 1539 int bpl = i.bytesPerLine; 1544 byte[] data = i.data; 1545 int newBpl = (i.scanlinePad != 4 && (bpl % 4 != 0)) ? 1546 bpl + (4 - (bpl % 4)) : 1547 bpl; 1540 byte[] data = i.data; 1541 int newBpl = (i.scanlinePad != 4 && (bpl % 4 != 0)) ? bpl + (4 - (bpl % 4)) : bpl; 1548 1542 byte[] newData = new byte[i.height * newBpl]; 1549 1543 int srcPtr = 0; … … 1556 1550 data = newData; 1557 1551 1558 1559 byte[] maskData = i.maskData; 1552 /* Do the same for the mask if it is an icon */ 1553 byte[] maskData = i.maskData; 1560 1554 if (i.getTransparencyType() == SWT.TRANSPARENCY_MASK) { 1561 1555 bpl = ((i.width + 7) / 8 + (i.maskPad - 1)) / i.maskPad * i.maskPad; 1562 newBpl = (i.maskPad != 4 && (bpl % 4 != 0)) ? 1563 bpl + (4 - (bpl % 4)) : 1564 bpl; 1556 newBpl = (i.maskPad != 4 && (bpl % 4 != 0)) ? bpl + (4 - (bpl % 4)) : bpl; 1565 1557 /* in OS/2 the mask always has double height (for XOR and AND patterns) */ 1566 1558 newData = new byte[i.height * newBpl * 2]; … … 1576 1568 1577 1569 int[] bitmapPS = new int [1]; 1578 int hBitmap = image.createBitmap ( 1579 i.width, i.height, 0, 0, data, bmi, bitmapPS, 0); 1570 int hBitmap = image.createBitmap (i.width, i.height, 0, 0, data, bmi, bitmapPS, 0); 1580 1571 int bmpPS = bitmapPS [0]; 1581 1572 1582 1583 1573 int[] result = null; 1574 if (i.getTransparencyType() == SWT.TRANSPARENCY_MASK) { 1584 1575 /* Create the mask */ 1585 bmi [2] *= 2; 1586 bmi [3] = 0x00010001; 1587 bmi [8] = 0; 1588 int hMask = image.createBitmap ( 1589 i.width, i.height * 2, 1, 1, maskData, bmi, bitmapPS, 0); 1590 OS.GpiSetBitmap (bmpPS, hMask); 1591 /* invert icon mask to get AND mask */ 1592 OS.GpiBitBlt (bmpPS, 0, 2, 1593 new int[] {0, i.height, i.width, i.height * 2}, OS.ROP_DSTINVERT, 0); 1594 /* determine black and white colors */ 1595 int cWhite = OS.CLR_WHITE; 1596 int cBlack = OS.CLR_BLACK; 1597 if (device.hPalette != 0) { 1598 cWhite = 15; 1599 cBlack = 0; 1600 } 1601 /* 1602 * Make the XOR mask by extracting non-zero icon pixels that are out of 1603 * the non-transparent area. 1604 */ 1605 OS.GpiSetColor (bmpPS, cWhite); 1606 OS.GpiSetBackColor (bmpPS, cBlack); 1607 OS.GpiWCBitBlt (bmpPS, hBitmap, 4, 1608 new int[] {0, 0, i.width - 1, i.height - 1, 0, 0, i.width, i.height}, 1609 OS.ROP_SRCCOPY, OS.BBO_IGNORE); 1610 OS.GpiBitBlt (bmpPS, bmpPS, 4, 1611 new int[] {0, 0, i.width, i.height, 0, i.height, i.width, i.height * 2}, 1612 OS.ROP_SRCAND, OS.BBO_IGNORE); 1613 /* 1614 * In OS/2 "inverted" icon pixels (those that invert colors of the 1615 * underlying screen area/bitmap) should be actually in black color 1616 * (not in white like in Windows) because OS/2 uses the separate 1617 * XOR mask (as defined above) which is applied after the AND mask is 1618 * applied and the icon is drawn using OR operation (in Windows the 1619 * AND mask is applied and then the icon is just drawn using XOR 1620 * operation). We should meet this requirement in order to create an 1621 * icon compatible with PM routines and having the same look like in 1622 * Windows -- so we simply invert these pixels. Inverting them also 1623 * gives the identical to Windows look for pixels in the 1624 * transparent area other than black, which can happen if the icon 1625 * has been created manually, not by the standard; however this only 1626 * works when the icon is drawn by SWT (for instance, when it has 1627 * non-standard size or when scaling), when drawn by standard PM 1628 * routines the result is different because of OR operation mentioned 1629 * above. 1630 */ 1631 OS.GpiSetBitmap (bmpPS, hBitmap); 1632 OS.GpiWCBitBlt (bmpPS, hMask, 4, 1633 new int [] {0, 0, i.width - 1, i.height - 1, 0, 0, i.width, i.height}, 1634 OS.ROP_SRCINVERT, OS.BBO_IGNORE); 1635 OS.GpiSetBitmap (bmpPS, 0); 1636 1576 bmi [2] *= 2; 1577 bmi [3] = 0x00010001; 1578 bmi [8] = 2; 1579 int hMask = image.createBitmap (i.width, i.height * 2, 1, 1, maskData, bmi, bitmapPS, 0); 1580 OS.GpiSetBitmap (bmpPS, hMask); 1581 /* invert icon mask to get AND mask */ 1582 OS.GpiBitBlt (bmpPS, 0, 2, new int[] {0, i.height, i.width, i.height * 2}, OS.ROP_DSTINVERT, 0); 1583 /* determine black and white colors */ 1584 int cWhite = OS.CLR_WHITE; 1585 int cBlack = OS.CLR_BLACK; 1586 if (device.hPalette != 0) { 1587 cWhite = 15; 1588 cBlack = 0; 1589 } 1590 /* 1591 * Make the XOR mask by extracting non-zero icon pixels that are out of 1592 * the non-transparent area. 1593 */ 1594 OS.GpiSetColor (bmpPS, cWhite); 1595 OS.GpiSetBackColor (bmpPS, cBlack); 1596 OS.GpiWCBitBlt (bmpPS, hBitmap, 4, new int[] {0, 0, i.width - 1, i.height - 1, 0, 0, i.width, i.height}, OS.ROP_SRCCOPY, OS.BBO_IGNORE); 1597 OS.GpiBitBlt (bmpPS, bmpPS, 4, new int[] {0, 0, i.width, i.height, 0, i.height, i.width, i.height * 2}, OS.ROP_SRCAND, OS.BBO_IGNORE); 1598 /* 1599 * In OS/2 "inverted" icon pixels (those that invert colors of the 1600 * underlying screen area/bitmap) should be actually in black color 1601 * (not in white like in Windows) because OS/2 uses the separate 1602 * XOR mask (as defined above) which is applied after the AND mask is 1603 * applied and the icon is drawn using OR operation (in Windows the 1604 * AND mask is applied and then the icon is just drawn using XOR 1605 * operation). We should meet this requirement in order to create an 1606 * icon compatible with PM routines and having the same look like in 1607 * Windows -- so we simply invert these pixels. Inverting them also 1608 * gives the identical to Windows look for pixels in the 1609 * transparent area other than black, which can happen if the icon 1610 * has been created manually, not by the standard; however this only 1611 * works when the icon is drawn by SWT (for instance, when it has 1612 * non-standard size or when scaling), when drawn by standard PM 1613 * routines the result is different because of OR operation mentioned 1614 * above. 1615 */ 1616 OS.GpiSetBitmap (bmpPS, hBitmap); 1617 OS.GpiWCBitBlt (bmpPS, hMask, 4, new int [] {0, 0, i.width - 1, i.height - 1, 0, 0, i.width, i.height}, OS.ROP_SRCINVERT, OS.BBO_IGNORE); 1618 OS.GpiSetBitmap (bmpPS, 0); 1637 1619 if (image == null) { 1638 1620 result = new int[] {hBitmap, hMask}; 1639 1621 } else { 1640 1622 /* Create the icon */ 1641 int sysIconWidth = OS.WinQuerySysValue (OS.HWND_DESKTOP, OS.SV_CXICON); 1642 int sysIconHeight = OS.WinQuerySysValue (OS.HWND_DESKTOP, OS.SV_CYICON); 1643 int sysPtrWidth = OS.WinQuerySysValue (OS.HWND_DESKTOP, OS.SV_CXPOINTER); 1644 int sysPtrHeight = OS.WinQuerySysValue (OS.HWND_DESKTOP, OS.SV_CYPOINTER); 1645 int fPointer = -1; 1646 /* 1647 * Bug in OS/2. When we query bitmap data from the bitmap handle that 1648 * is a part of an icon or pointer (i.e. it is obtained via the 1649 * WinQueryPointerInfo() call) OS/2 always returns the bitmap converted 1650 * to match the default system palette corresponding the icon's color 1651 * depth (so the "true" bitmap palette and bits used to create the icon 1652 * are lost). As a temporary solution the code below is commented 1653 * which prevents usage of OS/2 icons (pointers) at all -- every icon 1654 * in SWT just becomes a pair of bitmaps that are handled manually 1655 * by SWT drawing routines. 1656 * 1657 * @@TODO (dmik): make it permanent? 1658 */ 1659 // if (i.width == sysIconWidth && i.height == sysIconHeight) fPointer = 0; 1660 // else if (i.width == sysPtrWidth && i.height == sysPtrHeight) fPointer = 1; 1661 if (fPointer >= 0) { 1662 POINTERINFO info = new POINTERINFO(); 1663 info.fPointer = fPointer; 1664 info.hbmColor = hBitmap; 1665 info.hbmPointer = hMask; 1666 int hIcon = OS.WinCreatePointerIndirect (OS.HWND_DESKTOP, info); 1667 if (hIcon == 0) SWT.error(SWT.ERROR_NO_HANDLES); 1668 OS.GpiDeleteBitmap (hBitmap); 1669 OS.GpiDeleteBitmap (hMask); 1670 image.handle = hIcon; 1671 } else { 1672 image.handle = hBitmap; 1673 image.maskHandle = hMask; 1674 } 1675 image.type = SWT.ICON; 1623 int sysIconWidth = OS.WinQuerySysValue (OS.HWND_DESKTOP, OS.SV_CXICON); 1624 int sysIconHeight = OS.WinQuerySysValue (OS.HWND_DESKTOP, OS.SV_CYICON); 1625 int sysPtrWidth = OS.WinQuerySysValue (OS.HWND_DESKTOP, OS.SV_CXPOINTER); 1626 int sysPtrHeight = OS.WinQuerySysValue (OS.HWND_DESKTOP, OS.SV_CYPOINTER); 1627 int fPointer = -1; 1628 /* 1629 * Bug in OS/2. When we query bitmap data from the bitmap handle that 1630 * is a part of an icon or pointer (i.e. it is obtained via the 1631 * WinQueryPointerInfo() call) OS/2 always returns the bitmap converted 1632 * to match the default system palette corresponding the icon's color 1633 * depth (so the "true" bitmap palette and bits used to create the icon 1634 * are lost). As a temporary solution the code below is commented 1635 * which prevents usage of OS/2 icons (pointers) at all -- every icon 1636 * in SWT just becomes a pair of bitmaps that are handled manually 1637 * by SWT drawing routines. 1638 * 1639 * @@TODO (dmik): make it permanent? 1640 */ 1641 if (i.width == sysIconWidth) fPointer = 0; 1642 else if (i.width == sysPtrWidth) fPointer = 1; 1643 // @@TODO (lpino): Remove if not necessary in the future 1644 /* boolean isMini = false; 1645 boolean needCenter = false; 1646 switch(i.width){ 1647 case 16: 1648 isMini = true; 1649 needCenter = true; 1650 break; 1651 case 20: 1652 isMini = true; 1653 break; 1654 case 32: 1655 needCenter = true; 1656 break; 1657 case 40: 1658 break; 1659 } 1660 */ if (fPointer >= 0) { 1661 POINTERINFO info = new POINTERINFO(); 1662 info.fPointer = fPointer; 1663 info.hbmColor = hBitmap; 1664 info.hbmPointer = hMask; 1665 info.hbmMiniPointer = 0; 1666 info.hbmMiniColor = 0; 1667 int hIcon = OS.WinCreatePointerIndirect (OS.HWND_DESKTOP, info); 1668 if (hIcon == 0) SWT.error(SWT.ERROR_NO_HANDLES); 1669 OS.GpiDeleteBitmap (hBitmap); 1670 OS.GpiDeleteBitmap (hMask); 1671 image.handle = hIcon; 1672 } else { 1673 image.handle = hBitmap; 1674 image.maskHandle = hMask; 1675 } 1676 image.type = SWT.ICON; 1676 1677 } 1677 1678 } else { 1678 1679 if (image == null) { 1679 1680 result = new int[] {hBitmap}; 1680 1681 } else { 1681 1682 image.handle = hBitmap; 1682 1683 image.type = SWT.BITMAP; 1683 1684 image.transparentPixel = i.transparentPixel; … … 1958 1959 } 1959 1960 1960 } 1961 private String getBits(int value){ 1962 int displayMask = 1 << 31; 1963 StringBuffer buf = new StringBuffer(35); 1964 for(int c= 1; c<=32; c++){ 1965 buf.append((value & displayMask) == 0 ? '0' : '1' ); 1966 value <<=1; 1967 if(c %8 == 0) 1968 buf.append(' '); 1969 } 1970 return buf.toString(); 1971 } 1972 1973 }
Note:
See TracChangeset
for help on using the changeset viewer.