mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-02-08 03:41:52 +08:00
fix bugs in StrechBlt
This commit is contained in:
@@ -1343,6 +1343,66 @@ static void _line_scaled_stretchblt (void* context, const void* line, int y)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void StretchBltOld (PDC psdc, const RECT *srcOutput,
|
||||
PDC pddc, const RECT *dstOutput, DWORD dwRop)
|
||||
{
|
||||
PCLIPRECT cliprect;
|
||||
GAL_Rect src, dst;
|
||||
RECT eff_rc;
|
||||
|
||||
pddc->rc_output = *dstOutput;
|
||||
if (pddc->surface != psdc->surface && (psdc->surface == __gal_screen))
|
||||
psdc->rc_output = *srcOutput;
|
||||
|
||||
ENTER_DRAWING (pddc);
|
||||
|
||||
if (pddc->surface != psdc->surface && IS_SCREEN_SURFACE (psdc))
|
||||
kernel_ShowCursorForGDI (FALSE, psdc);
|
||||
|
||||
cliprect = pddc->ecrgn.head;
|
||||
while(cliprect) {
|
||||
if (IntersectRect (&eff_rc, &pddc->rc_output, &cliprect->rc)) {
|
||||
SET_GAL_CLIPRECT (pddc, eff_rc);
|
||||
|
||||
src.x = srcOutput->left; src.y = srcOutput->top;
|
||||
src.w = RECTWP (srcOutput); src.h = RECTHP (srcOutput);
|
||||
dst.x = dstOutput->left; dst.y = dstOutput->top;
|
||||
dst.w = RECTWP (dstOutput); dst.h = RECTHP (dstOutput);
|
||||
GAL_SoftStretch (psdc->surface, &src, pddc->surface, &dst);
|
||||
}
|
||||
|
||||
cliprect = cliprect->next;
|
||||
}
|
||||
|
||||
if (pddc->surface != psdc->surface && IS_SCREEN_SURFACE (psdc))
|
||||
kernel_ShowCursorForGDI (TRUE, psdc);
|
||||
|
||||
LEAVE_DRAWING (pddc);
|
||||
|
||||
error_ret:
|
||||
UNLOCK_GCRINFO (pddc);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void StretchBltSlow (HDC hsdc, int sx, int sy, int sw, int sh,
|
||||
HDC hddc, int dx, int dy, int dw, int dh, DWORD dwRop)
|
||||
{
|
||||
HDC newdc;
|
||||
POINT pt = { dw, dh };
|
||||
|
||||
LPtoDP (hddc, &pt);
|
||||
newdc = CreateCompatibleDCEx (hsdc, pt.x, pt.y);
|
||||
if (newdc == HDC_INVALID) {
|
||||
_WRN_PRINTF ("Failed to create a compatible memory DC\n");
|
||||
return;
|
||||
}
|
||||
|
||||
StretchBlt (hsdc, sx, sy, sw, sh, newdc, 0, 0, pt.x, pt.y, dwRop);
|
||||
BitBlt (newdc, 0, 0, pt.x, pt.y, hddc, dx, dy, dwRop);
|
||||
DeleteMemDC (newdc);
|
||||
}
|
||||
|
||||
void GUIAPI StretchBlt (HDC hsdc, int sx, int sy, int sw, int sh,
|
||||
HDC hddc, int dx, int dy, int dw, int dh, DWORD dwRop)
|
||||
{
|
||||
@@ -1352,35 +1412,18 @@ void GUIAPI StretchBlt (HDC hsdc, int sx, int sy, int sw, int sh,
|
||||
struct _SCALER_INFO_STRETCHBLT info;
|
||||
|
||||
psdc = dc_HDC2PDC (hsdc);
|
||||
pddc = dc_HDC2PDC (hddc);
|
||||
if (GAL_RMask (psdc->surface) != GAL_RMask (pddc->surface)
|
||||
|| GAL_GMask (psdc->surface) != GAL_GMask (pddc->surface)
|
||||
|| GAL_BMask (psdc->surface) != GAL_BMask (pddc->surface)
|
||||
|| GAL_AMask (psdc->surface) != GAL_AMask (pddc->surface)) {
|
||||
StretchBltSlow (hsdc, sx, sy, sw, sh, hddc, dx, dy, dw, dh, dwRop);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(pddc = __mg_check_ecrgn (hddc)))
|
||||
return;
|
||||
|
||||
if (GAL_BitsPerPixel (psdc->surface) != GAL_BitsPerPixel (pddc->surface)) {
|
||||
goto error_ret;
|
||||
}
|
||||
|
||||
if (sx < 0) sx = 0;
|
||||
if (sy < 0) sy = 0;
|
||||
if (dx < 0) dx = 0;
|
||||
if (dy < 0) dy = 0;
|
||||
|
||||
if (sx >= RECTW(psdc->DevRC))
|
||||
goto error_ret;
|
||||
if (sy >= RECTH(psdc->DevRC))
|
||||
goto error_ret;
|
||||
if (dx >= RECTW(pddc->DevRC))
|
||||
goto error_ret;
|
||||
if (dy >= RECTH(pddc->DevRC))
|
||||
goto error_ret;
|
||||
|
||||
if (sw <= 0 || sw > RECTW (psdc->DevRC) - sx) sw = RECTW (psdc->DevRC) - sx;
|
||||
if (sh <= 0 || sh > RECTH (psdc->DevRC) - sy) sh = RECTH (psdc->DevRC) - sy;
|
||||
if (dw <= 0 || dw > RECTW (pddc->DevRC) - dx) dw = RECTW (pddc->DevRC) - dx;
|
||||
if (dh <= 0 || dh > RECTH (pddc->DevRC) - dy) dh = RECTH (pddc->DevRC) - dy;
|
||||
|
||||
|
||||
/* The coordinates should be in device space. */
|
||||
#if 0
|
||||
// Transfer logical to device to screen here.
|
||||
sw += sx; sh += sy;
|
||||
coor_LP2SP(psdc, &sx, &sy);
|
||||
@@ -1395,17 +1438,64 @@ void GUIAPI StretchBlt (HDC hsdc, int sx, int sy, int sw, int sh,
|
||||
SetRect (&dstOutput, dx, dy, dw, dh);
|
||||
NormalizeRect (&dstOutput);
|
||||
dw = RECTW (dstOutput); dh = RECTH (dstOutput);
|
||||
#else
|
||||
coor_DP2SP (psdc, &sx, &sy);
|
||||
SetRect (&srcOutput, sx, sy, sx + sw, sy + sh);
|
||||
/*
|
||||
if (!IsCovered (&srcOutput, &psdc->DevRC))
|
||||
goto error_ret;
|
||||
*/
|
||||
|
||||
coor_DP2SP (pddc, &dx, &dy);
|
||||
SetRect (&dstOutput, dx, dy, dx + dw, dy + dh);
|
||||
#endif
|
||||
|
||||
if (sx < 0) sx = 0;
|
||||
if (sy < 0) sy = 0;
|
||||
if (sw <= 0) sw = RECTW (psdc->DevRC);
|
||||
if (sh <= 0) sh = RECTH (psdc->DevRC);
|
||||
if (dw <= 0) dw = RECTW (pddc->DevRC);
|
||||
if (dh <= 0) dh = RECTH (pddc->DevRC);
|
||||
|
||||
if (sx >= RECTW(psdc->DevRC) || (sx + sw) > RECTW(psdc->DevRC))
|
||||
goto error_ret;
|
||||
if (sy >= RECTH(psdc->DevRC) || (sy + sh) > RECTH(psdc->DevRC))
|
||||
goto error_ret;
|
||||
if (dx >= RECTW(pddc->DevRC))
|
||||
goto error_ret;
|
||||
if (dy >= RECTH(pddc->DevRC))
|
||||
goto error_ret;
|
||||
|
||||
// shrink source and destination rectangles if dx < 0
|
||||
if (dx < 0) {
|
||||
// dx and overflow is negative
|
||||
int overflow = (int)(dx * sw * 1.0f / dw + 0.5f);
|
||||
sx -= overflow;
|
||||
sw += overflow;
|
||||
|
||||
dw += dx;
|
||||
dx = 0;
|
||||
}
|
||||
|
||||
// shrink source and destination rectangles if dy < 0
|
||||
if (dy < 0) {
|
||||
// dy and overflow is negative
|
||||
int overflow = (int)(dy * sh * 1.0f / dh + 0.5f);
|
||||
sy -= overflow;
|
||||
sh += overflow;
|
||||
|
||||
dh += dy;
|
||||
dy = 0;
|
||||
}
|
||||
|
||||
// shrink source and destination rectangles if dx + dw is overflow
|
||||
if ((dx + dw) > RECTW (pddc->DevRC)) {
|
||||
int overflow = dx + dw - RECTW (pddc->DevRC);
|
||||
|
||||
sw -= (int)(sw * overflow * 1.0f / dw + 0.5f);
|
||||
dw -= overflow;
|
||||
}
|
||||
|
||||
// shrink source and destination rectangles if dy + dh is overflow
|
||||
if ((dy + dh) > RECTH (pddc->DevRC)) {
|
||||
int overflow = dy + dh - RECTH (pddc->DevRC);
|
||||
|
||||
sh -= (int)(sh * overflow * 1.0f / dh + 0.5f);
|
||||
dh -= overflow;
|
||||
}
|
||||
|
||||
if (sw <= 0 || sh <= 0 || dw <= 0 || dh <= 0)
|
||||
goto error_ret;
|
||||
|
||||
info.pdc = pddc;
|
||||
info.dst_x = dx; info.dst_y = dy;
|
||||
@@ -1413,6 +1503,7 @@ void GUIAPI StretchBlt (HDC hsdc, int sx, int sy, int sw, int sh,
|
||||
info.line_buff = malloc (GAL_BytesPerPixel (pddc->surface) * dw);
|
||||
|
||||
if (info.line_buff == NULL) {
|
||||
_WRN_PRINTF ("Failed to allocate line buffer\n");
|
||||
goto error_ret;
|
||||
}
|
||||
|
||||
@@ -1440,30 +1531,6 @@ void GUIAPI StretchBlt (HDC hsdc, int sx, int sy, int sw, int sh,
|
||||
if (pddc->surface != psdc->surface && IS_SCREEN_SURFACE (psdc))
|
||||
kernel_ShowCursorForGDI (FALSE, psdc);
|
||||
|
||||
#if 0
|
||||
PCLIPRECT cliprect;
|
||||
GAL_Rect src, dst;
|
||||
RECT eff_rc;
|
||||
|
||||
if (pddc->surface == psdc->surface && dy > sy)
|
||||
cliprect = pddc->ecrgn.tail;
|
||||
else
|
||||
cliprect = pddc->ecrgn.head;
|
||||
while(cliprect) {
|
||||
if (IntersectRect (&eff_rc, &pddc->rc_output, &cliprect->rc)) {
|
||||
SET_GAL_CLIPRECT (pddc, eff_rc);
|
||||
|
||||
src.x = sx; src.y = sy; src.w = sw; src.h = sh;
|
||||
dst.x = dx; dst.y = dy; dst.w = dw; dst.h = dh;
|
||||
GAL_SoftStretch (psdc->surface, &src, pddc->surface, &dst);
|
||||
}
|
||||
|
||||
if (pddc->surface == psdc->surface && dy > sy)
|
||||
cliprect = cliprect->prev;
|
||||
else
|
||||
cliprect = cliprect->next;
|
||||
}
|
||||
#else
|
||||
pddc->step = 1;
|
||||
pddc->cur_ban = NULL;
|
||||
if (pddc->surface == psdc->surface
|
||||
@@ -1474,25 +1541,18 @@ void GUIAPI StretchBlt (HDC hsdc, int sx, int sy, int sw, int sh,
|
||||
}
|
||||
else {
|
||||
info.bottom2top = FALSE;
|
||||
/*
|
||||
BitmapDDAScaler (&info, &bmp, dw, dh,
|
||||
_get_line_buff_stretchblt, _line_scaled_stretchblt);
|
||||
*/
|
||||
if ( pddc->bitmap_scaler )
|
||||
{
|
||||
if (pddc->bitmap_scaler) {
|
||||
pddc->bitmap_scaler(&info, &bmp, dw, dh,
|
||||
_get_line_buff_stretchblt,
|
||||
_line_scaled_stretchblt,
|
||||
pddc->surface->format);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
BitmapDDAScaler (&info, &bmp, dw, dh,
|
||||
_get_line_buff_stretchblt, _line_scaled_stretchblt);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pddc->surface != psdc->surface && IS_SCREEN_SURFACE (psdc))
|
||||
kernel_ShowCursorForGDI (TRUE, psdc);
|
||||
|
||||
Reference in New Issue
Block a user