/** * @brief Fill an area with a bitmap. * @note Optional - The high level driver can emulate using software. * * @param[in] x, y The start filled area * @param[in] cx, cy The width and height to be filled * @param[in] srcx, srcy The bitmap position to start the fill from * @param[in] srccx The width of a line in the bitmap. * @param[in] buffer The pixels to use to fill the area. * * @notapi */ void GDISP_LLD(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { BITMAPV4HEADER bmpInfo; RECT rect; #if GDISP_NEED_CONTROL pixel_t *srcimg; #endif #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP // Clip pre orientation change if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; } if (srcx+cx > srccx) cx = srccx - srcx; if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x; if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif // Make everything relative to the start of the line buffer += srccx*srcy; srcy = 0; memset(&bmpInfo, 0, sizeof(bmpInfo)); bmpInfo.bV4Size = sizeof(bmpInfo); bmpInfo.bV4Planes = 1; bmpInfo.bV4BitCount = 32; bmpInfo.bV4AlphaMask = 0; bmpInfo.bV4RedMask = RGB2COLOR(255,0,0); bmpInfo.bV4GreenMask = RGB2COLOR(0,255,0); bmpInfo.bV4BlueMask = RGB2COLOR(0,0,255); bmpInfo.bV4V4Compression = BI_BITFIELDS; bmpInfo.bV4XPelsPerMeter = 3078; bmpInfo.bV4YPelsPerMeter = 3078; bmpInfo.bV4ClrUsed = 0; bmpInfo.bV4ClrImportant = 0; bmpInfo.bV4CSType = 0; //LCS_sRGB; #if GDISP_NEED_CONTROL bmpInfo.bV4SizeImage = (cy*cx) * sizeof(pixel_t); srcimg = rotateimg(cx, cy, srcx, srccx, buffer); if (!srcimg) return; switch(GDISP.Orientation) { case GDISP_ROTATE_0: bmpInfo.bV4Width = cx; bmpInfo.bV4Height = -cy; /* top-down image */ rect.top = y; rect.bottom = rect.top+cy; rect.left = x; rect.right = rect.left+cx; break; case GDISP_ROTATE_90: bmpInfo.bV4Width = cy; bmpInfo.bV4Height = -cx; /* top-down image */ rect.top = x; rect.bottom = rect.top+cx; rect.right = GDISP.Height - y; rect.left = rect.right-cy; break; case GDISP_ROTATE_180: bmpInfo.bV4Width = cx; bmpInfo.bV4Height = -cy; /* top-down image */ rect.bottom = GDISP.Height - y; rect.top = rect.bottom-cy; rect.right = GDISP.Width - x; rect.left = rect.right-cx; break; case GDISP_ROTATE_270: bmpInfo.bV4Width = cy; bmpInfo.bV4Height = -cx; /* top-down image */ rect.bottom = GDISP.Width - x; rect.top = rect.bottom-cx; rect.left = y; rect.right = rect.left+cy; break; } SetDIBitsToDevice(dcBuffer, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, srcimg, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS); if (srcimg != (pixel_t *)buffer) free(srcimg); #else bmpInfo.bV4Width = srccx; bmpInfo.bV4Height = -cy; /* top-down image */ bmpInfo.bV4SizeImage = (cy*srccx) * sizeof(pixel_t); rect.top = y; rect.bottom = rect.top+cy; rect.left = x; rect.right = rect.left+cx; SetDIBitsToDevice(dcBuffer, x, y, cx, cy, srcx, 0, 0, cy, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS); #endif // Invalidate the region to get it on the screen. InvalidateRect(winRootWindow, &rect, FALSE); UpdateWindow(winRootWindow); }
LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { winPriv * priv; pixel_t * buffer; RECT rect; BITMAPV4HEADER bmpInfo; // Make everything relative to the start of the line priv = g->priv; buffer = g->p.ptr; buffer += g->p.x2*g->p.y1; memset(&bmpInfo, 0, sizeof(bmpInfo)); bmpInfo.bV4Size = sizeof(bmpInfo); bmpInfo.bV4Planes = 1; bmpInfo.bV4BitCount = COLOR_TYPE_BITS; bmpInfo.bV4AlphaMask = 0; bmpInfo.bV4RedMask = RGB2COLOR(255,0,0); bmpInfo.bV4GreenMask = RGB2COLOR(0,255,0); bmpInfo.bV4BlueMask = RGB2COLOR(0,0,255); bmpInfo.bV4V4Compression = BI_BITFIELDS; bmpInfo.bV4XPelsPerMeter = 3078; bmpInfo.bV4YPelsPerMeter = 3078; bmpInfo.bV4ClrUsed = 0; bmpInfo.bV4ClrImportant = 0; bmpInfo.bV4CSType = 0; //LCS_sRGB; #if GDISP_NEED_CONTROL switch(g->g.Orientation) { case GDISP_ROTATE_0: default: bmpInfo.bV4SizeImage = (g->p.cy*g->p.x2) * sizeof(pixel_t); bmpInfo.bV4Width = g->p.x2; bmpInfo.bV4Height = -g->p.cy; /* top-down image */ rect.top = g->p.y; rect.bottom = rect.top+g->p.cy; rect.left = g->p.x; rect.right = rect.left+g->p.cx; break; case GDISP_ROTATE_90: if (!(buffer = rotateimg(g, buffer))) return; bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t); bmpInfo.bV4Width = g->p.cy; bmpInfo.bV4Height = -g->p.cx; /* top-down image */ rect.bottom = g->g.Width - g->p.x; rect.top = rect.bottom-g->p.cx; rect.left = g->p.y; rect.right = rect.left+g->p.cy; break; case GDISP_ROTATE_180: if (!(buffer = rotateimg(g, buffer))) return; bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t); bmpInfo.bV4Width = g->p.cx; bmpInfo.bV4Height = -g->p.cy; /* top-down image */ rect.bottom = g->g.Height-1 - g->p.y; rect.top = rect.bottom-g->p.cy; rect.right = g->g.Width - g->p.x; rect.left = rect.right-g->p.cx; break; case GDISP_ROTATE_270: if (!(buffer = rotateimg(g, buffer))) return; bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t); bmpInfo.bV4Width = g->p.cy; bmpInfo.bV4Height = -g->p.cx; /* top-down image */ rect.top = g->p.x; rect.bottom = rect.top+g->p.cx; rect.right = g->g.Height - g->p.y; rect.left = rect.right-g->p.cy; break; } #else bmpInfo.bV4SizeImage = (g->p.cy*g->p.x2) * sizeof(pixel_t); bmpInfo.bV4Width = g->p.x2; bmpInfo.bV4Height = -g->p.cy; /* top-down image */ rect.top = g->p.y; rect.bottom = rect.top+g->p.cy; rect.left = g->p.x; rect.right = rect.left+g->p.cx; #endif WaitForSingleObject(drawMutex, INFINITE); SetDIBitsToDevice(priv->dcBuffer, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS); #if GDISP_WIN32_USE_INDIRECT_UPDATE ReleaseMutex(drawMutex); InvalidateRect(priv->hwnd, &rect, FALSE); #else { HDC dc; dc = GetDC(priv->hwnd); SetDIBitsToDevice(dc, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS); ReleaseDC(priv->hwnd, dc); ReleaseMutex(drawMutex); } #endif #if GDISP_NEED_CONTROL if (buffer != (pixel_t *)g->p.ptr) free(buffer); #endif }