diff options
| author | Bernard Xiong <[email protected]> | 2013-02-21 13:11:10 +0800 |
|---|---|---|
| committer | Bernard Xiong <[email protected]> | 2013-02-21 13:11:10 +0800 |
| commit | 385f682d7bfce81ba281faaffb0a250ab94985b8 (patch) | |
| tree | 94fca413db98390d21dc18938067a7a90e470a6f /components/rtgui/common/dc.c | |
| parent | c4bd0023f8da136c5788f47f9a0170a77f627be9 (diff) | |
remove RT-Thread GUI from RT-Thread temporary
Diffstat (limited to 'components/rtgui/common/dc.c')
| -rw-r--r-- | components/rtgui/common/dc.c | 1388 |
1 files changed, 0 insertions, 1388 deletions
diff --git a/components/rtgui/common/dc.c b/components/rtgui/common/dc.c deleted file mode 100644 index 9ba967ed29..0000000000 --- a/components/rtgui/common/dc.c +++ /dev/null @@ -1,1388 +0,0 @@ -/* - * File : dc.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2009-10-16 Bernard first version - * 2010-09-20 richard modified rtgui_dc_draw_round_rect - * 2010-09-27 Bernard fix draw_mono_bmp issue - * 2011-04-25 Bernard fix fill polygon issue, which found by loveic - */ -#include <rtgui/dc.h> -#include <rtgui/rtgui_system.h> - -#include <string.h> /* for strlen */ -#include <stdlib.h> /* fir qsort */ - -/* for sin/cos etc */ -#include <math.h> -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -static int _int_compare(const void *a, const void *b) -{ - return (*(const int *) a) - (*(const int *) b); -} - -void rtgui_dc_destory(struct rtgui_dc *dc) -{ - if (dc == RT_NULL) return; - - dc->engine->fini(dc); - rtgui_free(dc); -} -RTM_EXPORT(rtgui_dc_destory); - -void rtgui_dc_draw_line(struct rtgui_dc *dc, int x1, int y1, int x2, int y2) -{ - if (dc == RT_NULL) return; - - if (y1 == y2) - { - rtgui_dc_draw_hline(dc, x1, x2, y1); - } - else if (x1 == x2) - { - rtgui_dc_draw_vline(dc, x1, y1, y2); - } - else - { - int dx, dy, sdx, sdy, dxabs, dyabs, x, y, px, py; - register rt_base_t i; - /* rtgui_rect_t rect; */ - - dx = x2 - x1; /* the horizontal distance of the line */ - dy = y2 - y1; /* the vertical distance of the line */ - -#define rtgui_sgn(x) ((x<0)?-1:((x>0)?1:0)) /* macro to return the sign of a number */ -#define rtgui_abs(x) ((x)>=0? (x):-(x)) /* macro to return the absolute value */ - - dxabs = rtgui_abs(dx); - dyabs = rtgui_abs(dy); - sdx = rtgui_sgn(dx); - sdy = rtgui_sgn(dy); - x = dyabs >> 1; - y = dxabs >> 1; - px = x1; - py = y1; - - if (dxabs >= dyabs) /* the line is more horizontal than vertical */ - { - for (i = 0; i < dxabs; i++) - { - y += dyabs; - if (y >= dxabs) - { - y -= dxabs; - py += sdy; - } - px += sdx; - - /* draw this point */ - rtgui_dc_draw_point(dc, px, py); - } - } - else /* the line is more vertical than horizontal */ - { - for (i = 0; i < dyabs; i++) - { - x += dxabs; - if (x >= dyabs) - { - x -= dyabs; - px += sdx; - } - py += sdy; - - /* draw this point */ - rtgui_dc_draw_point(dc, px, py); - } - } - } -} -RTM_EXPORT(rtgui_dc_draw_line); - -void rtgui_dc_draw_horizontal_line(struct rtgui_dc *dc, int x1, int x2, int y) -{ - rtgui_color_t color; - - if (dc == RT_NULL) return ; - - /* save old color */ - color = RTGUI_DC_FC(dc); - - RTGUI_DC_FC(dc) = dark_grey; - rtgui_dc_draw_hline(dc, x1, x2, y); - - y ++; - - RTGUI_DC_FC(dc) = high_light; - rtgui_dc_draw_hline(dc, x1, x2, y); - - /* restore color */ - RTGUI_DC_FC(dc) = color; -} -RTM_EXPORT(rtgui_dc_draw_horizontal_line); - -void rtgui_dc_draw_vertical_line(struct rtgui_dc *dc, int x, int y1, int y2) -{ - rtgui_color_t color; - - if (dc == RT_NULL) return ; - - /* save old color */ - color = RTGUI_DC_FC(dc); - - RTGUI_DC_FC(dc) = dark_grey; - rtgui_dc_draw_vline(dc, x, y1, y2); - - x ++; - - RTGUI_DC_FC(dc) = high_light; - rtgui_dc_draw_vline(dc, x, y1, y2); - - /* restore color */ - RTGUI_DC_FC(dc) = color; -} -RTM_EXPORT(rtgui_dc_draw_vertical_line); - -void rtgui_dc_draw_rect(struct rtgui_dc *dc, struct rtgui_rect *rect) -{ - rtgui_dc_draw_hline(dc, rect->x1, rect->x2, rect->y1); - rtgui_dc_draw_hline(dc, rect->x1, rect->x2, rect->y2 - 1); - - rtgui_dc_draw_vline(dc, rect->x1, rect->y1, rect->y2); - rtgui_dc_draw_vline(dc, rect->x2 - 1, rect->y1, rect->y2); -} -RTM_EXPORT(rtgui_dc_draw_rect); - -void rtgui_dc_fill_rect_forecolor(struct rtgui_dc *dc, struct rtgui_rect *rect) -{ - int i = 0; - - rtgui_dc_draw_rect(dc, rect); - do - { - rtgui_dc_draw_hline(dc, rect->x1 + 1, rect->x2 - 1, rect->y1 + i); - i++; - } - while (!(rect->y1 + i == rect->y2)); -} -RTM_EXPORT(rtgui_dc_fill_rect_forecolor); - -void rtgui_dc_draw_round_rect(struct rtgui_dc *dc, struct rtgui_rect *rect, int r) -{ - RT_ASSERT(((rect->x2 - rect->x1) / 2 >= r) && ((rect->y2 - rect->y1) / 2 >= r)); - - if (r < 0) - { - return; - } - - if (r == 0) - { - rtgui_dc_draw_rect(dc, rect); - return; - } - - if (((rect->x2 - rect->x1) / 2 >= r) && ((rect->y2 - rect->y1) / 2 >= r)) - { - rtgui_dc_draw_arc(dc, rect->x1 + r, rect->y1 + r, r, 180, 270); - rtgui_dc_draw_arc(dc, rect->x2 - r, rect->y1 + r, r, 270, 360); - rtgui_dc_draw_arc(dc, rect->x1 + r, rect->y2 - r, r, 90, 180); - rtgui_dc_draw_arc(dc, rect->x2 - r, rect->y2 - r, r, 0, 90); - - rtgui_dc_draw_hline(dc, rect->x1 + r, rect->x2 - r, rect->y1); - rtgui_dc_draw_hline(dc, rect->x1 + r, rect->x2 - r, rect->y2); - rtgui_dc_draw_vline(dc, rect->x1, rect->y1 + r, rect->y2 - r); - rtgui_dc_draw_vline(dc, rect->x2, rect->y1 + r, rect->y2 - r); - } -} -RTM_EXPORT(rtgui_dc_draw_round_rect); - -void rtgui_dc_fill_round_rect(struct rtgui_dc *dc, struct rtgui_rect *rect, int r) -{ - struct rtgui_rect rect_temp; - - RT_ASSERT(((rect->x2 - rect->x1) / 2 >= r) && ((rect->y2 - rect->y1) / 2 >= r)); - - if (((rect->x2 - rect->x1) / 2 >= r) && ((rect->y2 - rect->y1) / 2 >= r)) - { - rect_temp.x1 = rect->x1 + r; - rect_temp.y1 = rect->y1; - rect_temp.x2 = rect->x2 - r; - rect_temp.y2 = rect->y2; - rtgui_dc_fill_rect_forecolor(dc, &rect_temp);//fill rect with foreground - - rect_temp.x1 = rect->x1; - rect_temp.y1 = rect->y1 + r; - rect_temp.x2 = rect->x1 + r; - rect_temp.y2 = rect->y2 - r; - rtgui_dc_fill_rect_forecolor(dc, &rect_temp);//fill rect with foreground - - rect_temp.x1 = rect->x2 - r; - rect_temp.y1 = rect->y1 + r; - rect_temp.x2 = rect->x2; - rect_temp.y2 = rect->y2 - r; - rtgui_dc_fill_rect_forecolor(dc, &rect_temp);//fill rect with foreground - - rtgui_dc_fill_circle(dc, rect->x1 + r, rect->y1 + r, r); - rtgui_dc_fill_circle(dc, rect->x2 - r, rect->y2 - r, r); - rtgui_dc_fill_circle(dc, rect->x2 - r, rect->y1 + r, r); - rtgui_dc_fill_circle(dc, rect->x1 + r, rect->y2 - r, r); - } -} -RTM_EXPORT(rtgui_dc_fill_round_rect); - -void rtgui_dc_draw_shaded_rect(struct rtgui_dc *dc, rtgui_rect_t *rect, - rtgui_color_t c1, rtgui_color_t c2) -{ - RT_ASSERT(dc != RT_NULL); - - RTGUI_DC_FC(dc) = c1; - rtgui_dc_draw_vline(dc, rect->x1, rect->y1, rect->y2); - rtgui_dc_draw_hline(dc, rect->x1 + 1, rect->x2, rect->y1); - - RTGUI_DC_FC(dc) = c2; - rtgui_dc_draw_vline(dc, rect->x2 - 1, rect->y1, rect->y2); - rtgui_dc_draw_hline(dc, rect->x1, rect->x2, rect->y2 - 1); -} -RTM_EXPORT(rtgui_dc_draw_shaded_rect); - -void rtgui_dc_draw_focus_rect(struct rtgui_dc *dc, rtgui_rect_t *rect) -{ - int x, y; - - for (x = rect->x1; x < rect->x2 - 1; x++) - { - if ((x + rect->y1) & 0x01) - rtgui_dc_draw_point(dc, x, rect->y1); - if ((x + rect->y2 - 1) & 0x01) - rtgui_dc_draw_point(dc, x, rect->y2 - 1); - } - - for (y = rect->y1; y < rect->y2; y++) - { - if ((rect->x1 + y) & 0x01) - rtgui_dc_draw_point(dc, rect->x1, y); - if ((rect->x2 - 1 + y) & 0x01) - rtgui_dc_draw_point(dc, rect->x2 - 1, y); - } -} -RTM_EXPORT(rtgui_dc_draw_focus_rect); - -void rtgui_dc_draw_text(struct rtgui_dc *dc, const char *text, struct rtgui_rect *rect) -{ - rt_uint32_t len; - struct rtgui_font *font; - struct rtgui_rect text_rect; - - RT_ASSERT(dc != RT_NULL); - - font = RTGUI_DC_FONT(dc); - if (font == RT_NULL) - { - /* use system default font */ - font = rtgui_font_default(); - } - - /* text align */ - rtgui_font_get_metrics(font, text, &text_rect); - rtgui_rect_moveto_align(rect, &text_rect, RTGUI_DC_TEXTALIGN(dc)); - - len = strlen((const char *)text); - rtgui_font_draw(font, dc, text, len, &text_rect); -} -RTM_EXPORT(rtgui_dc_draw_text); - -void rtgui_dc_draw_text_stroke(struct rtgui_dc *dc, const char *text, struct rtgui_rect *rect, - rtgui_color_t color_stroke, rtgui_color_t color_core) -{ - int x, y; - rtgui_rect_t r; - rtgui_color_t fc; - - RT_ASSERT(dc != RT_NULL); - - fc = RTGUI_DC_FC(dc); - RTGUI_DC_FC(dc) = color_stroke; - for (x = -1; x < 2; x++) - { - for (y = -1; y < 2; y++) - { - r = *rect; - rtgui_rect_moveto(&r, x, y); - rtgui_dc_draw_text(dc, text, &r); - } - } - RTGUI_DC_FC(dc) = color_core; - rtgui_dc_draw_text(dc, text, rect); - RTGUI_DC_FC(dc) = fc; -} -RTM_EXPORT(rtgui_dc_draw_text_stroke); - -/* - * draw a monochrome color bitmap data - */ -void rtgui_dc_draw_mono_bmp(struct rtgui_dc *dc, int x, int y, int w, int h, const rt_uint8_t *data) -{ - int i, j, k; - - /* get word bytes */ - w = (w + 7) / 8; - - /* draw mono bitmap data */ - for (i = 0; i < h; i ++) - for (j = 0; j < w; j++) - for (k = 0; k < 8; k++) - if (((data[i * w + j] >> (7 - k)) & 0x01) != 0) - rtgui_dc_draw_point(dc, x + 8 * j + k, y + i); -} -RTM_EXPORT(rtgui_dc_draw_mono_bmp); - -void rtgui_dc_draw_byte(struct rtgui_dc *dc, int x, int y, int h, const rt_uint8_t *data) -{ - rtgui_dc_draw_mono_bmp(dc, x, y, 8, h, data); -} -RTM_EXPORT(rtgui_dc_draw_byte); - -void rtgui_dc_draw_word(struct rtgui_dc *dc, int x, int y, int h, const rt_uint8_t *data) -{ - rtgui_dc_draw_mono_bmp(dc, x, y, 16, h, data); -} -RTM_EXPORT(rtgui_dc_draw_word); - -void rtgui_dc_draw_border(struct rtgui_dc *dc, rtgui_rect_t *rect, int flag) -{ - rtgui_rect_t r; - rtgui_color_t color; - - if (dc == RT_NULL) return ; - - /* save old color */ - color = RTGUI_DC_FC(dc); - - r = *rect; - switch (flag) - { - case RTGUI_BORDER_RAISE: - rtgui_dc_draw_shaded_rect(dc, &r, high_light, black); - rtgui_rect_inflate(&r, -1); - rtgui_dc_draw_shaded_rect(dc, &r, light_grey, dark_grey); - break; - - case RTGUI_BORDER_SUNKEN: - rtgui_dc_draw_shaded_rect(dc, &r, dark_grey, high_light); - rtgui_rect_inflate(&r, -1); - rtgui_dc_draw_shaded_rect(dc, &r, black, light_grey); - break; - - case RTGUI_BORDER_BOX: - rtgui_dc_draw_shaded_rect(dc, &r, dark_grey, high_light); - rtgui_rect_inflate(&r, -1); - rtgui_dc_draw_shaded_rect(dc, &r, high_light, dark_grey); - break; - - case RTGUI_BORDER_STATIC: - rtgui_dc_draw_shaded_rect(dc, &r, dark_grey, high_light); - break; - - case RTGUI_BORDER_EXTRA: - RTGUI_DC_FC(dc) = light_grey; - rtgui_dc_draw_rect(dc, &r); - break; - - case RTGUI_BORDER_SIMPLE: - RTGUI_DC_FC(dc) = black; - rtgui_dc_draw_rect(dc, &r); - break; - - default: - break; - } - - /* restore color */ - RTGUI_DC_FC(dc) = color; -} -RTM_EXPORT(rtgui_dc_draw_border); - -void rtgui_dc_draw_polygon(struct rtgui_dc *dc, const int *vx, const int *vy, int count) -{ - int i; - const int *x1, *y1, *x2, *y2; - - /* - * Sanity check - */ - if (count < 3) return; - - /* - * Pointer setup - */ - x1 = x2 = vx; - y1 = y2 = vy; - x2++; - y2++; - - /* - * Draw - */ - for (i = 1; i < count; i++) - { - rtgui_dc_draw_line(dc, *x1, *y1, *x2, *y2); - x1 = x2; - y1 = y2; - x2++; - y2++; - } - rtgui_dc_draw_line(dc, *x1, *y1, *vx, *vy); -} -RTM_EXPORT(rtgui_dc_draw_polygon); - -void rtgui_dc_draw_regular_polygon(struct rtgui_dc *dc, int x, int y, int r, int count, rt_uint16_t angle) -{ - int i, temp_val; - double temp; - float angle_interval; - int *xx; - int *x_head; - int *yy; - int *y_head; - - /* - * Sanity check - */ - if (count < 3) return; - - angle_interval = 360.0 / count; - - /* - * Pointer setup - */ - - x_head = xx = (int *)rtgui_malloc(sizeof(int) * count); - y_head = yy = (int *)rtgui_malloc(sizeof(int) * count); - - for (i = 0; i < count; i++) - { - temp = cos(((angle_interval * i) + angle) * M_PI / 180); - temp *= r; - temp_val = (int)temp; - *xx = temp_val + x; - - temp = sin(((angle_interval * i) + angle) * M_PI / 180); - temp *= r; - temp_val = (int)temp; - *yy = temp_val + y; - - xx++; - yy++; - } - - rtgui_dc_draw_polygon(dc, (const int *)x_head, (const int *)y_head, count); - - rtgui_free(x_head); - rtgui_free(y_head); - -} -RTM_EXPORT(rtgui_dc_draw_regular_polygon); - -void rtgui_dc_fill_polygon(struct rtgui_dc *dc, const int *vx, const int *vy, int count) -{ - int i; - int y, xa, xb; - int miny, maxy; - int x1, y1; - int x2, y2; - int ind1, ind2; - int ints; - int *poly_ints = RT_NULL; - - /* - * Sanity check number of edges - */ - if (count < 3) return; - - /* - * Allocate temp array, only grow array - */ - poly_ints = (int *) rtgui_malloc(sizeof(int) * count); - if (poly_ints == RT_NULL) return ; /* no memory, failed */ - - /* - * Determine Y maximal - */ - miny = vy[0]; - maxy = vy[0]; - for (i = 1; (i < count); i++) - { - if (vy[i] < miny) miny = vy[i]; - else if (vy[i] > maxy) maxy = vy[i]; - } - - /* - * Draw, scanning y - */ - for (y = miny; (y <= maxy); y++) - { - ints = 0; - for (i = 0; (i < count); i++) - { - if (!i) - { - ind1 = count - 1; - ind2 = 0; - } - else - { - ind1 = i - 1; - ind2 = i; - } - y1 = vy[ind1]; - y2 = vy[ind2]; - if (y1 < y2) - { - x1 = vx[ind1]; - x2 = vx[ind2]; - } - else if (y1 > y2) - { - y2 = vy[ind1]; - y1 = vy[ind2]; - x2 = vx[ind1]; - x1 = vx[ind2]; - } - else - { - continue; - } - - if (((y >= y1) && (y < y2)) || ((y == maxy) && (y > y1) && (y <= y2))) - { - poly_ints[ints++] = ((65536 * (y - y1)) / (y2 - y1)) * (x2 - x1) + (65536 * x1); - } - } - - qsort(poly_ints, ints, sizeof(int), _int_compare); - - for (i = 0; (i < ints); i += 2) - { - xa = poly_ints[i] + 1; - xa = (xa >> 16) + ((xa & 32768) >> 15); - xb = poly_ints[i + 1] - 1; - xb = (xb >> 16) + ((xb & 32768) >> 15); - rtgui_dc_draw_hline(dc, xa, xb, y); - } - } - - /* release memory */ - rtgui_free(poly_ints); -} -RTM_EXPORT(rtgui_dc_fill_polygon); - -void rtgui_dc_draw_circle(struct rtgui_dc *dc, int x, int y, int r) -{ - rt_int16_t cx = 0; - rt_int16_t cy = r; - rt_int16_t df = 1 - r; - rt_int16_t d_e = 3; - rt_int16_t d_se = -2 * r + 5; - rt_int16_t xpcx, xmcx, xpcy, xmcy; - rt_int16_t ypcy, ymcy, ypcx, ymcx; - - /* - * sanity check radius - */ - if (r < 0) return ; - - /* special case for r=0 - draw a point */ - if (r == 0) rtgui_dc_draw_point(dc, x, y); - - /* - * draw circle - */ - do - { - ypcy = y + cy; - ymcy = y - cy; - if (cx > 0) - { - xpcx = x + cx; - xmcx = x - cx; - rtgui_dc_draw_point(dc, xmcx, ypcy); - rtgui_dc_draw_point(dc, xpcx, ypcy); - rtgui_dc_draw_point(dc, xmcx, ymcy); - rtgui_dc_draw_point(dc, xpcx, ymcy); - } - else - { - rtgui_dc_draw_point(dc, x, ymcy); - rtgui_dc_draw_point(dc, x, ypcy); - } - xpcy = x + cy; - xmcy = x - cy; - if ((cx > 0) && (cx != cy)) - { - ypcx = y + cx; - ymcx = y - cx; - rtgui_dc_draw_point(dc, xmcy, ypcx); - rtgui_dc_draw_point(dc, xpcy, ypcx); - rtgui_dc_draw_point(dc, xmcy, ymcx); - rtgui_dc_draw_point(dc, xpcy, ymcx); - } - else if (cx == 0) - { - rtgui_dc_draw_point(dc, xmcy, y); - rtgui_dc_draw_point(dc, xpcy, y); - } - - /* - * Update - */ - if (df < 0) - { - df += d_e; - d_e += 2; - d_se += 2; - } - else - { - df += d_se; - d_e += 2; - d_se += 4; - cy--; - } - cx++; - } - while (cx <= cy); -} -RTM_EXPORT(rtgui_dc_draw_circle); - -void rtgui_dc_fill_circle(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r) -{ - rt_int16_t cx = 0; - rt_int16_t cy = r; - rt_int16_t ocx = (rt_int16_t) 0xffff; - rt_int16_t ocy = (rt_int16_t) 0xffff; - rt_int16_t df = 1 - r; - rt_int16_t d_e = 3; - rt_int16_t d_se = -2 * r + 5; - rt_int16_t xpcx, xmcx, xpcy, xmcy; - rt_int16_t ypcy, ymcy, ypcx, ymcx; - - /* - * Sanity check radius - */ - if (r < 0) return; - - /* - * Special case for r=0 - draw a point - */ - if (r == 0) - { - rtgui_dc_draw_point(dc, x, y); - return ; - } - - /* - * Draw - */ - do - { - xpcx = x + cx; - xmcx = x - cx; - xpcy = x + cy; - xmcy = x - cy; - if (ocy != cy) - { - if (cy > 0) - { - ypcy = y + cy; - ymcy = y - cy; - rtgui_dc_draw_hline(dc, xmcx, xpcx, ypcy); - rtgui_dc_draw_hline(dc, xmcx, xpcx, ymcy); - } - else - { - rtgui_dc_draw_hline(dc, xmcx, xpcx, y); - } - ocy = cy; - } - if (ocx != cx) - { - if (cx != cy) - { - if (cx > 0) - { - ypcx = y + cx; - ymcx = y - cx; - rtgui_dc_draw_hline(dc, xmcy, xpcy, ymcx); - rtgui_dc_draw_hline(dc, xmcy, xpcy, ypcx); - } - else - { - rtgui_dc_draw_hline(dc, xmcy, xpcy, y); - } - } - ocx = cx; - } - /* - * Update - */ - if (df < 0) - { - df += d_e; - d_e += 2; - d_se += 2; - } - else - { - df += d_se; - d_e += 2; - d_se += 4; - cy--; - } - cx++; - } - while (cx <= cy); -} -RTM_EXPORT(rtgui_dc_fill_circle); - -void rtgui_dc_draw_arc(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r, rt_int16_t start, rt_int16_t end) -{ - rt_int16_t cx = 0; - rt_int16_t cy = r; - rt_int16_t df = 1 - r; - rt_int16_t d_e = 3; - rt_int16_t d_se = -2 * r + 5; - rt_int16_t xpcx, xmcx, xpcy, xmcy; - rt_int16_t ypcy, ymcy, ypcx, ymcx; - rt_uint8_t drawoct; - int startoct, endoct, oct, stopval_start, stopval_end; - double temp; - - stopval_start = 0; - stopval_end = 0; - temp = 0; - - /* Sanity check radius */ - if (r < 0) return ; - /* Special case for r=0 - draw a point */ - if (r == 0) - { - rtgui_dc_draw_point(dc, x, y); - return; - } - - /* - * Draw arc - */ - - // Octant labelling - // - // \ 5 | 6 / - // \ | / - // 4 \ | / 7 - // \|/ - //------+------ +x - // /|\ - // 3 / | \ 0 - // / | \ - // / 2 | 1 \ - // +y - - drawoct = 0; // 0x00000000 - // whether or not to keep drawing a given octant. - // For example: 0x00111100 means we're drawing in octants 2-5 - - // 0 <= start & end < 360; note that sometimes start > end - if so, arc goes back through 0. - while (start < 0) start += 360; - while (end < 0) end += 360; - /* Fixup angles */ - start = start % 360; - end = end % 360; - - - // now, we find which octants we're drawing in. - startoct = start / 45; - endoct = end / 45; - oct = startoct - 1; // we increment as first step in loop - - //stopval_start, stopval_end; // what values of cx to stop at. - do - { - oct = (oct + 1) % 8; - - if (oct == startoct) - { - // need to compute stopval_start for this octant. Look at picture above if this is unclear - switch (oct) - { - case 0: - case 3: - temp = sin(start * M_PI / 180); - break; - case 1: - case 6: - temp = cos(start * M_PI / 180); - break; - case 2: - case 5: - temp = -cos(start * M_PI / 180); - break; - case 4: - case 7: - temp = -sin(start * M_PI / 180); - break; - } - temp *= r; - stopval_start = (int)temp; // always round down. - // This isn't arbitrary, but requires graph paper to explain well. - // The basic idea is that we're always changing drawoct after we draw, so we - // stop immediately after we render the last sensible pixel at x = ((int)temp). - - // and whether to draw in this octant initially - if (oct % 2) drawoct |= (1 << oct); // this is basically like saying drawoct[oct] = true, if drawoct were a bool array - else drawoct &= 255 - (1 << oct); // this is basically like saying drawoct[oct] = false - } - - if (oct == endoct) - { - // need to compute stopval_end for this octant - switch (oct) - { - case 0: - case 3: - temp = sin(end * M_PI / 180); - break; - case 1: - case 6: - temp = cos(end * M_PI / 180); - break; - case 2: - case 5: - temp = -cos(end * M_PI / 180); - break; - case 4: - case 7: - temp = -sin(end * M_PI / 180); - break; - } - temp *= r; - stopval_end = (int)temp; - - // and whether to draw in this octant initially - if (startoct == endoct) - { - // note: we start drawing, stop, then start again in this case - // otherwise: we only draw in this octant, so initialize it to false, it will get set back to true - if (start > end) - { - // unfortunately, if we're in the same octant and need to draw over the whole circle, - // we need to set the rest to true, because the while loop will end at the bottom. - drawoct = 255; - } - else - { - drawoct &= 255 - (1 << oct); - } - } - else if (oct % 2) drawoct &= 255 - (1 << oct); - else drawoct |= (1 << oct); - } - else if (oct != startoct) // already verified that it's != endoct - { - drawoct |= (1 << oct); // draw this entire segment - } - } - while (oct != endoct); - - // so now we have what octants to draw and when to draw them. all that's left is the actual raster code. - do - { - ypcy = y + cy; - ymcy = y - cy; - if (cx > 0) - { - xpcx = x + cx; - xmcx = x - cx; - // always check if we're drawing a certain octant before adding a pixel to that octant. - if (drawoct & 4) rtgui_dc_draw_point(dc, xmcx, ypcy); // drawoct & 4 = 22; drawoct[2] - if (drawoct & 2) rtgui_dc_draw_point(dc, xpcx, ypcy); - if (drawoct & 32) rtgui_dc_draw_point(dc, xmcx, ymcy); - if (drawoct & 64) rtgui_dc_draw_point(dc, xpcx, ymcy); - } - else - { - if (drawoct & 6) rtgui_dc_draw_point(dc, x, ypcy); // 4 + 2; drawoct[2] || drawoct[1] - if (drawoct & 96) rtgui_dc_draw_point(dc, x, ymcy); // 32 + 64 - } - - xpcy = x + cy; - xmcy = x - cy; - if (cx > 0 && cx != cy) - { - ypcx = y + cx; - ymcx = y - cx; - if (drawoct & 8) rtgui_dc_draw_point(dc, xmcy, ypcx); - if (drawoct & 1) rtgui_dc_draw_point(dc, xpcy, ypcx); - if (drawoct & 16) rtgui_dc_draw_point(dc, xmcy, ymcx); - if (drawoct & 128) rtgui_dc_draw_point(dc, xpcy, ymcx); - } - else if (cx == 0) - { - if (drawoct & 24) rtgui_dc_draw_point(dc, xmcy, y); // 8 + 16 - if (drawoct & 129) rtgui_dc_draw_point(dc, xpcy, y); // 1 + 128 - } - - /* - * Update whether we're drawing an octant - */ - if (stopval_start == cx) - { - // works like an on-off switch because start & end may be in the same octant. - if (drawoct & (1 << startoct)) drawoct &= 255 - (1 << startoct); - else drawoct |= (1 << startoct); - } - if (stopval_end == cx) - { - if (drawoct & (1 << endoct)) drawoct &= 255 - (1 << endoct); - else drawoct |= (1 << endoct); - } - - /* - * Update pixels - */ - if (df < 0) - { - df += d_e; - d_e += 2; - d_se += 2; - } - else - { - df += d_se; - d_e += 2; - d_se += 4; - cy--; - } - - cx++; - } - while (cx <= cy); -} -RTM_EXPORT(rtgui_dc_draw_arc); - -void rtgui_dc_draw_annulus(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r1, rt_int16_t r2, rt_int16_t start, rt_int16_t end) -{ - rt_int16_t start_x, start_y; - rt_int16_t end_x, end_y; - double temp; - rt_int16_t temp_val = 0; - - /* Sanity check radius */ - if ((r1 < 0) || (r2 < 0)) return ; - /* Special case for r=0 - draw a point */ - if ((r1 == 0) && (r2 == 0)) - { - rtgui_dc_draw_point(dc, x, y); - return; - } - - while (start < 0) start += 360; - while (end < 0) end += 360; - - rtgui_dc_draw_arc(dc, x, y, r1, start, end); - rtgui_dc_draw_arc(dc, x, y, r2, start, end); - - temp = cos(start * M_PI / 180); - temp_val = (int)(temp * r1); - start_x = x + temp_val; - temp_val = (int)(temp * r2); - end_x = x + temp_val; - - temp = sin(start * M_PI / 180); - temp_val = (int)(temp * r1); - start_y = y + temp_val; - temp_val = (int)(temp * r2); - end_y = y + temp_val; - - rtgui_dc_draw_line(dc, start_x, start_y, end_x, end_y); - - temp = cos(end * M_PI / 180); - temp_val = (int)(temp * r1); - start_x = x + temp_val; - temp_val = (int)(temp * r2); - end_x = x + temp_val; - - temp = sin(end * M_PI / 180); - temp_val = (int)(temp * r1); - start_y = y + temp_val; - temp_val = (int)(temp * r2); - end_y = y + temp_val; - - rtgui_dc_draw_line(dc, start_x, start_y, end_x, end_y); -} -RTM_EXPORT(rtgui_dc_draw_annulus); - -void rtgui_dc_draw_sector(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r, rt_int16_t start, rt_int16_t end) -{ - int start_x, start_y; - int end_x, end_y; - - /* Sanity check radius */ - if (r < 0) return ; - /* Special case for r=0 - draw a point */ - if (r == 0) - { - rtgui_dc_draw_point(dc, x, y); - return; - } - - while (start < 0) start += 360; - while (end < 0) end += 360; - - /* Fixup angles */ - start = start % 360; - end = end % 360; - - rtgui_dc_draw_arc(dc, x, y, r, start, end); - - start_x = x + r * cos(start * M_PI / 180); - start_y = y + r * sin(start * M_PI / 180); - - end_x = x + r * cos(end * M_PI / 180); - end_y = y + r * sin(end * M_PI / 180); - - rtgui_dc_draw_line(dc, x, y, start_x, start_y); - rtgui_dc_draw_line(dc, x, y, end_x, end_y); -} -RTM_EXPORT(rtgui_dc_draw_sector); - -void rtgui_dc_fill_sector(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r, rt_int16_t start, rt_int16_t end) -{ - int start_x, start_y; - int end_x, end_y; - - /* Sanity check radius */ - if (r < 0) return ; - /* Special case for r=0 - draw a point */ - if (r == 0) - { - rtgui_dc_draw_point(dc, x, y); - return; - } - - while (start < 0) start += 360; - while (end < 0) end += 360; - - /* Fixup angles */ - start = start % 360; - end = end % 360; - - end_x = x + r * cos(end * M_PI / 180); - end_y = y + r * sin(end * M_PI / 180); - - do - { - start_x = x + r * cos(start * M_PI / 180); - start_y = y + r * sin(start * M_PI / 180); - start ++; - - rtgui_dc_draw_line(dc, x, y, start_x, start_y); - } - while (!((start_x == end_x) && (start_y == end_y))); -} -RTM_EXPORT(rtgui_dc_fill_sector); - -void rtgui_dc_draw_ellipse(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t rx, rt_int16_t ry) -{ - int ix, iy; - int h, i, j, k; - int oh, oi, oj, ok; - int xmh, xph, ypk, ymk; - int xmi, xpi, ymj, ypj; - int xmj, xpj, ymi, ypi; - int xmk, xpk, ymh, yph; - - /* - * Sanity check radii - */ - if ((rx < 0) || (ry < 0)) return; - - /* - * Special case for rx=0 - draw a vline - */ - if (rx == 0) - { - rtgui_dc_draw_vline(dc, x, y - ry, y + ry); - return; - } - - /* - * Special case for ry=0 - draw a hline - */ - if (ry == 0) - { - rtgui_dc_draw_hline(dc, x - rx, x + rx, y); - return; - } - - /* - * Init vars - */ - oh = oi = oj = ok = 0xFFFF; - - if (rx > ry) - { - ix = 0; - iy = rx * 64; - - do - { - h = (ix + 32) >> 6; - i = (iy + 32) >> 6; - j = (h * ry) / rx; - k = (i * ry) / rx; - - if (((ok != k) && (oj != k)) || ((oj != j) && (ok != j)) || (k != j)) - { - xph = x + h; - xmh = x - h; - if (k > 0) - { - ypk = y + k; - ymk = y - k; - rtgui_dc_draw_point(dc, xmh, ypk); - rtgui_dc_draw_point(dc, xph, ypk); - rtgui_dc_draw_point(dc, xmh, ymk); - rtgui_dc_draw_point(dc, xph, ymk); - } - else - { - rtgui_dc_draw_point(dc, xmh, y); - rtgui_dc_draw_point(dc, xph, y); - } - ok = k; - xpi = x + i; - xmi = x - i; - if (j > 0) - { - ypj = y + j; - ymj = y - j; - rtgui_dc_draw_point(dc, xmi, ypj); - rtgui_dc_draw_point(dc, xpi, ypj); - rtgui_dc_draw_point(dc, xmi, ymj); - rtgui_dc_draw_point(dc, xpi, ymj); - } - else - { - rtgui_dc_draw_point(dc, xmi, y); - rtgui_dc_draw_point(dc, xpi, y); - } - oj = j; - } - - ix = ix + iy / rx; - iy = iy - ix / rx; - } - while (i > h); - } - else - { - ix = 0; - iy = ry * 64; - - do - { - h = (ix + 32) >> 6; - i = (iy + 32) >> 6; - j = (h * rx) / ry; - k = (i * rx) / ry; - - if (((oi != i) && (oh != i)) || ((oh != h) && (oi != h) && (i != h))) - { - xmj = x - j; - xpj = x + j; - if (i > 0) - { - ypi = y + i; - ymi = y - i; - rtgui_dc_draw_point(dc, xmj, ypi); - rtgui_dc_draw_point(dc, xpj, ypi); - rtgui_dc_draw_point(dc, xmj, ymi); - rtgui_dc_draw_point(dc, xpj, ymi); - } - else - { - rtgui_dc_draw_point(dc, xmj, y); - rtgui_dc_draw_point(dc, xpj, y); - } - oi = i; - xmk = x - k; - xpk = x + k; - if (h > 0) - { - yph = y + h; - ymh = y - h; - rtgui_dc_draw_point(dc, xmk, yph); - rtgui_dc_draw_point(dc, xpk, yph); - rtgui_dc_draw_point(dc, xmk, ymh); - rtgui_dc_draw_point(dc, xpk, ymh); - } - else - { - rtgui_dc_draw_point(dc, xmk, y); - rtgui_dc_draw_point(dc, xpk, y); - } - oh = h; - } - - ix = ix + iy / ry; - iy = iy - ix / ry; - } - while (i > h); - } -} -RTM_EXPORT(rtgui_dc_draw_ellipse); - -void rtgui_dc_fill_ellipse(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t rx, rt_int16_t ry) -{ - int ix, iy; - int h, i, j, k; - int oh, oi, oj, ok; - int xmh, xph; - int xmi, xpi; - int xmj, xpj; - int xmk, xpk; - - /* - * Special case for rx=0 - draw a vline - */ - if (rx == 0) - { - rtgui_dc_draw_vline(dc, x, y - ry, y + ry); - return; - } - - /* special case for ry=0 - draw a hline */ - if (ry == 0) - { - rtgui_dc_draw_hline(dc, x - rx, x + rx, y); - return; - } - - /* - * Init vars - */ - oh = oi = oj = ok = 0xFFFF; - - /* - * Draw - */ - if (rx > ry) - { - ix = 0; - iy = rx * 64; - - do - { - h = (ix + 32) >> 6; - i = (iy + 32) >> 6; - j = (h * ry) / rx; - k = (i * ry) / rx; - - if ((ok != k) && (oj != k)) - { - xph = x + h; - xmh = x - h; - if (k > 0) - { - rtgui_dc_draw_hline(dc, xmh, xph, y + k); - rtgui_dc_draw_hline(dc, xmh, xph, y - k); - } - else - { - rtgui_dc_draw_hline(dc, xmh, xph, y); - } - ok = k; - } - if ((oj != j) && (ok != j) && (k != j)) - { - xmi = x - i; - xpi = x + i; - if (j > 0) - { - rtgui_dc_draw_hline(dc, xmi, xpi, y + j); - rtgui_dc_draw_hline(dc, xmi, xpi, y - j); - } - else - { - rtgui_dc_draw_hline(dc, xmi, xpi, y); - } - oj = j; - } - - ix = ix + iy / rx; - iy = iy - ix / rx; - - } - while (i > h); - } - else - { - ix = 0; - iy = ry * 64; - - do - { - h = (ix + 32) >> 6; - i = (iy + 32) >> 6; - j = (h * rx) / ry; - k = (i * rx) / ry; - - if ((oi != i) && (oh != i)) - { - xmj = x - j; - xpj = x + j; - if (i > 0) - { - rtgui_dc_draw_hline(dc, xmj, xpj, y + i); - rtgui_dc_draw_hline(dc, xmj, xpj, y - i); - } - else - { - rtgui_dc_draw_hline(dc, xmj, xpj, y); - } - oi = i; - } - if ((oh != h) && (oi != h) && (i != h)) - { - xmk = x - k; - xpk = x + k; - if (h > 0) - { - rtgui_dc_draw_hline(dc, xmk, xpk, y + h); - rtgui_dc_draw_hline(dc, xmk, xpk, y - h); - } - else - { - rtgui_dc_draw_hline(dc, xmk, xpk, y); - } - oh = h; - } - ix = ix + iy / ry; - iy = iy - ix / ry; - } - while (i > h); - } -} -RTM_EXPORT(rtgui_dc_fill_ellipse); - |
