GDI+ line drawing and clipping bug
From: Chris Hill (Chris244_at_aol.com)
Date: 08/20/04
- Next message: Tim Roberts: "Re: how does Photoshop know the physical units when it shows image?"
- Previous message: Marton Anka: "Mirror driver and XP checked build kernel assertion"
- Next in thread: Severian: "Re: GDI+ line drawing and clipping bug"
- Reply: Severian: "Re: GDI+ line drawing and clipping bug"
- Reply: Chris Hill: "Re: GDI+ line drawing and clipping bug"
- Messages sorted by: [ date ] [ thread ]
Date: Fri, 20 Aug 2004 02:36:25 GMT
When I draw a one pixel thick line without antialiasing and the line
intersects the boundary of a clip rectangle that I have set, the line
doesn't always draw all the way to the clip rectangle boundary. It
may stop well (dozens of pixels) short of the clip rectangle. It
appears that the missing portion of the line starts at the last place
that the line changes pixel row or column.
This doesn't happen if:
- Antialiasing is enabled
- The pen is more than one pixel thick
- The line is perfectly horizontal or vertical
- The clipping is against the window boundaries rather than a clip
rectangle
Is this a bug in GDI+? This makes GDI+ very difficult to use for line
drawing in my application since it appears to be unreliable.
I have attached a small sample program demonstrating the issue I am
seeing. The nearly vertical line is drawn from the top of the window
to the bottom, advancing one pixel in the x direction. The horizontal
line represents the bottom of the clip rectangle. The vertical line
should always touch the horizonal line, but it doesn't when the mouse
is positioned slightly more than halfway down the window.
Chris
#include <windows.h>
#include <windowsx.h>
#include <gdiplus.h>
using namespace Gdiplus;
static char BUG_WINDOW_CLASS[] = "GDI+ Bug Window";
HINSTANCE hinst;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
switch(uMsg)
{
case WM_MOUSEMOVE:
{
Gdiplus::Graphics g(hwnd);
Gdiplus::SolidBrush wb(Gdiplus::Color::White);
Gdiplus::Pen bp(Gdiplus::Color::Black, 1.5);
g.SetPageUnit(Gdiplus::UnitPixel);
//g.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
RECT cr;
GetClientRect(hwnd, &cr);
Gdiplus::Rect pcr(cr.left, cr.top, cr.right-cr.left,
cr.bottom-cr.top);
g.FillRectangle(&wb, pcr);
int clipy = GET_Y_LPARAM(lParam);
int centerx = cr.right/2;
pcr.Height = clipy;
g.DrawLine(&bp,cr.left,clipy,cr.right,clipy);
g.SetClip(pcr);
g.DrawLine(&bp,centerx,cr.top,centerx+1,cr.bottom);
break;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
HWND MakeWindow()
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinst;
wc.hIcon = LoadIcon(NULL,IDI_EXCLAMATION);
wc.hCursor = LoadCursor(NULL, IDC_CROSS);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = BUG_WINDOW_CLASS;
RegisterClass(&wc);
return
CreateWindow(BUG_WINDOW_CLASS,BUG_WINDOW_CLASS,WS_VISIBLE|WS_TILEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, NULL,
NULL, hinst, 0);
}
int CALLBACK WinMain(HINSTANCE h, HINSTANCE prev, LPSTR cmdline, int
cmdshow)
{
HWND win;
MSG msg;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
hinst = h;
win = MakeWindow();
while(GetMessage(&msg, win, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GdiplusShutdown(gdiplusToken);
return 0;
}
- Next message: Tim Roberts: "Re: how does Photoshop know the physical units when it shows image?"
- Previous message: Marton Anka: "Mirror driver and XP checked build kernel assertion"
- Next in thread: Severian: "Re: GDI+ line drawing and clipping bug"
- Reply: Severian: "Re: GDI+ line drawing and clipping bug"
- Reply: Chris Hill: "Re: GDI+ line drawing and clipping bug"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|