Draw.c 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948
  1. /*
  2. * The Python Imaging Library.
  3. * $Id$
  4. *
  5. * a simple drawing package for the Imaging library
  6. *
  7. * history:
  8. * 1996-04-13 fl Created.
  9. * 1996-04-30 fl Added transforms and polygon support.
  10. * 1996-08-12 fl Added filled polygons.
  11. * 1996-11-05 fl Fixed float/int confusion in polygon filler
  12. * 1997-07-04 fl Support 32-bit images (C++ would have been nice)
  13. * 1998-09-09 fl Eliminated qsort casts; improved rectangle clipping
  14. * 1998-09-10 fl Fixed fill rectangle to include lower edge (!)
  15. * 1998-12-29 fl Added arc, chord, and pieslice primitives
  16. * 1999-01-10 fl Added some level 2 ("arrow") stuff (experimental)
  17. * 1999-02-06 fl Added bitmap primitive
  18. * 1999-07-26 fl Eliminated a compiler warning
  19. * 1999-07-31 fl Pass ink as void* instead of int
  20. * 2002-12-10 fl Added experimental RGBA-on-RGB drawing
  21. * 2004-09-04 fl Support simple wide lines (no joins)
  22. * 2005-05-25 fl Fixed line width calculation
  23. *
  24. * Copyright (c) 1996-2006 by Fredrik Lundh
  25. * Copyright (c) 1997-2006 by Secret Labs AB.
  26. *
  27. * See the README file for information on usage and redistribution.
  28. */
  29. /* FIXME: support fill/outline attribute for all filled shapes */
  30. /* FIXME: support zero-winding fill */
  31. /* FIXME: add drawing context, support affine transforms */
  32. /* FIXME: support clip window (and mask?) */
  33. #include "Imaging.h"
  34. #include <math.h>
  35. #include <stdint.h>
  36. #define CEIL(v) (int)ceil(v)
  37. #define FLOOR(v) ((v) >= 0.0 ? (int)(v) : (int)floor(v))
  38. #define INK8(ink) (*(UINT8 *)ink)
  39. #define INK16(ink) (*(UINT16 *)ink)
  40. /*
  41. * Rounds around zero (up=away from zero, down=towards zero)
  42. * This guarantees that ROUND_UP|DOWN(f) == -ROUND_UP|DOWN(-f)
  43. */
  44. #define ROUND_UP(f) ((int)((f) >= 0.0 ? floor((f) + 0.5F) : -floor(fabs(f) + 0.5F)))
  45. #define ROUND_DOWN(f) ((int)((f) >= 0.0 ? ceil((f)-0.5F) : -ceil(fabs(f) - 0.5F)))
  46. /* -------------------------------------------------------------------- */
  47. /* Primitives */
  48. /* -------------------------------------------------------------------- */
  49. typedef struct {
  50. /* edge descriptor for polygon engine */
  51. int d;
  52. int x0, y0;
  53. int xmin, ymin, xmax, ymax;
  54. float dx;
  55. } Edge;
  56. /* Type used in "polygon*" functions */
  57. typedef void (*hline_handler)(Imaging, int, int, int, int);
  58. static inline void
  59. point8(Imaging im, int x, int y, int ink) {
  60. if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) {
  61. if (strncmp(im->mode, "I;16", 4) == 0) {
  62. #ifdef WORDS_BIGENDIAN
  63. im->image8[y][x * 2] = (UINT8)(ink >> 8);
  64. im->image8[y][x * 2 + 1] = (UINT8)ink;
  65. #else
  66. im->image8[y][x * 2] = (UINT8)ink;
  67. im->image8[y][x * 2 + 1] = (UINT8)(ink >> 8);
  68. #endif
  69. } else {
  70. im->image8[y][x] = (UINT8)ink;
  71. }
  72. }
  73. }
  74. static inline void
  75. point32(Imaging im, int x, int y, int ink) {
  76. if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) {
  77. im->image32[y][x] = ink;
  78. }
  79. }
  80. static inline void
  81. point32rgba(Imaging im, int x, int y, int ink) {
  82. unsigned int tmp;
  83. if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) {
  84. UINT8 *out = (UINT8 *)im->image[y] + x * 4;
  85. UINT8 *in = (UINT8 *)&ink;
  86. out[0] = BLEND(in[3], out[0], in[0], tmp);
  87. out[1] = BLEND(in[3], out[1], in[1], tmp);
  88. out[2] = BLEND(in[3], out[2], in[2], tmp);
  89. }
  90. }
  91. static inline void
  92. hline8(Imaging im, int x0, int y0, int x1, int ink) {
  93. int pixelwidth;
  94. if (y0 >= 0 && y0 < im->ysize) {
  95. if (x0 < 0) {
  96. x0 = 0;
  97. } else if (x0 >= im->xsize) {
  98. return;
  99. }
  100. if (x1 < 0) {
  101. return;
  102. } else if (x1 >= im->xsize) {
  103. x1 = im->xsize - 1;
  104. }
  105. if (x0 <= x1) {
  106. pixelwidth = strncmp(im->mode, "I;16", 4) == 0 ? 2 : 1;
  107. memset(
  108. im->image8[y0] + x0 * pixelwidth,
  109. (UINT8)ink,
  110. (x1 - x0 + 1) * pixelwidth);
  111. }
  112. }
  113. }
  114. static inline void
  115. hline32(Imaging im, int x0, int y0, int x1, int ink) {
  116. INT32 *p;
  117. if (y0 >= 0 && y0 < im->ysize) {
  118. if (x0 < 0) {
  119. x0 = 0;
  120. } else if (x0 >= im->xsize) {
  121. return;
  122. }
  123. if (x1 < 0) {
  124. return;
  125. } else if (x1 >= im->xsize) {
  126. x1 = im->xsize - 1;
  127. }
  128. p = im->image32[y0];
  129. while (x0 <= x1) {
  130. p[x0++] = ink;
  131. }
  132. }
  133. }
  134. static inline void
  135. hline32rgba(Imaging im, int x0, int y0, int x1, int ink) {
  136. unsigned int tmp;
  137. if (y0 >= 0 && y0 < im->ysize) {
  138. if (x0 < 0) {
  139. x0 = 0;
  140. } else if (x0 >= im->xsize) {
  141. return;
  142. }
  143. if (x1 < 0) {
  144. return;
  145. } else if (x1 >= im->xsize) {
  146. x1 = im->xsize - 1;
  147. }
  148. if (x0 <= x1) {
  149. UINT8 *out = (UINT8 *)im->image[y0] + x0 * 4;
  150. UINT8 *in = (UINT8 *)&ink;
  151. while (x0 <= x1) {
  152. out[0] = BLEND(in[3], out[0], in[0], tmp);
  153. out[1] = BLEND(in[3], out[1], in[1], tmp);
  154. out[2] = BLEND(in[3], out[2], in[2], tmp);
  155. x0++;
  156. out += 4;
  157. }
  158. }
  159. }
  160. }
  161. static inline void
  162. line8(Imaging im, int x0, int y0, int x1, int y1, int ink) {
  163. int i, n, e;
  164. int dx, dy;
  165. int xs, ys;
  166. /* normalize coordinates */
  167. dx = x1 - x0;
  168. if (dx < 0) {
  169. dx = -dx, xs = -1;
  170. } else {
  171. xs = 1;
  172. }
  173. dy = y1 - y0;
  174. if (dy < 0) {
  175. dy = -dy, ys = -1;
  176. } else {
  177. ys = 1;
  178. }
  179. n = (dx > dy) ? dx : dy;
  180. if (dx == 0) {
  181. /* vertical */
  182. for (i = 0; i < dy; i++) {
  183. point8(im, x0, y0, ink);
  184. y0 += ys;
  185. }
  186. } else if (dy == 0) {
  187. /* horizontal */
  188. for (i = 0; i < dx; i++) {
  189. point8(im, x0, y0, ink);
  190. x0 += xs;
  191. }
  192. } else if (dx > dy) {
  193. /* bresenham, horizontal slope */
  194. n = dx;
  195. dy += dy;
  196. e = dy - dx;
  197. dx += dx;
  198. for (i = 0; i < n; i++) {
  199. point8(im, x0, y0, ink);
  200. if (e >= 0) {
  201. y0 += ys;
  202. e -= dx;
  203. }
  204. e += dy;
  205. x0 += xs;
  206. }
  207. } else {
  208. /* bresenham, vertical slope */
  209. n = dy;
  210. dx += dx;
  211. e = dx - dy;
  212. dy += dy;
  213. for (i = 0; i < n; i++) {
  214. point8(im, x0, y0, ink);
  215. if (e >= 0) {
  216. x0 += xs;
  217. e -= dy;
  218. }
  219. e += dx;
  220. y0 += ys;
  221. }
  222. }
  223. }
  224. static inline void
  225. line32(Imaging im, int x0, int y0, int x1, int y1, int ink) {
  226. int i, n, e;
  227. int dx, dy;
  228. int xs, ys;
  229. /* normalize coordinates */
  230. dx = x1 - x0;
  231. if (dx < 0) {
  232. dx = -dx, xs = -1;
  233. } else {
  234. xs = 1;
  235. }
  236. dy = y1 - y0;
  237. if (dy < 0) {
  238. dy = -dy, ys = -1;
  239. } else {
  240. ys = 1;
  241. }
  242. n = (dx > dy) ? dx : dy;
  243. if (dx == 0) {
  244. /* vertical */
  245. for (i = 0; i < dy; i++) {
  246. point32(im, x0, y0, ink);
  247. y0 += ys;
  248. }
  249. } else if (dy == 0) {
  250. /* horizontal */
  251. for (i = 0; i < dx; i++) {
  252. point32(im, x0, y0, ink);
  253. x0 += xs;
  254. }
  255. } else if (dx > dy) {
  256. /* bresenham, horizontal slope */
  257. n = dx;
  258. dy += dy;
  259. e = dy - dx;
  260. dx += dx;
  261. for (i = 0; i < n; i++) {
  262. point32(im, x0, y0, ink);
  263. if (e >= 0) {
  264. y0 += ys;
  265. e -= dx;
  266. }
  267. e += dy;
  268. x0 += xs;
  269. }
  270. } else {
  271. /* bresenham, vertical slope */
  272. n = dy;
  273. dx += dx;
  274. e = dx - dy;
  275. dy += dy;
  276. for (i = 0; i < n; i++) {
  277. point32(im, x0, y0, ink);
  278. if (e >= 0) {
  279. x0 += xs;
  280. e -= dy;
  281. }
  282. e += dx;
  283. y0 += ys;
  284. }
  285. }
  286. }
  287. static inline void
  288. line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink) {
  289. int i, n, e;
  290. int dx, dy;
  291. int xs, ys;
  292. /* normalize coordinates */
  293. dx = x1 - x0;
  294. if (dx < 0) {
  295. dx = -dx, xs = -1;
  296. } else {
  297. xs = 1;
  298. }
  299. dy = y1 - y0;
  300. if (dy < 0) {
  301. dy = -dy, ys = -1;
  302. } else {
  303. ys = 1;
  304. }
  305. n = (dx > dy) ? dx : dy;
  306. if (dx == 0) {
  307. /* vertical */
  308. for (i = 0; i < dy; i++) {
  309. point32rgba(im, x0, y0, ink);
  310. y0 += ys;
  311. }
  312. } else if (dy == 0) {
  313. /* horizontal */
  314. for (i = 0; i < dx; i++) {
  315. point32rgba(im, x0, y0, ink);
  316. x0 += xs;
  317. }
  318. } else if (dx > dy) {
  319. /* bresenham, horizontal slope */
  320. n = dx;
  321. dy += dy;
  322. e = dy - dx;
  323. dx += dx;
  324. for (i = 0; i < n; i++) {
  325. point32rgba(im, x0, y0, ink);
  326. if (e >= 0) {
  327. y0 += ys;
  328. e -= dx;
  329. }
  330. e += dy;
  331. x0 += xs;
  332. }
  333. } else {
  334. /* bresenham, vertical slope */
  335. n = dy;
  336. dx += dx;
  337. e = dx - dy;
  338. dy += dy;
  339. for (i = 0; i < n; i++) {
  340. point32rgba(im, x0, y0, ink);
  341. if (e >= 0) {
  342. x0 += xs;
  343. e -= dy;
  344. }
  345. e += dx;
  346. y0 += ys;
  347. }
  348. }
  349. }
  350. static int
  351. x_cmp(const void *x0, const void *x1) {
  352. float diff = *((float *)x0) - *((float *)x1);
  353. if (diff < 0) {
  354. return -1;
  355. } else if (diff > 0) {
  356. return 1;
  357. } else {
  358. return 0;
  359. }
  360. }
  361. static void
  362. draw_horizontal_lines(
  363. Imaging im, int n, Edge *e, int ink, int *x_pos, int y, hline_handler hline) {
  364. int i;
  365. for (i = 0; i < n; i++) {
  366. if (e[i].ymin == y && e[i].ymin == e[i].ymax) {
  367. int xmax;
  368. int xmin = e[i].xmin;
  369. if (*x_pos != -1 && *x_pos < xmin) {
  370. // Line would be after the current position
  371. continue;
  372. }
  373. xmax = e[i].xmax;
  374. if (*x_pos > xmin) {
  375. // Line would be partway through x_pos, so increase the starting point
  376. xmin = *x_pos;
  377. if (xmax < xmin) {
  378. // Line would now end before it started
  379. continue;
  380. }
  381. }
  382. (*hline)(im, xmin, e[i].ymin, xmax, ink);
  383. *x_pos = xmax + 1;
  384. }
  385. }
  386. }
  387. /*
  388. * Filled polygon draw function using scan line algorithm.
  389. */
  390. static inline int
  391. polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill, hline_handler hline, int hasAlpha) {
  392. Edge **edge_table;
  393. float *xx;
  394. int edge_count = 0;
  395. int ymin = im->ysize - 1;
  396. int ymax = 0;
  397. int i, j, k;
  398. float adjacent_line_x, adjacent_line_x_other_edge;
  399. if (n <= 0) {
  400. return 0;
  401. }
  402. /* Initialize the edge table and find polygon boundaries */
  403. /* malloc check ok, using calloc */
  404. edge_table = calloc(n, sizeof(Edge *));
  405. if (!edge_table) {
  406. return -1;
  407. }
  408. for (i = 0; i < n; i++) {
  409. if (ymin > e[i].ymin) {
  410. ymin = e[i].ymin;
  411. }
  412. if (ymax < e[i].ymax) {
  413. ymax = e[i].ymax;
  414. }
  415. if (e[i].ymin == e[i].ymax) {
  416. if (hasAlpha != 1) {
  417. (*hline)(im, e[i].xmin, e[i].ymin, e[i].xmax, ink);
  418. }
  419. continue;
  420. }
  421. edge_table[edge_count++] = (e + i);
  422. }
  423. if (ymin < 0) {
  424. ymin = 0;
  425. }
  426. if (ymax > im->ysize) {
  427. ymax = im->ysize;
  428. }
  429. /* Process the edge table with a scan line searching for intersections */
  430. /* malloc check ok, using calloc */
  431. xx = calloc(edge_count * 2, sizeof(float));
  432. if (!xx) {
  433. free(edge_table);
  434. return -1;
  435. }
  436. for (; ymin <= ymax; ymin++) {
  437. j = 0;
  438. for (i = 0; i < edge_count; i++) {
  439. Edge *current = edge_table[i];
  440. if (ymin >= current->ymin && ymin <= current->ymax) {
  441. xx[j++] = (ymin - current->y0) * current->dx + current->x0;
  442. if (ymin == current->ymax && ymin < ymax) {
  443. // Needed to draw consistent polygons
  444. xx[j] = xx[j - 1];
  445. j++;
  446. } else if (current->dx != 0 && roundf(xx[j-1]) == xx[j-1]) {
  447. // Connect discontiguous corners
  448. for (k = 0; k < i; k++) {
  449. Edge *other_edge = edge_table[k];
  450. if ((current->dx > 0 && other_edge->dx <= 0) ||
  451. (current->dx < 0 && other_edge->dx >= 0)) {
  452. continue;
  453. }
  454. // Check if the two edges join to make a corner
  455. if (((ymin == current->ymin && ymin == other_edge->ymin) ||
  456. (ymin == current->ymax && ymin == other_edge->ymax)) &&
  457. xx[j-1] == (ymin - other_edge->y0) * other_edge->dx + other_edge->x0) {
  458. // Determine points from the edges on the next row
  459. // Or if this is the last row, check the previous row
  460. int offset = ymin == ymax ? -1 : 1;
  461. adjacent_line_x = (ymin + offset - current->y0) * current->dx + current->x0;
  462. adjacent_line_x_other_edge = (ymin + offset - other_edge->y0) * other_edge->dx + other_edge->x0;
  463. if (ymin == current->ymax) {
  464. if (current->dx > 0) {
  465. xx[k] = fmax(adjacent_line_x, adjacent_line_x_other_edge) + 1;
  466. } else {
  467. xx[k] = fmin(adjacent_line_x, adjacent_line_x_other_edge) - 1;
  468. }
  469. } else {
  470. if (current->dx > 0) {
  471. xx[k] = fmin(adjacent_line_x, adjacent_line_x_other_edge);
  472. } else {
  473. xx[k] = fmax(adjacent_line_x, adjacent_line_x_other_edge) + 1;
  474. }
  475. }
  476. break;
  477. }
  478. }
  479. }
  480. }
  481. }
  482. qsort(xx, j, sizeof(float), x_cmp);
  483. if (hasAlpha == 1) {
  484. int x_pos = j == 0 ? -1 : 0;
  485. for (i = 1; i < j; i += 2) {
  486. int x_end = ROUND_DOWN(xx[i]);
  487. if (x_end < x_pos) {
  488. // Line would be before the current position
  489. continue;
  490. }
  491. draw_horizontal_lines(im, n, e, ink, &x_pos, ymin, hline);
  492. if (x_end < x_pos) {
  493. // Line would be before the current position
  494. continue;
  495. }
  496. int x_start = ROUND_UP(xx[i - 1]);
  497. if (x_pos > x_start) {
  498. // Line would be partway through x_pos, so increase the starting point
  499. x_start = x_pos;
  500. if (x_end < x_start) {
  501. // Line would now end before it started
  502. continue;
  503. }
  504. }
  505. (*hline)(im, x_start, ymin, x_end, ink);
  506. x_pos = x_end + 1;
  507. }
  508. draw_horizontal_lines(im, n, e, ink, &x_pos, ymin, hline);
  509. } else {
  510. for (i = 1; i < j; i += 2) {
  511. (*hline)(im, ROUND_UP(xx[i - 1]), ymin, ROUND_DOWN(xx[i]), ink);
  512. }
  513. }
  514. }
  515. free(xx);
  516. free(edge_table);
  517. return 0;
  518. }
  519. static inline int
  520. polygon8(Imaging im, int n, Edge *e, int ink, int eofill) {
  521. return polygon_generic(im, n, e, ink, eofill, hline8, 0);
  522. }
  523. static inline int
  524. polygon32(Imaging im, int n, Edge *e, int ink, int eofill) {
  525. return polygon_generic(im, n, e, ink, eofill, hline32, 0);
  526. }
  527. static inline int
  528. polygon32rgba(Imaging im, int n, Edge *e, int ink, int eofill) {
  529. return polygon_generic(im, n, e, ink, eofill, hline32rgba, 1);
  530. }
  531. static inline void
  532. add_edge(Edge *e, int x0, int y0, int x1, int y1) {
  533. /* printf("edge %d %d %d %d\n", x0, y0, x1, y1); */
  534. if (x0 <= x1) {
  535. e->xmin = x0, e->xmax = x1;
  536. } else {
  537. e->xmin = x1, e->xmax = x0;
  538. }
  539. if (y0 <= y1) {
  540. e->ymin = y0, e->ymax = y1;
  541. } else {
  542. e->ymin = y1, e->ymax = y0;
  543. }
  544. if (y0 == y1) {
  545. e->d = 0;
  546. e->dx = 0.0;
  547. } else {
  548. e->dx = ((float)(x1 - x0)) / (y1 - y0);
  549. if (y0 == e->ymin) {
  550. e->d = 1;
  551. } else {
  552. e->d = -1;
  553. }
  554. }
  555. e->x0 = x0;
  556. e->y0 = y0;
  557. }
  558. typedef struct {
  559. void (*point)(Imaging im, int x, int y, int ink);
  560. void (*hline)(Imaging im, int x0, int y0, int x1, int ink);
  561. void (*line)(Imaging im, int x0, int y0, int x1, int y1, int ink);
  562. int (*polygon)(Imaging im, int n, Edge *e, int ink, int eofill);
  563. } DRAW;
  564. DRAW draw8 = {point8, hline8, line8, polygon8};
  565. DRAW draw32 = {point32, hline32, line32, polygon32};
  566. DRAW draw32rgba = {point32rgba, hline32rgba, line32rgba, polygon32rgba};
  567. /* -------------------------------------------------------------------- */
  568. /* Interface */
  569. /* -------------------------------------------------------------------- */
  570. #define DRAWINIT() \
  571. if (im->image8) { \
  572. draw = &draw8; \
  573. if (strncmp(im->mode, "I;16", 4) == 0) { \
  574. ink = INK16(ink_); \
  575. } else { \
  576. ink = INK8(ink_); \
  577. } \
  578. } else { \
  579. draw = (op) ? &draw32rgba : &draw32; \
  580. memcpy(&ink, ink_, sizeof(ink)); \
  581. }
  582. int
  583. ImagingDrawPoint(Imaging im, int x0, int y0, const void *ink_, int op) {
  584. DRAW *draw;
  585. INT32 ink;
  586. DRAWINIT();
  587. draw->point(im, x0, y0, ink);
  588. return 0;
  589. }
  590. int
  591. ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void *ink_, int op) {
  592. DRAW *draw;
  593. INT32 ink;
  594. DRAWINIT();
  595. draw->line(im, x0, y0, x1, y1, ink);
  596. return 0;
  597. }
  598. int
  599. ImagingDrawWideLine(
  600. Imaging im, int x0, int y0, int x1, int y1, const void *ink_, int width, int op) {
  601. DRAW *draw;
  602. INT32 ink;
  603. int dx, dy;
  604. double big_hypotenuse, small_hypotenuse, ratio_max, ratio_min;
  605. int dxmin, dxmax, dymin, dymax;
  606. Edge e[4];
  607. DRAWINIT();
  608. dx = x1 - x0;
  609. dy = y1 - y0;
  610. if (dx == 0 && dy == 0) {
  611. draw->point(im, x0, y0, ink);
  612. return 0;
  613. }
  614. big_hypotenuse = hypot(dx, dy);
  615. small_hypotenuse = (width - 1) / 2.0;
  616. ratio_max = ROUND_UP(small_hypotenuse) / big_hypotenuse;
  617. ratio_min = ROUND_DOWN(small_hypotenuse) / big_hypotenuse;
  618. dxmin = ROUND_DOWN(ratio_min * dy);
  619. dxmax = ROUND_DOWN(ratio_max * dy);
  620. dymin = ROUND_DOWN(ratio_min * dx);
  621. dymax = ROUND_DOWN(ratio_max * dx);
  622. {
  623. int vertices[4][2] = {
  624. {x0 - dxmin, y0 + dymax},
  625. {x1 - dxmin, y1 + dymax},
  626. {x1 + dxmax, y1 - dymin},
  627. {x0 + dxmax, y0 - dymin}};
  628. add_edge(e + 0, vertices[0][0], vertices[0][1], vertices[1][0], vertices[1][1]);
  629. add_edge(e + 1, vertices[1][0], vertices[1][1], vertices[2][0], vertices[2][1]);
  630. add_edge(e + 2, vertices[2][0], vertices[2][1], vertices[3][0], vertices[3][1]);
  631. add_edge(e + 3, vertices[3][0], vertices[3][1], vertices[0][0], vertices[0][1]);
  632. draw->polygon(im, 4, e, ink, 0);
  633. }
  634. return 0;
  635. }
  636. int
  637. ImagingDrawRectangle(
  638. Imaging im,
  639. int x0,
  640. int y0,
  641. int x1,
  642. int y1,
  643. const void *ink_,
  644. int fill,
  645. int width,
  646. int op) {
  647. int i;
  648. int y;
  649. int tmp;
  650. DRAW *draw;
  651. INT32 ink;
  652. DRAWINIT();
  653. if (y0 > y1) {
  654. tmp = y0, y0 = y1, y1 = tmp;
  655. }
  656. if (fill) {
  657. if (y0 < 0) {
  658. y0 = 0;
  659. } else if (y0 >= im->ysize) {
  660. return 0;
  661. }
  662. if (y1 < 0) {
  663. return 0;
  664. } else if (y1 > im->ysize) {
  665. y1 = im->ysize;
  666. }
  667. for (y = y0; y <= y1; y++) {
  668. draw->hline(im, x0, y, x1, ink);
  669. }
  670. } else {
  671. /* outline */
  672. if (width == 0) {
  673. width = 1;
  674. }
  675. for (i = 0; i < width; i++) {
  676. draw->hline(im, x0, y0 + i, x1, ink);
  677. draw->hline(im, x0, y1 - i, x1, ink);
  678. draw->line(im, x1 - i, y0 + width, x1 - i, y1 - width + 1, ink);
  679. draw->line(im, x0 + i, y0 + width, x0 + i, y1 - width + 1, ink);
  680. }
  681. }
  682. return 0;
  683. }
  684. int
  685. ImagingDrawPolygon(Imaging im, int count, int *xy, const void *ink_, int fill, int width, int op) {
  686. int i, n, x0, y0, x1, y1;
  687. DRAW *draw;
  688. INT32 ink;
  689. if (count <= 0) {
  690. return 0;
  691. }
  692. DRAWINIT();
  693. if (fill) {
  694. /* Build edge list */
  695. /* malloc check ok, using calloc */
  696. Edge *e = calloc(count, sizeof(Edge));
  697. if (!e) {
  698. (void)ImagingError_MemoryError();
  699. return -1;
  700. }
  701. for (i = n = 0; i < count - 1; i++) {
  702. x0 = xy[i * 2];
  703. y0 = xy[i * 2 + 1];
  704. x1 = xy[i * 2 + 2];
  705. y1 = xy[i * 2 + 3];
  706. if (y0 == y1 && i != 0 && y0 == xy[i * 2 - 1]) {
  707. // This is a horizontal line,
  708. // that immediately follows another horizontal line
  709. Edge *last_e = &e[n-1];
  710. if (x1 > x0 && x0 > xy[i * 2 - 2]) {
  711. // They are both increasing in x
  712. last_e->xmax = x1;
  713. continue;
  714. } else if (x1 < x0 && x0 < xy[i * 2 - 2]) {
  715. // They are both decreasing in x
  716. last_e->xmin = x1;
  717. continue;
  718. }
  719. }
  720. add_edge(&e[n++], x0, y0, x1, y1);
  721. }
  722. if (xy[i * 2] != xy[0] || xy[i * 2 + 1] != xy[1]) {
  723. add_edge(&e[n++], xy[i * 2], xy[i * 2 + 1], xy[0], xy[1]);
  724. }
  725. draw->polygon(im, n, e, ink, 0);
  726. free(e);
  727. } else {
  728. /* Outline */
  729. if (width == 1) {
  730. for (i = 0; i < count - 1; i++) {
  731. draw->line(im, xy[i * 2], xy[i * 2 + 1], xy[i * 2 + 2], xy[i * 2 + 3], ink);
  732. }
  733. draw->line(im, xy[i * 2], xy[i * 2 + 1], xy[0], xy[1], ink);
  734. } else {
  735. for (i = 0; i < count - 1; i++) {
  736. ImagingDrawWideLine(im, xy[i * 2], xy[i * 2 + 1], xy[i * 2 + 2], xy[i * 2 + 3], ink_, width, op);
  737. }
  738. ImagingDrawWideLine(im, xy[i * 2], xy[i * 2 + 1], xy[0], xy[1], ink_, width, op);
  739. }
  740. }
  741. return 0;
  742. }
  743. int
  744. ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, const void *ink, int op) {
  745. return ImagingFill2(
  746. im, ink, bitmap, x0, y0, x0 + bitmap->xsize, y0 + bitmap->ysize);
  747. }
  748. /* -------------------------------------------------------------------- */
  749. /* standard shapes */
  750. // Imagine 2D plane and ellipse with center in (0, 0) and semi-major axes a and b.
  751. // Then quarter_* stuff approximates its top right quarter (x, y >= 0) with integer
  752. // points from set {(2x+x0, 2y+y0) | x,y in Z} where x0, y0 are from {0, 1} and
  753. // are such that point (a, b) is in the set.
  754. typedef struct {
  755. int32_t a, b, cx, cy, ex, ey;
  756. int64_t a2, b2, a2b2;
  757. int8_t finished;
  758. } quarter_state;
  759. void
  760. quarter_init(quarter_state *s, int32_t a, int32_t b) {
  761. if (a < 0 || b < 0) {
  762. s->finished = 1;
  763. } else {
  764. s->a = a;
  765. s->b = b;
  766. s->cx = a;
  767. s->cy = b % 2;
  768. s->ex = a % 2;
  769. s->ey = b;
  770. s->a2 = a * a;
  771. s->b2 = b * b;
  772. s->a2b2 = s->a2 * s->b2;
  773. s->finished = 0;
  774. }
  775. }
  776. // deviation of the point from ellipse curve, basically a substitution
  777. // of the point into the ellipse equation
  778. int64_t
  779. quarter_delta(quarter_state *s, int64_t x, int64_t y) {
  780. return llabs(s->a2 * y * y + s->b2 * x * x - s->a2b2);
  781. }
  782. int8_t
  783. quarter_next(quarter_state *s, int32_t *ret_x, int32_t *ret_y) {
  784. if (s->finished) {
  785. return -1;
  786. }
  787. *ret_x = s->cx;
  788. *ret_y = s->cy;
  789. if (s->cx == s->ex && s->cy == s->ey) {
  790. s->finished = 1;
  791. } else {
  792. // Bresenham's algorithm, possible optimization: only consider 2 of 3
  793. // next points depending on current slope
  794. int32_t nx = s->cx;
  795. int32_t ny = s->cy + 2;
  796. int64_t ndelta = quarter_delta(s, nx, ny);
  797. if (nx > 1) {
  798. int64_t newdelta = quarter_delta(s, s->cx - 2, s->cy + 2);
  799. if (ndelta > newdelta) {
  800. nx = s->cx - 2;
  801. ny = s->cy + 2;
  802. ndelta = newdelta;
  803. }
  804. newdelta = quarter_delta(s, s->cx - 2, s->cy);
  805. if (ndelta > newdelta) {
  806. nx = s->cx - 2;
  807. ny = s->cy;
  808. }
  809. }
  810. s->cx = nx;
  811. s->cy = ny;
  812. }
  813. return 0;
  814. }
  815. // quarter_* stuff can "draw" a quarter of an ellipse with thickness 1, great.
  816. // Now we use ellipse_* stuff to join all four quarters of two different sized
  817. // ellipses and receive horizontal segments of a complete ellipse with
  818. // specified thickness.
  819. //
  820. // Still using integer grid with step 2 at this point (like in quarter_*)
  821. // to ease angle clipping in future.
  822. typedef struct {
  823. quarter_state st_o, st_i;
  824. int32_t py, pl, pr;
  825. int32_t cy[4], cl[4], cr[4];
  826. int8_t bufcnt;
  827. int8_t finished;
  828. int8_t leftmost;
  829. } ellipse_state;
  830. void
  831. ellipse_init(ellipse_state *s, int32_t a, int32_t b, int32_t w) {
  832. s->bufcnt = 0;
  833. s->leftmost = a % 2;
  834. quarter_init(&s->st_o, a, b);
  835. if (w < 1 || quarter_next(&s->st_o, &s->pr, &s->py) == -1) {
  836. s->finished = 1;
  837. } else {
  838. s->finished = 0;
  839. quarter_init(&s->st_i, a - 2 * (w - 1), b - 2 * (w - 1));
  840. s->pl = s->leftmost;
  841. }
  842. }
  843. int8_t
  844. ellipse_next(ellipse_state *s, int32_t *ret_x0, int32_t *ret_y, int32_t *ret_x1) {
  845. if (s->bufcnt == 0) {
  846. if (s->finished) {
  847. return -1;
  848. }
  849. int32_t y = s->py;
  850. int32_t l = s->pl;
  851. int32_t r = s->pr;
  852. int32_t cx = 0, cy = 0;
  853. int8_t next_ret;
  854. while ((next_ret = quarter_next(&s->st_o, &cx, &cy)) != -1 && cy <= y) {
  855. }
  856. if (next_ret == -1) {
  857. s->finished = 1;
  858. } else {
  859. s->pr = cx;
  860. s->py = cy;
  861. }
  862. while ((next_ret = quarter_next(&s->st_i, &cx, &cy)) != -1 && cy <= y) {
  863. l = cx;
  864. }
  865. s->pl = next_ret == -1 ? s->leftmost : cx;
  866. if ((l > 0 || l < r) && y > 0) {
  867. s->cl[s->bufcnt] = l == 0 ? 2 : l;
  868. s->cy[s->bufcnt] = y;
  869. s->cr[s->bufcnt] = r;
  870. ++s->bufcnt;
  871. }
  872. if (y > 0) {
  873. s->cl[s->bufcnt] = -r;
  874. s->cy[s->bufcnt] = y;
  875. s->cr[s->bufcnt] = -l;
  876. ++s->bufcnt;
  877. }
  878. if (l > 0 || l < r) {
  879. s->cl[s->bufcnt] = l == 0 ? 2 : l;
  880. s->cy[s->bufcnt] = -y;
  881. s->cr[s->bufcnt] = r;
  882. ++s->bufcnt;
  883. }
  884. s->cl[s->bufcnt] = -r;
  885. s->cy[s->bufcnt] = -y;
  886. s->cr[s->bufcnt] = -l;
  887. ++s->bufcnt;
  888. }
  889. --s->bufcnt;
  890. *ret_x0 = s->cl[s->bufcnt];
  891. *ret_y = s->cy[s->bufcnt];
  892. *ret_x1 = s->cr[s->bufcnt];
  893. return 0;
  894. }
  895. // Clipping tree consists of half-plane clipping nodes and combining nodes.
  896. // We can throw a horizontal segment in such a tree and collect an ordered set
  897. // of resulting disjoint clipped segments organized into a sorted linked list
  898. // of their end points.
  899. typedef enum {
  900. CT_AND, // intersection
  901. CT_OR, // union
  902. CT_CLIP // half-plane clipping
  903. } clip_type;
  904. typedef struct clip_node {
  905. clip_type type;
  906. double a, b, c; // half-plane coeffs, only used in clipping nodes
  907. struct clip_node *l; // child pointers, are only non-NULL in combining nodes
  908. struct clip_node *r;
  909. } clip_node;
  910. // Linked list for the ends of the clipped horizontal segments.
  911. // Since the segment is always horizontal, we don't need to store Y coordinate.
  912. typedef struct event_list {
  913. int32_t x;
  914. int8_t type; // used internally, 1 for the left end (smaller X), -1 for the
  915. // right end; pointless in output since the output segments
  916. // are disjoint, therefore the types would always come in pairs
  917. // and interchange (1 -1 1 -1 ...)
  918. struct event_list *next;
  919. } event_list;
  920. // Mirrors all the clipping nodes of the tree relative to the y = x line.
  921. void
  922. clip_tree_transpose(clip_node *root) {
  923. if (root != NULL) {
  924. if (root->type == CT_CLIP) {
  925. double t = root->a;
  926. root->a = root->b;
  927. root->b = t;
  928. }
  929. clip_tree_transpose(root->l);
  930. clip_tree_transpose(root->r);
  931. }
  932. }
  933. // Outputs a sequence of open-close events (types -1 and 1) for
  934. // non-intersecting segments sorted by X coordinate.
  935. // Combining nodes (AND, OR) may also accept sequences for intersecting
  936. // segments, i.e. something like correct bracket sequences.
  937. int
  938. clip_tree_do_clip(
  939. clip_node *root, int32_t x0, int32_t y, int32_t x1, event_list **ret) {
  940. if (root == NULL) {
  941. event_list *start = malloc(sizeof(event_list));
  942. if (!start) {
  943. ImagingError_MemoryError();
  944. return -1;
  945. }
  946. event_list *end = malloc(sizeof(event_list));
  947. if (!end) {
  948. free(start);
  949. ImagingError_MemoryError();
  950. return -1;
  951. }
  952. start->x = x0;
  953. start->type = 1;
  954. start->next = end;
  955. end->x = x1;
  956. end->type = -1;
  957. end->next = NULL;
  958. *ret = start;
  959. return 0;
  960. }
  961. if (root->type == CT_CLIP) {
  962. double eps = 1e-9;
  963. double A = root->a;
  964. double B = root->b;
  965. double C = root->c;
  966. if (fabs(A) < eps) {
  967. if (B * y + C < -eps) {
  968. x0 = 1;
  969. x1 = 0;
  970. }
  971. } else {
  972. // X of intersection
  973. double ix = -(B * y + C) / A;
  974. if (A * x0 + B * y + C < eps) {
  975. x0 = lround(fmax(x0, ix));
  976. }
  977. if (A * x1 + B * y + C < eps) {
  978. x1 = lround(fmin(x1, ix));
  979. }
  980. }
  981. if (x0 <= x1) {
  982. event_list *start = malloc(sizeof(event_list));
  983. if (!start) {
  984. ImagingError_MemoryError();
  985. return -1;
  986. }
  987. event_list *end = malloc(sizeof(event_list));
  988. if (!end) {
  989. free(start);
  990. ImagingError_MemoryError();
  991. return -1;
  992. }
  993. start->x = x0;
  994. start->type = 1;
  995. start->next = end;
  996. end->x = x1;
  997. end->type = -1;
  998. end->next = NULL;
  999. *ret = start;
  1000. } else {
  1001. *ret = NULL;
  1002. }
  1003. return 0;
  1004. }
  1005. if (root->type == CT_OR || root->type == CT_AND) {
  1006. event_list *l1;
  1007. event_list *l2;
  1008. if (clip_tree_do_clip(root->l, x0, y, x1, &l1) < 0) {
  1009. return -1;
  1010. }
  1011. if (clip_tree_do_clip(root->r, x0, y, x1, &l2) < 0) {
  1012. while (l1) {
  1013. l2 = l1->next;
  1014. free(l1);
  1015. l1 = l2;
  1016. }
  1017. return -1;
  1018. }
  1019. *ret = NULL;
  1020. event_list *tail = NULL;
  1021. int32_t k1 = 0;
  1022. int32_t k2 = 0;
  1023. while (l1 != NULL || l2 != NULL) {
  1024. event_list *t;
  1025. if (l2 == NULL ||
  1026. (l1 != NULL &&
  1027. (l1->x < l2->x || (l1->x == l2->x && l1->type > l2->type)))) {
  1028. t = l1;
  1029. k1 += t->type;
  1030. assert(k1 >= 0);
  1031. l1 = l1->next;
  1032. } else {
  1033. t = l2;
  1034. k2 += t->type;
  1035. assert(k2 >= 0);
  1036. l2 = l2->next;
  1037. }
  1038. t->next = NULL;
  1039. if ((root->type == CT_OR &&
  1040. ((t->type == 1 && (tail == NULL || tail->type == -1)) ||
  1041. (t->type == -1 && k1 == 0 && k2 == 0))) ||
  1042. (root->type == CT_AND &&
  1043. ((t->type == 1 && (tail == NULL || tail->type == -1) && k1 > 0 &&
  1044. k2 > 0) ||
  1045. (t->type == -1 && tail != NULL && tail->type == 1 &&
  1046. (k1 == 0 || k2 == 0))))) {
  1047. if (tail == NULL) {
  1048. *ret = t;
  1049. } else {
  1050. tail->next = t;
  1051. }
  1052. tail = t;
  1053. } else {
  1054. free(t);
  1055. }
  1056. }
  1057. return 0;
  1058. }
  1059. *ret = NULL;
  1060. return 0;
  1061. }
  1062. // One more layer of processing on top of the regular ellipse.
  1063. // Uses the clipping tree.
  1064. // Used for producing ellipse derivatives such as arc, chord, pie, etc.
  1065. typedef struct {
  1066. ellipse_state st;
  1067. clip_node *root;
  1068. clip_node nodes[7];
  1069. int32_t node_count;
  1070. event_list *head;
  1071. int32_t y;
  1072. } clip_ellipse_state;
  1073. typedef void (*clip_ellipse_init)(
  1074. clip_ellipse_state *, int32_t, int32_t, int32_t, float, float);
  1075. void
  1076. debug_clip_tree(clip_node *root, int space) {
  1077. if (root == NULL) {
  1078. return;
  1079. }
  1080. if (root->type == CT_CLIP) {
  1081. int t = space;
  1082. while (t--) {
  1083. fputc(' ', stderr);
  1084. }
  1085. fprintf(stderr, "clip %+fx%+fy%+f > 0\n", root->a, root->b, root->c);
  1086. } else {
  1087. debug_clip_tree(root->l, space + 2);
  1088. int t = space;
  1089. while (t--) {
  1090. fputc(' ', stderr);
  1091. }
  1092. fprintf(stderr, "%s\n", root->type == CT_AND ? "and" : "or");
  1093. debug_clip_tree(root->r, space + 2);
  1094. }
  1095. if (space == 0) {
  1096. fputc('\n', stderr);
  1097. }
  1098. }
  1099. // Resulting angles will satisfy 0 <= al < 360, al <= ar <= al + 360
  1100. void
  1101. normalize_angles(float *al, float *ar) {
  1102. if (*ar - *al >= 360) {
  1103. *al = 0;
  1104. *ar = 360;
  1105. } else {
  1106. *al = fmod(*al < 0 ? 360 - (fmod(-*al, 360)) : *al, 360);
  1107. *ar = *al + fmod(*ar < *al ? 360 - fmod(*al - *ar, 360) : *ar - *al, 360);
  1108. }
  1109. }
  1110. // An arc with caps orthogonal to the ellipse curve.
  1111. void
  1112. arc_init(clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float ar) {
  1113. if (a < b) {
  1114. // transpose the coordinate system
  1115. arc_init(s, b, a, w, 90 - ar, 90 - al);
  1116. ellipse_init(&s->st, a, b, w);
  1117. clip_tree_transpose(s->root);
  1118. } else {
  1119. // a >= b, based on "wide" ellipse
  1120. ellipse_init(&s->st, a, b, w);
  1121. s->head = NULL;
  1122. s->node_count = 0;
  1123. normalize_angles(&al, &ar);
  1124. // building clipping tree, a lot of different cases
  1125. if (ar == al + 360) {
  1126. s->root = NULL;
  1127. } else {
  1128. clip_node *lc = s->nodes + s->node_count++;
  1129. clip_node *rc = s->nodes + s->node_count++;
  1130. lc->l = lc->r = rc->l = rc->r = NULL;
  1131. lc->type = rc->type = CT_CLIP;
  1132. lc->a = -a * sin(al * M_PI / 180.0);
  1133. lc->b = b * cos(al * M_PI / 180.0);
  1134. lc->c = (a * a - b * b) * sin(al * M_PI / 90.0) / 2.0;
  1135. rc->a = a * sin(ar * M_PI / 180.0);
  1136. rc->b = -b * cos(ar * M_PI / 180.0);
  1137. rc->c = (b * b - a * a) * sin(ar * M_PI / 90.0) / 2.0;
  1138. if (fmod(al, 180) == 0 || fmod(ar, 180) == 0) {
  1139. s->root = s->nodes + s->node_count++;
  1140. s->root->l = lc;
  1141. s->root->r = rc;
  1142. s->root->type = ar - al < 180 ? CT_AND : CT_OR;
  1143. } else if (((int)(al / 180) + (int)(ar / 180)) % 2 == 1) {
  1144. s->root = s->nodes + s->node_count++;
  1145. s->root->l = s->nodes + s->node_count++;
  1146. s->root->l->l = s->nodes + s->node_count++;
  1147. s->root->l->r = lc;
  1148. s->root->r = s->nodes + s->node_count++;
  1149. s->root->r->l = s->nodes + s->node_count++;
  1150. s->root->r->r = rc;
  1151. s->root->type = CT_OR;
  1152. s->root->l->type = CT_AND;
  1153. s->root->r->type = CT_AND;
  1154. s->root->l->l->type = CT_CLIP;
  1155. s->root->r->l->type = CT_CLIP;
  1156. s->root->l->l->l = s->root->l->l->r = NULL;
  1157. s->root->r->l->l = s->root->r->l->r = NULL;
  1158. s->root->l->l->a = s->root->l->l->c = 0;
  1159. s->root->r->l->a = s->root->r->l->c = 0;
  1160. s->root->l->l->b = (int)(al / 180) % 2 == 0 ? 1 : -1;
  1161. s->root->r->l->b = (int)(ar / 180) % 2 == 0 ? 1 : -1;
  1162. } else {
  1163. s->root = s->nodes + s->node_count++;
  1164. s->root->l = s->nodes + s->node_count++;
  1165. s->root->r = s->nodes + s->node_count++;
  1166. s->root->type = s->root->l->type = ar - al < 180 ? CT_AND : CT_OR;
  1167. s->root->l->l = lc;
  1168. s->root->l->r = rc;
  1169. s->root->r->type = CT_CLIP;
  1170. s->root->r->l = s->root->r->r = NULL;
  1171. s->root->r->a = s->root->r->c = 0;
  1172. s->root->r->b = ar < 180 || ar > 540 ? 1 : -1;
  1173. }
  1174. }
  1175. }
  1176. }
  1177. // A chord line.
  1178. void
  1179. chord_line_init(
  1180. clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float ar) {
  1181. ellipse_init(&s->st, a, b, a + b + 1);
  1182. s->head = NULL;
  1183. s->node_count = 0;
  1184. // line equation for chord
  1185. double xl = a * cos(al * M_PI / 180.0), xr = a * cos(ar * M_PI / 180.0);
  1186. double yl = b * sin(al * M_PI / 180.0), yr = b * sin(ar * M_PI / 180.0);
  1187. s->root = s->nodes + s->node_count++;
  1188. s->root->l = s->nodes + s->node_count++;
  1189. s->root->r = s->nodes + s->node_count++;
  1190. s->root->type = CT_AND;
  1191. s->root->l->type = s->root->r->type = CT_CLIP;
  1192. s->root->l->l = s->root->l->r = s->root->r->l = s->root->r->r = NULL;
  1193. s->root->l->a = yr - yl;
  1194. s->root->l->b = xl - xr;
  1195. s->root->l->c = -(s->root->l->a * xl + s->root->l->b * yl);
  1196. s->root->r->a = -s->root->l->a;
  1197. s->root->r->b = -s->root->l->b;
  1198. s->root->r->c =
  1199. 2 * w * sqrt(pow(s->root->l->a, 2.0) + pow(s->root->l->b, 2.0)) - s->root->l->c;
  1200. }
  1201. // Pie side.
  1202. void
  1203. pie_side_init(
  1204. clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float _) {
  1205. ellipse_init(&s->st, a, b, a + b + 1);
  1206. s->head = NULL;
  1207. s->node_count = 0;
  1208. double xl = a * cos(al * M_PI / 180.0);
  1209. double yl = b * sin(al * M_PI / 180.0);
  1210. double a1 = -yl;
  1211. double b1 = xl;
  1212. double c1 = w * sqrt(a1 * a1 + b1 * b1);
  1213. s->root = s->nodes + s->node_count++;
  1214. s->root->type = CT_AND;
  1215. s->root->l = s->nodes + s->node_count++;
  1216. s->root->l->type = CT_AND;
  1217. clip_node *cnode;
  1218. cnode = s->nodes + s->node_count++;
  1219. cnode->l = cnode->r = NULL;
  1220. cnode->type = CT_CLIP;
  1221. cnode->a = a1;
  1222. cnode->b = b1;
  1223. cnode->c = c1;
  1224. s->root->l->l = cnode;
  1225. cnode = s->nodes + s->node_count++;
  1226. cnode->l = cnode->r = NULL;
  1227. cnode->type = CT_CLIP;
  1228. cnode->a = -a1;
  1229. cnode->b = -b1;
  1230. cnode->c = c1;
  1231. s->root->l->r = cnode;
  1232. cnode = s->nodes + s->node_count++;
  1233. cnode->l = cnode->r = NULL;
  1234. cnode->type = CT_CLIP;
  1235. cnode->a = b1;
  1236. cnode->b = -a1;
  1237. cnode->c = 0;
  1238. s->root->r = cnode;
  1239. }
  1240. // A chord.
  1241. void
  1242. chord_init(clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float ar) {
  1243. ellipse_init(&s->st, a, b, w);
  1244. s->head = NULL;
  1245. s->node_count = 0;
  1246. // line equation for chord
  1247. double xl = a * cos(al * M_PI / 180.0), xr = a * cos(ar * M_PI / 180.0);
  1248. double yl = b * sin(al * M_PI / 180.0), yr = b * sin(ar * M_PI / 180.0);
  1249. s->root = s->nodes + s->node_count++;
  1250. s->root->l = s->root->r = NULL;
  1251. s->root->type = CT_CLIP;
  1252. s->root->a = yr - yl;
  1253. s->root->b = xl - xr;
  1254. s->root->c = -(s->root->a * xl + s->root->b * yl);
  1255. }
  1256. // A pie. Can also be used to draw an arc with ugly sharp caps.
  1257. void
  1258. pie_init(clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float ar) {
  1259. ellipse_init(&s->st, a, b, w);
  1260. s->head = NULL;
  1261. s->node_count = 0;
  1262. // line equations for pie sides
  1263. double xl = a * cos(al * M_PI / 180.0), xr = a * cos(ar * M_PI / 180.0);
  1264. double yl = b * sin(al * M_PI / 180.0), yr = b * sin(ar * M_PI / 180.0);
  1265. clip_node *lc = s->nodes + s->node_count++;
  1266. clip_node *rc = s->nodes + s->node_count++;
  1267. lc->l = lc->r = rc->l = rc->r = NULL;
  1268. lc->type = rc->type = CT_CLIP;
  1269. lc->a = -yl;
  1270. lc->b = xl;
  1271. lc->c = 0;
  1272. rc->a = yr;
  1273. rc->b = -xr;
  1274. rc->c = 0;
  1275. s->root = s->nodes + s->node_count++;
  1276. s->root->l = lc;
  1277. s->root->r = rc;
  1278. s->root->type = ar - al < 180 ? CT_AND : CT_OR;
  1279. // add one more semiplane to avoid spikes
  1280. if (ar - al < 90) {
  1281. clip_node *old_root = s->root;
  1282. clip_node *spike_clipper = s->nodes + s->node_count++;
  1283. s->root = s->nodes + s->node_count++;
  1284. s->root->l = old_root;
  1285. s->root->r = spike_clipper;
  1286. s->root->type = CT_AND;
  1287. spike_clipper->l = spike_clipper->r = NULL;
  1288. spike_clipper->type = CT_CLIP;
  1289. spike_clipper->a = (xl + xr) / 2.0;
  1290. spike_clipper->b = (yl + yr) / 2.0;
  1291. spike_clipper->c = 0;
  1292. }
  1293. }
  1294. void
  1295. clip_ellipse_free(clip_ellipse_state *s) {
  1296. while (s->head != NULL) {
  1297. event_list *t = s->head;
  1298. s->head = s->head->next;
  1299. free(t);
  1300. }
  1301. }
  1302. int8_t
  1303. clip_ellipse_next(
  1304. clip_ellipse_state *s, int32_t *ret_x0, int32_t *ret_y, int32_t *ret_x1) {
  1305. int32_t x0, y, x1;
  1306. while (s->head == NULL && ellipse_next(&s->st, &x0, &y, &x1) >= 0) {
  1307. if (clip_tree_do_clip(s->root, x0, y, x1, &s->head) < 0) {
  1308. return -2;
  1309. }
  1310. s->y = y;
  1311. }
  1312. if (s->head != NULL) {
  1313. *ret_y = s->y;
  1314. event_list *t = s->head;
  1315. s->head = s->head->next;
  1316. *ret_x0 = t->x;
  1317. free(t);
  1318. t = s->head;
  1319. assert(t != NULL);
  1320. s->head = s->head->next;
  1321. *ret_x1 = t->x;
  1322. free(t);
  1323. return 0;
  1324. }
  1325. return -1;
  1326. }
  1327. static int
  1328. ellipseNew(
  1329. Imaging im,
  1330. int x0,
  1331. int y0,
  1332. int x1,
  1333. int y1,
  1334. const void *ink_,
  1335. int fill,
  1336. int width,
  1337. int op) {
  1338. DRAW *draw;
  1339. INT32 ink;
  1340. DRAWINIT();
  1341. int a = x1 - x0;
  1342. int b = y1 - y0;
  1343. if (a < 0 || b < 0) {
  1344. return 0;
  1345. }
  1346. if (fill) {
  1347. width = a + b;
  1348. }
  1349. ellipse_state st;
  1350. ellipse_init(&st, a, b, width);
  1351. int32_t X0, Y, X1;
  1352. while (ellipse_next(&st, &X0, &Y, &X1) != -1) {
  1353. draw->hline(im, x0 + (X0 + a) / 2, y0 + (Y + b) / 2, x0 + (X1 + a) / 2, ink);
  1354. }
  1355. return 0;
  1356. }
  1357. static int
  1358. clipEllipseNew(
  1359. Imaging im,
  1360. int x0,
  1361. int y0,
  1362. int x1,
  1363. int y1,
  1364. float start,
  1365. float end,
  1366. const void *ink_,
  1367. int width,
  1368. int op,
  1369. clip_ellipse_init init) {
  1370. DRAW *draw;
  1371. INT32 ink;
  1372. DRAWINIT();
  1373. int a = x1 - x0;
  1374. int b = y1 - y0;
  1375. if (a < 0 || b < 0) {
  1376. return 0;
  1377. }
  1378. clip_ellipse_state st;
  1379. init(&st, a, b, width, start, end);
  1380. // debug_clip_tree(st.root, 0);
  1381. int32_t X0, Y, X1;
  1382. int next_code;
  1383. while ((next_code = clip_ellipse_next(&st, &X0, &Y, &X1)) >= 0) {
  1384. draw->hline(im, x0 + (X0 + a) / 2, y0 + (Y + b) / 2, x0 + (X1 + a) / 2, ink);
  1385. }
  1386. clip_ellipse_free(&st);
  1387. return next_code == -1 ? 0 : -1;
  1388. }
  1389. static int
  1390. arcNew(
  1391. Imaging im,
  1392. int x0,
  1393. int y0,
  1394. int x1,
  1395. int y1,
  1396. float start,
  1397. float end,
  1398. const void *ink_,
  1399. int width,
  1400. int op) {
  1401. return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, arc_init);
  1402. }
  1403. static int
  1404. chordNew(
  1405. Imaging im,
  1406. int x0,
  1407. int y0,
  1408. int x1,
  1409. int y1,
  1410. float start,
  1411. float end,
  1412. const void *ink_,
  1413. int width,
  1414. int op) {
  1415. return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, chord_init);
  1416. }
  1417. static int
  1418. chordLineNew(
  1419. Imaging im,
  1420. int x0,
  1421. int y0,
  1422. int x1,
  1423. int y1,
  1424. float start,
  1425. float end,
  1426. const void *ink_,
  1427. int width,
  1428. int op) {
  1429. return clipEllipseNew(
  1430. im, x0, y0, x1, y1, start, end, ink_, width, op, chord_line_init);
  1431. }
  1432. static int
  1433. pieNew(
  1434. Imaging im,
  1435. int x0,
  1436. int y0,
  1437. int x1,
  1438. int y1,
  1439. float start,
  1440. float end,
  1441. const void *ink_,
  1442. int width,
  1443. int op) {
  1444. return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, pie_init);
  1445. }
  1446. static int
  1447. pieSideNew(
  1448. Imaging im,
  1449. int x0,
  1450. int y0,
  1451. int x1,
  1452. int y1,
  1453. float start,
  1454. const void *ink_,
  1455. int width,
  1456. int op) {
  1457. return clipEllipseNew(im, x0, y0, x1, y1, start, 0, ink_, width, op, pie_side_init);
  1458. }
  1459. int
  1460. ImagingDrawEllipse(
  1461. Imaging im,
  1462. int x0,
  1463. int y0,
  1464. int x1,
  1465. int y1,
  1466. const void *ink,
  1467. int fill,
  1468. int width,
  1469. int op) {
  1470. return ellipseNew(im, x0, y0, x1, y1, ink, fill, width, op);
  1471. }
  1472. int
  1473. ImagingDrawArc(
  1474. Imaging im,
  1475. int x0,
  1476. int y0,
  1477. int x1,
  1478. int y1,
  1479. float start,
  1480. float end,
  1481. const void *ink,
  1482. int width,
  1483. int op) {
  1484. normalize_angles(&start, &end);
  1485. if (start + 360 == end) {
  1486. return ImagingDrawEllipse(im, x0, y0, x1, y1, ink, 0, width, op);
  1487. }
  1488. if (start == end) {
  1489. return 0;
  1490. }
  1491. return arcNew(im, x0, y0, x1, y1, start, end, ink, width, op);
  1492. }
  1493. int
  1494. ImagingDrawChord(
  1495. Imaging im,
  1496. int x0,
  1497. int y0,
  1498. int x1,
  1499. int y1,
  1500. float start,
  1501. float end,
  1502. const void *ink,
  1503. int fill,
  1504. int width,
  1505. int op) {
  1506. normalize_angles(&start, &end);
  1507. if (start + 360 == end) {
  1508. return ImagingDrawEllipse(im, x0, y0, x1, y1, ink, fill, width, op);
  1509. }
  1510. if (start == end) {
  1511. return 0;
  1512. }
  1513. if (fill) {
  1514. return chordNew(im, x0, y0, x1, y1, start, end, ink, x1 - x0 + y1 - y0 + 1, op);
  1515. } else {
  1516. if (chordLineNew(im, x0, y0, x1, y1, start, end, ink, width, op)) {
  1517. return -1;
  1518. }
  1519. return chordNew(im, x0, y0, x1, y1, start, end, ink, width, op);
  1520. }
  1521. }
  1522. int
  1523. ImagingDrawPieslice(
  1524. Imaging im,
  1525. int x0,
  1526. int y0,
  1527. int x1,
  1528. int y1,
  1529. float start,
  1530. float end,
  1531. const void *ink,
  1532. int fill,
  1533. int width,
  1534. int op) {
  1535. normalize_angles(&start, &end);
  1536. if (start + 360 == end) {
  1537. return ellipseNew(im, x0, y0, x1, y1, ink, fill, width, op);
  1538. }
  1539. if (start == end) {
  1540. return 0;
  1541. }
  1542. if (fill) {
  1543. return pieNew(im, x0, y0, x1, y1, start, end, ink, x1 + y1 - x0 - y0, op);
  1544. } else {
  1545. if (pieSideNew(im, x0, y0, x1, y1, start, ink, width, op)) {
  1546. return -1;
  1547. }
  1548. if (pieSideNew(im, x0, y0, x1, y1, end, ink, width, op)) {
  1549. return -1;
  1550. }
  1551. int xc = lround((x0 + x1 - width) / 2.0), yc = lround((y0 + y1 - width) / 2.0);
  1552. ellipseNew(im, xc, yc, xc + width - 1, yc + width - 1, ink, 1, 0, op);
  1553. return pieNew(im, x0, y0, x1, y1, start, end, ink, width, op);
  1554. }
  1555. }
  1556. /* -------------------------------------------------------------------- */
  1557. /* experimental level 2 ("arrow") graphics stuff. this implements
  1558. portions of the arrow api on top of the Edge structure. the
  1559. semantics are ok, except that "curve" flattens the bezier curves by
  1560. itself */
  1561. struct ImagingOutlineInstance {
  1562. float x0, y0;
  1563. float x, y;
  1564. int count;
  1565. Edge *edges;
  1566. int size;
  1567. };
  1568. ImagingOutline
  1569. ImagingOutlineNew(void) {
  1570. ImagingOutline outline;
  1571. outline = calloc(1, sizeof(struct ImagingOutlineInstance));
  1572. if (!outline) {
  1573. return (ImagingOutline)ImagingError_MemoryError();
  1574. }
  1575. outline->edges = NULL;
  1576. outline->count = outline->size = 0;
  1577. ImagingOutlineMove(outline, 0, 0);
  1578. return outline;
  1579. }
  1580. void
  1581. ImagingOutlineDelete(ImagingOutline outline) {
  1582. if (!outline) {
  1583. return;
  1584. }
  1585. if (outline->edges) {
  1586. free(outline->edges);
  1587. }
  1588. free(outline);
  1589. }
  1590. static Edge *
  1591. allocate(ImagingOutline outline, int extra) {
  1592. Edge *e;
  1593. if (outline->count + extra > outline->size) {
  1594. /* expand outline buffer */
  1595. outline->size += extra + 25;
  1596. if (!outline->edges) {
  1597. /* malloc check ok, uses calloc for overflow */
  1598. e = calloc(outline->size, sizeof(Edge));
  1599. } else {
  1600. if (outline->size > INT_MAX / (int)sizeof(Edge)) {
  1601. return NULL;
  1602. }
  1603. /* malloc check ok, overflow checked above */
  1604. e = realloc(outline->edges, outline->size * sizeof(Edge));
  1605. }
  1606. if (!e) {
  1607. return NULL;
  1608. }
  1609. outline->edges = e;
  1610. }
  1611. e = outline->edges + outline->count;
  1612. outline->count += extra;
  1613. return e;
  1614. }
  1615. int
  1616. ImagingOutlineMove(ImagingOutline outline, float x0, float y0) {
  1617. outline->x = outline->x0 = x0;
  1618. outline->y = outline->y0 = y0;
  1619. return 0;
  1620. }
  1621. int
  1622. ImagingOutlineLine(ImagingOutline outline, float x1, float y1) {
  1623. Edge *e;
  1624. e = allocate(outline, 1);
  1625. if (!e) {
  1626. return -1; /* out of memory */
  1627. }
  1628. add_edge(e, (int)outline->x, (int)outline->y, (int)x1, (int)y1);
  1629. outline->x = x1;
  1630. outline->y = y1;
  1631. return 0;
  1632. }
  1633. int
  1634. ImagingOutlineCurve(
  1635. ImagingOutline outline,
  1636. float x1,
  1637. float y1,
  1638. float x2,
  1639. float y2,
  1640. float x3,
  1641. float y3) {
  1642. Edge *e;
  1643. int i;
  1644. float xo, yo;
  1645. #define STEPS 32
  1646. e = allocate(outline, STEPS);
  1647. if (!e) {
  1648. return -1; /* out of memory */
  1649. }
  1650. xo = outline->x;
  1651. yo = outline->y;
  1652. /* flatten the bezier segment */
  1653. for (i = 1; i <= STEPS; i++) {
  1654. float t = ((float)i) / STEPS;
  1655. float t2 = t * t;
  1656. float t3 = t2 * t;
  1657. float u = 1.0F - t;
  1658. float u2 = u * u;
  1659. float u3 = u2 * u;
  1660. float x = outline->x * u3 + 3 * (x1 * t * u2 + x2 * t2 * u) + x3 * t3 + 0.5;
  1661. float y = outline->y * u3 + 3 * (y1 * t * u2 + y2 * t2 * u) + y3 * t3 + 0.5;
  1662. add_edge(e++, xo, yo, (int)x, (int)y);
  1663. xo = x, yo = y;
  1664. }
  1665. outline->x = xo;
  1666. outline->y = yo;
  1667. return 0;
  1668. }
  1669. int
  1670. ImagingOutlineClose(ImagingOutline outline) {
  1671. if (outline->x == outline->x0 && outline->y == outline->y0) {
  1672. return 0;
  1673. }
  1674. return ImagingOutlineLine(outline, outline->x0, outline->y0);
  1675. }
  1676. int
  1677. ImagingOutlineTransform(ImagingOutline outline, double a[6]) {
  1678. Edge *eIn;
  1679. Edge *eOut;
  1680. int i, n;
  1681. int x0, y0, x1, y1;
  1682. int X0, Y0, X1, Y1;
  1683. double a0 = a[0];
  1684. double a1 = a[1];
  1685. double a2 = a[2];
  1686. double a3 = a[3];
  1687. double a4 = a[4];
  1688. double a5 = a[5];
  1689. eIn = outline->edges;
  1690. n = outline->count;
  1691. eOut = allocate(outline, n);
  1692. if (!eOut) {
  1693. ImagingError_MemoryError();
  1694. return -1;
  1695. }
  1696. for (i = 0; i < n; i++) {
  1697. x0 = eIn->x0;
  1698. y0 = eIn->y0;
  1699. /* FIXME: ouch! */
  1700. if (eIn->x0 == eIn->xmin) {
  1701. x1 = eIn->xmax;
  1702. } else {
  1703. x1 = eIn->xmin;
  1704. }
  1705. if (eIn->y0 == eIn->ymin) {
  1706. y1 = eIn->ymax;
  1707. } else {
  1708. y1 = eIn->ymin;
  1709. }
  1710. /* full moon tonight! if this doesn't work, you may need to
  1711. upgrade your compiler (make sure you have the right service
  1712. pack) */
  1713. X0 = (int)(a0 * x0 + a1 * y0 + a2);
  1714. Y0 = (int)(a3 * x0 + a4 * y0 + a5);
  1715. X1 = (int)(a0 * x1 + a1 * y1 + a2);
  1716. Y1 = (int)(a3 * x1 + a4 * y1 + a5);
  1717. add_edge(eOut, X0, Y0, X1, Y1);
  1718. eIn++;
  1719. eOut++;
  1720. }
  1721. free(outline->edges);
  1722. /* FIXME: ugly! */
  1723. outline->edges = NULL;
  1724. outline->count = outline->size = 0;
  1725. return 0;
  1726. }
  1727. int
  1728. ImagingDrawOutline(
  1729. Imaging im, ImagingOutline outline, const void *ink_, int fill, int op) {
  1730. DRAW *draw;
  1731. INT32 ink;
  1732. DRAWINIT();
  1733. draw->polygon(im, outline->count, outline->edges, ink, 0);
  1734. return 0;
  1735. }