mifillarc.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  1. /************************************************************
  2. Copyright 1989, 1998 The Open Group
  3. Permission to use, copy, modify, distribute, and sell this software and its
  4. documentation for any purpose is hereby granted without fee, provided that
  5. the above copyright notice appear in all copies and that both that
  6. copyright notice and this permission notice appear in supporting
  7. documentation.
  8. The above copyright notice and this permission notice shall be included in
  9. all copies or substantial portions of the Software.
  10. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  11. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  12. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  13. OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  14. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  15. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  16. Except as contained in this notice, the name of The Open Group shall not be
  17. used in advertising or otherwise to promote the sale, use or other dealings
  18. in this Software without prior written authorization from The Open Group.
  19. Author: Bob Scheifler, MIT X Consortium
  20. ********************************************************/
  21. #ifdef HAVE_DIX_CONFIG_H
  22. #include <dix-config.h>
  23. #endif
  24. #include <math.h>
  25. #include <X11/X.h>
  26. #include <X11/Xprotostr.h>
  27. #include "regionstr.h"
  28. #include "gcstruct.h"
  29. #include "pixmapstr.h"
  30. #include "mifpoly.h"
  31. #include "mi.h"
  32. #include "mifillarc.h"
  33. #define QUADRANT (90 * 64)
  34. #define HALFCIRCLE (180 * 64)
  35. #define QUADRANT3 (270 * 64)
  36. #ifndef M_PI
  37. #define M_PI 3.14159265358979323846
  38. #endif
  39. #define Dsin(d) sin((double)d*(M_PI/11520.0))
  40. #define Dcos(d) cos((double)d*(M_PI/11520.0))
  41. _X_EXPORT void
  42. miFillArcSetup(arc, info)
  43. xArc *arc;
  44. miFillArcRec *info;
  45. {
  46. info->y = arc->height >> 1;
  47. info->dy = arc->height & 1;
  48. info->yorg = arc->y + info->y;
  49. info->dx = arc->width & 1;
  50. info->xorg = arc->x + (arc->width >> 1) + info->dx;
  51. info->dx = 1 - info->dx;
  52. if (arc->width == arc->height)
  53. {
  54. /* (2x - 2xorg)^2 = d^2 - (2y - 2yorg)^2 */
  55. /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
  56. info->ym = 8;
  57. info->xm = 8;
  58. info->yk = info->y << 3;
  59. if (!info->dx)
  60. {
  61. info->xk = 0;
  62. info->e = -1;
  63. }
  64. else
  65. {
  66. info->y++;
  67. info->yk += 4;
  68. info->xk = -4;
  69. info->e = - (info->y << 3);
  70. }
  71. }
  72. else
  73. {
  74. /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
  75. /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
  76. info->ym = (arc->width * arc->width) << 3;
  77. info->xm = (arc->height * arc->height) << 3;
  78. info->yk = info->y * info->ym;
  79. if (!info->dy)
  80. info->yk -= info->ym >> 1;
  81. if (!info->dx)
  82. {
  83. info->xk = 0;
  84. info->e = - (info->xm >> 3);
  85. }
  86. else
  87. {
  88. info->y++;
  89. info->yk += info->ym;
  90. info->xk = -(info->xm >> 1);
  91. info->e = info->xk - info->yk;
  92. }
  93. }
  94. }
  95. void
  96. miFillArcDSetup(arc, info)
  97. xArc *arc;
  98. miFillArcDRec *info;
  99. {
  100. /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
  101. /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
  102. info->y = arc->height >> 1;
  103. info->dy = arc->height & 1;
  104. info->yorg = arc->y + info->y;
  105. info->dx = arc->width & 1;
  106. info->xorg = arc->x + (arc->width >> 1) + info->dx;
  107. info->dx = 1 - info->dx;
  108. info->ym = ((double)arc->width) * (arc->width * 8);
  109. info->xm = ((double)arc->height) * (arc->height * 8);
  110. info->yk = info->y * info->ym;
  111. if (!info->dy)
  112. info->yk -= info->ym / 2.0;
  113. if (!info->dx)
  114. {
  115. info->xk = 0;
  116. info->e = - (info->xm / 8.0);
  117. }
  118. else
  119. {
  120. info->y++;
  121. info->yk += info->ym;
  122. info->xk = -info->xm / 2.0;
  123. info->e = info->xk - info->yk;
  124. }
  125. }
  126. static void
  127. miGetArcEdge(
  128. register xArc *arc,
  129. register miSliceEdgePtr edge,
  130. int k,
  131. Bool top,
  132. Bool left )
  133. {
  134. int xady, y;
  135. y = arc->height >> 1;
  136. if (!(arc->width & 1))
  137. y++;
  138. if (!top)
  139. {
  140. y = -y;
  141. if (arc->height & 1)
  142. y--;
  143. }
  144. xady = k + y * edge->dx;
  145. if (xady <= 0)
  146. edge->x = - ((-xady) / edge->dy + 1);
  147. else
  148. edge->x = (xady - 1) / edge->dy;
  149. edge->e = xady - edge->x * edge->dy;
  150. if ((top && (edge->dx < 0)) || (!top && (edge->dx > 0)))
  151. edge->e = edge->dy - edge->e + 1;
  152. if (left)
  153. edge->x++;
  154. edge->x += arc->x + (arc->width >> 1);
  155. if (edge->dx > 0)
  156. {
  157. edge->deltax = 1;
  158. edge->stepx = edge->dx / edge->dy;
  159. edge->dx = edge->dx % edge->dy;
  160. }
  161. else
  162. {
  163. edge->deltax = -1;
  164. edge->stepx = - ((-edge->dx) / edge->dy);
  165. edge->dx = (-edge->dx) % edge->dy;
  166. }
  167. if (!top)
  168. {
  169. edge->deltax = -edge->deltax;
  170. edge->stepx = -edge->stepx;
  171. }
  172. }
  173. void
  174. miEllipseAngleToSlope (angle, width, height, dxp, dyp, d_dxp, d_dyp)
  175. int angle;
  176. int width;
  177. int height;
  178. int *dxp;
  179. int *dyp;
  180. double *d_dxp;
  181. double *d_dyp;
  182. {
  183. int dx, dy;
  184. double d_dx, d_dy, scale;
  185. Bool negative_dx, negative_dy;
  186. switch (angle) {
  187. case 0:
  188. *dxp = -1;
  189. *dyp = 0;
  190. if (d_dxp) {
  191. *d_dxp = width / 2.0;
  192. *d_dyp = 0;
  193. }
  194. break;
  195. case QUADRANT:
  196. *dxp = 0;
  197. *dyp = 1;
  198. if (d_dxp) {
  199. *d_dxp = 0;
  200. *d_dyp = - height / 2.0;
  201. }
  202. break;
  203. case HALFCIRCLE:
  204. *dxp = 1;
  205. *dyp = 0;
  206. if (d_dxp) {
  207. *d_dxp = - width / 2.0;
  208. *d_dyp = 0;
  209. }
  210. break;
  211. case QUADRANT3:
  212. *dxp = 0;
  213. *dyp = -1;
  214. if (d_dxp) {
  215. *d_dxp = 0;
  216. *d_dyp = height / 2.0;
  217. }
  218. break;
  219. default:
  220. d_dx = Dcos(angle) * width;
  221. d_dy = Dsin(angle) * height;
  222. if (d_dxp) {
  223. *d_dxp = d_dx / 2.0;
  224. *d_dyp = - d_dy / 2.0;
  225. }
  226. negative_dx = FALSE;
  227. if (d_dx < 0.0)
  228. {
  229. d_dx = -d_dx;
  230. negative_dx = TRUE;
  231. }
  232. negative_dy = FALSE;
  233. if (d_dy < 0.0)
  234. {
  235. d_dy = -d_dy;
  236. negative_dy = TRUE;
  237. }
  238. scale = d_dx;
  239. if (d_dy > d_dx)
  240. scale = d_dy;
  241. dx = floor ((d_dx * 32768) / scale + 0.5);
  242. if (negative_dx)
  243. dx = -dx;
  244. *dxp = dx;
  245. dy = floor ((d_dy * 32768) / scale + 0.5);
  246. if (negative_dy)
  247. dy = -dy;
  248. *dyp = dy;
  249. break;
  250. }
  251. }
  252. static void
  253. miGetPieEdge(
  254. register xArc *arc,
  255. register int angle,
  256. register miSliceEdgePtr edge,
  257. Bool top,
  258. Bool left )
  259. {
  260. int k;
  261. int dx, dy;
  262. miEllipseAngleToSlope (angle, arc->width, arc->height, &dx, &dy, 0, 0);
  263. if (dy == 0)
  264. {
  265. edge->x = left ? -65536 : 65536;
  266. edge->stepx = 0;
  267. edge->e = 0;
  268. edge->dx = -1;
  269. return;
  270. }
  271. if (dx == 0)
  272. {
  273. edge->x = arc->x + (arc->width >> 1);
  274. if (left && (arc->width & 1))
  275. edge->x++;
  276. else if (!left && !(arc->width & 1))
  277. edge->x--;
  278. edge->stepx = 0;
  279. edge->e = 0;
  280. edge->dx = -1;
  281. return;
  282. }
  283. if (dy < 0) {
  284. dx = -dx;
  285. dy = -dy;
  286. }
  287. k = (arc->height & 1) ? dx : 0;
  288. if (arc->width & 1)
  289. k += dy;
  290. edge->dx = dx << 1;
  291. edge->dy = dy << 1;
  292. miGetArcEdge(arc, edge, k, top, left);
  293. }
  294. _X_EXPORT void
  295. miFillArcSliceSetup(arc, slice, pGC)
  296. xArc *arc;
  297. miArcSliceRec *slice;
  298. GCPtr pGC;
  299. {
  300. int angle1, angle2;
  301. angle1 = arc->angle1;
  302. if (arc->angle2 < 0)
  303. {
  304. angle2 = angle1;
  305. angle1 += arc->angle2;
  306. }
  307. else
  308. angle2 = angle1 + arc->angle2;
  309. while (angle1 < 0)
  310. angle1 += FULLCIRCLE;
  311. while (angle1 >= FULLCIRCLE)
  312. angle1 -= FULLCIRCLE;
  313. while (angle2 < 0)
  314. angle2 += FULLCIRCLE;
  315. while (angle2 >= FULLCIRCLE)
  316. angle2 -= FULLCIRCLE;
  317. slice->min_top_y = 0;
  318. slice->max_top_y = arc->height >> 1;
  319. slice->min_bot_y = 1 - (arc->height & 1);
  320. slice->max_bot_y = slice->max_top_y - 1;
  321. slice->flip_top = FALSE;
  322. slice->flip_bot = FALSE;
  323. if (pGC->arcMode == ArcPieSlice)
  324. {
  325. slice->edge1_top = (angle1 < HALFCIRCLE);
  326. slice->edge2_top = (angle2 <= HALFCIRCLE);
  327. if ((angle2 == 0) || (angle1 == HALFCIRCLE))
  328. {
  329. if (angle2 ? slice->edge2_top : slice->edge1_top)
  330. slice->min_top_y = slice->min_bot_y;
  331. else
  332. slice->min_top_y = arc->height;
  333. slice->min_bot_y = 0;
  334. }
  335. else if ((angle1 == 0) || (angle2 == HALFCIRCLE))
  336. {
  337. slice->min_top_y = slice->min_bot_y;
  338. if (angle1 ? slice->edge1_top : slice->edge2_top)
  339. slice->min_bot_y = arc->height;
  340. else
  341. slice->min_bot_y = 0;
  342. }
  343. else if (slice->edge1_top == slice->edge2_top)
  344. {
  345. if (angle2 < angle1)
  346. {
  347. slice->flip_top = slice->edge1_top;
  348. slice->flip_bot = !slice->edge1_top;
  349. }
  350. else if (slice->edge1_top)
  351. {
  352. slice->min_top_y = 1;
  353. slice->min_bot_y = arc->height;
  354. }
  355. else
  356. {
  357. slice->min_bot_y = 0;
  358. slice->min_top_y = arc->height;
  359. }
  360. }
  361. miGetPieEdge(arc, angle1, &slice->edge1,
  362. slice->edge1_top, !slice->edge1_top);
  363. miGetPieEdge(arc, angle2, &slice->edge2,
  364. slice->edge2_top, slice->edge2_top);
  365. }
  366. else
  367. {
  368. double w2, h2, x1, y1, x2, y2, dx, dy, scale;
  369. int signdx, signdy, y, k;
  370. Bool isInt1 = TRUE, isInt2 = TRUE;
  371. w2 = (double)arc->width / 2.0;
  372. h2 = (double)arc->height / 2.0;
  373. if ((angle1 == 0) || (angle1 == HALFCIRCLE))
  374. {
  375. x1 = angle1 ? -w2 : w2;
  376. y1 = 0.0;
  377. }
  378. else if ((angle1 == QUADRANT) || (angle1 == QUADRANT3))
  379. {
  380. x1 = 0.0;
  381. y1 = (angle1 == QUADRANT) ? h2 : -h2;
  382. }
  383. else
  384. {
  385. isInt1 = FALSE;
  386. x1 = Dcos(angle1) * w2;
  387. y1 = Dsin(angle1) * h2;
  388. }
  389. if ((angle2 == 0) || (angle2 == HALFCIRCLE))
  390. {
  391. x2 = angle2 ? -w2 : w2;
  392. y2 = 0.0;
  393. }
  394. else if ((angle2 == QUADRANT) || (angle2 == QUADRANT3))
  395. {
  396. x2 = 0.0;
  397. y2 = (angle2 == QUADRANT) ? h2 : -h2;
  398. }
  399. else
  400. {
  401. isInt2 = FALSE;
  402. x2 = Dcos(angle2) * w2;
  403. y2 = Dsin(angle2) * h2;
  404. }
  405. dx = x2 - x1;
  406. dy = y2 - y1;
  407. if (arc->height & 1)
  408. {
  409. y1 -= 0.5;
  410. y2 -= 0.5;
  411. }
  412. if (arc->width & 1)
  413. {
  414. x1 += 0.5;
  415. x2 += 0.5;
  416. }
  417. if (dy < 0.0)
  418. {
  419. dy = -dy;
  420. signdy = -1;
  421. }
  422. else
  423. signdy = 1;
  424. if (dx < 0.0)
  425. {
  426. dx = -dx;
  427. signdx = -1;
  428. }
  429. else
  430. signdx = 1;
  431. if (isInt1 && isInt2)
  432. {
  433. slice->edge1.dx = dx * 2;
  434. slice->edge1.dy = dy * 2;
  435. }
  436. else
  437. {
  438. scale = (dx > dy) ? dx : dy;
  439. slice->edge1.dx = floor((dx * 32768) / scale + .5);
  440. slice->edge1.dy = floor((dy * 32768) / scale + .5);
  441. }
  442. if (!slice->edge1.dy)
  443. {
  444. if (signdx < 0)
  445. {
  446. y = floor(y1 + 1.0);
  447. if (y >= 0)
  448. {
  449. slice->min_top_y = y;
  450. slice->min_bot_y = arc->height;
  451. }
  452. else
  453. {
  454. slice->max_bot_y = -y - (arc->height & 1);
  455. }
  456. }
  457. else
  458. {
  459. y = floor(y1);
  460. if (y >= 0)
  461. slice->max_top_y = y;
  462. else
  463. {
  464. slice->min_top_y = arc->height;
  465. slice->min_bot_y = -y - (arc->height & 1);
  466. }
  467. }
  468. slice->edge1_top = TRUE;
  469. slice->edge1.x = 65536;
  470. slice->edge1.stepx = 0;
  471. slice->edge1.e = 0;
  472. slice->edge1.dx = -1;
  473. slice->edge2 = slice->edge1;
  474. slice->edge2_top = FALSE;
  475. }
  476. else if (!slice->edge1.dx)
  477. {
  478. if (signdy < 0)
  479. x1 -= 1.0;
  480. slice->edge1.x = ceil(x1);
  481. slice->edge1_top = signdy < 0;
  482. slice->edge1.x += arc->x + (arc->width >> 1);
  483. slice->edge1.stepx = 0;
  484. slice->edge1.e = 0;
  485. slice->edge1.dx = -1;
  486. slice->edge2_top = !slice->edge1_top;
  487. slice->edge2 = slice->edge1;
  488. }
  489. else
  490. {
  491. if (signdx < 0)
  492. slice->edge1.dx = -slice->edge1.dx;
  493. if (signdy < 0)
  494. slice->edge1.dx = -slice->edge1.dx;
  495. k = ceil(((x1 + x2) * slice->edge1.dy - (y1 + y2) * slice->edge1.dx) / 2.0);
  496. slice->edge2.dx = slice->edge1.dx;
  497. slice->edge2.dy = slice->edge1.dy;
  498. slice->edge1_top = signdy < 0;
  499. slice->edge2_top = !slice->edge1_top;
  500. miGetArcEdge(arc, &slice->edge1, k,
  501. slice->edge1_top, !slice->edge1_top);
  502. miGetArcEdge(arc, &slice->edge2, k,
  503. slice->edge2_top, slice->edge2_top);
  504. }
  505. }
  506. }
  507. #define ADDSPANS() \
  508. pts->x = xorg - x; \
  509. pts->y = yorg - y; \
  510. *wids = slw; \
  511. pts++; \
  512. wids++; \
  513. if (miFillArcLower(slw)) \
  514. { \
  515. pts->x = xorg - x; \
  516. pts->y = yorg + y + dy; \
  517. pts++; \
  518. *wids++ = slw; \
  519. }
  520. static void
  521. miFillEllipseI(
  522. DrawablePtr pDraw,
  523. GCPtr pGC,
  524. xArc *arc )
  525. {
  526. int x, y, e;
  527. int yk, xk, ym, xm, dx, dy, xorg, yorg;
  528. int slw;
  529. miFillArcRec info;
  530. DDXPointPtr points;
  531. DDXPointPtr pts;
  532. int *widths;
  533. int *wids;
  534. points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * arc->height);
  535. if (!points)
  536. return;
  537. widths = (int *)ALLOCATE_LOCAL(sizeof(int) * arc->height);
  538. if (!widths)
  539. {
  540. DEALLOCATE_LOCAL(points);
  541. return;
  542. }
  543. miFillArcSetup(arc, &info);
  544. MIFILLARCSETUP();
  545. if (pGC->miTranslate)
  546. {
  547. xorg += pDraw->x;
  548. yorg += pDraw->y;
  549. }
  550. pts = points;
  551. wids = widths;
  552. while (y > 0)
  553. {
  554. MIFILLARCSTEP(slw);
  555. ADDSPANS();
  556. }
  557. (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
  558. DEALLOCATE_LOCAL(widths);
  559. DEALLOCATE_LOCAL(points);
  560. }
  561. static void
  562. miFillEllipseD(
  563. DrawablePtr pDraw,
  564. GCPtr pGC,
  565. xArc *arc )
  566. {
  567. int x, y;
  568. int xorg, yorg, dx, dy, slw;
  569. double e, yk, xk, ym, xm;
  570. miFillArcDRec info;
  571. DDXPointPtr points;
  572. DDXPointPtr pts;
  573. int *widths;
  574. int *wids;
  575. points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * arc->height);
  576. if (!points)
  577. return;
  578. widths = (int *)ALLOCATE_LOCAL(sizeof(int) * arc->height);
  579. if (!widths)
  580. {
  581. DEALLOCATE_LOCAL(points);
  582. return;
  583. }
  584. miFillArcDSetup(arc, &info);
  585. MIFILLARCSETUP();
  586. if (pGC->miTranslate)
  587. {
  588. xorg += pDraw->x;
  589. yorg += pDraw->y;
  590. }
  591. pts = points;
  592. wids = widths;
  593. while (y > 0)
  594. {
  595. MIFILLARCSTEP(slw);
  596. ADDSPANS();
  597. }
  598. (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
  599. DEALLOCATE_LOCAL(widths);
  600. DEALLOCATE_LOCAL(points);
  601. }
  602. #define ADDSPAN(l,r) \
  603. if (r >= l) \
  604. { \
  605. pts->x = l; \
  606. pts->y = ya; \
  607. pts++; \
  608. *wids++ = r - l + 1; \
  609. }
  610. #define ADDSLICESPANS(flip) \
  611. if (!flip) \
  612. { \
  613. ADDSPAN(xl, xr); \
  614. } \
  615. else \
  616. { \
  617. xc = xorg - x; \
  618. ADDSPAN(xc, xr); \
  619. xc += slw - 1; \
  620. ADDSPAN(xl, xc); \
  621. }
  622. static void
  623. miFillArcSliceI(
  624. DrawablePtr pDraw,
  625. GCPtr pGC,
  626. xArc *arc )
  627. {
  628. int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
  629. int x, y, e;
  630. miFillArcRec info;
  631. miArcSliceRec slice;
  632. int ya, xl, xr, xc;
  633. DDXPointPtr points;
  634. DDXPointPtr pts;
  635. int *widths;
  636. int *wids;
  637. miFillArcSetup(arc, &info);
  638. miFillArcSliceSetup(arc, &slice, pGC);
  639. MIFILLARCSETUP();
  640. slw = arc->height;
  641. if (slice.flip_top || slice.flip_bot)
  642. slw += (arc->height >> 1) + 1;
  643. points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * slw);
  644. if (!points)
  645. return;
  646. widths = (int *)ALLOCATE_LOCAL(sizeof(int) * slw);
  647. if (!widths)
  648. {
  649. DEALLOCATE_LOCAL(points);
  650. return;
  651. }
  652. if (pGC->miTranslate)
  653. {
  654. xorg += pDraw->x;
  655. yorg += pDraw->y;
  656. slice.edge1.x += pDraw->x;
  657. slice.edge2.x += pDraw->x;
  658. }
  659. pts = points;
  660. wids = widths;
  661. while (y > 0)
  662. {
  663. MIFILLARCSTEP(slw);
  664. MIARCSLICESTEP(slice.edge1);
  665. MIARCSLICESTEP(slice.edge2);
  666. if (miFillSliceUpper(slice))
  667. {
  668. ya = yorg - y;
  669. MIARCSLICEUPPER(xl, xr, slice, slw);
  670. ADDSLICESPANS(slice.flip_top);
  671. }
  672. if (miFillSliceLower(slice))
  673. {
  674. ya = yorg + y + dy;
  675. MIARCSLICELOWER(xl, xr, slice, slw);
  676. ADDSLICESPANS(slice.flip_bot);
  677. }
  678. }
  679. (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
  680. DEALLOCATE_LOCAL(widths);
  681. DEALLOCATE_LOCAL(points);
  682. }
  683. static void
  684. miFillArcSliceD(
  685. DrawablePtr pDraw,
  686. GCPtr pGC,
  687. xArc *arc )
  688. {
  689. int x, y;
  690. int dx, dy, xorg, yorg, slw;
  691. double e, yk, xk, ym, xm;
  692. miFillArcDRec info;
  693. miArcSliceRec slice;
  694. int ya, xl, xr, xc;
  695. DDXPointPtr points;
  696. DDXPointPtr pts;
  697. int *widths;
  698. int *wids;
  699. miFillArcDSetup(arc, &info);
  700. miFillArcSliceSetup(arc, &slice, pGC);
  701. MIFILLARCSETUP();
  702. slw = arc->height;
  703. if (slice.flip_top || slice.flip_bot)
  704. slw += (arc->height >> 1) + 1;
  705. points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * slw);
  706. if (!points)
  707. return;
  708. widths = (int *)ALLOCATE_LOCAL(sizeof(int) * slw);
  709. if (!widths)
  710. {
  711. DEALLOCATE_LOCAL(points);
  712. return;
  713. }
  714. if (pGC->miTranslate)
  715. {
  716. xorg += pDraw->x;
  717. yorg += pDraw->y;
  718. slice.edge1.x += pDraw->x;
  719. slice.edge2.x += pDraw->x;
  720. }
  721. pts = points;
  722. wids = widths;
  723. while (y > 0)
  724. {
  725. MIFILLARCSTEP(slw);
  726. MIARCSLICESTEP(slice.edge1);
  727. MIARCSLICESTEP(slice.edge2);
  728. if (miFillSliceUpper(slice))
  729. {
  730. ya = yorg - y;
  731. MIARCSLICEUPPER(xl, xr, slice, slw);
  732. ADDSLICESPANS(slice.flip_top);
  733. }
  734. if (miFillSliceLower(slice))
  735. {
  736. ya = yorg + y + dy;
  737. MIARCSLICELOWER(xl, xr, slice, slw);
  738. ADDSLICESPANS(slice.flip_bot);
  739. }
  740. }
  741. (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
  742. DEALLOCATE_LOCAL(widths);
  743. DEALLOCATE_LOCAL(points);
  744. }
  745. /* MIPOLYFILLARC -- The public entry for the PolyFillArc request.
  746. * Since we don't have to worry about overlapping segments, we can just
  747. * fill each arc as it comes.
  748. */
  749. _X_EXPORT void
  750. miPolyFillArc(pDraw, pGC, narcs, parcs)
  751. DrawablePtr pDraw;
  752. GCPtr pGC;
  753. int narcs;
  754. xArc *parcs;
  755. {
  756. int i;
  757. xArc *arc;
  758. for(i = narcs, arc = parcs; --i >= 0; arc++)
  759. {
  760. if (miFillArcEmpty(arc))
  761. continue;;
  762. if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE))
  763. {
  764. if (miCanFillArc(arc))
  765. miFillEllipseI(pDraw, pGC, arc);
  766. else
  767. miFillEllipseD(pDraw, pGC, arc);
  768. }
  769. else
  770. {
  771. if (miCanFillArc(arc))
  772. miFillArcSliceI(pDraw, pGC, arc);
  773. else
  774. miFillArcSliceD(pDraw, pGC, arc);
  775. }
  776. }
  777. }