Blame examples/windows.c

Packit ed3af9
/*
Packit ed3af9
Sample usage of GD on windows. This little program opens a window, fetch its DIB
Packit ed3af9
and assigns to a GD truecolor image.
Packit ed3af9
Packit ed3af9
Thanks to Mateusz Loskot (http://mateusz.loskot.net) for the AttachBuffer function!
Packit ed3af9
$Id$
Packit ed3af9
*/
Packit ed3af9
#include <windows.h>
Packit ed3af9
#include <gd.h>
Packit ed3af9
#include <gdfontg.h>
Packit ed3af9
#include <gdfontl.h>
Packit ed3af9
Packit ed3af9
Packit ed3af9
gdImagePtr gdImageTrueColorAttachBuffer(int* buffer, int sx, int sy, int stride)
Packit ed3af9
{
Packit ed3af9
	int i;
Packit ed3af9
	int height;
Packit ed3af9
	int* rowptr;
Packit ed3af9
	gdImagePtr im;
Packit ed3af9
	im = (gdImage *) malloc (sizeof (gdImage));
Packit ed3af9
	if (!im) {
Packit ed3af9
		return 0;
Packit ed3af9
	}
Packit ed3af9
	memset (im, 0, sizeof (gdImage));
Packit ed3af9
Packit ed3af9
#if 0
Packit ed3af9
	if (overflow2(sizeof (int *), sy)) {
Packit ed3af9
		return 0;
Packit ed3af9
	}
Packit ed3af9
#endif
Packit ed3af9
Packit ed3af9
	im->tpixels = (int **) malloc (sizeof (int *) * sy);
Packit ed3af9
	if (!im->tpixels) {
Packit ed3af9
		free(im);
Packit ed3af9
		return 0;
Packit ed3af9
	}
Packit ed3af9
Packit ed3af9
	im->polyInts = 0;
Packit ed3af9
	im->polyAllocated = 0;
Packit ed3af9
	im->brush = 0;
Packit ed3af9
	im->tile = 0;
Packit ed3af9
	im->style = 0;
Packit ed3af9
Packit ed3af9
	height = sy;
Packit ed3af9
	rowptr = buffer;
Packit ed3af9
	if (stride < 0) {
Packit ed3af9
		int startoff = (height - 1) * stride;
Packit ed3af9
		rowptr = buffer - startoff;
Packit ed3af9
	}
Packit ed3af9
Packit ed3af9
	i = 0;
Packit ed3af9
	while (height--) {
Packit ed3af9
		im->tpixels[i] = rowptr;
Packit ed3af9
		rowptr += stride;
Packit ed3af9
		i++;
Packit ed3af9
	}
Packit ed3af9
Packit ed3af9
	im->sx = sx;
Packit ed3af9
	im->sy = sy;
Packit ed3af9
	im->transparent = (-1);
Packit ed3af9
	im->interlace = 0;
Packit ed3af9
	im->trueColor = 1;
Packit ed3af9
	im->saveAlphaFlag = 0;
Packit ed3af9
	im->alphaBlendingFlag = 1;
Packit ed3af9
	im->thick = 1;
Packit ed3af9
	im->AA = 0;
Packit ed3af9
	im->cx1 = 0;
Packit ed3af9
	im->cy1 = 0;
Packit ed3af9
	im->cx2 = im->sx - 1;
Packit ed3af9
	im->cy2 = im->sy - 1;
Packit ed3af9
	return im;
Packit ed3af9
}
Packit ed3af9
Packit ed3af9
void gdImageDetachBuffer(gdImagePtr im)
Packit ed3af9
{
Packit ed3af9
	free(im->tpixels);
Packit ed3af9
	free(im);
Packit ed3af9
}
Packit ed3af9
Packit ed3af9
Packit ed3af9
BITMAPINFO gdCreateBmp(int width, int height)
Packit ed3af9
{
Packit ed3af9
	BITMAPINFO bmp_info;
Packit ed3af9
Packit ed3af9
	// Configure bitmap properties
Packit ed3af9
Packit ed3af9
	ZeroMemory(&bmp_info, sizeof(BITMAPINFO));
Packit ed3af9
	bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
Packit ed3af9
	bmp_info.bmiHeader.biWidth = width;
Packit ed3af9
	bmp_info.bmiHeader.biHeight = height;
Packit ed3af9
	bmp_info.bmiHeader.biPlanes = 1;
Packit ed3af9
	bmp_info.bmiHeader.biBitCount = 32;
Packit ed3af9
	bmp_info.bmiHeader.biCompression = BI_RGB;
Packit ed3af9
	bmp_info.bmiHeader.biSizeImage = 0;
Packit ed3af9
	bmp_info.bmiHeader.biXPelsPerMeter = 0;
Packit ed3af9
	bmp_info.bmiHeader.biYPelsPerMeter = 0;
Packit ed3af9
	bmp_info.bmiHeader.biClrUsed = 0;
Packit ed3af9
	bmp_info.bmiHeader.biClrImportant = 0;
Packit ed3af9
	return bmp_info;
Packit ed3af9
}
Packit ed3af9
Packit ed3af9
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
Packit ed3af9
Packit ed3af9
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
Packit ed3af9
                    PSTR szCmdLine, int iCmdShow)
Packit ed3af9
{
Packit ed3af9
	static TCHAR szAppName[] = TEXT ("Bezier") ;
Packit ed3af9
	HWND         hwnd ;
Packit ed3af9
	MSG          msg ;
Packit ed3af9
	WNDCLASS     wndclass ;
Packit ed3af9
Packit ed3af9
	wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
Packit ed3af9
	wndclass.lpfnWndProc   = WndProc ;
Packit ed3af9
	wndclass.cbClsExtra    = 0 ;
Packit ed3af9
	wndclass.cbWndExtra    = 0 ;
Packit ed3af9
	wndclass.hInstance     = hInstance ;
Packit ed3af9
	wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
Packit ed3af9
	wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
Packit ed3af9
	wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
Packit ed3af9
	wndclass.lpszMenuName  = NULL ;
Packit ed3af9
	wndclass.lpszClassName = szAppName ;
Packit ed3af9
Packit ed3af9
	if (!RegisterClass (&wndclass)) {
Packit ed3af9
		// UNICODE-Compilierung ist die einzige realistische Fehlermöglichkeit
Packit ed3af9
		MessageBox (NULL, TEXT ("Programm arbeitet mit Unicode und setzt Windows NT voraus!"),
Packit ed3af9
		            szAppName, MB_ICONERROR) ;
Packit ed3af9
		return 0 ;
Packit ed3af9
	}
Packit ed3af9
Packit ed3af9
	hwnd = CreateWindow (szAppName, TEXT ("Bezierkurven"),
Packit ed3af9
	                     WS_OVERLAPPEDWINDOW,
Packit ed3af9
	                     CW_USEDEFAULT, CW_USEDEFAULT,
Packit ed3af9
	                     CW_USEDEFAULT, CW_USEDEFAULT,
Packit ed3af9
	                     NULL, NULL, hInstance, NULL) ;
Packit ed3af9
Packit ed3af9
	ShowWindow (hwnd, iCmdShow) ;
Packit ed3af9
	UpdateWindow (hwnd) ;
Packit ed3af9
Packit ed3af9
	while (GetMessage (&msg, NULL, 0, 0)) {
Packit ed3af9
		TranslateMessage (&msg) ;
Packit ed3af9
		DispatchMessage (&msg) ;
Packit ed3af9
	}
Packit ed3af9
	return msg.wParam ;
Packit ed3af9
}
Packit ed3af9
Packit ed3af9
void DrawBezier (HDC hdc, POINT apt[])
Packit ed3af9
{
Packit ed3af9
	PolyBezier (hdc, apt, 4) ;
Packit ed3af9
Packit ed3af9
	MoveToEx (hdc, apt[0].x, apt[0].y, NULL) ;
Packit ed3af9
	LineTo   (hdc, apt[1].x, apt[1].y) ;
Packit ed3af9
Packit ed3af9
	MoveToEx (hdc, apt[2].x, apt[2].y, NULL) ;
Packit ed3af9
	LineTo   (hdc, apt[3].x, apt[3].y) ;
Packit ed3af9
}
Packit ed3af9
Packit ed3af9
Packit ed3af9
void gdDrawImage(HDC hdc, RECT *rc)
Packit ed3af9
{
Packit ed3af9
	HDC  mem_dc;
Packit ed3af9
	BITMAPINFO bmp_info;
Packit ed3af9
	void* bits;
Packit ed3af9
	HBITMAP bmp, temp;
Packit ed3af9
	gdImagePtr im;
Packit ed3af9
	int width, height, stride;
Packit ed3af9
	int white, black, blue, red;
Packit ed3af9
	char *s = "Hello world!";
Packit ed3af9
	gdFontPtr lfont, gfont;
Packit ed3af9
Packit ed3af9
	width = rc->right - rc->left;
Packit ed3af9
	height = rc->bottom - rc->top;
Packit ed3af9
Packit ed3af9
	bmp_info = gdCreateBmp(width, height);
Packit ed3af9
Packit ed3af9
	// Create memory device context
Packit ed3af9
	mem_dc = CreateCompatibleDC(hdc);
Packit ed3af9
	if (!mem_dc) {
Packit ed3af9
		MessageBox(NULL, "Can't create a compatible DC!", "Error!", MB_ICONEXCLAMATION | MB_OK);
Packit ed3af9
		return;
Packit ed3af9
	}
Packit ed3af9
Packit ed3af9
	// bits points to a shared buffer of pixels
Packit ed3af9
	bits = NULL;
Packit ed3af9
	bmp = CreateDIBSection(mem_dc, &bmp_info, DIB_RGB_COLORS, (void**)&bits, 0, 0);
Packit ed3af9
Packit ed3af9
	// Selecting the object before doing anything allows you to use libgd
Packit ed3af9
	// together with native Windows GDI.
Packit ed3af9
	temp = (HBITMAP)SelectObject(mem_dc, bmp);
Packit ed3af9
Packit ed3af9
	/*stride = ((width * 1 + 3) >> 2) << 2;*/
Packit ed3af9
	// always uses 32bit in BMPINFO
Packit ed3af9
	stride = width;
Packit ed3af9
	im = NULL;
Packit ed3af9
Packit ed3af9
	// Attach shared buffer of pixels to GD image
Packit ed3af9
	// Negative stride places 0,0 in upper-left corner
Packit ed3af9
	im = gdImageTrueColorAttachBuffer((int*)bits, width, height, -stride);
Packit ed3af9
	if (!im) {
Packit ed3af9
		MessageBox(NULL, "GD image creation failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
Packit ed3af9
		return;
Packit ed3af9
	}
Packit ed3af9
Packit ed3af9
	// Start of GD drawing
Packit ed3af9
	white = gdImageColorAllocate(im, 255, 255, 255);
Packit ed3af9
	black = gdImageColorAllocate(im, 0, 0, 0);
Packit ed3af9
	blue = gdImageColorAllocate(im, 0, 0, 255);
Packit ed3af9
Packit ed3af9
	// Allocate the color red, 50% transparent.
Packit ed3af9
	red = gdImageColorAllocateAlpha(im, 255, 0, 0, 64);
Packit ed3af9
Packit ed3af9
	// Erase background with white color
Packit ed3af9
	gdImageFilledRectangle(im, 0, 0, width, height, 0xFF0000);
Packit ed3af9
Packit ed3af9
	lfont = gdFontGetLarge();
Packit ed3af9
	gfont = gdFontGetGiant();
Packit ed3af9
Packit ed3af9
	// Draw a dashed line from the upper left corner to the lower right corner.
Packit ed3af9
	gdImageFilledRectangle(im, 25, 25, 100, 100, blue);
Packit ed3af9
Packit ed3af9
	gdImageChar(im, gfont, 35, 35, 'Q', white);
Packit ed3af9
	gdImageFilledRectangle(im, 50, 50, 75, 175, red);
Packit ed3af9
	gdImageLine(im, 0, 0, 150, 150, black);
Packit ed3af9
Packit ed3af9
	gdImageString(im, gdFontGetLarge(),
Packit ed3af9
	              im->sx / 2 - (strlen(s) * lfont->w / 2),
Packit ed3af9
	              im->sy / 2 - lfont->h / 2,
Packit ed3af9
	              (unsigned char*)s, black);
Packit ed3af9
Packit ed3af9
	// Copy drawing from memory context (shared bitmap buffer) to screen DC.
Packit ed3af9
	BitBlt(hdc, rc->left, rc->top, width, height, mem_dc, 0, 0, SRCCOPY);
Packit ed3af9
Packit ed3af9
	// Free
Packit ed3af9
	gdImageDetachBuffer(im);
Packit ed3af9
	SelectObject(mem_dc, temp);
Packit ed3af9
	DeleteObject(bmp);
Packit ed3af9
	DeleteObject(mem_dc);
Packit ed3af9
}
Packit ed3af9
Packit ed3af9
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Packit ed3af9
{
Packit ed3af9
	static POINT apt[4] ;
Packit ed3af9
	HDC          hdc ;
Packit ed3af9
	int          cxClient, cyClient ;
Packit ed3af9
	PAINTSTRUCT  ps ;
Packit ed3af9
	RECT rc;
Packit ed3af9
Packit ed3af9
	GetClientRect(hwnd, &rc);
Packit ed3af9
Packit ed3af9
	switch (message) {
Packit ed3af9
	case WM_SIZE:
Packit ed3af9
		cxClient = LOWORD (lParam) ;
Packit ed3af9
		cyClient = HIWORD (lParam) ;
Packit ed3af9
Packit ed3af9
		apt[0].x = cxClient / 4 ;
Packit ed3af9
		apt[0].y = cyClient / 2 ;
Packit ed3af9
Packit ed3af9
		apt[1].x = cxClient / 2 ;
Packit ed3af9
		apt[1].y = cyClient / 4 ;
Packit ed3af9
Packit ed3af9
		apt[2].x =     cxClient / 2 ;
Packit ed3af9
		apt[2].y = 3 * cyClient / 4 ;
Packit ed3af9
Packit ed3af9
		apt[3].x = 3 * cxClient / 4 ;
Packit ed3af9
		apt[3].y =     cyClient / 2 ;
Packit ed3af9
		return 0 ;
Packit ed3af9
Packit ed3af9
	case WM_LBUTTONDOWN:
Packit ed3af9
	case WM_RBUTTONDOWN:
Packit ed3af9
	case WM_MOUSEMOVE:
Packit ed3af9
		if (wParam & MK_LBUTTON || wParam & MK_RBUTTON) {
Packit ed3af9
			hdc = GetDC (hwnd) ;
Packit ed3af9
Packit ed3af9
			// alte Kurve löschen (mit Weiß übermalen)
Packit ed3af9
			SelectObject (hdc, GetStockObject (WHITE_PEN)) ;
Packit ed3af9
			DrawBezier (hdc, apt) ;
Packit ed3af9
Packit ed3af9
			if (wParam & MK_LBUTTON) {
Packit ed3af9
				apt[1].x = LOWORD (lParam) ;
Packit ed3af9
				apt[1].y = HIWORD (lParam) ;
Packit ed3af9
			}
Packit ed3af9
Packit ed3af9
			if (wParam & MK_RBUTTON) {
Packit ed3af9
				apt[2].x = LOWORD (lParam) ;
Packit ed3af9
				apt[2].y = HIWORD (lParam) ;
Packit ed3af9
			}
Packit ed3af9
Packit ed3af9
			// neue Kurve (mit Schwarz) zeichnen
Packit ed3af9
			SelectObject (hdc, GetStockObject (BLACK_PEN)) ;
Packit ed3af9
			gdDrawImage(hdc, &rc);
Packit ed3af9
			DrawBezier (hdc, apt) ;
Packit ed3af9
			ReleaseDC (hwnd, hdc) ;
Packit ed3af9
		}
Packit ed3af9
		return 0 ;
Packit ed3af9
Packit ed3af9
Packit ed3af9
	case WM_PAINT:
Packit ed3af9
		hdc = BeginPaint (hwnd, &ps) ;
Packit ed3af9
Packit ed3af9
		GetClientRect(hwnd, &rc);
Packit ed3af9
		gdDrawImage(hdc, &rc);
Packit ed3af9
		DrawBezier (hdc, apt) ;
Packit ed3af9
Packit ed3af9
		EndPaint (hwnd, &ps) ;
Packit ed3af9
		return 0 ;
Packit ed3af9
Packit ed3af9
	case WM_DESTROY:
Packit ed3af9
		PostQuitMessage (0) ;
Packit ed3af9
		return 0 ;
Packit ed3af9
	}
Packit ed3af9
	return DefWindowProc (hwnd, message, wParam, lParam) ;
Packit ed3af9
}