到现在为止,对于已有的矩形和椭圆,由于我们知道边界的位置,且它们都是凸多边形,所以区域填色非常容易。
在这里简单汇聚一下代码,由于没加双缓冲等问题,现在的图形遮挡和刷新的闪烁现象都很难让我们接受,目前只是理论上的解决方式,这些问题将在今后更改。
为了阅读方便,代码完全用C语言编写,但没有任何注释。
定义方面
define.h
#ifndef DEFINE_H_INCLUDED
#define DEFINE_H_INCLUDED
typedef short int16;
typedef int int32;
typedef long long int64;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long long uint64;
#define swap(x, y) x ^= y, y ^= x, x ^= y;
#include "define_device.h"
#include "define_operation.h"
#include "define_menu.h"
#endif // DEFINE_H_INCLUDED
define_device.h
#ifndef DEFINE_DEVICE_H_INCLUDED
#define DEFINE_DEVICE_H_INCLUDED
#define MOUSE_LEFT 0
#define MOUSE_MIDDLE 1
#define MOUSE_RIGHT 2
#define MOUSE_DOWN 3
#define MOUSE_UP 4
#define KEY_STATE_DOWN 0
#define KEY_STATE_UP 1
#endif // DEFINE_DEVICE_H_INCLUDED
define_operation.h
#ifndef DEFINE_OPERATION_H_INCLUDED
#define DEFINE_OPERATION_H_INCLUDED
#define OP_DRAW_NULL 0
#define OP_DRAW_POINT_FREE 1
#define OP_DRAW_LINE_FREE 2
#define OP_DRAW_LINE_CLICK1 3
#define OP_DRAW_CIRCLE_FREE 4
#define OP_DRAW_CIRCLE_CLICK1 5
#define OP_DRAW_ELLIPSE_FREE 6
#define OP_DRAW_ELLIPSE_CLICK1 7
#define OP_DRAW_RECTANGLE_FREE 8
#define OP_DRAW_RECTANGLE_CLICK1 9
#define OP_DRAW_POLYGON_FREE 10
#define OP_DRAW_POLYGON_CLICK 11
#endif // DEFINE_OPERATION_H_INCLUDED
define_menu.h
#ifndef DEFINE_MENU_H_INCLUDED
#define DEFINE_MENU_H_INCLUDED
#define MENU_TYPE_POPUP 0
#define MENU_TYPE_STRING 1
#define MENU_TYPE_POPUP_END 2
#define MENU_TYPE_END 3
#endif // DEFINE_MENU_H_INCLUDED
界面方面
gui.h
#ifndef GUI_H_INCLUDED
#define GUI_H_INCLUDED
#include "define.h"
#if defined(SYSTEM_WIN)
#include "gui_windows.h"
#endif
#include "gui_menu.h"
#endif // GUI_H_INCLUDED
gui_windows.h
#ifndef GUI_WINDOWS_H_INCLUDED
#define GUI_WINDOWS_H_INCLUDED
#include <assert.h>
#include <windows.h>
#include <commctrl.h>
#include "define.h"
#define main fake_main
int fake_main();
int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int);
LRESULT CALLBACK gui_mainProcess(HWND, UINT, WPARAM, LPARAM);
void gui_createMainWindow(const char *);
void gui_setMainWindowPosition(int32 x, int32 y);
void gui_setMainWindowSize(int32 w, int32 h);
void gui_setMainWindowToCenter(void);
void gui_setMainWindowMinimize(void);
void gui_setMainWindowMaximize(void);
void gui_setMainWindowRestore(void);
void gui_mainLoop(void);
int32 gui_appendSubMenu(HMENU menu, const char *text[], const int32 id[], const int32 type[]);
void gui_appendMainMenu(const char *text[], const int32 id[], const int32 type[]);
void gui_createStatusBar(void);
void gui_setStatusBarText(int32 pos, const char *text);
void gui_repaint(void);
void gui_setPixel_2i1u(int32 x, int32 y, uint32 color);
void gui_setPixel_5i(int32 x, int32 y, uint32 r, uint32 g, uint32 b);
uint32 gui_getPixel(int32 x, int32 y);
void gui_setDisplayFunction(void (*func)(void));
void gui_setReshapeFunction(void (*func)(int32 w, int32 h));
void gui_setKeyboardFunction(void (*func)(int32 key, int32 state, int32 x, int32 y));
void gui_setMouseFunction(void (*func)(int32 button, int32 state, int32 x, int32 y));
void gui_setMotionFunction(void (*func)(int32 x, int32 y));
void gui_setMenuFunction(void (*func)(int32 id));
void gui_informationBox(const char *title, const char *text);
#endif // GUI_WINDOWS_H_INCLUDED
gui_windows.c
#include "gui_windows.h"
static HINSTANCE mainInstance;
static HWND handleMainWindow;
static HWND handleMainStatusBar;
static HMENU handleMainMenu;
static HDC handleMainWindowDeviceContext;
//static HDC mainWindowBuffer;
static RECT mainWindowRect;
static int32 systemWidth, systemHeight;
static void (*mainWindowDisplayFunction)();
static void (*mainWindowReshapeFunction)(int32, int32);
static void (*mainWindowKeyboardFunction)(int32, int32, int32, int32);
static void (*mainWindowMouseFunction)(int32, int32, int32, int32);
static void (*mainWindowMotionFunction)(int32, int32);
static void (*mainWindowMenuFunction)(int32);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
mainInstance = hInstance;
systemWidth = GetSystemMetrics(SM_CXSCREEN);
systemHeight = GetSystemMetrics(SM_CYSCREEN);
InitCommonControls();
return fake_main();
}
void gui_createMainWindow(const char *title)
{
WNDCLASS mainWindow;
mainWindow.style = CS_HREDRAW | CS_VREDRAW;
mainWindow.lpfnWndProc = gui_mainProcess;
mainWindow.cbClsExtra = 0;
mainWindow.cbWndExtra = 0;
mainWindow.hInstance = mainInstance;
mainWindow.hIcon = LoadIcon(NULL, IDI_APPLICATION);
mainWindow.hCursor = LoadCursor(NULL, IDC_ARROW);
//mainWindow.hbrBackground = NULL;
mainWindow.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
mainWindow.lpszMenuName = "mainMenu";
mainWindow.lpszClassName = "mainWindow";
if(!RegisterClass(&mainWindow))
{
MessageBox(NULL, TEXT("Cannot register class for main window."), TEXT(title), MB_ICONERROR);
exit(0);
}
handleMainMenu = CreateMenu();
handleMainWindow = CreateWindow("mainWindow",
title,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
handleMainMenu,
mainInstance,
NULL);
SetMenu(handleMainWindow, handleMainMenu);
ShowWindow(handleMainWindow, 1);
UpdateWindow(handleMainWindow);
}
void gui_setMainWindowPosition(int32 x, int32 y)
{
assert(handleMainWindow != NULL);
SetWindowPos(handleMainWindow, NULL, x, y, 0, 0, SWP_NOSIZE);
}
void gui_setMainWindowSize(int32 w, int32 h)
{
assert(handleMainWindow != NULL);
SetWindowPos(handleMainWindow, NULL, 0, 0, w, h, SWP_NOMOVE);
}
void gui_setMainWindowToCenter(void)
{
assert(handleMainWindow != NULL);
RECT rect;
GetWindowRect(handleMainWindow, &rect);
int32 w = rect.right - rect.left;
int32 h = rect.bottom - rect.top;
gui_setMainWindowPosition((systemWidth - w) >> 1, (systemHeight - h) >> 1);
}
void gui_setMainWindowMinimize(void)
{
assert(handleMainWindow != NULL);
SendMessage(handleMainWindow, WM_SYSCOMMAND, SC_MINIMIZE, (LPARAM)NULL);
}
void gui_setMainWindowMaximize(void)
{
assert(handleMainWindow != NULL);
SendMessage(handleMainWindow, WM_SYSCOMMAND, SC_MAXIMIZE, (LPARAM)NULL);
}
void gui_setMainWindowRestore(void)
{
assert(handleMainWindow != NULL);
SendMessage(handleMainWindow, WM_SYSCOMMAND, SC_RESTORE, (LPARAM)NULL);
}
void gui_mainLoop(void)
{
assert(handleMainWindow != NULL);
MSG message;
while(GetMessage(&message, NULL, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
}
int32 gui_appendSubMenu(HMENU menu, const char *text[], const int32 id[], const int32 type[])
{
int32 i;
const char *curText;
HMENU subMenu;
for(i=0;;++i)
{
switch(type[i])
{
case MENU_TYPE_POPUP:
curText = text[i];
subMenu = CreatePopupMenu();
i += gui_appendSubMenu(subMenu, text + i + 1, id + i + 1, type + i + 1) + 1;
AppendMenu(menu, MF_STRING | MF_POPUP, (UINT)subMenu, curText);
break;
case MENU_TYPE_POPUP_END:
AppendMenu(menu, MF_STRING, id[i], text[i]);
return i;
case MENU_TYPE_STRING:
case MENU_TYPE_END:
AppendMenu(menu, MF_STRING, id[i], text[i]);
break;
}
if(type[i] == MENU_TYPE_END)
{
return i;
}
}
}
void gui_appendMainMenu(const char *text[], const int32 id[], const int32 type[])
{
gui_appendSubMenu(handleMainMenu, text, id, type);
SetMenu(handleMainWindow, handleMainMenu);
}
void gui_createStatusBar(void)
{
int32 statwidths[] = {200, 400, 600, -1};
handleMainStatusBar = CreateStatusWindow(WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
"mainStatus",
handleMainWindow,
0);
SendMessage(handleMainStatusBar, SB_SETPARTS, sizeof(statwidths)/sizeof(int32), (LPARAM)statwidths);
}
void gui_setStatusBarText(int32 pos, const char *text)
{
SendMessage(handleMainStatusBar, SB_SETTEXT, pos, (LPARAM)text);
}
void gui_repaint(void)
{
InvalidateRect(handleMainWindow, NULL, TRUE);
/*BitBlt(handleMainWindowDeviceContext,
mainWindowRect.left,
mainWindowRect.top,
mainWindowRect.right - mainWindowRect.left,
mainWindowRect.bottom - mainWindowRect.top,
mainWindowBuffer,
0,
0,
SRCCOPY);*/
//DeleteDC(mainWindowBuffer);
UpdateWindow(handleMainWindow);
}
void gui_setPixel_2i1u(int32 x, int32 y, uint32 color)
{
SetPixel(handleMainWindowDeviceContext, x, y, color);
}
void gui_setPixel_5i(int32 x, int32 y, uint32 r, uint32 g, uint32 b)
{
COLORREF color = RGB(r, g, b);
SetPixel(handleMainWindowDeviceContext, x, y, color);
}
uint32 gui_getPixel(int x, int y)
{
return GetPixel(handleMainWindowDeviceContext, x, y);
}
LRESULT CALLBACK gui_mainProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
switch (message)
{
case WM_PAINT:
handleMainWindowDeviceContext = BeginPaint(hwnd, &ps);
//mainWindowBuffer = CreateCompatibleDC(handleMainWindowDeviceContext);
GetClientRect(hwnd, &mainWindowRect);
if(mainWindowDisplayFunction)
{
mainWindowDisplayFunction();
}
EndPaint(hwnd, &ps) ;
break;
case WM_COMMAND:
if(mainWindowMenuFunction)
{
mainWindowMenuFunction(LOWORD(wParam));
}
break;
case WM_SIZE:
if(mainWindowReshapeFunction)
{
mainWindowReshapeFunction(LOWORD(lParam), HIWORD(lParam));
}
break;
case WM_MOUSEMOVE:
if(mainWindowMotionFunction)
{
mainWindowMotionFunction(LOWORD(lParam), HIWORD(lParam));
}
break;
case WM_LBUTTONDOWN:
if(mainWindowMouseFunction)
{
mainWindowMouseFunction(MOUSE_LEFT, MOUSE_DOWN, LOWORD(lParam), HIWORD(lParam));
}
break;
case WM_LBUTTONUP:
if(mainWindowMouseFunction)
{
mainWindowMouseFunction(MOUSE_LEFT, MOUSE_UP, LOWORD(lParam), HIWORD(lParam));
}
break;
case WM_RBUTTONDOWN:
if(mainWindowMouseFunction)
{
mainWindowMouseFunction(MOUSE_RIGHT, MOUSE_DOWN, LOWORD(lParam), HIWORD(lParam));
}
break;
case WM_RBUTTONUP:
if(mainWindowMouseFunction)
{
mainWindowMouseFunction(MOUSE_RIGHT, MOUSE_UP, LOWORD(lParam), HIWORD(lParam));
}
break;
case WM_MBUTTONDOWN:
if(mainWindowMouseFunction)
{
mainWindowMouseFunction(MOUSE_MIDDLE, MOUSE_DOWN, LOWORD(lParam), HIWORD(lParam));
}
break;
case WM_MBUTTONUP:
if(mainWindowMouseFunction)
{
mainWindowMouseFunction(MOUSE_MIDDLE, MOUSE_UP, LOWORD(lParam), HIWORD(lParam));
}
break;
case WM_KEYDOWN:
break;
case WM_KEYUP:
break;
case WM_MOUSEWHEEL:
break;
case WM_DESTROY:
PostQuitMessage(0) ;
break;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
void gui_setDisplayFunction(void (*func)(void))
{
mainWindowDisplayFunction = func;
}
void gui_setReshapeFunction(void (*func)(int32 w, int32 h))
{
mainWindowReshapeFunction = func;
}
void gui_setKeyboardFunction(void (*func)(int32 key, int32 state, int32 x, int32 y))
{
mainWindowKeyboardFunction = func;
}
void gui_setMouseFunction(void (*func)(int32 button, int32 state, int32 x, int32 y))
{
mainWindowMouseFunction = func;
}
void gui_setMotionFunction(void (*func)(int32 x, int32 y))
{
mainWindowMotionFunction = func;
}
void gui_setMenuFunction(void (*func)(int32 id))
{
mainWindowMenuFunction = func;
}
void gui_informationBox(const char *title, const char *text)
{
MessageBox(handleMainWindow, text, title, MB_ICONINFORMATION);
}
gui_menu.h
#ifndef GUI_MENU_H_INCLUDED
#define GUI_MENU_H_INCLUDED
#include "define.h"
#include "gui.h"
#define MENU_MAIN_TOP 0
#define MENU_FILE 1000
#define MENU_FILE_EXIT 1001
#define MENU_TOOLS 2000
#define MENU_TOOLS_POINT 2001
#define MENU_TOOLS_LINE 2002
#define MENU_TOOLS_RECTANGLE 2003
#define MENU_TOOLS_CIRCLE 2004
#define MENU_TOOLS_ELLIPSE 2005
#define MENU_TOOLS_POLYGON 2006
#define MENU_HELP 3000
#define MENU_HELP_ABOUT 3001
void gui_menu_createMenu(void);
#endif // GUI_MENU_H_INCLUDED
gui_menu.c
#include "gui_menu.h"
static const char *gui_menu_text[] =
{
"File(&F)",
"Exit(&E)",
"Tools(&T)",
"Point",
"Line",
"Rectangle",
"Circle",
"Ellipse",
"Polygon",
"Help(&H)",
"About..."
};
static const int32 gui_menu_id[] =
{
MENU_FILE,
MENU_FILE_EXIT,
MENU_TOOLS,
MENU_TOOLS_POINT,
MENU_TOOLS_LINE,
MENU_TOOLS_RECTANGLE,
MENU_TOOLS_CIRCLE,
MENU_TOOLS_ELLIPSE,
MENU_TOOLS_POLYGON,
MENU_HELP,
MENU_HELP_ABOUT,
};
static const int32 gui_menu_type[] =
{
MENU_TYPE_POPUP,
MENU_TYPE_POPUP_END,
MENU_TYPE_POPUP,
MENU_TYPE_STRING,
MENU_TYPE_STRING,
MENU_TYPE_STRING,
MENU_TYPE_STRING,
MENU_TYPE_STRING,
MENU_TYPE_POPUP_END,
MENU_TYPE_POPUP,
MENU_TYPE_END
};
void gui_menu_createMenu(void)
{
gui_appendMainMenu(gui_menu_text, gui_menu_id, gui_menu_type);
}
绘制方面
draw.h
#ifndef DRAW_H_INCLUDED
#define DRAW_H_INCLUDED
#include "draw_point.h"
#include "draw_pen.h"
#include "draw_brush.h"
#include "draw_line.h"
#include "draw_rectangle.h"
#include "draw_circle.h"
#include "draw_ellipse.h"
#include "draw_polygon.h"
void draw_init();
#endif // DRAW_H_INCLUDED
draw.c
#include "draw.h"
void draw_init()
{
draw_pen_init();
draw_brush_init();
}
draw_color.h
#ifndef DRAW_COLOR_H_INCLUDED
#define DRAW_COLOR_H_INCLUDED
#include "define.h"
static const uint32 draw_color_alpha_component = 0xff000000;
static const uint32 draw_color_red_component = 0x00ff0000;
static const uint32 draw_color_green_component = 0x0000ff00;
static const uint32 draw_color_blue_component = 0x000000ff;
typedef uint32 draw_color;
draw_color draw_color_getColor_3i(uint32 r, uint32 g, uint32 b);
draw_color draw_color_getColor_4i(uint32 r, uint32 g, uint32 b, uint32 a);
uint32 draw_color_getRed(uint32 color);
uint32 draw_color_getGreen(uint32 color);
uint32 draw_color_getBlue(uint32 color);
uint32 draw_color_getAlpha(uint32 color);
#endif // DRAW_COLOR_H_INCLUDED
draw_color.c
#include "draw_color.h"
draw_color draw_color_getColor_3i(uint32 r, uint32 g, uint32 b)
{
return draw_color_getColor_4i(r, g, b, 255);
}
draw_color draw_color_getColor_4i(uint32 r, uint32 g, uint32 b, uint32 a)
{
return (((((a << 8) + r) << 8) + g) << 8) + b;
}
uint32 draw_color_getAlpha(uint32 color)
{
return (color & draw_color_alpha_component) >> 24;
}
uint32 draw_color_getRed(uint32 color)
{
return (color & draw_color_red_component) >> 16;
}
uint32 draw_color_getGreen(uint32 color)
{
return (color & draw_color_green_component) >> 8;
}
uint32 draw_color_getBlue(uint32 color)
{
return color & draw_color_blue_component;
}
draw_pen.h
#ifndef DRAW_PEN_H_INCLUDED
#define DRAW_PEN_H_INCLUDED
#include <stdlib.h>
#include "define.h"
#include "draw_color.h"
typedef struct draw_pen_
{
draw_color color;
}draw_pen_;
typedef draw_pen_ *draw_pen;
void draw_pen_init();
void draw_pen_setColor(draw_color color);
draw_color draw_pen_getColor();
#endif // DRAW_PEN_H_INCLUDED
draw_pen.c
#include "draw_pen.h"
static draw_pen draw_default_pen;
void draw_pen_init()
{
draw_default_pen = (draw_pen) malloc(sizeof(*draw_default_pen));
}
void draw_pen_setColor(draw_color color)
{
draw_default_pen->color = color;
}
draw_color draw_pen_getColor()
{
return draw_default_pen->color;
}
draw_brush.h
#ifndef DRAW_BRUSH_H_INCLUDED
#define DRAW_BRUSH_H_INCLUDED
#include <stdlib.h>
#include "define.h"
#include "draw_color.h"
typedef struct draw_brush_
{
draw_color color;
}draw_brush_;
typedef draw_brush_ *draw_brush;
void draw_brush_init();
void draw_brush_setColor(draw_color color);
draw_color draw_brush_getColor();
#endif // DRAW_BRUSH_H_INCLUDED
draw_brush.c
#include "draw_brush.h"
static draw_brush draw_default_brush;
void draw_brush_init()
{
draw_default_brush = (draw_brush) malloc(sizeof(*draw_default_brush));
}
void draw_brush_setColor(draw_color color)
{
draw_default_brush->color = color;
}
draw_color draw_brush_getColor()
{
return draw_default_brush->color;
}
draw_point.h
#ifndef DRAW_POINT_H_INCLUDED
#define DRAW_POINT_H_INCLUDED
#include "define.h"
#include "gui.h"
#include "draw_color.h"
#include "draw_pen.h"
#include "draw_brush.h"
typedef struct Point_2i
{
int32 x, y;
}Point_2i;
void draw_point_T_2i(const Point_2i point);
void draw_point_2i(int32 x, int32 y);
void draw_point_pen_2i(int32 x, int32 y);
void draw_point_brush_2i(int32 x, int32 y);
#endif // DRAW_POINT_H_INCLUDED
draw_point.c
#include "draw_point.h"
void draw_point_T_2i(const Point_2i point)
{
draw_point_2i(point.x, point.y);
}
void draw_point_2i(int32 x, int32 y)
{
draw_point_pen_2i(x, y);
}
void draw_point_pen_2i(int32 x, int32 y)
{
uint32 r, g, b;
r = draw_color_getRed(draw_pen_getColor());
g = draw_color_getGreen(draw_pen_getColor());
b = draw_color_getBlue(draw_pen_getColor());
gui_setPixel_5i(x, y, r, g, b);
}
void draw_point_brush_2i(int32 x, int32 y)
{
uint32 r, g, b;
r = draw_color_getRed(draw_brush_getColor());
g = draw_color_getGreen(draw_brush_getColor());
b = draw_color_getBlue(draw_brush_getColor());
gui_setPixel_5i(x, y, r, g, b);
}
draw_line.h
#ifndef DRAW_LINE_H_INCLUDED
#define DRAW_LINE_H_INCLUDED
#include <math.h>
#include "define.h"
#include "draw_point.h"
typedef struct Line_4i
{
int32 x0, y0;
int32 x1, y1;
}Line_4i;
void draw_line_T_4i(const Line_4i line);
void draw_line_4i(int32 x0, int32 y0, int32 x1, int32 y1);
void draw_line_DDA_4i(int32 x0, int32 y0, int32 x1, int32 y1);
void draw_line_MidPoint_4i(int32 x0, int32 y0, int32 x1, int32 y1);
void draw_line_Bresenham_4i(int32 x0, int32 y0, int32 x1, int32 y1);
#endif // DRAW_LINE_H_INCLUDED
draw_line.c
#include "draw_line.h"
void draw_line_T_4i(const Line_4i line)
{
draw_line_4i(line.x0, line.y0, line.x1, line.y1);
}
void draw_line_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
draw_line_Bresenham_4i(x0, y0, x1, y1);
}
void draw_line_DDA_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
float ky, ty;
int32 kx;
if(abs(y1 - y0) < abs(x1 - x0))
{
kx = x1 > x0 ? 1 : -1;
ky = (float)kx * (y1 - y0) / (x1 - x0);
ty = y0;
while(x0 != x1)
{
draw_point_pen_2i(x0, round(ty));
x0 += kx;
ty += ky;
}
}
else if(abs(y1 - y0) > abs(x1 - x0))
{
kx = y1 > y0 ? 1 : -1;
ky = (float)kx * (x1 - x0) / (y1 - y0);
ty = x0;
while(y0 != y1)
{
draw_point_pen_2i(round(ty), y0);
y0 += kx;
ty += ky;
}
}
else
{
draw_point_pen_2i(x0, y0);
}
}
void draw_line_MidPoint_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
int32 a, b, c;
int32 d, d1, d2;
int32 kx, ky;
a = y0 - y1;
b = x1 - x0;
c = x0 * y1 - x1 * y0;
kx = x1 > x0 ? 1 : -1;
ky = y1 > y0 ? 1 : -1;
draw_point_pen_2i(x0, y0);
if(abs(y1 - y0) < abs(x1 - x0))
{
a *= kx;
b *= ky;
d = (a << 1) + b;
d1 = (a << 1) * kx;
d2 = ((a + b) << 1) * kx;
while(x0 != x1)
{
x0 += kx;
if((ky > 0 && d < 0) || (ky < 0 && d > 0))
{
y0 += ky;
d += d2;
}
else
{
d += d1;
}
draw_point_pen_2i(x0, y0);
}
}
else
{
a *= ky;
b *= kx;
d = a + (b << 1);
d1 = (b << 1) * ky;
d2 = ((a + b) << 1) * ky;
while(y0 != y1)
{
y0 += ky;
if((ky > 0 && d > 0) || (ky < 0 && d < 0))
{
x0 += kx;
d += d2;
}
else
{
d += d1;
}
draw_point_pen_2i(x0, y0);
}
}
}
void draw_line_Bresenham_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
int32 dx, dy, e;
if(abs(y1 - y0) < abs(x1 - x0))
{
if(x0 > x1)
{
swap(x0, x1);
swap(y0, y1);
}
dx = (x1 - x0) << 1;
dy = (y1 - y0) << 1;
if(y0 < y1)
{
e = - (dx >> 1);
while(x0 != x1)
{
draw_point_pen_2i(x0, y0);
++ x0;
e = e + dy;
if(e > 0)
{
++ y0;
e -= dx;
}
}
}
else
{
e = dx >> 1;
while(x0 != x1)
{
draw_point_pen_2i(x0, y0);
++ x0;
e = e + dy;
if(e < 0)
{
-- y0;
e += dx;
}
}
}
}
else
{
if(y0 > y1)
{
swap(x0, x1);
swap(y0, y1);
}
dx = (x1 - x0) << 1;
dy = (y1 - y0) << 1;
if(x0 < x1)
{
e = - (dy >> 1);
while(y0 != y1)
{
draw_point_pen_2i(x0, y0);
++ y0;
e = e + dx;
if(e > 0)
{
++ x0;
e -= dy;
}
}
}
else
{
e = dy >> 1;
while(y0 != y1)
{
draw_point_pen_2i(x0, y0);
++ y0;
e = e + dx;
if(e < 0)
{
-- x0;
e += dy;
}
}
}
}
draw_point_pen_2i(x0, y0);
}
draw_rectangle.h
#ifndef DRAW_RECTANGULAR_H_INCLUDED
#define DRAW_RECTANGULAR_H_INCLUDED
#include "define.h"
#include "draw_line.h"
typedef struct Rectangle_4i
{
int32 x0, y0;
int32 x1, y1;
}Rectangle_4i;
void draw_rectangle_T_4i(const Rectangle_4i rectangle);
void draw_rectangle_4i(int32 x0, int32 y0, int32 x1, int32 y1);
#endif // DRAW_RECTANGULAR_H_INCLUDED
draw_rectangle.c
#include "draw_rectangle.h"
void draw_rectangle_T_4i(const Rectangle_4i rectangle)
{
draw_rectangle_4i(rectangle.x0, rectangle.y0,
rectangle.x1, rectangle.y1);
}
void draw_rectangle_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
int32 i, j;
draw_line_4i(x0, y0, x1, y0);
draw_line_4i(x0, y1, x1, y1);
draw_line_4i(x0, y0, x0, y1);
draw_line_4i(x1, y0, x1, y1);
if(x0 > x1)
{
swap(x0, x1);
}
if(y0 > y1)
{
swap(y0, y1);
}
++ x0, -- x1;
++ y0, -- y1;
for(i=x0;i<=x1;++i)
{
for(j=y0;j<=y1;++j)
{
draw_point_brush_2i(i, j);
}
}
}
draw_circle.h
#ifndef DRAW_CIRCLE_H_INCLUDED
#define DRAW_CIRCLE_H_INCLUDED
#include <math.h>
#include "define.h"
#include "draw_point.h"
typedef struct Circle_3i
{
int32 x, y;
int32 r;
}Circle_3i;
void draw_circle_T_3i(const Circle_3i circle);
void draw_circle_3i(int32 x, int32 y, int32 r);
void draw_circle_Coordinate_3i(int32 x, int32 y, int32 r);
void draw_circle_MidPoint_3i(int32 x, int32 y, int32 r);
void draw_circle_Bresenham_3i(int32 x, int32 y, int32 r);
#endif // DRAW_CIRCLE_H_INCLUDED
draw_circle.c
#include "draw_circle.h"
void draw_circle_T_3i(const Circle_3i circle)
{
draw_circle_3i(circle.x, circle.y, circle.r);
}
void draw_circle_3i(int32 x, int32 y, int32 r)
{
draw_circle_Bresenham_3i(x, y, r);
}
void draw_circle_Coordinate_3i(int32 x, int32 y, int32 r)
{
int32 i, k, t, rr = (int32)ceil(r / sqrt(2.0));
for(i=0;i<=rr;++i)
{
t = (int32)sqrt(r * r - i * i);
for(k=y-i+1;k<y+i;++k)
{
draw_point_brush_2i(x + t, k);
draw_point_brush_2i(x - t, k);
}
for(k=y-t+1;k<y+t;++k)
{
draw_point_brush_2i(x + i, k);
draw_point_brush_2i(x - i, k);
}
draw_point_2i(x + i, y + t);
draw_point_2i(x + i, y - t);
draw_point_2i(x + t, y + i);
draw_point_2i(x - t, y + i);
draw_point_2i(x - i, y + t);
draw_point_2i(x - i, y - t);
draw_point_2i(x + t, y - i);
draw_point_2i(x - t, y - i);
}
}
void draw_circle_MidPoint_3i(int32 x, int32 y, int32 r)
{
int32 d, i, j, k;
int32 rr = (int32)ceil(r / sqrt(2.0));
j = r;
d = - (j<<2) + 5;
for(i=0;i<=rr;++i)
{
for(k=y-i+1;k<y+i;++k)
{
draw_point_brush_2i(x + j, k);
draw_point_brush_2i(x - j, k);
}
for(k=y-j+1;k<y+j;++k)
{
draw_point_brush_2i(x + i, k);
draw_point_brush_2i(x - i, k);
}
draw_point_2i(x + i, y + j);
draw_point_2i(x + i, y - j);
draw_point_2i(x + j, y + i);
draw_point_2i(x - j, y + i);
draw_point_2i(x - i, y + j);
draw_point_2i(x - i, y - j);
draw_point_2i(x + j, y - i);
draw_point_2i(x - j, y - i);
if(d > 0)
{
d -= (i << 3) + 4;
}
else
{
-- j;
d -= (i - j + 1) << 3;
}
}
}
void draw_circle_Bresenham_3i(int32 x, int32 y, int32 r)
{
int32 e, i, j, k;
int32 rr = (int32)ceil(r / sqrt(2.0));
j = r;
e = 3 - (r << 1);
for(i=0;i<=rr;++i)
{
for(k=y-i+1;k<y+i;++k)
{
draw_point_brush_2i(x + j, k);
draw_point_brush_2i(x - j, k);
}
for(k=y-j+1;k<y+j;++k)
{
draw_point_brush_2i(x + i, k);
draw_point_brush_2i(x - i, k);
}
draw_point_2i(x + i, y + j);
draw_point_2i(x + i, y - j);
draw_point_2i(x + j, y + i);
draw_point_2i(x - j, y + i);
draw_point_2i(x - i, y + j);
draw_point_2i(x - i, y - j);
draw_point_2i(x + j, y - i);
draw_point_2i(x - j, y - i);
if(e < 0)
{
e += (i << 2) + 6;
}
else
{
e += ((i - j)<<2) + 10;
-- j;
}
}
}
draw_ellipse.h
#ifndef DRAW_ELLIPSE_H_INCLUDED
#define DRAW_ELLIPSE_H_INCLUDED
#include <math.h>
#include "define.h"
#include "draw_point.h"
typedef struct Ellipse_4i
{
int32 x0, y0;
int32 x1, y1;
}Ellipse_4i;
void draw_ellipse_T_4i(const Ellipse_4i ellipse);
void draw_ellipse_4i(int32 x0, int32 y0, int32 x1, int32 y1);
void draw_ellipse_Coordinate_4i(int32 x0, int32 y0, int32 x1, int32 y1);
void draw_ellipse_Bresenham_4i(int32 x0, int32 y0, int32 x1, int32 y1);
#endif // DRAW_ELLIPSE_H_INCLUDED
draw_ellipse.c
#include "draw_ellipse.h"
void draw_ellipse_T_4i(const Ellipse_4i ellipse)
{
draw_ellipse_4i(ellipse.x0, ellipse.y0, ellipse.x1, ellipse.y1);
}
void draw_ellipse_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
draw_ellipse_Bresenham_4i(x0, y0, x1, y1);
}
void draw_ellipse_Coordinate_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
int32 i, j, t;
int32 x = (x0 + x1) >> 1;
int32 y = (y0 + y1) >> 1;
int32 a = abs(x0 - x1) >> 1;
int32 b = abs(y0 - y1) >> 1;
int32 aa = a * a;
int32 bb = b * b;
for(i=0;i<=a;++i)
{
t = (int32)sqrt(bb - 1.0 * bb / aa * i * i);
for(j=y-t+1;j<y+t;++j)
{
draw_point_brush_2i(x + i, j);
draw_point_brush_2i(x - i, j);
}
draw_point_2i(x + i, y + t);
draw_point_2i(x + i, y - t);
draw_point_2i(x - i, y + t);
draw_point_2i(x - i, y - t);
}
for(i=0;i<=b;++i)
{
t = (int32)sqrt(aa - 1.0 * aa / bb * i * i);
for(j=y-i+1;j<y+i;++j)
{
draw_point_brush_2i(x + t, j);
draw_point_brush_2i(x - t, j);
}
draw_point_2i(x + t, y + i);
draw_point_2i(x - t, y + i);
draw_point_2i(x + t, y - i);
draw_point_2i(x - t, y - i);
}
}
void draw_ellipse_Bresenham_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
int32 i, j, k;
int32 x = (x0 + x1) >> 1;
int32 y = (y0 + y1) >> 1;
int32 a = abs(x0 - x1) >> 1;
int32 b = abs(y0 - y1) >> 1;
int64 e, aa, bb;
aa = a * a;
bb = b * b;
j = b;
e = (bb << 2) + aa * (1 - (b << 2));
for(i=0;i<=a;++i)
{
for(k=y-j+1;k<y+j;++k)
{
draw_point_brush_2i(x + i, k);
draw_point_brush_2i(x - i, k);
}
draw_point_2i(x + i, y + j);
draw_point_2i(x + i, y - j);
draw_point_2i(x - i, y + j);
draw_point_2i(x - i, y - j);
if(e <= 0)
{
e += bb * (12 + (i<<3));
}
else
{
e += bb * (12 + (i<<3)) + aa * (8 - (j<<3));
-- j;
}
if(bb * ((i<<1) + 2) > aa * ((j<<1) - 1))
{
break;
}
}
e = bb * ((i<<1) + 1) * ((i<<1) + 1) + aa * ((j<<1) - 2) * ((j<<1) - 2) - ((aa * bb)<<2);
for(;j>=0;--j)
{
for(k=y-j+1;k<y+j;++k)
{
draw_point_brush_2i(x + i, k);
draw_point_brush_2i(x - i, k);
}
draw_point_2i(x + i, y + j);
draw_point_2i(x + i, y - j);
draw_point_2i(x - i, y + j);
draw_point_2i(x - i, y - j);
if(e <= 0)
{
e += bb * (8 + (i<<3)) + aa * (12 - (j<<3));
++ i;
}
else
{
e += aa * (12 - (j<<3));
}
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include <math.h>
#include "define.h"
#include "gui.h"
#include "draw.h"
#define MAXN 100
static char tempText[1024];
static int32 operationState;
Point_2i points[MAXN];
Line_4i lines[MAXN];
Rectangle_4i rectangles[MAXN];
Circle_3i circles[MAXN];
Ellipse_4i ellipses[MAXN];
int32 pointNumber;
int32 lineNumber;
int32 rectangleNumber;
int32 circleNumber;
int32 ellipseNumber;
void displayFunction(void)
{
int i;
for(i=0;i<pointNumber;++i)
{
draw_point_T_2i(points[i]);
}
for(i=0;i<lineNumber;++i)
{
draw_line_T_4i(lines[i]);
}
for(i=0;i<rectangleNumber;++i)
{
draw_rectangle_T_4i(rectangles[i]);
}
for(i=0;i<circleNumber;++i)
{
draw_circle_T_3i(circles[i]);
}
for(i=0;i<ellipseNumber;++i)
{
draw_ellipse_T_4i(ellipses[i]);
}
}
void reshapeFunction(int32 w, int32 h)
{
gui_repaint();
}
void keyboardFunction(int32 key, int32 state, int32 x, int32 y)
{
//TODO
}
void showCurrentStatus(int32 x, int32 y)
{
struct tm *local;
time_t t;
t = time(NULL);
local = localtime(&t);
gui_setStatusBarText(0, "Zsys Studio 2012");
switch(operationState)
{
case OP_DRAW_POINT_FREE:
gui_setStatusBarText(1, "Draw Point");
break;
case OP_DRAW_LINE_FREE:
case OP_DRAW_LINE_CLICK1:
gui_setStatusBarText(1, "Draw Line");
break;
case OP_DRAW_RECTANGLE_FREE:
case OP_DRAW_RECTANGLE_CLICK1:
gui_setStatusBarText(1, "Draw Rectangle");
break;
case OP_DRAW_CIRCLE_FREE:
case OP_DRAW_CIRCLE_CLICK1:
gui_setStatusBarText(1, "Draw Circle");
break;
case OP_DRAW_ELLIPSE_FREE:
case OP_DRAW_ELLIPSE_CLICK1:
gui_setStatusBarText(1, "Draw Ellipse");
break;
default:
gui_setStatusBarText(1, "No Operation");
}
sprintf(tempText, "Position: (%d, %d)", x, y);
gui_setStatusBarText(2, tempText);
strcpy(tempText, "Time: 00:00:00");
if(local->tm_hour > 9)
{
tempText[6] = local->tm_hour / 10 + '0';
}
tempText[7] = local->tm_hour % 10 + '0';
if(local->tm_min > 9)
{
tempText[9] = local->tm_min / 10 + '0';
}
tempText[10] = local->tm_min % 10 + '0';
if(local->tm_sec > 9)
{
tempText[12] = local->tm_sec / 10 + '0';
}
tempText[13] = local->tm_sec % 10 + '0';
gui_setStatusBarText(3, tempText);
}
void mouseFunction(int32 button, int32 state, int32 x, int32 y)
{
switch(state)
{
case MOUSE_DOWN:
switch(button)
{
case MOUSE_LEFT:
switch(operationState)
{
case OP_DRAW_POINT_FREE:
points[pointNumber].x = x;
points[pointNumber].y = y;
++ pointNumber;
break;
case OP_DRAW_LINE_FREE:
lines[lineNumber].x0 = x;
lines[lineNumber].y0 = y;
lines[lineNumber].x1 = x;
lines[lineNumber].y1 = y;
++ lineNumber;
operationState = OP_DRAW_LINE_CLICK1;
break;
case OP_DRAW_RECTANGLE_FREE:
rectangles[rectangleNumber].x0 = x;
rectangles[rectangleNumber].y0 = y;
rectangles[rectangleNumber].x1 = x;
rectangles[rectangleNumber].y1 = y;
++ rectangleNumber;
operationState = OP_DRAW_RECTANGLE_CLICK1;
break;
case OP_DRAW_CIRCLE_FREE:
circles[circleNumber].x = x;
circles[circleNumber].y = y;
circles[circleNumber].r = 0;
++ circleNumber;
operationState = OP_DRAW_CIRCLE_CLICK1;
break;
case OP_DRAW_ELLIPSE_FREE:
ellipses[ellipseNumber].x0 = x;
ellipses[ellipseNumber].y0 = y;
ellipses[ellipseNumber].x1 = x;
ellipses[ellipseNumber].y1 = y;
++ ellipseNumber;
operationState = OP_DRAW_ELLIPSE_CLICK1;
break;
}
break;
case MOUSE_MIDDLE:
break;
case MOUSE_RIGHT:
switch(operationState)
{
case OP_DRAW_LINE_CLICK1:
-- lineNumber;
operationState = OP_DRAW_LINE_FREE;
break;
case OP_DRAW_RECTANGLE_CLICK1:
-- rectangleNumber;
operationState = OP_DRAW_RECTANGLE_FREE;
break;
case OP_DRAW_CIRCLE_CLICK1:
-- circleNumber;
operationState = OP_DRAW_CIRCLE_FREE;
break;
case OP_DRAW_ELLIPSE_CLICK1:
-- ellipseNumber;
operationState = OP_DRAW_ELLIPSE_FREE;
break;
}
break;
}
break;
case MOUSE_UP:
switch(button)
{
case MOUSE_LEFT:
switch(operationState)
{
case OP_DRAW_LINE_CLICK1:
lines[lineNumber - 1].x1 = x;
lines[lineNumber - 1].y1 = y;
operationState = OP_DRAW_LINE_FREE;
break;
case OP_DRAW_RECTANGLE_CLICK1:
rectangles[rectangleNumber - 1].x1 = x;
rectangles[rectangleNumber - 1].y1 = y;
operationState = OP_DRAW_RECTANGLE_FREE;
break;
case OP_DRAW_CIRCLE_CLICK1:
circles[circleNumber - 1].r = sqrt((circles[circleNumber-1].x - x) *
(circles[circleNumber-1].x - x) +
(circles[circleNumber-1].y - y) *
(circles[circleNumber-1].y - y));
operationState = OP_DRAW_CIRCLE_FREE;
break;
case OP_DRAW_ELLIPSE_CLICK1:
ellipses[ellipseNumber - 1].x1 = x;
ellipses[ellipseNumber - 1].y1 = y;
operationState = OP_DRAW_ELLIPSE_FREE;
break;
}
break;
break;
case MOUSE_MIDDLE:
break;
case MOUSE_RIGHT:
break;
}
break;
}
showCurrentStatus(x, y);
gui_repaint();
}
void motionFunction(int32 x, int32 y)
{
switch(operationState)
{
case OP_DRAW_LINE_CLICK1:
lines[lineNumber - 1].x1 = x;
lines[lineNumber - 1].y1 = y;
break;
case OP_DRAW_RECTANGLE_CLICK1:
rectangles[rectangleNumber - 1].x1 = x;
rectangles[rectangleNumber - 1].y1 = y;
break;
case OP_DRAW_CIRCLE_CLICK1:
circles[circleNumber - 1].r = sqrt((circles[circleNumber-1].x - x) *
(circles[circleNumber-1].x - x) +
(circles[circleNumber-1].y - y) *
(circles[circleNumber-1].y - y));
break;
case OP_DRAW_ELLIPSE_CLICK1:
ellipses[ellipseNumber - 1].x1 = x;
ellipses[ellipseNumber - 1].y1 = y;
break;
}
gui_repaint();
showCurrentStatus(x, y);
}
void menuFunction(int32 id)
{
switch(id)
{
case MENU_FILE_EXIT:
exit(0);
break;
case MENU_TOOLS_POINT:
operationState = OP_DRAW_POINT_FREE;
break;
case MENU_TOOLS_LINE:
operationState = OP_DRAW_LINE_FREE;
break;
case MENU_TOOLS_RECTANGLE:
operationState = OP_DRAW_RECTANGLE_FREE;
break;
case MENU_TOOLS_CIRCLE:
operationState = OP_DRAW_CIRCLE_FREE;
break;
case MENU_TOOLS_ELLIPSE:
operationState = OP_DRAW_ELLIPSE_FREE;
break;
case MENU_HELP_ABOUT:
gui_informationBox("About...", "Zsys Studio 2012");
break;
}
}
int main()
{
#ifndef DEBUG
freopen("log.txt", "w", stdout);
#endif
freopen("error.txt", "w", stderr);
gui_createMainWindow("ZPIC");
gui_setMainWindowSize(800, 600);
gui_setMainWindowToCenter();
gui_menu_createMenu();
gui_createStatusBar();
gui_setDisplayFunction(displayFunction);
gui_setReshapeFunction(reshapeFunction);
gui_setKeyboardFunction(keyboardFunction);
gui_setMouseFunction(mouseFunction);
gui_setMotionFunction(motionFunction);
gui_setMenuFunction(menuFunction);
draw_init();
draw_pen_setColor(draw_color_getColor_3i(0, 0, 0));
draw_brush_setColor(draw_color_getColor_3i(180, 180, 200));
operationState = OP_DRAW_NULL;
pointNumber = 0;
lineNumber = 0;
rectangleNumber = 0;
circleNumber = 0;
ellipseNumber = 0;
gui_mainLoop();
return 0;
}