1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry - Version 2.2 3 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) 4 // 5 // Permission to copy, use, modify, sell and distribute this software 6 // is granted provided this copyright notice appears in all copies. 7 // This software is provided "as is" without express or implied 8 // warranty, and with no claim as to its suitability for any purpose. 9 // 10 //---------------------------------------------------------------------------- 11 // Contact: mcseem@antigrain.com 12 // mcseemagg@yahoo.com 13 // http://www.antigrain.com 14 //---------------------------------------------------------------------------- 15 #ifndef AGG_RENDERER_OUTLINE_AA_INCLUDED 16 #define AGG_RENDERER_OUTLINE_AA_INCLUDED 17 18 #include "agg_basics.h" 19 #include "agg_math.h" 20 #include "agg_line_aa_basics.h" 21 #include "agg_dda_line.h" 22 #include "agg_ellipse_bresenham.h" 23 #include "agg_renderer_base.h" 24 #include "agg_gamma_functions.h" 25 26 namespace agg 27 { 28 29 //===================================================distance_interpolator0 30 class distance_interpolator0 31 { 32 public: 33 //--------------------------------------------------------------------- 34 distance_interpolator0() {} 35 distance_interpolator0(int x1, int y1, int x2, int y2, int x, int y) : 36 m_dx(line_mr(x2) - line_mr(x1)), 37 m_dy(line_mr(y2) - line_mr(y1)), 38 m_dist((line_mr(x + line_subpixel_size/2) - line_mr(x2)) * m_dy - 39 (line_mr(y + line_subpixel_size/2) - line_mr(y2)) * m_dx) 40 { 41 m_dx <<= line_mr_subpixel_shift; 42 m_dy <<= line_mr_subpixel_shift; 43 } 44 45 //--------------------------------------------------------------------- 46 void inc_x() { m_dist += m_dy; } 47 void dec_x() { m_dist -= m_dy; } 48 void inc_y() { m_dist -= m_dx; } 49 void dec_y() { m_dist += m_dx; } 50 51 //--------------------------------------------------------------------- 52 void inc_x(int dy) 53 { 54 m_dist += m_dy; 55 if(dy > 0) m_dist -= m_dx; 56 if(dy < 0) m_dist += m_dx; 57 } 58 59 //--------------------------------------------------------------------- 60 void dec_x(int dy) 61 { 62 m_dist -= m_dy; 63 if(dy > 0) m_dist -= m_dx; 64 if(dy < 0) m_dist += m_dx; 65 } 66 67 //--------------------------------------------------------------------- 68 void inc_y(int dx) 69 { 70 m_dist -= m_dx; 71 if(dx > 0) m_dist += m_dy; 72 if(dx < 0) m_dist -= m_dy; 73 } 74 75 void dec_y(int dx) 76 //--------------------------------------------------------------------- 77 { 78 m_dist += m_dx; 79 if(dx > 0) m_dist += m_dy; 80 if(dx < 0) m_dist -= m_dy; 81 } 82 83 //--------------------------------------------------------------------- 84 int dist() const { return m_dist; } 85 int dx() const { return m_dx; } 86 int dy() const { return m_dy; } 87 88 private: 89 //--------------------------------------------------------------------- 90 int m_dx; 91 int m_dy; 92 int m_dist; 93 }; 94 95 96 97 //===================================================distance_interpolator1 98 class distance_interpolator1 99 { 100 public: 101 //--------------------------------------------------------------------- 102 distance_interpolator1() {} 103 distance_interpolator1(int x1, int y1, int x2, int y2, int x, int y) : 104 m_dx(x2 - x1), 105 m_dy(y2 - y1), 106 m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) - 107 double(y + line_subpixel_size/2 - y2) * double(m_dx))) 108 { 109 m_dx <<= line_subpixel_shift; 110 m_dy <<= line_subpixel_shift; 111 } 112 113 //--------------------------------------------------------------------- 114 void inc_x() { m_dist += m_dy; } 115 void dec_x() { m_dist -= m_dy; } 116 void inc_y() { m_dist -= m_dx; } 117 void dec_y() { m_dist += m_dx; } 118 119 //--------------------------------------------------------------------- 120 void inc_x(int dy) 121 { 122 m_dist += m_dy; 123 if(dy > 0) m_dist -= m_dx; 124 if(dy < 0) m_dist += m_dx; 125 } 126 127 //--------------------------------------------------------------------- 128 void dec_x(int dy) 129 { 130 m_dist -= m_dy; 131 if(dy > 0) m_dist -= m_dx; 132 if(dy < 0) m_dist += m_dx; 133 } 134 135 //--------------------------------------------------------------------- 136 void inc_y(int dx) 137 { 138 m_dist -= m_dx; 139 if(dx > 0) m_dist += m_dy; 140 if(dx < 0) m_dist -= m_dy; 141 } 142 143 void dec_y(int dx) 144 //--------------------------------------------------------------------- 145 { 146 m_dist += m_dx; 147 if(dx > 0) m_dist += m_dy; 148 if(dx < 0) m_dist -= m_dy; 149 } 150 151 //--------------------------------------------------------------------- 152 int dist() const { return m_dist; } 153 int dx() const { return m_dx; } 154 int dy() const { return m_dy; } 155 156 private: 157 //--------------------------------------------------------------------- 158 int m_dx; 159 int m_dy; 160 int m_dist; 161 }; 162 163 164 165 166 167 //===================================================distance_interpolator2 168 class distance_interpolator2 169 { 170 public: 171 //--------------------------------------------------------------------- 172 distance_interpolator2() {} 173 distance_interpolator2(int x1, int y1, int x2, int y2, 174 int sx, int sy, int x, int y) : 175 m_dx(x2 - x1), 176 m_dy(y2 - y1), 177 m_dx_start(line_mr(sx) - line_mr(x1)), 178 m_dy_start(line_mr(sy) - line_mr(y1)), 179 180 m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) - 181 double(y + line_subpixel_size/2 - y2) * double(m_dx))), 182 183 m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(sx)) * m_dy_start - 184 (line_mr(y + line_subpixel_size/2) - line_mr(sy)) * m_dx_start) 185 { 186 m_dx <<= line_subpixel_shift; 187 m_dy <<= line_subpixel_shift; 188 m_dx_start <<= line_mr_subpixel_shift; 189 m_dy_start <<= line_mr_subpixel_shift; 190 } 191 192 distance_interpolator2(int x1, int y1, int x2, int y2, 193 int ex, int ey, int x, int y, int) : 194 m_dx(x2 - x1), 195 m_dy(y2 - y1), 196 m_dx_start(line_mr(ex) - line_mr(x2)), 197 m_dy_start(line_mr(ey) - line_mr(y2)), 198 199 m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) - 200 double(y + line_subpixel_size/2 - y2) * double(m_dx))), 201 202 m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(ex)) * m_dy_start - 203 (line_mr(y + line_subpixel_size/2) - line_mr(ey)) * m_dx_start) 204 { 205 m_dx <<= line_subpixel_shift; 206 m_dy <<= line_subpixel_shift; 207 m_dx_start <<= line_mr_subpixel_shift; 208 m_dy_start <<= line_mr_subpixel_shift; 209 } 210 211 212 //--------------------------------------------------------------------- 213 void inc_x() { m_dist += m_dy; m_dist_start += m_dy_start; } 214 void dec_x() { m_dist -= m_dy; m_dist_start -= m_dy_start; } 215 void inc_y() { m_dist -= m_dx; m_dist_start -= m_dx_start; } 216 void dec_y() { m_dist += m_dx; m_dist_start += m_dx_start; } 217 218 //--------------------------------------------------------------------- 219 void inc_x(int dy) 220 { 221 m_dist += m_dy; 222 m_dist_start += m_dy_start; 223 if(dy > 0) 224 { 225 m_dist -= m_dx; 226 m_dist_start -= m_dx_start; 227 } 228 if(dy < 0) 229 { 230 m_dist += m_dx; 231 m_dist_start += m_dx_start; 232 } 233 } 234 235 //--------------------------------------------------------------------- 236 void dec_x(int dy) 237 { 238 m_dist -= m_dy; 239 m_dist_start -= m_dy_start; 240 if(dy > 0) 241 { 242 m_dist -= m_dx; 243 m_dist_start -= m_dx_start; 244 } 245 if(dy < 0) 246 { 247 m_dist += m_dx; 248 m_dist_start += m_dx_start; 249 } 250 } 251 252 //--------------------------------------------------------------------- 253 void inc_y(int dx) 254 { 255 m_dist -= m_dx; 256 m_dist_start -= m_dx_start; 257 if(dx > 0) 258 { 259 m_dist += m_dy; 260 m_dist_start += m_dy_start; 261 } 262 if(dx < 0) 263 { 264 m_dist -= m_dy; 265 m_dist_start -= m_dy_start; 266 } 267 } 268 269 //--------------------------------------------------------------------- 270 void dec_y(int dx) 271 { 272 m_dist += m_dx; 273 m_dist_start += m_dx_start; 274 if(dx > 0) 275 { 276 m_dist += m_dy; 277 m_dist_start += m_dy_start; 278 } 279 if(dx < 0) 280 { 281 m_dist -= m_dy; 282 m_dist_start -= m_dy_start; 283 } 284 } 285 286 //--------------------------------------------------------------------- 287 int dist() const { return m_dist; } 288 int dist_start() const { return m_dist_start; } 289 int dist_end() const { return m_dist_start; } 290 291 //--------------------------------------------------------------------- 292 int dx() const { return m_dx; } 293 int dy() const { return m_dy; } 294 int dx_start() const { return m_dx_start; } 295 int dy_start() const { return m_dy_start; } 296 int dx_end() const { return m_dx_start; } 297 int dy_end() const { return m_dy_start; } 298 299 private: 300 //--------------------------------------------------------------------- 301 int m_dx; 302 int m_dy; 303 int m_dx_start; 304 int m_dy_start; 305 306 int m_dist; 307 int m_dist_start; 308 }; 309 310 311 312 313 314 //===================================================distance_interpolator3 315 class distance_interpolator3 316 { 317 public: 318 //--------------------------------------------------------------------- 319 distance_interpolator3() {} 320 distance_interpolator3(int x1, int y1, int x2, int y2, 321 int sx, int sy, int ex, int ey, 322 int x, int y) : 323 m_dx(x2 - x1), 324 m_dy(y2 - y1), 325 m_dx_start(line_mr(sx) - line_mr(x1)), 326 m_dy_start(line_mr(sy) - line_mr(y1)), 327 m_dx_end(line_mr(ex) - line_mr(x2)), 328 m_dy_end(line_mr(ey) - line_mr(y2)), 329 330 m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) - 331 double(y + line_subpixel_size/2 - y2) * double(m_dx))), 332 333 m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(sx)) * m_dy_start - 334 (line_mr(y + line_subpixel_size/2) - line_mr(sy)) * m_dx_start), 335 336 m_dist_end((line_mr(x + line_subpixel_size/2) - line_mr(ex)) * m_dy_end - 337 (line_mr(y + line_subpixel_size/2) - line_mr(ey)) * m_dx_end) 338 { 339 m_dx <<= line_subpixel_shift; 340 m_dy <<= line_subpixel_shift; 341 m_dx_start <<= line_mr_subpixel_shift; 342 m_dy_start <<= line_mr_subpixel_shift; 343 m_dx_end <<= line_mr_subpixel_shift; 344 m_dy_end <<= line_mr_subpixel_shift; 345 } 346 347 //--------------------------------------------------------------------- 348 void inc_x() { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_end += m_dy_end; } 349 void dec_x() { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_end -= m_dy_end; } 350 void inc_y() { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_end -= m_dx_end; } 351 void dec_y() { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_end += m_dx_end; } 352 353 //--------------------------------------------------------------------- 354 void inc_x(int dy) 355 { 356 m_dist += m_dy; 357 m_dist_start += m_dy_start; 358 m_dist_end += m_dy_end; 359 if(dy > 0) 360 { 361 m_dist -= m_dx; 362 m_dist_start -= m_dx_start; 363 m_dist_end -= m_dx_end; 364 } 365 if(dy < 0) 366 { 367 m_dist += m_dx; 368 m_dist_start += m_dx_start; 369 m_dist_end += m_dx_end; 370 } 371 } 372 373 //--------------------------------------------------------------------- 374 void dec_x(int dy) 375 { 376 m_dist -= m_dy; 377 m_dist_start -= m_dy_start; 378 m_dist_end -= m_dy_end; 379 if(dy > 0) 380 { 381 m_dist -= m_dx; 382 m_dist_start -= m_dx_start; 383 m_dist_end -= m_dx_end; 384 } 385 if(dy < 0) 386 { 387 m_dist += m_dx; 388 m_dist_start += m_dx_start; 389 m_dist_end += m_dx_end; 390 } 391 } 392 393 //--------------------------------------------------------------------- 394 void inc_y(int dx) 395 { 396 m_dist -= m_dx; 397 m_dist_start -= m_dx_start; 398 m_dist_end -= m_dx_end; 399 if(dx > 0) 400 { 401 m_dist += m_dy; 402 m_dist_start += m_dy_start; 403 m_dist_end += m_dy_end; 404 } 405 if(dx < 0) 406 { 407 m_dist -= m_dy; 408 m_dist_start -= m_dy_start; 409 m_dist_end -= m_dy_end; 410 } 411 } 412 413 //--------------------------------------------------------------------- 414 void dec_y(int dx) 415 { 416 m_dist += m_dx; 417 m_dist_start += m_dx_start; 418 m_dist_end += m_dx_end; 419 if(dx > 0) 420 { 421 m_dist += m_dy; 422 m_dist_start += m_dy_start; 423 m_dist_end += m_dy_end; 424 } 425 if(dx < 0) 426 { 427 m_dist -= m_dy; 428 m_dist_start -= m_dy_start; 429 m_dist_end -= m_dy_end; 430 } 431 } 432 433 //--------------------------------------------------------------------- 434 int dist() const { return m_dist; } 435 int dist_start() const { return m_dist_start; } 436 int dist_end() const { return m_dist_end; } 437 438 //--------------------------------------------------------------------- 439 int dx() const { return m_dx; } 440 int dy() const { return m_dy; } 441 int dx_start() const { return m_dx_start; } 442 int dy_start() const { return m_dy_start; } 443 int dx_end() const { return m_dx_end; } 444 int dy_end() const { return m_dy_end; } 445 446 private: 447 //--------------------------------------------------------------------- 448 int m_dx; 449 int m_dy; 450 int m_dx_start; 451 int m_dy_start; 452 int m_dx_end; 453 int m_dy_end; 454 455 int m_dist; 456 int m_dist_start; 457 int m_dist_end; 458 }; 459 460 461 462 463 464 //================================================line_interpolator_aa_base 465 template<class Renderer> class line_interpolator_aa_base 466 { 467 public: 468 typedef Renderer renderer_type; 469 typedef typename Renderer::color_type color_type; 470 471 //--------------------------------------------------------------------- 472 enum 473 { 474 max_half_width = 64 475 }; 476 477 //--------------------------------------------------------------------- 478 line_interpolator_aa_base(renderer_type& ren, const line_parameters& lp) : 479 m_lp(&lp), 480 m_li(lp.vertical ? line_dbl_hr(lp.x2 - lp.x1) : 481 line_dbl_hr(lp.y2 - lp.y1), 482 lp.vertical ? abs(lp.y2 - lp.y1) : 483 abs(lp.x2 - lp.x1) + 1), 484 m_ren(ren), 485 m_len((lp.vertical == (lp.inc > 0)) ? -lp.len : lp.len), 486 m_x(lp.x1 >> line_subpixel_shift), 487 m_y(lp.y1 >> line_subpixel_shift), 488 m_old_x(m_x), 489 m_old_y(m_y), 490 m_count((lp.vertical ? abs((lp.y2 >> line_subpixel_shift) - m_y) : 491 abs((lp.x2 >> line_subpixel_shift) - m_x))), 492 m_width(ren.subpixel_width()), 493 m_max_extent(m_width >> (line_subpixel_shift - 2)), 494 m_step(0) 495 { 496 agg::dda2_line_interpolator li(0, lp.vertical ? 497 (lp.dy << agg::line_subpixel_shift) : 498 (lp.dx << agg::line_subpixel_shift), 499 lp.len); 500 501 unsigned i; 502 int stop = m_width + line_subpixel_size * 2; 503 for(i = 0; i < max_half_width; ++i) 504 { 505 m_dist[i] = li.y(); 506 if(m_dist[i] >= stop) break; 507 ++li; 508 } 509 m_dist[i++] = 0x7FFF0000; 510 } 511 512 //--------------------------------------------------------------------- 513 template<class DI> int step_hor_base(DI& di) 514 { 515 ++m_li; 516 m_x += m_lp->inc; 517 m_y = (m_lp->y1 + m_li.y()) >> line_subpixel_shift; 518 519 if(m_lp->inc > 0) di.inc_x(m_y - m_old_y); 520 else di.dec_x(m_y - m_old_y); 521 522 m_old_y = m_y; 523 524 return di.dist() / m_len; 525 } 526 527 //--------------------------------------------------------------------- 528 template<class DI> int step_ver_base(DI& di) 529 { 530 ++m_li; 531 m_y += m_lp->inc; 532 m_x = (m_lp->x1 + m_li.y()) >> line_subpixel_shift; 533 534 if(m_lp->inc > 0) di.inc_y(m_x - m_old_x); 535 else di.dec_y(m_x - m_old_x); 536 537 m_old_x = m_x; 538 539 return di.dist() / m_len; 540 } 541 542 //--------------------------------------------------------------------- 543 bool vertical() const { return m_lp->vertical; } 544 int width() const { return m_width; } 545 int count() const { return m_count; } 546 547 private: 548 line_interpolator_aa_base(const line_interpolator_aa_base<Renderer>&); 549 const line_interpolator_aa_base<Renderer>& 550 operator = (const line_interpolator_aa_base<Renderer>&); 551 552 protected: 553 const line_parameters* m_lp; 554 dda2_line_interpolator m_li; 555 renderer_type& m_ren; 556 int m_len; 557 int m_x; 558 int m_y; 559 int m_old_x; 560 int m_old_y; 561 int m_count; 562 int m_width; 563 int m_max_extent; 564 int m_step; 565 int m_dist[max_half_width + 1]; 566 cover_type m_covers[max_half_width * 2 + 4]; 567 }; 568 569 570 571 572 573 574 575 //====================================================line_interpolator_aa0 576 template<class Renderer> class line_interpolator_aa0 : 577 public line_interpolator_aa_base<Renderer> 578 { 579 public: 580 typedef Renderer renderer_type; 581 typedef typename Renderer::color_type color_type; 582 typedef line_interpolator_aa_base<Renderer> base_type; 583 584 //--------------------------------------------------------------------- 585 line_interpolator_aa0(renderer_type& ren, const line_parameters& lp) : 586 line_interpolator_aa_base<Renderer>(ren, lp), 587 m_di(lp.x1, lp.y1, lp.x2, lp.y2, 588 lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask) 589 { 590 base_type::m_li.adjust_forward(); 591 } 592 593 //--------------------------------------------------------------------- 594 bool step_hor() 595 { 596 int dist; 597 int dy; 598 int s1 = base_type::step_hor_base(m_di); 599 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; 600 cover_type* p1 = p0; 601 602 *p1++ = (cover_type)base_type::m_ren.cover(s1); 603 604 dy = 1; 605 while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) 606 { 607 *p1++ = (cover_type)base_type::m_ren.cover(dist); 608 ++dy; 609 } 610 611 dy = 1; 612 while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) 613 { 614 *--p0 = (cover_type)base_type::m_ren.cover(dist); 615 ++dy; 616 } 617 base_type::m_ren.blend_solid_vspan(base_type::m_x, 618 base_type::m_y - dy + 1, 619 unsigned(p1 - p0), 620 p0); 621 return ++base_type::m_step < base_type::m_count; 622 } 623 624 //--------------------------------------------------------------------- 625 bool step_ver() 626 { 627 int dist; 628 int dx; 629 int s1 = base_type::step_ver_base(m_di); 630 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; 631 cover_type* p1 = p0; 632 633 *p1++ = (cover_type)base_type::m_ren.cover(s1); 634 635 dx = 1; 636 while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) 637 { 638 *p1++ = (cover_type)base_type::m_ren.cover(dist); 639 ++dx; 640 } 641 642 dx = 1; 643 while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) 644 { 645 *--p0 = (cover_type)base_type::m_ren.cover(dist); 646 ++dx; 647 } 648 base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, 649 base_type::m_y, 650 unsigned(p1 - p0), 651 p0); 652 return ++base_type::m_step < base_type::m_count; 653 } 654 655 private: 656 line_interpolator_aa0(const line_interpolator_aa0<Renderer>&); 657 const line_interpolator_aa0<Renderer>& 658 operator = (const line_interpolator_aa0<Renderer>&); 659 660 //--------------------------------------------------------------------- 661 distance_interpolator1 m_di; 662 }; 663 664 665 666 667 668 669 //====================================================line_interpolator_aa1 670 template<class Renderer> class line_interpolator_aa1 : 671 public line_interpolator_aa_base<Renderer> 672 { 673 public: 674 typedef Renderer renderer_type; 675 typedef typename Renderer::color_type color_type; 676 typedef line_interpolator_aa_base<Renderer> base_type; 677 678 //--------------------------------------------------------------------- 679 line_interpolator_aa1(renderer_type& ren, const line_parameters& lp, 680 int sx, int sy) : 681 line_interpolator_aa_base<Renderer>(ren, lp), 682 m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, 683 lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask) 684 { 685 int dist1_start; 686 int dist2_start; 687 688 int npix = 1; 689 690 if(lp.vertical) 691 { 692 do 693 { 694 --base_type::m_li; 695 base_type::m_y -= lp.inc; 696 base_type::m_x = (base_type::m_lp->x1 + base_type::m_li.y()) >> line_subpixel_shift; 697 698 if(lp.inc > 0) m_di.dec_y(base_type::m_x - base_type::m_old_x); 699 else m_di.inc_y(base_type::m_x - base_type::m_old_x); 700 701 base_type::m_old_x = base_type::m_x; 702 703 dist1_start = dist2_start = m_di.dist_start(); 704 705 int dx = 0; 706 if(dist1_start < 0) ++npix; 707 do 708 { 709 dist1_start += m_di.dy_start(); 710 dist2_start -= m_di.dy_start(); 711 if(dist1_start < 0) ++npix; 712 if(dist2_start < 0) ++npix; 713 ++dx; 714 } 715 while(base_type::m_dist[dx] <= base_type::m_width); 716 --base_type::m_step; 717 if(npix == 0) break; 718 npix = 0; 719 } 720 while(base_type::m_step >= -base_type::m_max_extent); 721 } 722 else 723 { 724 do 725 { 726 --base_type::m_li; 727 base_type::m_x -= lp.inc; 728 base_type::m_y = (base_type::m_lp->y1 + base_type::m_li.y()) >> line_subpixel_shift; 729 730 if(lp.inc > 0) m_di.dec_x(base_type::m_y - base_type::m_old_y); 731 else m_di.inc_x(base_type::m_y - base_type::m_old_y); 732 733 base_type::m_old_y = base_type::m_y; 734 735 dist1_start = dist2_start = m_di.dist_start(); 736 737 int dy = 0; 738 if(dist1_start < 0) ++npix; 739 do 740 { 741 dist1_start -= m_di.dx_start(); 742 dist2_start += m_di.dx_start(); 743 if(dist1_start < 0) ++npix; 744 if(dist2_start < 0) ++npix; 745 ++dy; 746 } 747 while(base_type::m_dist[dy] <= base_type::m_width); 748 --base_type::m_step; 749 if(npix == 0) break; 750 npix = 0; 751 } 752 while(base_type::m_step >= -base_type::m_max_extent); 753 } 754 base_type::m_li.adjust_forward(); 755 } 756 757 //--------------------------------------------------------------------- 758 bool step_hor() 759 { 760 int dist_start; 761 int dist; 762 int dy; 763 int s1 = base_type::step_hor_base(m_di); 764 765 dist_start = m_di.dist_start(); 766 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; 767 cover_type* p1 = p0; 768 769 *p1 = 0; 770 if(dist_start <= 0) 771 { 772 *p1 = (cover_type)base_type::m_ren.cover(s1); 773 } 774 ++p1; 775 776 dy = 1; 777 while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) 778 { 779 dist_start -= m_di.dx_start(); 780 *p1 = 0; 781 if(dist_start <= 0) 782 { 783 *p1 = (cover_type)base_type::m_ren.cover(dist); 784 } 785 ++p1; 786 ++dy; 787 } 788 789 dy = 1; 790 dist_start = m_di.dist_start(); 791 while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) 792 { 793 dist_start += m_di.dx_start(); 794 *--p0 = 0; 795 if(dist_start <= 0) 796 { 797 *p0 = (cover_type)base_type::m_ren.cover(dist); 798 } 799 ++dy; 800 } 801 802 base_type::m_ren.blend_solid_vspan(base_type::m_x, 803 base_type::m_y - dy + 1, 804 unsigned(p1 - p0), 805 p0); 806 return ++base_type::m_step < base_type::m_count; 807 } 808 809 //--------------------------------------------------------------------- 810 bool step_ver() 811 { 812 int dist_start; 813 int dist; 814 int dx; 815 int s1 = base_type::step_ver_base(m_di); 816 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; 817 cover_type* p1 = p0; 818 819 dist_start = m_di.dist_start(); 820 821 *p1 = 0; 822 if(dist_start <= 0) 823 { 824 *p1 = (cover_type)base_type::m_ren.cover(s1); 825 } 826 ++p1; 827 828 dx = 1; 829 while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) 830 { 831 dist_start += m_di.dy_start(); 832 *p1 = 0; 833 if(dist_start <= 0) 834 { 835 *p1 = (cover_type)base_type::m_ren.cover(dist); 836 } 837 ++p1; 838 ++dx; 839 } 840 841 dx = 1; 842 dist_start = m_di.dist_start(); 843 while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) 844 { 845 dist_start -= m_di.dy_start(); 846 *--p0 = 0; 847 if(dist_start <= 0) 848 { 849 *p0 = (cover_type)base_type::m_ren.cover(dist); 850 } 851 ++dx; 852 } 853 base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, 854 base_type::m_y, 855 unsigned(p1 - p0), 856 p0); 857 return ++base_type::m_step < base_type::m_count; 858 } 859 860 private: 861 line_interpolator_aa1(const line_interpolator_aa1<Renderer>&); 862 const line_interpolator_aa1<Renderer>& 863 operator = (const line_interpolator_aa1<Renderer>&); 864 865 //--------------------------------------------------------------------- 866 distance_interpolator2 m_di; 867 }; 868 869 870 871 872 873 874 875 876 877 878 879 880 //====================================================line_interpolator_aa2 881 template<class Renderer> class line_interpolator_aa2 : 882 public line_interpolator_aa_base<Renderer> 883 { 884 public: 885 typedef Renderer renderer_type; 886 typedef typename Renderer::color_type color_type; 887 typedef line_interpolator_aa_base<Renderer> base_type; 888 889 //--------------------------------------------------------------------- 890 line_interpolator_aa2(renderer_type& ren, const line_parameters& lp, 891 int ex, int ey) : 892 line_interpolator_aa_base<Renderer>(ren, lp), 893 m_di(lp.x1, lp.y1, lp.x2, lp.y2, ex, ey, 894 lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask, 895 0) 896 { 897 base_type::m_li.adjust_forward(); 898 base_type::m_step -= base_type::m_max_extent; 899 } 900 901 //--------------------------------------------------------------------- 902 bool step_hor() 903 { 904 int dist_end; 905 int dist; 906 int dy; 907 int s1 = base_type::step_hor_base(m_di); 908 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; 909 cover_type* p1 = p0; 910 911 dist_end = m_di.dist_end(); 912 913 int npix = 0; 914 *p1 = 0; 915 if(dist_end > 0) 916 { 917 *p1 = (cover_type)base_type::m_ren.cover(s1); 918 ++npix; 919 } 920 ++p1; 921 922 dy = 1; 923 while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) 924 { 925 dist_end -= m_di.dx_end(); 926 *p1 = 0; 927 if(dist_end > 0) 928 { 929 *p1 = (cover_type)base_type::m_ren.cover(dist); 930 ++npix; 931 } 932 ++p1; 933 ++dy; 934 } 935 936 dy = 1; 937 dist_end = m_di.dist_end(); 938 while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) 939 { 940 dist_end += m_di.dx_end(); 941 *--p0 = 0; 942 if(dist_end > 0) 943 { 944 *p0 = (cover_type)base_type::m_ren.cover(dist); 945 ++npix; 946 } 947 ++dy; 948 } 949 base_type::m_ren.blend_solid_vspan(base_type::m_x, 950 base_type::m_y - dy + 1, 951 unsigned(p1 - p0), 952 p0); 953 return npix && ++base_type::m_step < base_type::m_count; 954 } 955 956 //--------------------------------------------------------------------- 957 bool step_ver() 958 { 959 int dist_end; 960 int dist; 961 int dx; 962 int s1 = base_type::step_ver_base(m_di); 963 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; 964 cover_type* p1 = p0; 965 966 dist_end = m_di.dist_end(); 967 968 int npix = 0; 969 *p1 = 0; 970 if(dist_end > 0) 971 { 972 *p1 = (cover_type)base_type::m_ren.cover(s1); 973 ++npix; 974 } 975 ++p1; 976 977 dx = 1; 978 while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) 979 { 980 dist_end += m_di.dy_end(); 981 *p1 = 0; 982 if(dist_end > 0) 983 { 984 *p1 = (cover_type)base_type::m_ren.cover(dist); 985 ++npix; 986 } 987 ++p1; 988 ++dx; 989 } 990 991 dx = 1; 992 dist_end = m_di.dist_end(); 993 while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) 994 { 995 dist_end -= m_di.dy_end(); 996 *--p0 = 0; 997 if(dist_end > 0) 998 { 999 *p0 = (cover_type)base_type::m_ren.cover(dist); 1000 ++npix; 1001 } 1002 ++dx; 1003 } 1004 base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, 1005 base_type::m_y, 1006 unsigned(p1 - p0), 1007 p0); 1008 return npix && ++base_type::m_step < base_type::m_count; 1009 } 1010 1011 private: 1012 line_interpolator_aa2(const line_interpolator_aa2<Renderer>&); 1013 const line_interpolator_aa2<Renderer>& 1014 operator = (const line_interpolator_aa2<Renderer>&); 1015 1016 //--------------------------------------------------------------------- 1017 distance_interpolator2 m_di; 1018 }; 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 //====================================================line_interpolator_aa3 1030 template<class Renderer> class line_interpolator_aa3 : 1031 public line_interpolator_aa_base<Renderer> 1032 { 1033 public: 1034 typedef Renderer renderer_type; 1035 typedef typename Renderer::color_type color_type; 1036 typedef line_interpolator_aa_base<Renderer> base_type; 1037 1038 //--------------------------------------------------------------------- 1039 line_interpolator_aa3(renderer_type& ren, const line_parameters& lp, 1040 int sx, int sy, int ex, int ey) : 1041 line_interpolator_aa_base<Renderer>(ren, lp), 1042 m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, 1043 lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask) 1044 { 1045 int dist1_start; 1046 int dist2_start; 1047 int npix = 1; 1048 if(lp.vertical) 1049 { 1050 do 1051 { 1052 --base_type::m_li; 1053 base_type::m_y -= lp.inc; 1054 base_type::m_x = (base_type::m_lp->x1 + base_type::m_li.y()) >> line_subpixel_shift; 1055 1056 if(lp.inc > 0) m_di.dec_y(base_type::m_x - base_type::m_old_x); 1057 else m_di.inc_y(base_type::m_x - base_type::m_old_x); 1058 1059 base_type::m_old_x = base_type::m_x; 1060 1061 dist1_start = dist2_start = m_di.dist_start(); 1062 1063 int dx = 0; 1064 if(dist1_start < 0) ++npix; 1065 do 1066 { 1067 dist1_start += m_di.dy_start(); 1068 dist2_start -= m_di.dy_start(); 1069 if(dist1_start < 0) ++npix; 1070 if(dist2_start < 0) ++npix; 1071 ++dx; 1072 } 1073 while(base_type::m_dist[dx] <= base_type::m_width); 1074 if(npix == 0) break; 1075 npix = 0; 1076 } 1077 while(--base_type::m_step >= -base_type::m_max_extent); 1078 } 1079 else 1080 { 1081 do 1082 { 1083 --base_type::m_li; 1084 base_type::m_x -= lp.inc; 1085 base_type::m_y = (base_type::m_lp->y1 + base_type::m_li.y()) >> line_subpixel_shift; 1086 1087 if(lp.inc > 0) m_di.dec_x(base_type::m_y - base_type::m_old_y); 1088 else m_di.inc_x(base_type::m_y - base_type::m_old_y); 1089 1090 base_type::m_old_y = base_type::m_y; 1091 1092 dist1_start = dist2_start = m_di.dist_start(); 1093 1094 int dy = 0; 1095 if(dist1_start < 0) ++npix; 1096 do 1097 { 1098 dist1_start -= m_di.dx_start(); 1099 dist2_start += m_di.dx_start(); 1100 if(dist1_start < 0) ++npix; 1101 if(dist2_start < 0) ++npix; 1102 ++dy; 1103 } 1104 while(base_type::m_dist[dy] <= base_type::m_width); 1105 if(npix == 0) break; 1106 npix = 0; 1107 } 1108 while(--base_type::m_step >= -base_type::m_max_extent); 1109 } 1110 base_type::m_li.adjust_forward(); 1111 base_type::m_step -= base_type::m_max_extent; 1112 } 1113 1114 1115 //--------------------------------------------------------------------- 1116 bool step_hor() 1117 { 1118 int dist_start; 1119 int dist_end; 1120 int dist; 1121 int dy; 1122 int s1 = base_type::step_hor_base(m_di); 1123 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; 1124 cover_type* p1 = p0; 1125 1126 dist_start = m_di.dist_start(); 1127 dist_end = m_di.dist_end(); 1128 1129 int npix = 0; 1130 *p1 = 0; 1131 if(dist_end > 0) 1132 { 1133 if(dist_start <= 0) 1134 { 1135 *p1 = (cover_type)base_type::m_ren.cover(s1); 1136 } 1137 ++npix; 1138 } 1139 ++p1; 1140 1141 dy = 1; 1142 while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) 1143 { 1144 dist_start -= m_di.dx_start(); 1145 dist_end -= m_di.dx_end(); 1146 *p1 = 0; 1147 if(dist_end > 0 && dist_start <= 0) 1148 { 1149 *p1 = (cover_type)base_type::m_ren.cover(dist); 1150 ++npix; 1151 } 1152 ++p1; 1153 ++dy; 1154 } 1155 1156 dy = 1; 1157 dist_start = m_di.dist_start(); 1158 dist_end = m_di.dist_end(); 1159 while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) 1160 { 1161 dist_start += m_di.dx_start(); 1162 dist_end += m_di.dx_end(); 1163 *--p0 = 0; 1164 if(dist_end > 0 && dist_start <= 0) 1165 { 1166 *p0 = (cover_type)base_type::m_ren.cover(dist); 1167 ++npix; 1168 } 1169 ++dy; 1170 } 1171 base_type::m_ren.blend_solid_vspan(base_type::m_x, 1172 base_type::m_y - dy + 1, 1173 unsigned(p1 - p0), 1174 p0); 1175 return npix && ++base_type::m_step < base_type::m_count; 1176 } 1177 1178 //--------------------------------------------------------------------- 1179 bool step_ver() 1180 { 1181 int dist_start; 1182 int dist_end; 1183 int dist; 1184 int dx; 1185 int s1 = base_type::step_ver_base(m_di); 1186 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; 1187 cover_type* p1 = p0; 1188 1189 dist_start = m_di.dist_start(); 1190 dist_end = m_di.dist_end(); 1191 1192 int npix = 0; 1193 *p1 = 0; 1194 if(dist_end > 0) 1195 { 1196 if(dist_start <= 0) 1197 { 1198 *p1 = (cover_type)base_type::m_ren.cover(s1); 1199 } 1200 ++npix; 1201 } 1202 ++p1; 1203 1204 dx = 1; 1205 while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) 1206 { 1207 dist_start += m_di.dy_start(); 1208 dist_end += m_di.dy_end(); 1209 *p1 = 0; 1210 if(dist_end > 0 && dist_start <= 0) 1211 { 1212 *p1 = (cover_type)base_type::m_ren.cover(dist); 1213 ++npix; 1214 } 1215 ++p1; 1216 ++dx; 1217 } 1218 1219 dx = 1; 1220 dist_start = m_di.dist_start(); 1221 dist_end = m_di.dist_end(); 1222 while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) 1223 { 1224 dist_start -= m_di.dy_start(); 1225 dist_end -= m_di.dy_end(); 1226 *--p0 = 0; 1227 if(dist_end > 0 && dist_start <= 0) 1228 { 1229 *p0 = (cover_type)base_type::m_ren.cover(dist); 1230 ++npix; 1231 } 1232 ++dx; 1233 } 1234 base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, 1235 base_type::m_y, 1236 unsigned(p1 - p0), 1237 p0); 1238 return npix && ++base_type::m_step < base_type::m_count; 1239 } 1240 1241 private: 1242 line_interpolator_aa3(const line_interpolator_aa3<Renderer>&); 1243 const line_interpolator_aa3<Renderer>& 1244 operator = (const line_interpolator_aa3<Renderer>&); 1245 1246 //--------------------------------------------------------------------- 1247 distance_interpolator3 m_di; 1248 }; 1249 1250 1251 1252 1253 //==========================================================line_profile_aa 1254 // 1255 // See Implementation agg_line_profile_aa.cpp 1256 // 1257 class line_profile_aa 1258 { 1259 public: 1260 //--------------------------------------------------------------------- 1261 typedef int8u value_type; 1262 enum 1263 { 1264 subpixel_shift = line_subpixel_shift, 1265 subpixel_size = 1 << subpixel_shift, 1266 subpixel_mask = subpixel_size - 1 1267 }; 1268 1269 enum 1270 { 1271 aa_shift = 8, 1272 aa_num = 1 << aa_shift, 1273 aa_mask = aa_num - 1 1274 }; 1275 1276 //--------------------------------------------------------------------- 1277 ~line_profile_aa() { delete [] m_profile; } 1278 1279 //--------------------------------------------------------------------- 1280 line_profile_aa() : 1281 m_size(0), 1282 m_profile(0), 1283 m_subpixel_width(0), 1284 m_min_width(1.0), 1285 m_smoother_width(1.0) 1286 { 1287 int i; 1288 for(i = 0; i < aa_num; i++) m_gamma[i] = (value_type)i; 1289 } 1290 1291 //--------------------------------------------------------------------- 1292 template<class GammaF> 1293 line_profile_aa(double w, const GammaF& gamma_function) : 1294 m_size(0), 1295 m_profile(0), 1296 m_subpixel_width(0), 1297 m_min_width(1.0), 1298 m_smoother_width(1.0) 1299 { 1300 gamma(gamma_function); 1301 width(w); 1302 } 1303 1304 //--------------------------------------------------------------------- 1305 void min_width(double w) { m_min_width = w; } 1306 void smoother_width(double w) { m_smoother_width = w; } 1307 1308 //--------------------------------------------------------------------- 1309 template<class GammaF> void gamma(const GammaF& gamma_function) 1310 { 1311 int i; 1312 for(i = 0; i < aa_num; i++) 1313 { 1314 m_gamma[i] = value_type( 1315 floor( 1316 gamma_function(double(i) / aa_mask) * aa_mask + 0.5)); 1317 } 1318 } 1319 1320 void width(double w); 1321 1322 unsigned profile_size() const { return m_size; } 1323 int subpixel_width() const { return m_subpixel_width; } 1324 1325 //--------------------------------------------------------------------- 1326 double min_width() const { return m_min_width; } 1327 double smoother_width() const { return m_smoother_width; } 1328 1329 //--------------------------------------------------------------------- 1330 value_type value(int dist) const 1331 { 1332 return m_profile[dist + subpixel_size*2]; 1333 } 1334 1335 private: 1336 line_profile_aa(const line_profile_aa&); 1337 const line_profile_aa& operator = (const line_profile_aa&); 1338 1339 value_type* profile(double w); 1340 void set(double center_width, double smoother_width); 1341 1342 //--------------------------------------------------------------------- 1343 unsigned m_size; 1344 value_type* m_profile; 1345 value_type m_gamma[aa_num]; 1346 int m_subpixel_width; 1347 double m_min_width; 1348 double m_smoother_width; 1349 }; 1350 1351 1352 1353 1354 1355 1356 //======================================================renderer_outline_aa 1357 template<class BaseRenderer> class renderer_outline_aa 1358 { 1359 public: 1360 //--------------------------------------------------------------------- 1361 typedef BaseRenderer base_ren_type; 1362 typedef renderer_outline_aa<base_ren_type> self_type; 1363 typedef typename base_ren_type::color_type color_type; 1364 1365 //--------------------------------------------------------------------- 1366 renderer_outline_aa(base_ren_type& ren, const line_profile_aa& prof) : 1367 m_ren(&ren), 1368 m_profile(&prof) 1369 { 1370 } 1371 1372 //--------------------------------------------------------------------- 1373 void color(const color_type& c) { m_color = c; } 1374 const color_type& color() const { return m_color; } 1375 1376 //--------------------------------------------------------------------- 1377 void profile(const line_profile_aa& prof) { m_profile = &prof; } 1378 const line_profile_aa& profile() const { return *m_profile; } 1379 line_profile_aa& profile() { return *m_profile; } 1380 1381 //--------------------------------------------------------------------- 1382 int subpixel_width() const { return m_profile->subpixel_width(); } 1383 1384 //--------------------------------------------------------------------- 1385 int cover(int d) const 1386 { 1387 return m_profile->value(d); 1388 } 1389 1390 //------------------------------------------------------------------------- 1391 void blend_solid_hspan(int x, int y, unsigned len, const cover_type* covers) 1392 { 1393 m_ren->blend_solid_hspan(x, y, len, m_color, covers); 1394 } 1395 1396 //------------------------------------------------------------------------- 1397 void blend_solid_vspan(int x, int y, unsigned len, const cover_type* covers) 1398 { 1399 m_ren->blend_solid_vspan(x, y, len, m_color, covers); 1400 } 1401 1402 //------------------------------------------------------------------------- 1403 static bool accurate_join_only() { return false; } 1404 1405 //------------------------------------------------------------------------- 1406 template<class Cmp> 1407 void semidot_hline(Cmp cmp, 1408 int xc1, int yc1, int xc2, int yc2, 1409 int x1, int y1, int x2) 1410 { 1411 cover_type covers[line_interpolator_aa_base<self_type>::max_half_width * 2 + 4]; 1412 cover_type* p0 = covers; 1413 cover_type* p1 = covers; 1414 int x = x1 << line_subpixel_shift; 1415 int y = y1 << line_subpixel_shift; 1416 int w = subpixel_width(); 1417 distance_interpolator0 di(xc1, yc1, xc2, yc2, x, y); 1418 x += line_subpixel_size/2; 1419 y += line_subpixel_size/2; 1420 1421 int x0 = x1; 1422 int dx = x - xc1; 1423 int dy = y - yc1; 1424 do 1425 { 1426 int d = int(fast_sqrt(dx*dx + dy*dy)); 1427 *p1 = 0; 1428 if(cmp(di.dist()) && d <= w) 1429 { 1430 *p1 = (cover_type)cover(d); 1431 } 1432 ++p1; 1433 dx += line_subpixel_size; 1434 di.inc_x(); 1435 } 1436 while(++x1 <= x2); 1437 m_ren->blend_solid_hspan(x0, y1, 1438 unsigned(p1 - p0), 1439 color(), 1440 p0); 1441 } 1442 1443 //------------------------------------------------------------------------- 1444 template<class Cmp> 1445 void semidot(Cmp cmp, int xc1, int yc1, int xc2, int yc2) 1446 { 1447 int r = ((subpixel_width() + line_subpixel_mask) >> line_subpixel_shift); 1448 if(r < 1) r = 1; 1449 ellipse_bresenham_interpolator ei(r, r); 1450 int dx = 0; 1451 int dy = -r; 1452 int dy0 = dy; 1453 int dx0 = dx; 1454 int x = xc1 >> line_subpixel_shift; 1455 int y = yc1 >> line_subpixel_shift; 1456 1457 do 1458 { 1459 dx += ei.dx(); 1460 dy += ei.dy(); 1461 1462 if(dy != dy0) 1463 { 1464 semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y+dy0, x+dx0); 1465 semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y-dy0, x+dx0); 1466 } 1467 dx0 = dx; 1468 dy0 = dy; 1469 ++ei; 1470 } 1471 while(dy < 0); 1472 semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y+dy0, x+dx0); 1473 } 1474 1475 //------------------------------------------------------------------------- 1476 void line0(const line_parameters& lp) 1477 { 1478 line_interpolator_aa0<self_type> li(*this, lp); 1479 if(li.count()) 1480 { 1481 if(li.vertical()) 1482 { 1483 while(li.step_ver()); 1484 } 1485 else 1486 { 1487 while(li.step_hor()); 1488 } 1489 } 1490 } 1491 1492 //------------------------------------------------------------------------- 1493 void line1(const line_parameters& lp, int sx, int sy) 1494 { 1495 line_interpolator_aa1<self_type> li(*this, lp, sx, sy); 1496 if(li.vertical()) 1497 { 1498 while(li.step_ver()); 1499 } 1500 else 1501 { 1502 while(li.step_hor()); 1503 } 1504 } 1505 1506 //------------------------------------------------------------------------- 1507 void line2(const line_parameters& lp, int ex, int ey) 1508 { 1509 line_interpolator_aa2<self_type> li(*this, lp, ex, ey); 1510 if(li.vertical()) 1511 { 1512 while(li.step_ver()); 1513 } 1514 else 1515 { 1516 while(li.step_hor()); 1517 } 1518 } 1519 1520 //------------------------------------------------------------------------- 1521 void line3(const line_parameters& lp, 1522 int sx, int sy, int ex, int ey) 1523 { 1524 line_interpolator_aa3<self_type> li(*this, lp, sx, sy, ex, ey); 1525 if(li.vertical()) 1526 { 1527 while(li.step_ver()); 1528 } 1529 else 1530 { 1531 while(li.step_hor()); 1532 } 1533 } 1534 1535 private: 1536 base_ren_type* m_ren; 1537 const line_profile_aa* m_profile; 1538 color_type m_color; 1539 }; 1540 1541 1542 1543 } 1544 1545 #endif 1546