📄 udsimnt.c
字号:
WIN_HBITMAP hTempBitmap; WIN_HBITMAP hOldBitmap = NULL; WIN_BITMAPINFO * pBitmapInfo; void * pInitData = UGL_NULL; void * pTmpData = UGL_NULL; /* get destination bitmap */ if (pDdb == (UGL_SIMNT_DDB *)UGL_DEFAULT_ID) pDdb = (UGL_SIMNT_DDB *)gc->pDefaultBitmap; if (pDdb == (UGL_SIMNT_DDB *)UGL_DISPLAY_ID) pDdb = (UGL_SIMNT_DDB *)pDriver->generic.pDrawPage->pDdb; /* allocate a Windows BITMAPINFO structure */ if (pDib->imageFormat == UGL_DIRECT && (pUgiDriver->pMode->flags & UGL_MODE_DIRECT_COLOR) != 0) { pBitmapInfo = UGL_MALLOC (sizeof (WIN_BITMAPINFO) + 3 * sizeof (UGL_UINT32)); } else { if (pDib->imageFormat == UGL_DIRECT) clutSize = 1 << pUgiDriver->pMode->colorDepth; else clutSize = pDib->clutSize; pBitmapInfo = UGL_MALLOC (sizeof (WIN_BITMAPINFO) + clutSize * sizeof (WIN_RGBQUAD)); } if (pBitmapInfo == UGL_NULL) return (UGL_STATUS_ERROR); /* initialize the shared portion of the bitmap info structure */ pBitmapInfo->bmiHeader.biSize = sizeof (WIN_BITMAPINFOHEADER); pBitmapInfo->bmiHeader.biWidth = pDib->width; pBitmapInfo->bmiHeader.biHeight = -pDib->height; pBitmapInfo->bmiHeader.biPlanes = 1; pBitmapInfo->bmiHeader.biSizeImage = 0; pBitmapInfo->bmiHeader.biXPelsPerMeter = 0; pBitmapInfo->bmiHeader.biYPelsPerMeter = 0; pBitmapInfo->bmiHeader.biClrUsed = clutSize; pBitmapInfo->bmiHeader.biClrImportant = 0; /* initialize bitmap data */ if (pDib->imageFormat == UGL_DIRECT) { /* DIB structure has no CLUT */ if (pDib->colorFormat == UGL_DEVICE_COLOR_32 && pUgiDriver->pMode->flags & UGL_MODE_INDEXED_COLOR) { int i; int x, y; int winStride = (pDib->width + 3) / 4 * 4; UGL_UINT32 * pSrc; UGL_UINT8 * pDst; /* allocate temporary buffer for bitmap data */ pTmpData = UGL_MALLOC (pDib->height * winStride); if (pTmpData == UGL_NULL) { UGL_FREE (pBitmapInfo); return (UGL_NULL); } /* convert 32-bit DIB data to 8-bit index data */ pSrc = (UGL_UINT32 *)pDib->pImage; pDst = (UGL_UINT8 *)pTmpData; for (y = 0; y < pDib->height; y++) { for (x = 0; x < pDib->width; x++) pDst[x] = (UGL_UINT8)pSrc[x]; pSrc += pDib->stride; pDst += winStride; } /* get CLUT */ (*pUgiDriver->clutGet) (pUgiDriver, 0, (UGL_ARGB *)pBitmapInfo->bmiColors, clutSize); /* convert CLUT to Windows format */ for (i = 0; i < clutSize; i++) pBitmapInfo->bmiColors [i].rgbReserved = 0; /* setup initialization data */ pInitData = pTmpData; pBitmapInfo->bmiHeader.biBitCount = 8; pBitmapInfo->bmiHeader.biCompression = WIN_BI_RGB; } else { int bitsPerPixel = 0; int winStride; switch (pDib->colorFormat) { case UGL_DEVICE_COLOR_32: bitsPerPixel = 32; break; case UGL_ARGB8888: bitsPerPixel = 32; break; case UGL_DEVICE_COLOR: bitsPerPixel = 16; break; case UGL_RGB565: bitsPerPixel = 16; break; } if (bitsPerPixel == 16) winStride = (pDib->width + 1) / 2 * 2; else winStride = pDib->width; if (pDib->stride != winStride) { char * pSrc; char * pDst; int y; pTmpData = UGL_MALLOC (pDib->height * winStride * bitsPerPixel / 8); if (pTmpData == UGL_NULL) { UGL_FREE (pBitmapInfo); return (UGL_NULL); } pSrc = (char *)pDib->pImage; pDst = (char *)pTmpData; /* Copy relevant dib data */ for (y = 0; y < pDib->height; y++) { bcopy (pSrc, pDst, pDib->width * bitsPerPixel / 8); pSrc += pDib->stride * bitsPerPixel / 8; pDst += winStride * bitsPerPixel / 8; } pInitData = pTmpData; } else pInitData = pDib->pImage; pBitmapInfo->bmiHeader.biBitCount = bitsPerPixel; pBitmapInfo->bmiHeader.biCompression = WIN_BI_BITFIELDS; if (bitsPerPixel == 16 || pDib->colorFormat == UGL_DEVICE_COLOR_32) { ((UGL_UINT32 *)pBitmapInfo->bmiColors) [0] = 0x0000F800; ((UGL_UINT32 *)pBitmapInfo->bmiColors) [1] = 0x000007E0; ((UGL_UINT32 *)pBitmapInfo->bmiColors) [2] = 0x0000001F; } else { ((UGL_UINT32 *)pBitmapInfo->bmiColors) [0] = 0x00FF0000; ((UGL_UINT32 *)pBitmapInfo->bmiColors) [1] = 0x0000FF00; ((UGL_UINT32 *)pBitmapInfo->bmiColors) [2] = 0x000000FF; } } } else /* DIB structure has a CLUT */ { int sourceStride; int destStride; int i; /* copy clut into BITMAPINFO structure */ (*pDriver->generic.ugi.colorConvert) ((UGL_UGI_DRIVER *)pDriver, pDib->pClut, pDib->colorFormat, pBitmapInfo->bmiColors, UGL_ARGB8888, pDib->clutSize); /* mask off alpha channel */ for (i = 0; i < pDib->clutSize; i++) ((UGL_UINT32 *)pBitmapInfo->bmiColors) [i] &= 0x00FFFFFF; /* setup initialization data */ pBitmapInfo->bmiHeader.biBitCount = pDib->imageFormat & UGL_DIB_INDEX_MASK; pBitmapInfo->bmiHeader.biCompression = WIN_BI_RGB; /* * !WARNING! * * Byte alignment in DIB is assumed. */ sourceStride = (pDib->stride * pBitmapInfo->bmiHeader.biBitCount + 7) / 8; /* Windows requires "LONG" alignment */ destStride = (pDib->width * pBitmapInfo->bmiHeader.biBitCount + sizeof (WIN_LONG) * 8 - 1) / (sizeof (WIN_LONG) * 8) * sizeof (WIN_LONG); if (sourceStride != destStride) { int i; int lineSize; UGL_UINT8 * pSource; UGL_UINT8 * pDest; /* bitmap must be aligned to WORD boundary */ pTmpData = UGL_MALLOC (pDib->height * destStride); if (pTmpData == UGL_NULL) { UGL_FREE (pBitmapInfo); return (UGL_NULL); } pSource = (UGL_UINT8 *)pDib->pImage; pDest = (UGL_UINT8 *)pTmpData; lineSize = (pDib->width * pBitmapInfo->bmiHeader.biBitCount + 7) / 8; for (i = 0; i < pDib->height; i++) { memcpy (pDest, pSource, lineSize); pSource += sourceStride; pDest += destStride; } pInitData = pTmpData; } else pInitData = pDib->pImage; } /* create a temporary Windows bitmap and device context */ key = intLock (); hTempBitmap = win_CreateDIBitmap (pDriver->hScreenDc, &pBitmapInfo->bmiHeader, WIN_CBM_INIT, pInitData, pBitmapInfo, WIN_DIB_RGB_COLORS); hTempDc = win_CreateCompatibleDC (pDriver->hScreenDc); win_SelectObject (hTempDc, hTempBitmap); /* set up destination device context */ if (pDdb == pDriver->pDrawDdb) { hDstDc = pDriver->hDrawDc; win_SelectClipRgn (pDriver->hDrawDc, NULL); } else { hDstDc = pDriver->hExtraDc; hOldBitmap = win_SelectObject (hDstDc, pDdb->hBitmap); } /* Write the bitmap data by performing a bitblt */ win_BitBlt (hDstDc, pDstPoint->x, pDstPoint->y, UGL_RECT_WIDTH (*pSrcRect), UGL_RECT_HEIGHT (*pSrcRect), hTempDc, pSrcRect->left, pSrcRect->top, WIN_SRCCOPY); /* update the display */ if (pDdb == (UGL_SIMNT_DDB *)pDriver->generic.pVisiblePage->pDdb) { win_SelectClipRgn (pDriver->hScreenDc, NULL); win_BitBlt (pDriver->hScreenDc, pDstPoint->x, pDstPoint->y, UGL_RECT_WIDTH (*pSrcRect), UGL_RECT_HEIGHT (*pSrcRect), hTempDc, pSrcRect->left, pSrcRect->top, WIN_SRCCOPY); win_SelectClipRgn (pDriver->hScreenDc, pDriver->hClipRegion); } /* restore destination device context */ if (pDdb == pDriver->pDrawDdb) win_SelectClipRgn (pDriver->hDrawDc, pDriver->hClipRegion); else win_SelectObject (hDstDc, hOldBitmap); /* clean up */ win_DeleteDC (hTempDc); win_DeleteObject (hTempBitmap); intUnlock (key); if (pTmpData != UGL_NULL) UGL_FREE (pInitData); UGL_FREE (pBitmapInfo); return (UGL_STATUS_OK); }/***************************************************************************** uglSimPcBitmapBlt - bit-block transfer a bitmap**/UGL_STATUS uglSimPcBitmapBlt ( UGL_UGI_DRIVER * pUgiDriver, UGL_DDB * pUgiSrcDdb, UGL_RECT * pSrcRect, UGL_DDB * pUgiDstDdb, UGL_POINT * pDstPoint ) { UGL_SIMNT_DRIVER * pDriver = (UGL_SIMNT_DRIVER *)pUgiDriver; UGL_SIMNT_DDB * pSrcDdb = (UGL_SIMNT_DDB *)pUgiSrcDdb; UGL_SIMNT_DDB * pDstDdb = (UGL_SIMNT_DDB *)pUgiDstDdb; UGL_GC * gc = pDriver->generic.gc; WIN_HDC hSrcDc; WIN_HDC hDstDc; WIN_HBITMAP hOldSrcBitmap = NULL; WIN_HBITMAP hOldDstBitmap = NULL; WIN_DWORD rop = 0; /* get source bitmap */ if (pSrcDdb == (UGL_SIMNT_DDB *)UGL_DEFAULT_ID) { pSrcDdb = (UGL_SIMNT_DDB *)gc->pDefaultBitmap; UGL_RECT_MOVE (*pSrcRect, gc->viewPort.left, gc->viewPort.top); } if (pSrcDdb == (UGL_SIMNT_DDB *)UGL_DISPLAY_ID) pSrcDdb = (UGL_SIMNT_DDB *)pDriver->generic.pDrawPage->pDdb; /* get destination bitmap */ if (pDstDdb == (UGL_SIMNT_DDB *)UGL_DEFAULT_ID) { pDstDdb = (UGL_SIMNT_DDB *)gc->pDefaultBitmap; UGL_POINT_MOVE (*pDstPoint, gc->viewPort.left, gc->viewPort.top); } if (pDstDdb == (UGL_SIMNT_DDB *)UGL_DISPLAY_ID) pDstDdb = (UGL_SIMNT_DDB *)pDriver->generic.pDrawPage->pDdb; /* set raster operation */ if (gc->rasterOp == UGL_RASTER_OP_COPY) rop = WIN_SRCCOPY; else if (gc->rasterOp == UGL_RASTER_OP_XOR) rop = WIN_SRCINVERT; else if (gc->rasterOp == UGL_RASTER_OP_AND) rop = WIN_SRCAND; else if (gc->rasterOp == UGL_RASTER_OP_OR) rop = WIN_SRCPAINT; /* protect device contexts used in WM_PAINT */ key = intLock (); win_EnterCriticalSection (&criticalSection); /* setup destination device context */ if (pDstDdb == pDriver->pDrawDdb) { hDstDc = pDriver->hDrawDc; /* remove clipping because GC bitmap not used */ if (pUgiDstDdb != UGL_DEFAULT_ID) { win_SelectClipRgn (hDstDc, NULL); } } else { hDstDc = pDriver->hBltDc; hOldDstBitmap = win_SelectObject (hDstDc, pDstDdb->hBitmap); } /* setup source device context */ if (pSrcDdb == pDriver->pDrawDdb) hSrcDc = pDriver->hDrawDc; else { hSrcDc = pDriver->hExtraDc; hOldSrcBitmap = win_SelectObject (hSrcDc, pSrcDdb->hBitmap); } /* perform the bitblt */ win_BitBlt (hDstDc, pDstPoint->x, pDstPoint->y, UGL_RECT_WIDTH (*pSrcRect), UGL_RECT_HEIGHT (*pSrcRect), hSrcDc, pSrcRect->left, pSrcRect->top, rop); intUnlock (key); /* update the display */ if (pDstDdb == (UGL_SIMNT_DDB *)pDriver->generic.pVisiblePage->pDdb) { key = intLock (); win_SelectClipRgn (pDriver->hScreenDc, NULL); win_BitBlt (pDriver->hScreenDc, pDstPoint->x, pDstPoint->y, UGL_RECT_WIDTH (*pSrcRect), UGL_RECT_HEIGHT (*pSrcRect), hDstDc, pDstPoint->x, pDstPoint->y, WIN_SRCCOPY); win_SelectClipRgn (pDriver->hScreenDc, pDriver->hClipRegion); intUnlock (key); } /* restore device contexts */ key = intLock (); if (pDstDdb != pDriver->pDrawDdb) win_SelectObject (hDstDc, hOldDstBitmap); else if (pUgiDstDdb != UGL_DEFAULT_ID) win_SelectClipRgn (hDstDc, pDriver->hClipRegion); if (pSrcDdb != pDriver->pDrawDdb) win_SelectObject (hSrcDc, hOldSrcBitmap); win_LeaveCriticalSection (&criticalSection); intUnlock (key); return (UGL_STATUS_OK); }/***************************************************************************** uglSimPcBitm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -