📄 gc.java
字号:
rect = rect.intersection(new Rectangle(destX, destY, destWidth, destHeight)); if (rect.isEmpty()) return; /* * Optimization. Recalculate src and dest rectangles so that * only the clipping area is drawn. */ int sx1 = srcX + (((rect.x - destX) * srcWidth) / destWidth); int sx2 = srcX + ((((rect.x + rect.width) - destX) * srcWidth) / destWidth); int sy1 = srcY + (((rect.y - destY) * srcHeight) / destHeight); int sy2 = srcY + ((((rect.y + rect.height) - destY) * srcHeight) / destHeight); destX = rect.x; destY = rect.y; destWidth = rect.width; destHeight = rect.height; srcX = sx1; srcY = sy1; srcWidth = Math.max(1, sx2 - sx1); srcHeight = Math.max(1, sy2 - sy1); /* Create resources */ int srcHdc = OS.CreateCompatibleDC(handle); int oldSrcBitmap = OS.SelectObject(srcHdc, srcImage.handle); int memHdc = OS.CreateCompatibleDC(handle); int memDib = createDIB(Math.max(srcWidth, destWidth), Math.max(srcHeight, destHeight)); int oldMemBitmap = OS.SelectObject(memHdc, memDib); BITMAP dibBM = new BITMAP(); OS.GetObject(memDib, BITMAP.sizeof, dibBM); int sizeInBytes = dibBM.bmWidthBytes * dibBM.bmHeight; /* Get the background pixels */ OS.BitBlt(memHdc, 0, 0, destWidth, destHeight, handle, destX, destY, OS.SRCCOPY); byte[] destData = new byte[sizeInBytes]; OS.MoveMemory(destData, dibBM.bmBits, sizeInBytes); /* Get the foreground pixels */ OS.BitBlt(memHdc, 0, 0, srcWidth, srcHeight, srcHdc, srcX, srcY, OS.SRCCOPY); byte[] srcData = new byte[sizeInBytes]; OS.MoveMemory(srcData, dibBM.bmBits, sizeInBytes); /* Merge the alpha channel in place */ int alpha = srcImage.alpha; final boolean hasAlphaChannel = (srcImage.alpha == -1); if (hasAlphaChannel) { final int apinc = imgWidth - srcWidth; final int spinc = dibBM.bmWidthBytes - srcWidth * 4; int ap = srcY * imgWidth + srcX, sp = 3; byte[] alphaData = srcImage.alphaData; for (int y = 0; y < srcHeight; ++y) { for (int x = 0; x < srcWidth; ++x) { srcData[sp] = alphaData[ap++]; sp += 4; } ap += apinc; sp += spinc; } } /* Scale the foreground pixels with alpha */ OS.MoveMemory(dibBM.bmBits, srcData, sizeInBytes); /* * Bug in WinCE and Win98. StretchBlt does not correctly stretch when * the source and destination HDCs are the same. The workaround is to * stretch to a temporary HDC and blit back into the original HDC. * Note that on WinCE StretchBlt correctly compresses the image when the * source and destination HDCs are the same. */ if ((OS.IsWinCE && (destWidth > srcWidth || destHeight > srcHeight)) || (!OS.IsWinNT && !OS.IsWinCE)) { int tempHdc = OS.CreateCompatibleDC(handle); int tempDib = createDIB(destWidth, destHeight); int oldTempBitmap = OS.SelectObject(tempHdc, tempDib); if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) { if (!OS.IsWinCE) OS.SetStretchBltMode(memHdc, OS.COLORONCOLOR); OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, srcWidth, srcHeight, OS.SRCCOPY); } else { OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, OS.SRCCOPY); } OS.BitBlt(memHdc, 0, 0, destWidth, destHeight, tempHdc, 0, 0, OS.SRCCOPY); OS.SelectObject(tempHdc, oldTempBitmap); OS.DeleteObject(tempDib); OS.DeleteDC(tempHdc); } else { if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) { if (!OS.IsWinCE) OS.SetStretchBltMode(memHdc, OS.COLORONCOLOR); OS.StretchBlt(memHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, srcWidth, srcHeight, OS.SRCCOPY); } else { OS.BitBlt(memHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, OS.SRCCOPY); } } OS.MoveMemory(srcData, dibBM.bmBits, sizeInBytes); /* Compose the pixels */ final int dpinc = dibBM.bmWidthBytes - destWidth * 4; int dp = 0; for (int y = 0; y < destHeight; ++y) { for (int x = 0; x < destWidth; ++x) { if (hasAlphaChannel) alpha = srcData[dp + 3] & 0xff; destData[dp] += ((srcData[dp] & 0xff) - (destData[dp] & 0xff)) * alpha / 255; destData[dp + 1] += ((srcData[dp + 1] & 0xff) - (destData[dp + 1] & 0xff)) * alpha / 255; destData[dp + 2] += ((srcData[dp + 2] & 0xff) - (destData[dp + 2] & 0xff)) * alpha / 255; dp += 4; } dp += dpinc; } /* Draw the composed pixels */ OS.MoveMemory(dibBM.bmBits, destData, sizeInBytes); OS.BitBlt(handle, destX, destY, destWidth, destHeight, memHdc, 0, 0, OS.SRCCOPY); /* Free resources */ OS.SelectObject(memHdc, oldMemBitmap); OS.DeleteDC(memHdc); OS.DeleteObject(memDib); OS.SelectObject(srcHdc, oldSrcBitmap); OS.DeleteDC(srcHdc);}void drawBitmapTransparentByClipping(int srcHdc, int maskHdc, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, int imgWidth, int imgHeight) { int rgn = OS.CreateRectRgn(0, 0, 0, 0); for (int y=0; y<imgHeight; y++) { for (int x=0; x<imgWidth; x++) { if (OS.GetPixel(maskHdc, x, y) == 0) { int tempRgn = OS.CreateRectRgn(x, y, x+1, y+1); OS.CombineRgn(rgn, rgn, tempRgn, OS.RGN_OR); OS.DeleteObject(tempRgn); } } } OS.OffsetRgn(rgn, destX, destY); int clip = OS.CreateRectRgn(0, 0, 0, 0); int result = OS.GetClipRgn(handle, clip); if (result == 1) OS.CombineRgn(rgn, rgn, clip, OS.RGN_AND); OS.SelectClipRgn(handle, rgn); int rop2 = 0; if (!OS.IsWinCE) { rop2 = OS.GetROP2(handle); } else { rop2 = OS.SetROP2 (handle, OS.R2_COPYPEN); OS.SetROP2 (handle, rop2); } int dwRop = rop2 == OS.R2_XORPEN ? OS.SRCINVERT : OS.SRCCOPY; if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) { int mode = 0; if (!OS.IsWinCE) mode = OS.SetStretchBltMode(handle, OS.COLORONCOLOR); OS.StretchBlt(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, dwRop); if (!OS.IsWinCE) OS.SetStretchBltMode(handle, mode); } else { OS.BitBlt(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, dwRop); } OS.SelectClipRgn(handle, result == 1 ? clip : 0); OS.DeleteObject(clip); OS.DeleteObject(rgn);}void drawBitmapTransparent(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, BITMAP bm, int imgWidth, int imgHeight) { /* Get the HDC for the device */ Device device = data.device; int hDC = device.internal_new_GC(null); /* Find the RGB values for the transparent pixel. */ int transBlue = 0, transGreen = 0, transRed = 0; boolean isDib = bm.bmBits != 0; int hBitmap = srcImage.handle; int srcHdc = OS.CreateCompatibleDC(handle); int oldSrcBitmap = OS.SelectObject(srcHdc, hBitmap); byte[] originalColors = null; if (bm.bmBitsPixel <= 8) { if (isDib) { /* Palette-based DIBSECTION */ if (OS.IsWinCE) { byte[] pBits = new byte[1]; OS.MoveMemory(pBits, bm.bmBits, 1); byte oldValue = pBits[0]; int mask = (0xFF << (8 - bm.bmBitsPixel)) & 0x00FF; pBits[0] = (byte)((srcImage.transparentPixel << (8 - bm.bmBitsPixel)) | (pBits[0] & ~mask)); OS.MoveMemory(bm.bmBits, pBits, 1); int color = OS.GetPixel(srcHdc, 0, 0); pBits[0] = oldValue; OS.MoveMemory(bm.bmBits, pBits, 1); transBlue = (color & 0xFF0000) >> 16; transGreen = (color & 0xFF00) >> 8; transRed = color & 0xFF; } else { int maxColors = 1 << bm.bmBitsPixel; byte[] oldColors = new byte[maxColors * 4]; OS.GetDIBColorTable(srcHdc, 0, maxColors, oldColors); int offset = srcImage.transparentPixel * 4; byte[] newColors = new byte[oldColors.length]; transRed = transGreen = transBlue = 0xff; newColors[offset] = (byte)transBlue; newColors[offset+1] = (byte)transGreen; newColors[offset+2] = (byte)transRed; OS.SetDIBColorTable(srcHdc, 0, maxColors, newColors); originalColors = oldColors; } } else { /* Palette-based bitmap */ int numColors = 1 << bm.bmBitsPixel; /* Set the few fields necessary to get the RGB data out */ BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER(); bmiHeader.biSize = BITMAPINFOHEADER.sizeof; bmiHeader.biPlanes = bm.bmPlanes; bmiHeader.biBitCount = bm.bmBitsPixel; byte[] bmi = new byte[BITMAPINFOHEADER.sizeof + numColors * 4]; OS.MoveMemory(bmi, bmiHeader, BITMAPINFOHEADER.sizeof); if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); OS.GetDIBits(srcHdc, srcImage.handle, 0, 0, 0, bmi, OS.DIB_RGB_COLORS); int offset = BITMAPINFOHEADER.sizeof + 4 * srcImage.transparentPixel; transRed = bmi[offset + 2] & 0xFF; transGreen = bmi[offset + 1] & 0xFF; transBlue = bmi[offset] & 0xFF; } } else { /* Direct color image */ int pixel = srcImage.transparentPixel; switch (bm.bmBitsPixel) { case 16: transBlue = (pixel & 0x1F) << 3; transGreen = (pixel & 0x3E0) >> 2; transRed = (pixel & 0x7C00) >> 7; break; case 24: transBlue = (pixel & 0xFF0000) >> 16; transGreen = (pixel & 0xFF00) >> 8; transRed = pixel & 0xFF; break; case 32: transBlue = (pixel & 0xFF000000) >>> 24; transGreen = (pixel & 0xFF0000) >> 16; transRed = (pixel & 0xFF00) >> 8; break; } } if (OS.IsWinCE) { /* * Note in WinCE. TransparentImage uses the first entry of a palette * based image when there are multiple entries that have the same * transparent color. */ int transparentColor = transBlue << 16 | transGreen << 8 | transRed; OS.TransparentImage(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, transparentColor); } else { /* Create the mask for the source image */ int maskHdc = OS.CreateCompatibleDC(hDC); int maskBitmap = OS.CreateBitmap(imgWidth, imgHeight, 1, 1, null); int oldMaskBitmap = OS.SelectObject(maskHdc, maskBitmap); OS.SetBkColor(srcHdc, (transBlue << 16) | (transGreen << 8) | transRed); OS.BitBlt(maskHdc, 0, 0, imgWidth, imgHeight, srcHdc, 0, 0, OS.SRCCOPY); if (originalColors != null) OS.SetDIBColorTable(srcHdc, 0, 1 << bm.bmBitsPixel, originalColors); if (OS.GetDeviceCaps(handle, OS.TECHNOLOGY) == OS.DT_RASPRINTER) { /* Most printers do not support BitBlt(), draw the source bitmap transparently using clipping */ drawBitmapTransparentByClipping(srcHdc, maskHdc, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, imgWidth, imgHeight); } else { /* Draw the source bitmap transparently using invert/and mask/invert */ int tempHdc = OS.CreateCompatibleDC(hDC); int tempBitmap = OS.CreateCompatibleBitmap(hDC, destWidth, destHeight); int oldTempBitmap = OS.SelectObject(tempHdc, tempBitmap); OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, handle, destX, destY, OS.SRCCOPY); if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) { if (!OS.IsWinCE) OS.SetStretchBltMode(tempHdc, OS.COLORONCOLOR); OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCINVERT); OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, maskHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCAND); OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCINVERT); } else { OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, OS.SRCINVERT); OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, maskHdc, srcX, srcY, OS.SRCAND); OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, OS.SRCINVERT); } OS.BitBlt(handle, destX, destY, destWidth, destHeight, tempHdc, 0, 0, OS.SRCCOPY); OS.SelectObject(tempHdc, oldTempBitmap); OS.DeleteDC(tempHdc); OS.DeleteObject(tempBitmap); } OS.SelectObject(maskHdc, oldMaskBitmap); OS.DeleteDC(maskHdc); OS.DeleteObject(maskBitmap); } OS.SelectObject(srcHdc, oldSrcBitmap); if (hBitmap != srcImage.handle) OS.DeleteObject(hBitmap); OS.DeleteDC(srcHdc); /* Release the HDC for the device */ device.internal_dispose_GC(hDC, null);}void drawBitmap(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, BITMAP bm, int imgWidth, int imgHeight) { int srcHdc = OS.CreateCompatibleDC(handle); int oldSrcBitmap = OS.SelectObject(srcHdc, srcImage.handle); int rop2 = 0; if (!OS.IsWinCE) { rop2 = OS.GetROP2(handle); } else { rop2 = OS.SetROP2 (handle, OS.R2_COPYPEN); OS.SetROP2 (handle, rop2); } int dwRop = rop2 == OS.R2_XORPEN ? OS.SRCINVERT : OS.SRCCOPY; if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) { int mode = 0; if (!OS.IsWinCE) mode = OS.SetStretchBltMode(handle, OS.COLORONCOLOR); OS.StretchBlt(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, dwRop); if (!OS.IsWinCE) OS.SetStretchBltMode(handle, mode); } else { OS.BitBlt(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, dwRop); } OS.SelectObject(srcHdc, oldSrcBitmap); OS.DeleteDC(srcHdc);}/** * Draws a line, using the foreground color, between the points * (<code>x1</code>, <code>y1</code>) and (<code>x2</code>, <code>y2</code>). * * @param x1 the first point's x coordinate * @param y1 the first point's y coordinate * @param x2 the second point's x coordinate * @param y2 the second point's y coordinate * * @exception SWTException <ul> * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> * </ul> */public void drawLine (int x1, int y1, int x2, int y2) { if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); if (OS.IsWinCE) { int [] points = new int [] {x1, y1, x2, y2}; OS.Polyline (handle, points, points.length / 2); } else { OS.MoveToEx (handle, x1, y1, 0); OS.LineTo (handle, x2, y2); } OS.SetPixel (handle, x2, y2, OS.GetTextColor (handle));}/** * Draws the outline of an oval, using the foreground color, * within the specified rectangular area. * <p> * The result is a circle or ellipse that fits within the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -