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