dc.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
  1. /*
  2. * File : dc.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2009-10-16 Bernard first version
  13. * 2010-09-20 richard modified rtgui_dc_draw_round_rect
  14. * 2010-09-27 Bernard fix draw_mono_bmp issue
  15. * 2011-04-25 Bernard fix fill polygon issue, which found by loveic
  16. */
  17. #include <rtgui/dc.h>
  18. #include <rtgui/rtgui_system.h>
  19. #include <string.h> /* for strlen */
  20. #include <stdlib.h> /* fir qsort */
  21. /* for sin/cos etc */
  22. #include <math.h>
  23. #ifndef M_PI
  24. #define M_PI 3.14159265358979323846
  25. #endif
  26. static int _int_compare(const void *a, const void *b)
  27. {
  28. return (*(const int *) a) - (*(const int *) b);
  29. }
  30. void rtgui_dc_destory(struct rtgui_dc* dc)
  31. {
  32. if (dc == RT_NULL) return;
  33. dc->engine->fini(dc);
  34. rtgui_free(dc);
  35. }
  36. RTM_EXPORT(rtgui_dc_destory);
  37. void rtgui_dc_draw_line (struct rtgui_dc* dc, int x1, int y1, int x2, int y2)
  38. {
  39. if (dc == RT_NULL) return;
  40. if (y1 == y2)
  41. {
  42. rtgui_dc_draw_hline(dc, x1, x2, y1);
  43. }
  44. else if (x1 == x2)
  45. {
  46. rtgui_dc_draw_vline(dc, x1, y1, y2);
  47. }
  48. else
  49. {
  50. int dx, dy, sdx, sdy, dxabs, dyabs, x, y, px, py;
  51. register rt_base_t i;
  52. /* rtgui_rect_t rect; */
  53. dx = x2 - x1; /* the horizontal distance of the line */
  54. dy = y2 - y1; /* the vertical distance of the line */
  55. #define rtgui_sgn(x) ((x<0)?-1:((x>0)?1:0)) /* macro to return the sign of a number */
  56. #define rtgui_abs(x) ((x)>=0? (x):-(x)) /* macro to return the absolute value */
  57. dxabs = rtgui_abs(dx);
  58. dyabs = rtgui_abs(dy);
  59. sdx = rtgui_sgn(dx);
  60. sdy = rtgui_sgn(dy);
  61. x = dyabs >> 1;
  62. y = dxabs >> 1;
  63. px = x1;
  64. py = y1;
  65. if(dxabs >= dyabs) /* the line is more horizontal than vertical */
  66. {
  67. for(i = 0; i < dxabs; i++)
  68. {
  69. y += dyabs;
  70. if(y >= dxabs)
  71. {
  72. y -= dxabs;
  73. py += sdy;
  74. }
  75. px += sdx;
  76. /* draw this point */
  77. rtgui_dc_draw_point(dc, px, py);
  78. }
  79. }
  80. else /* the line is more vertical than horizontal */
  81. {
  82. for(i = 0; i < dyabs; i++)
  83. {
  84. x += dxabs;
  85. if(x >= dyabs)
  86. {
  87. x -= dyabs;
  88. px += sdx;
  89. }
  90. py += sdy;
  91. /* draw this point */
  92. rtgui_dc_draw_point(dc, px, py);
  93. }
  94. }
  95. }
  96. }
  97. RTM_EXPORT(rtgui_dc_draw_line);
  98. void rtgui_dc_draw_horizontal_line(struct rtgui_dc* dc, int x1, int x2, int y)
  99. {
  100. rtgui_color_t color;
  101. if (dc == RT_NULL) return ;
  102. /* save old color */
  103. color = RTGUI_DC_FC(dc);
  104. RTGUI_DC_FC(dc) = dark_grey;
  105. rtgui_dc_draw_hline(dc, x1, x2, y);
  106. y ++;
  107. RTGUI_DC_FC(dc) = high_light;
  108. rtgui_dc_draw_hline(dc, x1, x2, y);
  109. /* restore color */
  110. RTGUI_DC_FC(dc) = color;
  111. }
  112. RTM_EXPORT(rtgui_dc_draw_horizontal_line);
  113. void rtgui_dc_draw_vertical_line(struct rtgui_dc* dc, int x, int y1, int y2)
  114. {
  115. rtgui_color_t color;
  116. if (dc == RT_NULL) return ;
  117. /* save old color */
  118. color = RTGUI_DC_FC(dc);
  119. RTGUI_DC_FC(dc) = dark_grey;
  120. rtgui_dc_draw_vline(dc, x, y1, y2);
  121. x ++;
  122. RTGUI_DC_FC(dc) = high_light;
  123. rtgui_dc_draw_vline(dc, x, y1, y2);
  124. /* restore color */
  125. RTGUI_DC_FC(dc) = color;
  126. }
  127. RTM_EXPORT(rtgui_dc_draw_vertical_line);
  128. void rtgui_dc_draw_rect (struct rtgui_dc* dc, struct rtgui_rect* rect)
  129. {
  130. rtgui_dc_draw_hline(dc, rect->x1, rect->x2, rect->y1);
  131. rtgui_dc_draw_hline(dc, rect->x1, rect->x2, rect->y2 - 1);
  132. rtgui_dc_draw_vline(dc, rect->x1, rect->y1, rect->y2);
  133. rtgui_dc_draw_vline(dc, rect->x2 - 1, rect->y1, rect->y2);
  134. }
  135. RTM_EXPORT(rtgui_dc_draw_rect);
  136. void rtgui_dc_fill_rect_forecolor(struct rtgui_dc* dc, struct rtgui_rect* rect)
  137. {
  138. int i = 0;
  139. rtgui_dc_draw_rect(dc, rect);
  140. do
  141. {
  142. rtgui_dc_draw_hline(dc, rect->x1+1, rect->x2-1, rect->y1+i);
  143. i++;
  144. }while(!(rect->y1+i == rect->y2));
  145. }
  146. RTM_EXPORT(rtgui_dc_fill_rect_forecolor);
  147. void rtgui_dc_draw_round_rect(struct rtgui_dc* dc, struct rtgui_rect* rect, int r)
  148. {
  149. RT_ASSERT(((rect->x2 - rect->x1)/2 >= r)&&((rect->y2-rect->y1)/2 >= r));
  150. if(r < 0)
  151. {
  152. return;
  153. }
  154. if(r == 0)
  155. {
  156. rtgui_dc_draw_rect(dc, rect);
  157. return;
  158. }
  159. if(((rect->x2 - rect->x1)/2 >= r)&&((rect->y2-rect->y1)/2 >= r))
  160. {
  161. rtgui_dc_draw_arc(dc, rect->x1 + r, rect->y1 + r, r, 180, 270);
  162. rtgui_dc_draw_arc(dc, rect->x2 - r, rect->y1 + r, r, 270, 360);
  163. rtgui_dc_draw_arc(dc, rect->x1 + r, rect->y2 - r, r, 90, 180);
  164. rtgui_dc_draw_arc(dc, rect->x2 - r, rect->y2 - r, r, 0, 90);
  165. rtgui_dc_draw_hline(dc, rect->x1 + r, rect->x2 - r, rect->y1);
  166. rtgui_dc_draw_hline(dc, rect->x1 + r, rect->x2 - r, rect->y2);
  167. rtgui_dc_draw_vline(dc, rect->x1, rect->y1 + r, rect->y2 - r);
  168. rtgui_dc_draw_vline(dc, rect->x2, rect->y1 + r, rect->y2 - r);
  169. }
  170. }
  171. RTM_EXPORT(rtgui_dc_draw_round_rect);
  172. void rtgui_dc_fill_round_rect(struct rtgui_dc* dc, struct rtgui_rect* rect, int r)
  173. {
  174. struct rtgui_rect rect_temp;
  175. RT_ASSERT(((rect->x2 - rect->x1)/2 >= r)&&((rect->y2-rect->y1)/2 >= r));
  176. if(((rect->x2 - rect->x1)/2 >= r)&&((rect->y2-rect->y1)/2 >= r))
  177. {
  178. rect_temp.x1 = rect->x1 + r;
  179. rect_temp.y1 = rect->y1;
  180. rect_temp.x2 = rect->x2 - r;
  181. rect_temp.y2 = rect->y2;
  182. rtgui_dc_fill_rect_forecolor(dc, &rect_temp);//fill rect with foreground
  183. rect_temp.x1 = rect->x1;
  184. rect_temp.y1 = rect->y1 + r;
  185. rect_temp.x2 = rect->x1 + r;
  186. rect_temp.y2 = rect->y2 - r;
  187. rtgui_dc_fill_rect_forecolor(dc, &rect_temp);//fill rect with foreground
  188. rect_temp.x1 = rect->x2 - r;
  189. rect_temp.y1 = rect->y1 + r;
  190. rect_temp.x2 = rect->x2;
  191. rect_temp.y2 = rect->y2 - r;
  192. rtgui_dc_fill_rect_forecolor(dc, &rect_temp);//fill rect with foreground
  193. rtgui_dc_fill_circle(dc, rect->x1 + r, rect->y1 + r, r);
  194. rtgui_dc_fill_circle(dc, rect->x2 - r, rect->y2 - r, r);
  195. rtgui_dc_fill_circle(dc, rect->x2 - r, rect->y1 + r, r);
  196. rtgui_dc_fill_circle(dc, rect->x1 + r, rect->y2 - r, r);
  197. }
  198. }
  199. RTM_EXPORT(rtgui_dc_fill_round_rect);
  200. void rtgui_dc_draw_shaded_rect(struct rtgui_dc* dc, rtgui_rect_t* rect,
  201. rtgui_color_t c1, rtgui_color_t c2)
  202. {
  203. RT_ASSERT(dc != RT_NULL);
  204. RTGUI_DC_FC(dc) = c1;
  205. rtgui_dc_draw_vline(dc, rect->x1, rect->y1, rect->y2);
  206. rtgui_dc_draw_hline(dc, rect->x1 + 1, rect->x2, rect->y1);
  207. RTGUI_DC_FC(dc) = c2;
  208. rtgui_dc_draw_vline(dc, rect->x2 - 1, rect->y1, rect->y2);
  209. rtgui_dc_draw_hline(dc, rect->x1, rect->x2, rect->y2 - 1);
  210. }
  211. RTM_EXPORT(rtgui_dc_draw_shaded_rect);
  212. void rtgui_dc_draw_focus_rect(struct rtgui_dc* dc, rtgui_rect_t* rect)
  213. {
  214. int x,y;
  215. for (x=rect->x1; x<rect->x2-1; x++)
  216. {
  217. if ((x+rect->y1)&0x01)
  218. rtgui_dc_draw_point(dc, x, rect->y1);
  219. if ((x+rect->y2-1)&0x01)
  220. rtgui_dc_draw_point(dc, x, rect->y2-1);
  221. }
  222. for (y=rect->y1; y<rect->y2; y++)
  223. {
  224. if ((rect->x1+y)&0x01)
  225. rtgui_dc_draw_point(dc, rect->x1, y);
  226. if ((rect->x2-1+y)&0x01)
  227. rtgui_dc_draw_point(dc, rect->x2-1, y);
  228. }
  229. }
  230. RTM_EXPORT(rtgui_dc_draw_focus_rect);
  231. void rtgui_dc_draw_text (struct rtgui_dc* dc, const char* text, struct rtgui_rect* rect)
  232. {
  233. rt_uint32_t len;
  234. struct rtgui_font *font;
  235. struct rtgui_rect text_rect;
  236. RT_ASSERT(dc != RT_NULL);
  237. font = RTGUI_DC_FONT(dc);
  238. if (font == RT_NULL)
  239. {
  240. /* use system default font */
  241. font = rtgui_font_default();
  242. }
  243. /* text align */
  244. rtgui_font_get_metrics(font, text, &text_rect);
  245. rtgui_rect_moveto_align(rect, &text_rect, RTGUI_DC_TEXTALIGN(dc));
  246. len = strlen((const char*)text);
  247. rtgui_font_draw(font, dc, text, len, &text_rect);
  248. }
  249. RTM_EXPORT(rtgui_dc_draw_text);
  250. void rtgui_dc_draw_text_stroke (struct rtgui_dc* dc, const char* text, struct rtgui_rect* rect,
  251. rtgui_color_t color_stroke, rtgui_color_t color_core)
  252. {
  253. int x, y;
  254. rtgui_rect_t r;
  255. rtgui_color_t fc;
  256. RT_ASSERT(dc != RT_NULL);
  257. fc = RTGUI_DC_FC(dc);
  258. RTGUI_DC_FC(dc) = color_stroke;
  259. for(x=-1; x<2; x++)
  260. {
  261. for(y=-1; y<2; y++)
  262. {
  263. r = *rect;
  264. rtgui_rect_moveto(&r, x, y);
  265. rtgui_dc_draw_text(dc, text, &r);
  266. }
  267. }
  268. RTGUI_DC_FC(dc) = color_core;
  269. rtgui_dc_draw_text(dc, text, rect);
  270. RTGUI_DC_FC(dc) = fc;
  271. }
  272. RTM_EXPORT(rtgui_dc_draw_text_stroke);
  273. /*
  274. * draw a monochrome color bitmap data
  275. */
  276. void rtgui_dc_draw_mono_bmp(struct rtgui_dc* dc, int x, int y, int w, int h, const rt_uint8_t* data)
  277. {
  278. int i, j, k;
  279. /* get word bytes */
  280. w = (w + 7)/8;
  281. /* draw mono bitmap data */
  282. for (i = 0; i < h; i ++)
  283. for (j = 0; j < w; j++)
  284. for (k = 0; k < 8; k++)
  285. if ( ((data[i*w + j] >> (7-k)) & 0x01) != 0)
  286. rtgui_dc_draw_point(dc, x + 8*j + k, y + i);
  287. }
  288. RTM_EXPORT(rtgui_dc_draw_mono_bmp);
  289. void rtgui_dc_draw_byte(struct rtgui_dc*dc, int x, int y, int h, const rt_uint8_t* data)
  290. {
  291. rtgui_dc_draw_mono_bmp(dc, x, y, 8, h, data);
  292. }
  293. RTM_EXPORT(rtgui_dc_draw_byte);
  294. void rtgui_dc_draw_word(struct rtgui_dc*dc, int x, int y, int h, const rt_uint8_t* data)
  295. {
  296. rtgui_dc_draw_mono_bmp(dc, x, y, 16, h, data);
  297. }
  298. RTM_EXPORT(rtgui_dc_draw_word);
  299. void rtgui_dc_draw_border(struct rtgui_dc* dc, rtgui_rect_t* rect, int flag)
  300. {
  301. rtgui_rect_t r;
  302. rtgui_color_t color;
  303. if (dc == RT_NULL) return ;
  304. /* save old color */
  305. color = RTGUI_DC_FC(dc);
  306. r = *rect;
  307. switch (flag)
  308. {
  309. case RTGUI_BORDER_RAISE:
  310. rtgui_dc_draw_shaded_rect(dc, &r, high_light, black);
  311. rtgui_rect_inflate(&r, -1);
  312. rtgui_dc_draw_shaded_rect(dc, &r, light_grey, dark_grey);
  313. break;
  314. case RTGUI_BORDER_SUNKEN:
  315. rtgui_dc_draw_shaded_rect(dc, &r, dark_grey, high_light);
  316. rtgui_rect_inflate(&r, -1);
  317. rtgui_dc_draw_shaded_rect(dc, &r, black, light_grey);
  318. break;
  319. case RTGUI_BORDER_BOX:
  320. rtgui_dc_draw_shaded_rect(dc, &r, dark_grey, high_light);
  321. rtgui_rect_inflate(&r, -1);
  322. rtgui_dc_draw_shaded_rect(dc, &r, high_light, dark_grey);
  323. break;
  324. case RTGUI_BORDER_STATIC:
  325. rtgui_dc_draw_shaded_rect(dc, &r, dark_grey, high_light);
  326. break;
  327. case RTGUI_BORDER_EXTRA:
  328. RTGUI_DC_FC(dc) = light_grey;
  329. rtgui_dc_draw_rect(dc, &r);
  330. break;
  331. case RTGUI_BORDER_SIMPLE:
  332. RTGUI_DC_FC(dc) = black;
  333. rtgui_dc_draw_rect(dc, &r);
  334. break;
  335. default:
  336. break;
  337. }
  338. /* restore color */
  339. RTGUI_DC_FC(dc) = color;
  340. }
  341. RTM_EXPORT(rtgui_dc_draw_border);
  342. void rtgui_dc_draw_polygon(struct rtgui_dc* dc, const int *vx, const int *vy, int count)
  343. {
  344. int i;
  345. const int *x1, *y1, *x2, *y2;
  346. /*
  347. * Sanity check
  348. */
  349. if (count < 3) return;
  350. /*
  351. * Pointer setup
  352. */
  353. x1 = x2 = vx;
  354. y1 = y2 = vy;
  355. x2++;
  356. y2++;
  357. /*
  358. * Draw
  359. */
  360. for (i = 1; i < count; i++)
  361. {
  362. rtgui_dc_draw_line(dc, *x1, *y1, *x2, *y2);
  363. x1 = x2;
  364. y1 = y2;
  365. x2++;
  366. y2++;
  367. }
  368. rtgui_dc_draw_line(dc, *x1, *y1, *vx, *vy);
  369. }
  370. RTM_EXPORT(rtgui_dc_draw_polygon);
  371. void rtgui_dc_draw_regular_polygon(struct rtgui_dc* dc, int x, int y, int r, int count, rt_uint16_t angle)
  372. {
  373. int i, temp_val;
  374. double temp;
  375. float angle_interval;
  376. int *xx;
  377. int *x_head;
  378. int *yy;
  379. int *y_head;
  380. /*
  381. * Sanity check
  382. */
  383. if (count < 3) return;
  384. angle_interval = 360.0 / count;
  385. /*
  386. * Pointer setup
  387. */
  388. x_head = xx = (int *)rtgui_malloc(sizeof(int) * count);
  389. y_head = yy = (int *)rtgui_malloc(sizeof(int) * count);
  390. for(i = 0; i < count; i++)
  391. {
  392. temp = cos(((angle_interval * i) + angle) * M_PI / 180);
  393. temp *= r;
  394. temp_val = (int)temp;
  395. *xx = temp_val + x;
  396. temp = sin(((angle_interval * i) + angle) * M_PI / 180);
  397. temp *= r;
  398. temp_val = (int)temp;
  399. *yy = temp_val + y;
  400. xx++;
  401. yy++;
  402. }
  403. rtgui_dc_draw_polygon(dc, (const int *)x_head, (const int *)y_head, count);
  404. rtgui_free(x_head);
  405. rtgui_free(y_head);
  406. }
  407. RTM_EXPORT(rtgui_dc_draw_regular_polygon);
  408. void rtgui_dc_fill_polygon(struct rtgui_dc* dc, const int* vx, const int* vy, int count)
  409. {
  410. int i;
  411. int y, xa, xb;
  412. int miny, maxy;
  413. int x1, y1;
  414. int x2, y2;
  415. int ind1, ind2;
  416. int ints;
  417. int *poly_ints = RT_NULL;
  418. /*
  419. * Sanity check number of edges
  420. */
  421. if (count < 3) return;
  422. /*
  423. * Allocate temp array, only grow array
  424. */
  425. poly_ints = (int *) rtgui_malloc(sizeof(int) * count);
  426. if (poly_ints == RT_NULL) return ; /* no memory, failed */
  427. /*
  428. * Determine Y maximal
  429. */
  430. miny = vy[0];
  431. maxy = vy[0];
  432. for (i = 1; (i < count); i++)
  433. {
  434. if (vy[i] < miny) miny = vy[i];
  435. else if (vy[i] > maxy) maxy = vy[i];
  436. }
  437. /*
  438. * Draw, scanning y
  439. */
  440. for (y = miny; (y <= maxy); y++) {
  441. ints = 0;
  442. for (i = 0; (i < count); i++) {
  443. if (!i) {
  444. ind1 = count - 1;
  445. ind2 = 0;
  446. } else {
  447. ind1 = i - 1;
  448. ind2 = i;
  449. }
  450. y1 = vy[ind1];
  451. y2 = vy[ind2];
  452. if (y1 < y2) {
  453. x1 = vx[ind1];
  454. x2 = vx[ind2];
  455. } else if (y1 > y2) {
  456. y2 = vy[ind1];
  457. y1 = vy[ind2];
  458. x2 = vx[ind1];
  459. x1 = vx[ind2];
  460. } else {
  461. continue;
  462. }
  463. if ( ((y >= y1) && (y < y2)) || ((y == maxy) && (y > y1) && (y <= y2)) )
  464. {
  465. poly_ints[ints++] = ((65536 * (y - y1)) / (y2 - y1)) * (x2 - x1) + (65536 * x1);
  466. }
  467. }
  468. qsort(poly_ints, ints, sizeof(int), _int_compare);
  469. for (i = 0; (i < ints); i += 2)
  470. {
  471. xa = poly_ints[i] + 1;
  472. xa = (xa >> 16) + ((xa & 32768) >> 15);
  473. xb = poly_ints[i+1] - 1;
  474. xb = (xb >> 16) + ((xb & 32768) >> 15);
  475. rtgui_dc_draw_hline(dc, xa, xb, y);
  476. }
  477. }
  478. /* release memory */
  479. rtgui_free(poly_ints);
  480. }
  481. RTM_EXPORT(rtgui_dc_fill_polygon);
  482. void rtgui_dc_draw_circle(struct rtgui_dc* dc, int x, int y, int r)
  483. {
  484. rt_int16_t cx = 0;
  485. rt_int16_t cy = r;
  486. rt_int16_t df = 1 - r;
  487. rt_int16_t d_e = 3;
  488. rt_int16_t d_se = -2 * r + 5;
  489. rt_int16_t xpcx, xmcx, xpcy, xmcy;
  490. rt_int16_t ypcy, ymcy, ypcx, ymcx;
  491. /*
  492. * sanity check radius
  493. */
  494. if (r < 0) return ;
  495. /* special case for r=0 - draw a point */
  496. if (r == 0) rtgui_dc_draw_point(dc, x, y);
  497. /*
  498. * draw circle
  499. */
  500. do
  501. {
  502. ypcy = y + cy;
  503. ymcy = y - cy;
  504. if (cx > 0)
  505. {
  506. xpcx = x + cx;
  507. xmcx = x - cx;
  508. rtgui_dc_draw_point(dc, xmcx, ypcy);
  509. rtgui_dc_draw_point(dc, xpcx, ypcy);
  510. rtgui_dc_draw_point(dc, xmcx, ymcy);
  511. rtgui_dc_draw_point(dc, xpcx, ymcy);
  512. }
  513. else
  514. {
  515. rtgui_dc_draw_point(dc, x, ymcy);
  516. rtgui_dc_draw_point(dc, x, ypcy);
  517. }
  518. xpcy = x + cy;
  519. xmcy = x - cy;
  520. if ((cx > 0) && (cx != cy))
  521. {
  522. ypcx = y + cx;
  523. ymcx = y - cx;
  524. rtgui_dc_draw_point(dc, xmcy, ypcx);
  525. rtgui_dc_draw_point(dc, xpcy, ypcx);
  526. rtgui_dc_draw_point(dc, xmcy, ymcx);
  527. rtgui_dc_draw_point(dc, xpcy, ymcx);
  528. }
  529. else if (cx == 0)
  530. {
  531. rtgui_dc_draw_point(dc, xmcy, y);
  532. rtgui_dc_draw_point(dc, xpcy, y);
  533. }
  534. /*
  535. * Update
  536. */
  537. if (df < 0)
  538. {
  539. df += d_e;
  540. d_e += 2;
  541. d_se += 2;
  542. }
  543. else
  544. {
  545. df += d_se;
  546. d_e += 2;
  547. d_se += 4;
  548. cy--;
  549. }
  550. cx++;
  551. }while (cx <= cy);
  552. }
  553. RTM_EXPORT(rtgui_dc_draw_circle);
  554. void rtgui_dc_fill_circle(struct rtgui_dc* dc, rt_int16_t x, rt_int16_t y, rt_int16_t r)
  555. {
  556. rt_int16_t cx = 0;
  557. rt_int16_t cy = r;
  558. rt_int16_t ocx = (rt_int16_t) 0xffff;
  559. rt_int16_t ocy = (rt_int16_t) 0xffff;
  560. rt_int16_t df = 1 - r;
  561. rt_int16_t d_e = 3;
  562. rt_int16_t d_se = -2 * r + 5;
  563. rt_int16_t xpcx, xmcx, xpcy, xmcy;
  564. rt_int16_t ypcy, ymcy, ypcx, ymcx;
  565. /*
  566. * Sanity check radius
  567. */
  568. if (r < 0) return;
  569. /*
  570. * Special case for r=0 - draw a point
  571. */
  572. if (r == 0)
  573. {
  574. rtgui_dc_draw_point(dc, x, y);
  575. return ;
  576. }
  577. /*
  578. * Draw
  579. */
  580. do {
  581. xpcx = x + cx;
  582. xmcx = x - cx;
  583. xpcy = x + cy;
  584. xmcy = x - cy;
  585. if (ocy != cy) {
  586. if (cy > 0) {
  587. ypcy = y + cy;
  588. ymcy = y - cy;
  589. rtgui_dc_draw_hline(dc, xmcx, xpcx, ypcy);
  590. rtgui_dc_draw_hline(dc, xmcx, xpcx, ymcy);
  591. } else {
  592. rtgui_dc_draw_hline(dc, xmcx, xpcx, y);
  593. }
  594. ocy = cy;
  595. }
  596. if (ocx != cx) {
  597. if (cx != cy) {
  598. if (cx > 0) {
  599. ypcx = y + cx;
  600. ymcx = y - cx;
  601. rtgui_dc_draw_hline(dc, xmcy, xpcy, ymcx);
  602. rtgui_dc_draw_hline(dc, xmcy, xpcy, ypcx);
  603. } else {
  604. rtgui_dc_draw_hline(dc, xmcy, xpcy, y);
  605. }
  606. }
  607. ocx = cx;
  608. }
  609. /*
  610. * Update
  611. */
  612. if (df < 0) {
  613. df += d_e;
  614. d_e += 2;
  615. d_se += 2;
  616. } else {
  617. df += d_se;
  618. d_e += 2;
  619. d_se += 4;
  620. cy--;
  621. }
  622. cx++;
  623. } while (cx <= cy);
  624. }
  625. RTM_EXPORT(rtgui_dc_fill_circle);
  626. 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)
  627. {
  628. rt_int16_t cx = 0;
  629. rt_int16_t cy = r;
  630. rt_int16_t df = 1 - r;
  631. rt_int16_t d_e = 3;
  632. rt_int16_t d_se = -2 * r + 5;
  633. rt_int16_t xpcx, xmcx, xpcy, xmcy;
  634. rt_int16_t ypcy, ymcy, ypcx, ymcx;
  635. rt_uint8_t drawoct;
  636. int startoct, endoct, oct, stopval_start, stopval_end;
  637. double temp;
  638. stopval_start = 0;
  639. stopval_end = 0;
  640. temp = 0;
  641. /* Sanity check radius */
  642. if (r < 0) return ;
  643. /* Special case for r=0 - draw a point */
  644. if (r == 0)
  645. {
  646. rtgui_dc_draw_point(dc, x, y);
  647. return;
  648. }
  649. /*
  650. * Draw arc
  651. */
  652. // Octant labelling
  653. //
  654. // \ 5 | 6 /
  655. // \ | /
  656. // 4 \ | / 7
  657. // \|/
  658. //------+------ +x
  659. // /|\
  660. // 3 / | \ 0
  661. // / | \
  662. // / 2 | 1 \
  663. // +y
  664. drawoct = 0; // 0x00000000
  665. // whether or not to keep drawing a given octant.
  666. // For example: 0x00111100 means we're drawing in octants 2-5
  667. // 0 <= start & end < 360; note that sometimes start > end - if so, arc goes back through 0.
  668. while (start < 0) start += 360;
  669. while (end < 0) end += 360;
  670. /* Fixup angles */
  671. start = start % 360;
  672. end = end % 360;
  673. // now, we find which octants we're drawing in.
  674. startoct = start / 45;
  675. endoct = end / 45;
  676. oct = startoct - 1; // we increment as first step in loop
  677. //stopval_start, stopval_end; // what values of cx to stop at.
  678. do {
  679. oct = (oct + 1) % 8;
  680. if (oct == startoct)
  681. {
  682. // need to compute stopval_start for this octant. Look at picture above if this is unclear
  683. switch (oct)
  684. {
  685. case 0:
  686. case 3:
  687. temp = sin(start * M_PI / 180);
  688. break;
  689. case 1:
  690. case 6:
  691. temp = cos(start * M_PI / 180);
  692. break;
  693. case 2:
  694. case 5:
  695. temp = -cos(start * M_PI / 180);
  696. break;
  697. case 4:
  698. case 7:
  699. temp = -sin(start * M_PI / 180);
  700. break;
  701. }
  702. temp *= r;
  703. stopval_start = (int)temp; // always round down.
  704. // This isn't arbitrary, but requires graph paper to explain well.
  705. // The basic idea is that we're always changing drawoct after we draw, so we
  706. // stop immediately after we render the last sensible pixel at x = ((int)temp).
  707. // and whether to draw in this octant initially
  708. if (oct % 2) drawoct |= (1 << oct); // this is basically like saying drawoct[oct] = true, if drawoct were a bool array
  709. else drawoct &= 255 - (1 << oct); // this is basically like saying drawoct[oct] = false
  710. }
  711. if (oct == endoct)
  712. {
  713. // need to compute stopval_end for this octant
  714. switch (oct)
  715. {
  716. case 0:
  717. case 3:
  718. temp = sin(end * M_PI / 180);
  719. break;
  720. case 1:
  721. case 6:
  722. temp = cos(end * M_PI / 180);
  723. break;
  724. case 2:
  725. case 5:
  726. temp = -cos(end * M_PI / 180);
  727. break;
  728. case 4:
  729. case 7:
  730. temp = -sin(end * M_PI / 180);
  731. break;
  732. }
  733. temp *= r;
  734. stopval_end = (int)temp;
  735. // and whether to draw in this octant initially
  736. if (startoct == endoct)
  737. {
  738. // note: we start drawing, stop, then start again in this case
  739. // otherwise: we only draw in this octant, so initialize it to false, it will get set back to true
  740. if (start > end)
  741. {
  742. // unfortunately, if we're in the same octant and need to draw over the whole circle,
  743. // we need to set the rest to true, because the while loop will end at the bottom.
  744. drawoct = 255;
  745. }
  746. else
  747. {
  748. drawoct &= 255 - (1 << oct);
  749. }
  750. }
  751. else if (oct % 2) drawoct &= 255 - (1 << oct);
  752. else drawoct |= (1 << oct);
  753. } else if (oct != startoct) { // already verified that it's != endoct
  754. drawoct |= (1 << oct); // draw this entire segment
  755. }
  756. } while (oct != endoct);
  757. // so now we have what octants to draw and when to draw them. all that's left is the actual raster code.
  758. do
  759. {
  760. ypcy = y + cy;
  761. ymcy = y - cy;
  762. if (cx > 0)
  763. {
  764. xpcx = x + cx;
  765. xmcx = x - cx;
  766. // always check if we're drawing a certain octant before adding a pixel to that octant.
  767. if (drawoct & 4) rtgui_dc_draw_point(dc, xmcx, ypcy); // drawoct & 4 = 22; drawoct[2]
  768. if (drawoct & 2) rtgui_dc_draw_point(dc, xpcx, ypcy);
  769. if (drawoct & 32) rtgui_dc_draw_point(dc, xmcx, ymcy);
  770. if (drawoct & 64) rtgui_dc_draw_point(dc, xpcx, ymcy);
  771. }
  772. else
  773. {
  774. if (drawoct & 6) rtgui_dc_draw_point(dc, x, ypcy); // 4 + 2; drawoct[2] || drawoct[1]
  775. if (drawoct & 96) rtgui_dc_draw_point(dc, x, ymcy); // 32 + 64
  776. }
  777. xpcy = x + cy;
  778. xmcy = x - cy;
  779. if (cx > 0 && cx != cy)
  780. {
  781. ypcx = y + cx;
  782. ymcx = y - cx;
  783. if (drawoct & 8) rtgui_dc_draw_point(dc, xmcy, ypcx);
  784. if (drawoct & 1) rtgui_dc_draw_point(dc, xpcy, ypcx);
  785. if (drawoct & 16) rtgui_dc_draw_point(dc, xmcy, ymcx);
  786. if (drawoct & 128) rtgui_dc_draw_point(dc, xpcy, ymcx);
  787. }
  788. else if (cx == 0)
  789. {
  790. if (drawoct & 24) rtgui_dc_draw_point(dc, xmcy, y); // 8 + 16
  791. if (drawoct & 129) rtgui_dc_draw_point(dc, xpcy, y); // 1 + 128
  792. }
  793. /*
  794. * Update whether we're drawing an octant
  795. */
  796. if (stopval_start == cx)
  797. {
  798. // works like an on-off switch because start & end may be in the same octant.
  799. if (drawoct & (1 << startoct)) drawoct &= 255 - (1 << startoct);
  800. else drawoct |= (1 << startoct);
  801. }
  802. if (stopval_end == cx)
  803. {
  804. if (drawoct & (1 << endoct)) drawoct &= 255 - (1 << endoct);
  805. else drawoct |= (1 << endoct);
  806. }
  807. /*
  808. * Update pixels
  809. */
  810. if (df < 0)
  811. {
  812. df += d_e;
  813. d_e += 2;
  814. d_se += 2;
  815. }
  816. else
  817. {
  818. df += d_se;
  819. d_e += 2;
  820. d_se += 4;
  821. cy--;
  822. }
  823. cx++;
  824. } while (cx <= cy);
  825. }
  826. RTM_EXPORT(rtgui_dc_draw_arc);
  827. 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)
  828. {
  829. rt_int16_t start_x, start_y;
  830. rt_int16_t end_x, end_y;
  831. double temp;
  832. rt_int16_t temp_val = 0;
  833. /* Sanity check radius */
  834. if ((r1 < 0) || (r2 < 0)) return ;
  835. /* Special case for r=0 - draw a point */
  836. if ((r1 == 0) && (r2 == 0))
  837. {
  838. rtgui_dc_draw_point(dc, x, y);
  839. return;
  840. }
  841. while (start < 0) start += 360;
  842. while (end < 0) end += 360;
  843. rtgui_dc_draw_arc(dc, x, y, r1, start, end);
  844. rtgui_dc_draw_arc(dc, x, y, r2, start, end);
  845. temp = cos(start * M_PI / 180);
  846. temp_val = (int)(temp * r1);
  847. start_x = x + temp_val;
  848. temp_val = (int)(temp * r2);
  849. end_x = x + temp_val;
  850. temp = sin(start * M_PI / 180);
  851. temp_val = (int)(temp * r1);
  852. start_y = y + temp_val;
  853. temp_val = (int)(temp * r2);
  854. end_y = y + temp_val;
  855. rtgui_dc_draw_line(dc, start_x, start_y, end_x, end_y);
  856. temp = cos(end * M_PI / 180);
  857. temp_val = (int)(temp * r1);
  858. start_x = x + temp_val;
  859. temp_val = (int)(temp * r2);
  860. end_x = x + temp_val;
  861. temp = sin(end * M_PI / 180);
  862. temp_val = (int)(temp * r1);
  863. start_y = y + temp_val;
  864. temp_val = (int)(temp * r2);
  865. end_y = y + temp_val;
  866. rtgui_dc_draw_line(dc, start_x, start_y, end_x, end_y);
  867. }
  868. RTM_EXPORT(rtgui_dc_draw_annulus);
  869. 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)
  870. {
  871. int start_x, start_y;
  872. int end_x, end_y;
  873. /* Sanity check radius */
  874. if (r < 0) return ;
  875. /* Special case for r=0 - draw a point */
  876. if (r == 0)
  877. {
  878. rtgui_dc_draw_point(dc, x, y);
  879. return;
  880. }
  881. while (start < 0) start += 360;
  882. while (end < 0) end += 360;
  883. /* Fixup angles */
  884. start = start % 360;
  885. end = end % 360;
  886. rtgui_dc_draw_arc(dc, x, y, r, start, end);
  887. start_x = x + r * cos(start * M_PI / 180);
  888. start_y = y + r * sin(start * M_PI / 180);
  889. end_x = x + r * cos(end * M_PI / 180);
  890. end_y = y + r * sin(end * M_PI / 180);
  891. rtgui_dc_draw_line(dc, x, y, start_x, start_y);
  892. rtgui_dc_draw_line(dc, x, y, end_x, end_y);
  893. }
  894. RTM_EXPORT(rtgui_dc_draw_sector);
  895. 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)
  896. {
  897. int start_x, start_y;
  898. int end_x, end_y;
  899. /* Sanity check radius */
  900. if (r < 0) return ;
  901. /* Special case for r=0 - draw a point */
  902. if (r == 0)
  903. {
  904. rtgui_dc_draw_point(dc, x, y);
  905. return;
  906. }
  907. while (start < 0) start += 360;
  908. while (end < 0) end += 360;
  909. /* Fixup angles */
  910. start = start % 360;
  911. end = end % 360;
  912. end_x = x + r * cos(end * M_PI / 180);
  913. end_y = y + r * sin(end * M_PI / 180);
  914. do
  915. {
  916. start_x = x + r * cos(start * M_PI / 180);
  917. start_y = y + r * sin(start * M_PI / 180);
  918. start ++;
  919. rtgui_dc_draw_line(dc, x, y, start_x, start_y);
  920. }while(!((start_x == end_x) && (start_y == end_y)));
  921. }
  922. RTM_EXPORT(rtgui_dc_fill_sector);
  923. 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)
  924. {
  925. int ix, iy;
  926. int h, i, j, k;
  927. int oh, oi, oj, ok;
  928. int xmh, xph, ypk, ymk;
  929. int xmi, xpi, ymj, ypj;
  930. int xmj, xpj, ymi, ypi;
  931. int xmk, xpk, ymh, yph;
  932. /*
  933. * Sanity check radii
  934. */
  935. if ((rx < 0) || (ry < 0)) return;
  936. /*
  937. * Special case for rx=0 - draw a vline
  938. */
  939. if (rx == 0)
  940. {
  941. rtgui_dc_draw_vline(dc, x, y - ry, y + ry);
  942. return;
  943. }
  944. /*
  945. * Special case for ry=0 - draw a hline
  946. */
  947. if (ry == 0)
  948. {
  949. rtgui_dc_draw_hline(dc, x - rx, x + rx, y);
  950. return;
  951. }
  952. /*
  953. * Init vars
  954. */
  955. oh = oi = oj = ok = 0xFFFF;
  956. if (rx > ry)
  957. {
  958. ix = 0;
  959. iy = rx * 64;
  960. do
  961. {
  962. h = (ix + 32) >> 6;
  963. i = (iy + 32) >> 6;
  964. j = (h * ry) / rx;
  965. k = (i * ry) / rx;
  966. if (((ok != k) && (oj != k)) || ((oj != j) && (ok != j)) || (k != j))
  967. {
  968. xph = x + h;
  969. xmh = x - h;
  970. if (k > 0)
  971. {
  972. ypk = y + k;
  973. ymk = y - k;
  974. rtgui_dc_draw_point(dc, xmh, ypk);
  975. rtgui_dc_draw_point(dc, xph, ypk);
  976. rtgui_dc_draw_point(dc, xmh, ymk);
  977. rtgui_dc_draw_point(dc, xph, ymk);
  978. }
  979. else
  980. {
  981. rtgui_dc_draw_point(dc, xmh, y);
  982. rtgui_dc_draw_point(dc, xph, y);
  983. }
  984. ok = k;
  985. xpi = x + i;
  986. xmi = x - i;
  987. if (j > 0)
  988. {
  989. ypj = y + j;
  990. ymj = y - j;
  991. rtgui_dc_draw_point(dc, xmi, ypj);
  992. rtgui_dc_draw_point(dc, xpi, ypj);
  993. rtgui_dc_draw_point(dc, xmi, ymj);
  994. rtgui_dc_draw_point(dc, xpi, ymj);
  995. }
  996. else
  997. {
  998. rtgui_dc_draw_point(dc, xmi, y);
  999. rtgui_dc_draw_point(dc, xpi, y);
  1000. }
  1001. oj = j;
  1002. }
  1003. ix = ix + iy / rx;
  1004. iy = iy - ix / rx;
  1005. } while (i > h);
  1006. }
  1007. else
  1008. {
  1009. ix = 0;
  1010. iy = ry * 64;
  1011. do
  1012. {
  1013. h = (ix + 32) >> 6;
  1014. i = (iy + 32) >> 6;
  1015. j = (h * rx) / ry;
  1016. k = (i * rx) / ry;
  1017. if (((oi != i) && (oh != i)) || ((oh != h) && (oi != h) && (i != h)))
  1018. {
  1019. xmj = x - j;
  1020. xpj = x + j;
  1021. if (i > 0)
  1022. {
  1023. ypi = y + i;
  1024. ymi = y - i;
  1025. rtgui_dc_draw_point(dc, xmj, ypi);
  1026. rtgui_dc_draw_point(dc, xpj, ypi);
  1027. rtgui_dc_draw_point(dc, xmj, ymi);
  1028. rtgui_dc_draw_point(dc, xpj, ymi);
  1029. }
  1030. else
  1031. {
  1032. rtgui_dc_draw_point(dc, xmj, y);
  1033. rtgui_dc_draw_point(dc, xpj, y);
  1034. }
  1035. oi = i;
  1036. xmk = x - k;
  1037. xpk = x + k;
  1038. if (h > 0)
  1039. {
  1040. yph = y + h;
  1041. ymh = y - h;
  1042. rtgui_dc_draw_point(dc, xmk, yph);
  1043. rtgui_dc_draw_point(dc, xpk, yph);
  1044. rtgui_dc_draw_point(dc, xmk, ymh);
  1045. rtgui_dc_draw_point(dc, xpk, ymh);
  1046. }
  1047. else
  1048. {
  1049. rtgui_dc_draw_point(dc, xmk, y);
  1050. rtgui_dc_draw_point(dc, xpk, y);
  1051. }
  1052. oh = h;
  1053. }
  1054. ix = ix + iy / ry;
  1055. iy = iy - ix / ry;
  1056. } while (i > h);
  1057. }
  1058. }
  1059. RTM_EXPORT(rtgui_dc_draw_ellipse);
  1060. 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)
  1061. {
  1062. int ix, iy;
  1063. int h, i, j, k;
  1064. int oh, oi, oj, ok;
  1065. int xmh, xph;
  1066. int xmi, xpi;
  1067. int xmj, xpj;
  1068. int xmk, xpk;
  1069. /*
  1070. * Special case for rx=0 - draw a vline
  1071. */
  1072. if (rx == 0)
  1073. {
  1074. rtgui_dc_draw_vline(dc, x, y - ry, y + ry);
  1075. return;
  1076. }
  1077. /* special case for ry=0 - draw a hline */
  1078. if (ry == 0) {
  1079. rtgui_dc_draw_hline(dc, x - rx, x + rx, y);
  1080. return;
  1081. }
  1082. /*
  1083. * Init vars
  1084. */
  1085. oh = oi = oj = ok = 0xFFFF;
  1086. /*
  1087. * Draw
  1088. */
  1089. if (rx > ry) {
  1090. ix = 0;
  1091. iy = rx * 64;
  1092. do {
  1093. h = (ix + 32) >> 6;
  1094. i = (iy + 32) >> 6;
  1095. j = (h * ry) / rx;
  1096. k = (i * ry) / rx;
  1097. if ((ok != k) && (oj != k)) {
  1098. xph = x + h;
  1099. xmh = x - h;
  1100. if (k > 0) {
  1101. rtgui_dc_draw_hline(dc, xmh, xph, y + k);
  1102. rtgui_dc_draw_hline(dc, xmh, xph, y - k);
  1103. } else {
  1104. rtgui_dc_draw_hline(dc, xmh, xph, y);
  1105. }
  1106. ok = k;
  1107. }
  1108. if ((oj != j) && (ok != j) && (k != j)) {
  1109. xmi = x - i;
  1110. xpi = x + i;
  1111. if (j > 0) {
  1112. rtgui_dc_draw_hline(dc, xmi, xpi, y + j);
  1113. rtgui_dc_draw_hline(dc, xmi, xpi, y - j);
  1114. } else {
  1115. rtgui_dc_draw_hline(dc, xmi, xpi, y);
  1116. }
  1117. oj = j;
  1118. }
  1119. ix = ix + iy / rx;
  1120. iy = iy - ix / rx;
  1121. } while (i > h);
  1122. } else {
  1123. ix = 0;
  1124. iy = ry * 64;
  1125. do {
  1126. h = (ix + 32) >> 6;
  1127. i = (iy + 32) >> 6;
  1128. j = (h * rx) / ry;
  1129. k = (i * rx) / ry;
  1130. if ((oi != i) && (oh != i)) {
  1131. xmj = x - j;
  1132. xpj = x + j;
  1133. if (i > 0) {
  1134. rtgui_dc_draw_hline(dc, xmj, xpj, y + i);
  1135. rtgui_dc_draw_hline(dc, xmj, xpj, y - i);
  1136. } else {
  1137. rtgui_dc_draw_hline(dc, xmj, xpj, y);
  1138. }
  1139. oi = i;
  1140. }
  1141. if ((oh != h) && (oi != h) && (i != h)) {
  1142. xmk = x - k;
  1143. xpk = x + k;
  1144. if (h > 0) {
  1145. rtgui_dc_draw_hline(dc, xmk, xpk, y + h);
  1146. rtgui_dc_draw_hline(dc, xmk, xpk, y - h);
  1147. } else {
  1148. rtgui_dc_draw_hline(dc, xmk, xpk, y);
  1149. }
  1150. oh = h;
  1151. }
  1152. ix = ix + iy / ry;
  1153. iy = iy - ix / ry;
  1154. } while (i > h);
  1155. }
  1156. }
  1157. RTM_EXPORT(rtgui_dc_fill_ellipse);