INLINE BOOL gdi_InvalidateRegion(HGDI_DC hdc, int x, int y, int w, int h) { GDI_RECT inv; GDI_RECT rgn; HGDI_RGN invalid; HGDI_RGN cinvalid; if (!hdc->hwnd) return TRUE; if (!hdc->hwnd->invalid) return TRUE; if (w == 0 || h == 0) return TRUE; cinvalid = hdc->hwnd->cinvalid; if ((hdc->hwnd->ninvalid + 1) > hdc->hwnd->count) { int new_cnt; HGDI_RGN new_rgn; new_cnt = hdc->hwnd->count * 2; new_rgn = (HGDI_RGN) realloc(cinvalid, sizeof(GDI_RGN) * new_cnt); if (!new_rgn) return FALSE; hdc->hwnd->count = new_cnt; cinvalid = new_rgn; } gdi_SetRgn(&cinvalid[hdc->hwnd->ninvalid++], x, y, w, h); hdc->hwnd->cinvalid = cinvalid; invalid = hdc->hwnd->invalid; if (invalid->null) { invalid->x = x; invalid->y = y; invalid->w = w; invalid->h = h; invalid->null = 0; return TRUE; } gdi_CRgnToRect(x, y, w, h, &rgn); gdi_RgnToRect(invalid, &inv); if (rgn.left < 0) rgn.left = 0; if (rgn.top < 0) rgn.top = 0; if (rgn.left < inv.left) inv.left = rgn.left; if (rgn.top < inv.top) inv.top = rgn.top; if (rgn.right > inv.right) inv.right = rgn.right; if (rgn.bottom > inv.bottom) inv.bottom = rgn.bottom; gdi_RectToRgn(&inv, invalid); return TRUE; }
int test_gdi_InvalidateRegion(void) { HGDI_DC hdc; HGDI_RGN rgn1; HGDI_RGN rgn2; HGDI_RGN invalid; HGDI_BITMAP bmp; if (!(hdc = gdi_GetDC())) { printf("failed to get gdi device context\n"); return -1; } hdc->bytesPerPixel = 4; hdc->bitsPerPixel = 32; bmp = gdi_CreateBitmapEx(1024, 768, 4, NULL, NULL); gdi_SelectObject(hdc, (HGDIOBJECT) bmp); gdi_SetNullClipRgn(hdc); hdc->hwnd = (HGDI_WND) calloc(1, sizeof(GDI_WND)); hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0); hdc->hwnd->invalid->null = 1; invalid = hdc->hwnd->invalid; hdc->hwnd->count = 16; hdc->hwnd->cinvalid = (HGDI_RGN) calloc(hdc->hwnd->count, sizeof(GDI_RGN)); rgn1 = gdi_CreateRectRgn(0, 0, 0, 0); rgn2 = gdi_CreateRectRgn(0, 0, 0, 0); rgn1->null = 1; rgn2->null = 1; /* no previous invalid region */ invalid->null = 1; gdi_SetRgn(rgn1, 300, 300, 100, 100); gdi_SetRgn(rgn2, 300, 300, 100, 100); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; /* region same as invalid region */ gdi_SetRgn(invalid, 300, 300, 100, 100); gdi_SetRgn(rgn1, 300, 300, 100, 100); gdi_SetRgn(rgn2, 300, 300, 100, 100); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; /* left outside */ gdi_SetRgn(invalid, 300, 300, 100, 100); gdi_SetRgn(rgn1, 100, 300, 300, 100); gdi_SetRgn(rgn2, 100, 300, 300, 100); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; /* right outside */ gdi_SetRgn(invalid, 300, 300, 100, 100); gdi_SetRgn(rgn1, 300, 300, 300, 100); gdi_SetRgn(rgn2, 300, 300, 300, 100); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; /* top outside */ gdi_SetRgn(invalid, 300, 300, 100, 100); gdi_SetRgn(rgn1, 300, 100, 100, 300); gdi_SetRgn(rgn2, 300, 100, 100, 300); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; /* bottom outside */ gdi_SetRgn(invalid, 300, 300, 100, 100); gdi_SetRgn(rgn1, 300, 300, 100, 300); gdi_SetRgn(rgn2, 300, 300, 100, 300); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; /* left outside, right outside */ gdi_SetRgn(invalid, 300, 300, 100, 100); gdi_SetRgn(rgn1, 100, 300, 600, 300); gdi_SetRgn(rgn2, 100, 300, 600, 300); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; /* top outside, bottom outside */ gdi_SetRgn(invalid, 300, 300, 100, 100); gdi_SetRgn(rgn1, 300, 100, 100, 500); gdi_SetRgn(rgn2, 300, 100, 100, 500); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; /* all outside, left */ gdi_SetRgn(invalid, 300, 300, 100, 100); gdi_SetRgn(rgn1, 100, 300, 100, 100); gdi_SetRgn(rgn2, 100, 300, 300, 100); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; /* all outside, right */ gdi_SetRgn(invalid, 300, 300, 100, 100); gdi_SetRgn(rgn1, 700, 300, 100, 100); gdi_SetRgn(rgn2, 300, 300, 500, 100); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; /* all outside, top */ gdi_SetRgn(invalid, 300, 300, 100, 100); gdi_SetRgn(rgn1, 300, 100, 100, 100); gdi_SetRgn(rgn2, 300, 100, 100, 300); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; /* all outside, bottom */ gdi_SetRgn(invalid, 300, 300, 100, 100); gdi_SetRgn(rgn1, 300, 500, 100, 100); gdi_SetRgn(rgn2, 300, 300, 100, 300); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; /* all outside */ gdi_SetRgn(invalid, 300, 300, 100, 100); gdi_SetRgn(rgn1, 100, 100, 600, 600); gdi_SetRgn(rgn2, 100, 100, 600, 600); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; /* everything */ gdi_SetRgn(invalid, 300, 300, 100, 100); gdi_SetRgn(rgn1, 0, 0, 1024, 768); gdi_SetRgn(rgn2, 0, 0, 1024, 768); gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); if (!gdi_EqualRgn(invalid, rgn2)) return -1; return 0; }
int test_gdi_ClipCoords(void) { BOOL draw; HGDI_DC hdc; HGDI_RGN rgn1; HGDI_RGN rgn2; HGDI_BITMAP bmp; if (!(hdc = gdi_GetDC())) { printf("failed to get gdi device context\n"); return -1; } hdc->bytesPerPixel = 4; hdc->bitsPerPixel = 32; bmp = gdi_CreateBitmapEx(1024, 768, 4, NULL, NULL); gdi_SelectObject(hdc, (HGDIOBJECT) bmp); gdi_SetNullClipRgn(hdc); rgn1 = gdi_CreateRectRgn(0, 0, 0, 0); rgn2 = gdi_CreateRectRgn(0, 0, 0, 0); rgn1->null = 1; rgn2->null = 1; /* null clipping region */ gdi_SetNullClipRgn(hdc); gdi_SetRgn(rgn1, 20, 20, 100, 100); gdi_SetRgn(rgn2, 20, 20, 100, 100); gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); if (!gdi_EqualRgn(rgn1, rgn2)) return -1; /* region all inside clipping region */ gdi_SetClipRgn(hdc, 0, 0, 1024, 768); gdi_SetRgn(rgn1, 20, 20, 100, 100); gdi_SetRgn(rgn2, 20, 20, 100, 100); gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); if (!gdi_EqualRgn(rgn1, rgn2)) return -1; /* region all outside clipping region, on the left */ gdi_SetClipRgn(hdc, 300, 300, 100, 100); gdi_SetRgn(rgn1, 20, 20, 100, 100); gdi_SetRgn(rgn2, 0, 0, 0, 0); draw = gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); if (draw) return -1; /* region all outside clipping region, on the right */ gdi_SetClipRgn(hdc, 300, 300, 100, 100); gdi_SetRgn(rgn1, 420, 420, 100, 100); gdi_SetRgn(rgn2, 0, 0, 0, 0); draw = gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); if (draw) return -1; /* region all outside clipping region, on top */ gdi_SetClipRgn(hdc, 300, 300, 100, 100); gdi_SetRgn(rgn1, 300, 20, 100, 100); gdi_SetRgn(rgn2, 0, 0, 0, 0); draw = gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); if (draw) return -1; /* region all outside clipping region, at the bottom */ gdi_SetClipRgn(hdc, 300, 300, 100, 100); gdi_SetRgn(rgn1, 300, 420, 100, 100); gdi_SetRgn(rgn2, 0, 0, 0, 0); draw = gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); if (draw) return -1; /* left outside, right = clip, top = clip, bottom = clip */ gdi_SetClipRgn(hdc, 300, 300, 100, 100); gdi_SetRgn(rgn1, 100, 300, 300, 100); gdi_SetRgn(rgn2, 300, 300, 100, 100); gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); if (!gdi_EqualRgn(rgn1, rgn2)) return -1; /* left outside, right inside, top = clip, bottom = clip */ gdi_SetClipRgn(hdc, 300, 300, 100, 100); gdi_SetRgn(rgn1, 100, 300, 250, 100); gdi_SetRgn(rgn2, 300, 300, 50, 100); gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); if (!gdi_EqualRgn(rgn1, rgn2)) return -1; /* left = clip, right outside, top = clip, bottom = clip */ gdi_SetClipRgn(hdc, 300, 300, 100, 100); gdi_SetRgn(rgn1, 300, 300, 300, 100); gdi_SetRgn(rgn2, 300, 300, 100, 100); gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); if (!gdi_EqualRgn(rgn1, rgn2)) return -1; /* left inside, right outside, top = clip, bottom = clip */ gdi_SetClipRgn(hdc, 300, 300, 100, 100); gdi_SetRgn(rgn1, 350, 300, 200, 100); gdi_SetRgn(rgn2, 350, 300, 50, 100); gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); if (!gdi_EqualRgn(rgn1, rgn2)) return -1; /* top outside, bottom = clip, left = clip, right = clip */ gdi_SetClipRgn(hdc, 300, 300, 100, 100); gdi_SetRgn(rgn1, 300, 100, 300, 300); gdi_SetRgn(rgn2, 300, 300, 100, 100); gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); if (!gdi_EqualRgn(rgn1, rgn2)) return -1; /* top = clip, bottom outside, left = clip, right = clip */ gdi_SetClipRgn(hdc, 300, 300, 100, 100); gdi_SetRgn(rgn1, 300, 300, 100, 200); gdi_SetRgn(rgn2, 300, 300, 100, 100); gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); if (!gdi_EqualRgn(rgn1, rgn2)) return -1; /* top = clip, bottom = clip, top = clip, bottom = clip */ gdi_SetClipRgn(hdc, 300, 300, 100, 100); gdi_SetRgn(rgn1, 300, 300, 100, 100); gdi_SetRgn(rgn2, 300, 300, 100, 100); gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); if (!gdi_EqualRgn(rgn1, rgn2)) return -1; return 0; }
BOOL gdi_SetClipRgn(HGDI_DC hdc, INT32 nXLeft, INT32 nYLeft, INT32 nWidth, INT32 nHeight) { return gdi_SetRgn(hdc->clip, nXLeft, nYLeft, nWidth, nHeight); }
int gdi_SetClipRgn(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight) { return gdi_SetRgn(hdc->clip, nXLeft, nYLeft, nWidth, nHeight); }
INLINE int gdi_InvalidateRegion(HGDI_DC hdc, int x, int y, int w, int h) { GDI_RECT inv; GDI_RECT rgn; HGDI_RGN invalid; HGDI_RGN cinvalid; if (hdc->hwnd == NULL) return 0; if (hdc->hwnd->invalid == NULL) return 0; cinvalid = hdc->hwnd->cinvalid; if (hdc->hwnd->ninvalid + 1 > hdc->hwnd->count) { hdc->hwnd->count *= 2; cinvalid = (HGDI_RGN) realloc(cinvalid, sizeof(GDI_RGN) * (hdc->hwnd->count)); } gdi_SetRgn(&cinvalid[hdc->hwnd->ninvalid++], x, y, w, h); hdc->hwnd->cinvalid = cinvalid; invalid = hdc->hwnd->invalid; if (invalid->null) { invalid->x = x; invalid->y = y; invalid->w = w; invalid->h = h; invalid->null = 0; return 0; } gdi_CRgnToRect(x, y, w, h, &rgn); gdi_RgnToRect(invalid, &inv); if (rgn.left < 0) rgn.left = 0; if (rgn.top < 0) rgn.top = 0; if (rgn.left < inv.left) inv.left = rgn.left; if (rgn.top < inv.top) inv.top = rgn.top; if (rgn.right > inv.right) inv.right = rgn.right; if (rgn.bottom > inv.bottom) inv.bottom = rgn.bottom; gdi_RectToRgn(&inv, invalid); return 0; }