15 #ifndef AGG_RENDERER_OUTLINE_AA_INCLUDED 16 #define AGG_RENDERER_OUTLINE_AA_INCLUDED 19 #include "agg_array.h" 21 #include "agg_line_aa_basics.h" 22 #include "agg_dda_line.h" 23 #include "agg_ellipse_bresenham.h" 24 #include "agg_renderer_base.h" 25 #include "agg_gamma_functions.h" 26 #include "agg_clip_liang_barsky.h" 38 m_dx(line_mr(x2) - line_mr(x1)),
39 m_dy(line_mr(y2) - line_mr(y1)),
40 m_dist((line_mr(x + line_subpixel_scale/2) - line_mr(x2)) * m_dy -
41 (line_mr(y + line_subpixel_scale/2) - line_mr(y2)) * m_dx)
43 m_dx <<= line_mr_subpixel_shift;
44 m_dy <<= line_mr_subpixel_shift;
48 void inc_x() { m_dist += m_dy; }
49 int dist()
const {
return m_dist; }
65 int x1,
int y1,
int x2,
int y2,
67 m_dx1(line_mr(x1) - line_mr(xc)),
68 m_dy1(line_mr(y1) - line_mr(yc)),
69 m_dx2(line_mr(x2) - line_mr(xc)),
70 m_dy2(line_mr(y2) - line_mr(yc)),
71 m_dist1((line_mr(x + line_subpixel_scale/2) - line_mr(x1)) * m_dy1 -
72 (line_mr(y + line_subpixel_scale/2) - line_mr(y1)) * m_dx1),
73 m_dist2((line_mr(x + line_subpixel_scale/2) - line_mr(x2)) * m_dy2 -
74 (line_mr(y + line_subpixel_scale/2) - line_mr(y2)) * m_dx2)
76 m_dx1 <<= line_mr_subpixel_shift;
77 m_dy1 <<= line_mr_subpixel_shift;
78 m_dx2 <<= line_mr_subpixel_shift;
79 m_dy2 <<= line_mr_subpixel_shift;
83 void inc_x() { m_dist1 += m_dy1; m_dist2 += m_dy2; }
84 int dist1()
const {
return m_dist1; }
85 int dist2()
const {
return m_dist2; }
106 m_dist(iround(
double(x + line_subpixel_scale/2 - x2) *
double(m_dy) -
107 double(y + line_subpixel_scale/2 - y2) *
double(m_dx)))
109 m_dx <<= line_subpixel_shift;
110 m_dy <<= line_subpixel_shift;
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; }
123 if(dy > 0) m_dist -= m_dx;
124 if(dy < 0) m_dist += m_dx;
131 if(dy > 0) m_dist -= m_dx;
132 if(dy < 0) m_dist += m_dx;
139 if(dx > 0) m_dist += m_dy;
140 if(dx < 0) m_dist -= m_dy;
147 if(dx > 0) m_dist += m_dy;
148 if(dx < 0) m_dist -= m_dy;
152 int dist()
const {
return m_dist; }
153 int dx()
const {
return m_dx; }
154 int dy()
const {
return m_dy; }
174 int sx,
int sy,
int x,
int y) :
177 m_dx_start(line_mr(sx) - line_mr(x1)),
178 m_dy_start(line_mr(sy) - line_mr(y1)),
180 m_dist(iround(
double(x + line_subpixel_scale/2 - x2) *
double(m_dy) -
181 double(y + line_subpixel_scale/2 - y2) *
double(m_dx))),
183 m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(sx)) * m_dy_start -
184 (line_mr(y + line_subpixel_scale/2) - line_mr(sy)) * m_dx_start)
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;
193 int ex,
int ey,
int x,
int y,
int) :
196 m_dx_start(line_mr(ex) - line_mr(x2)),
197 m_dy_start(line_mr(ey) - line_mr(y2)),
199 m_dist(iround(
double(x + line_subpixel_scale/2 - x2) *
double(m_dy) -
200 double(y + line_subpixel_scale/2 - y2) *
double(m_dx))),
202 m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(ex)) * m_dy_start -
203 (line_mr(y + line_subpixel_scale/2) - line_mr(ey)) * m_dx_start)
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;
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; }
222 m_dist_start += m_dy_start;
226 m_dist_start -= m_dx_start;
231 m_dist_start += m_dx_start;
239 m_dist_start -= m_dy_start;
243 m_dist_start -= m_dx_start;
248 m_dist_start += m_dx_start;
256 m_dist_start -= m_dx_start;
260 m_dist_start += m_dy_start;
265 m_dist_start -= m_dy_start;
273 m_dist_start += m_dx_start;
277 m_dist_start += m_dy_start;
282 m_dist_start -= m_dy_start;
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; }
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; }
321 int sx,
int sy,
int ex,
int ey,
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)),
330 m_dist(iround(
double(x + line_subpixel_scale/2 - x2) *
double(m_dy) -
331 double(y + line_subpixel_scale/2 - y2) *
double(m_dx))),
333 m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(sx)) * m_dy_start -
334 (line_mr(y + line_subpixel_scale/2) - line_mr(sy)) * m_dx_start),
336 m_dist_end((line_mr(x + line_subpixel_scale/2) - line_mr(ex)) * m_dy_end -
337 (line_mr(y + line_subpixel_scale/2) - line_mr(ey)) * m_dx_end)
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;
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; }
357 m_dist_start += m_dy_start;
358 m_dist_end += m_dy_end;
362 m_dist_start -= m_dx_start;
363 m_dist_end -= m_dx_end;
368 m_dist_start += m_dx_start;
369 m_dist_end += m_dx_end;
377 m_dist_start -= m_dy_start;
378 m_dist_end -= m_dy_end;
382 m_dist_start -= m_dx_start;
383 m_dist_end -= m_dx_end;
388 m_dist_start += m_dx_start;
389 m_dist_end += m_dx_end;
397 m_dist_start -= m_dx_start;
398 m_dist_end -= m_dx_end;
402 m_dist_start += m_dy_start;
403 m_dist_end += m_dy_end;
408 m_dist_start -= m_dy_start;
409 m_dist_end -= m_dy_end;
417 m_dist_start += m_dx_start;
418 m_dist_end += m_dx_end;
422 m_dist_start += m_dy_start;
423 m_dist_end += m_dy_end;
428 m_dist_start -= m_dy_start;
429 m_dist_end -= m_dy_end;
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; }
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; }
468 typedef Renderer renderer_type;
469 typedef typename Renderer::color_type color_type;
472 enum max_half_width_e
480 m_li(lp.vertical ? line_dbl_hr(lp.x2 - lp.x1) :
481 line_dbl_hr(lp.y2 - lp.y1),
482 lp.vertical ? std::abs(lp.y2 - lp.y1) :
483 std::abs(lp.x2 - lp.x1) + 1),
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),
490 m_count((lp.vertical ? std::abs((lp.y2 >> line_subpixel_shift) - m_y) :
491 std::abs((lp.x2 >> line_subpixel_shift) - m_x))),
492 m_width(ren.subpixel_width()),
494 m_max_extent((m_width + line_subpixel_mask) >> line_subpixel_shift),
498 (lp.dy << agg::line_subpixel_shift) :
499 (lp.dx << agg::line_subpixel_shift),
503 int stop = m_width + line_subpixel_scale * 2;
504 for(i = 0; i < max_half_width; ++i)
507 if(m_dist[i] >= stop)
break;
510 m_dist[i++] = 0x7FFF0000;
514 template<
class DI>
int step_hor_base(DI& di)
518 m_y = (m_lp->y1 + m_li.y()) >> line_subpixel_shift;
520 if(m_lp->inc > 0) di.inc_x(m_y - m_old_y);
521 else di.dec_x(m_y - m_old_y);
525 return di.dist() / m_len;
529 template<
class DI>
int step_ver_base(DI& di)
533 m_x = (m_lp->x1 + m_li.y()) >> line_subpixel_shift;
535 if(m_lp->inc > 0) di.inc_y(m_x - m_old_x);
536 else di.dec_y(m_x - m_old_x);
540 return di.dist() / m_len;
544 bool vertical()
const {
return m_lp->vertical; }
545 int width()
const {
return m_width; }
546 int count()
const {
return m_count; }
556 renderer_type& m_ren;
566 int m_dist[max_half_width + 1];
567 cover_type m_covers[max_half_width * 2 + 4];
581 typedef Renderer renderer_type;
582 typedef typename Renderer::color_type color_type;
588 m_di(lp.x1, lp.y1, lp.x2, lp.y2,
589 lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask)
591 base_type::m_li.adjust_forward();
599 int s1 = base_type::step_hor_base(m_di);
600 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
603 *p1++ = (cover_type)base_type::m_ren.cover(s1);
606 while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width)
608 *p1++ = (cover_type)base_type::m_ren.cover(dist);
613 while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width)
615 *--p0 = (cover_type)base_type::m_ren.cover(dist);
618 base_type::m_ren.blend_solid_vspan(base_type::m_x,
619 base_type::m_y - dy + 1,
622 return ++base_type::m_step < base_type::m_count;
630 int s1 = base_type::step_ver_base(m_di);
631 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
634 *p1++ = (cover_type)base_type::m_ren.cover(s1);
637 while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width)
639 *p1++ = (cover_type)base_type::m_ren.cover(dist);
644 while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width)
646 *--p0 = (cover_type)base_type::m_ren.cover(dist);
649 base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1,
653 return ++base_type::m_step < base_type::m_count;
675 typedef Renderer renderer_type;
676 typedef typename Renderer::color_type color_type;
683 m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy,
684 lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask)
696 base_type::m_y -= lp.inc;
697 base_type::m_x = (base_type::m_lp->x1 + base_type::m_li.y()) >> line_subpixel_shift;
699 if(lp.inc > 0) m_di.dec_y(base_type::m_x - base_type::m_old_x);
700 else m_di.inc_y(base_type::m_x - base_type::m_old_x);
702 base_type::m_old_x = base_type::m_x;
704 dist1_start = dist2_start = m_di.dist_start();
707 if(dist1_start < 0) ++npix;
710 dist1_start += m_di.dy_start();
711 dist2_start -= m_di.dy_start();
712 if(dist1_start < 0) ++npix;
713 if(dist2_start < 0) ++npix;
716 while(base_type::m_dist[dx] <= base_type::m_width);
721 while(base_type::m_step >= -base_type::m_max_extent);
728 base_type::m_x -= lp.inc;
729 base_type::m_y = (base_type::m_lp->y1 + base_type::m_li.y()) >> line_subpixel_shift;
731 if(lp.inc > 0) m_di.dec_x(base_type::m_y - base_type::m_old_y);
732 else m_di.inc_x(base_type::m_y - base_type::m_old_y);
734 base_type::m_old_y = base_type::m_y;
736 dist1_start = dist2_start = m_di.dist_start();
739 if(dist1_start < 0) ++npix;
742 dist1_start -= m_di.dx_start();
743 dist2_start += m_di.dx_start();
744 if(dist1_start < 0) ++npix;
745 if(dist2_start < 0) ++npix;
748 while(base_type::m_dist[dy] <= base_type::m_width);
753 while(base_type::m_step >= -base_type::m_max_extent);
755 base_type::m_li.adjust_forward();
764 int s1 = base_type::step_hor_base(m_di);
766 dist_start = m_di.dist_start();
767 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
773 *p1 = (cover_type)base_type::m_ren.cover(s1);
778 while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width)
780 dist_start -= m_di.dx_start();
784 *p1 = (cover_type)base_type::m_ren.cover(dist);
791 dist_start = m_di.dist_start();
792 while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width)
794 dist_start += m_di.dx_start();
798 *p0 = (cover_type)base_type::m_ren.cover(dist);
803 base_type::m_ren.blend_solid_vspan(base_type::m_x,
804 base_type::m_y - dy + 1,
807 return ++base_type::m_step < base_type::m_count;
816 int s1 = base_type::step_ver_base(m_di);
817 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
820 dist_start = m_di.dist_start();
825 *p1 = (cover_type)base_type::m_ren.cover(s1);
830 while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width)
832 dist_start += m_di.dy_start();
836 *p1 = (cover_type)base_type::m_ren.cover(dist);
843 dist_start = m_di.dist_start();
844 while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width)
846 dist_start -= m_di.dy_start();
850 *p0 = (cover_type)base_type::m_ren.cover(dist);
854 base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1,
858 return ++base_type::m_step < base_type::m_count;
886 typedef Renderer renderer_type;
887 typedef typename Renderer::color_type color_type;
894 m_di(lp.x1, lp.y1, lp.x2, lp.y2, ex, ey,
895 lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask,
898 base_type::m_li.adjust_forward();
899 base_type::m_step -= base_type::m_max_extent;
908 int s1 = base_type::step_hor_base(m_di);
909 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
912 dist_end = m_di.dist_end();
918 *p1 = (cover_type)base_type::m_ren.cover(s1);
924 while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width)
926 dist_end -= m_di.dx_end();
930 *p1 = (cover_type)base_type::m_ren.cover(dist);
938 dist_end = m_di.dist_end();
939 while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width)
941 dist_end += m_di.dx_end();
945 *p0 = (cover_type)base_type::m_ren.cover(dist);
950 base_type::m_ren.blend_solid_vspan(base_type::m_x,
951 base_type::m_y - dy + 1,
954 return npix && ++base_type::m_step < base_type::m_count;
963 int s1 = base_type::step_ver_base(m_di);
964 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
967 dist_end = m_di.dist_end();
973 *p1 = (cover_type)base_type::m_ren.cover(s1);
979 while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width)
981 dist_end += m_di.dy_end();
985 *p1 = (cover_type)base_type::m_ren.cover(dist);
993 dist_end = m_di.dist_end();
994 while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width)
996 dist_end -= m_di.dy_end();
1000 *p0 = (cover_type)base_type::m_ren.cover(dist);
1005 base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1,
1009 return npix && ++base_type::m_step < base_type::m_count;
1035 typedef Renderer renderer_type;
1036 typedef typename Renderer::color_type color_type;
1041 int sx,
int sy,
int ex,
int ey) :
1043 m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey,
1044 lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask)
1054 base_type::m_y -= lp.inc;
1055 base_type::m_x = (base_type::m_lp->x1 + base_type::m_li.y()) >> line_subpixel_shift;
1057 if(lp.inc > 0) m_di.dec_y(base_type::m_x - base_type::m_old_x);
1058 else m_di.inc_y(base_type::m_x - base_type::m_old_x);
1060 base_type::m_old_x = base_type::m_x;
1062 dist1_start = dist2_start = m_di.dist_start();
1065 if(dist1_start < 0) ++npix;
1068 dist1_start += m_di.dy_start();
1069 dist2_start -= m_di.dy_start();
1070 if(dist1_start < 0) ++npix;
1071 if(dist2_start < 0) ++npix;
1074 while(base_type::m_dist[dx] <= base_type::m_width);
1075 if(npix == 0)
break;
1078 while(--base_type::m_step >= -base_type::m_max_extent);
1085 base_type::m_x -= lp.inc;
1086 base_type::m_y = (base_type::m_lp->y1 + base_type::m_li.y()) >> line_subpixel_shift;
1088 if(lp.inc > 0) m_di.dec_x(base_type::m_y - base_type::m_old_y);
1089 else m_di.inc_x(base_type::m_y - base_type::m_old_y);
1091 base_type::m_old_y = base_type::m_y;
1093 dist1_start = dist2_start = m_di.dist_start();
1096 if(dist1_start < 0) ++npix;
1099 dist1_start -= m_di.dx_start();
1100 dist2_start += m_di.dx_start();
1101 if(dist1_start < 0) ++npix;
1102 if(dist2_start < 0) ++npix;
1105 while(base_type::m_dist[dy] <= base_type::m_width);
1106 if(npix == 0)
break;
1109 while(--base_type::m_step >= -base_type::m_max_extent);
1111 base_type::m_li.adjust_forward();
1112 base_type::m_step -= base_type::m_max_extent;
1123 int s1 = base_type::step_hor_base(m_di);
1124 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
1125 cover_type* p1 = p0;
1127 dist_start = m_di.dist_start();
1128 dist_end = m_di.dist_end();
1136 *p1 = (cover_type)base_type::m_ren.cover(s1);
1143 while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width)
1145 dist_start -= m_di.dx_start();
1146 dist_end -= m_di.dx_end();
1148 if(dist_end > 0 && dist_start <= 0)
1150 *p1 = (cover_type)base_type::m_ren.cover(dist);
1158 dist_start = m_di.dist_start();
1159 dist_end = m_di.dist_end();
1160 while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width)
1162 dist_start += m_di.dx_start();
1163 dist_end += m_di.dx_end();
1165 if(dist_end > 0 && dist_start <= 0)
1167 *p0 = (cover_type)base_type::m_ren.cover(dist);
1172 base_type::m_ren.blend_solid_vspan(base_type::m_x,
1173 base_type::m_y - dy + 1,
1176 return npix && ++base_type::m_step < base_type::m_count;
1186 int s1 = base_type::step_ver_base(m_di);
1187 cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
1188 cover_type* p1 = p0;
1190 dist_start = m_di.dist_start();
1191 dist_end = m_di.dist_end();
1199 *p1 = (cover_type)base_type::m_ren.cover(s1);
1206 while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width)
1208 dist_start += m_di.dy_start();
1209 dist_end += m_di.dy_end();
1211 if(dist_end > 0 && dist_start <= 0)
1213 *p1 = (cover_type)base_type::m_ren.cover(dist);
1221 dist_start = m_di.dist_start();
1222 dist_end = m_di.dist_end();
1223 while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width)
1225 dist_start -= m_di.dy_start();
1226 dist_end -= m_di.dy_end();
1228 if(dist_end > 0 && dist_start <= 0)
1230 *p0 = (cover_type)base_type::m_ren.cover(dist);
1235 base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1,
1239 return npix && ++base_type::m_step < base_type::m_count;
1262 typedef int8u value_type;
1263 enum subpixel_scale_e
1265 subpixel_shift = line_subpixel_shift,
1266 subpixel_scale = 1 << subpixel_shift,
1267 subpixel_mask = subpixel_scale - 1
1273 aa_scale = 1 << aa_shift,
1274 aa_mask = aa_scale - 1
1279 m_subpixel_width(0),
1281 m_smoother_width(1.0)
1284 for(i = 0; i < aa_scale; i++) m_gamma[i] = (value_type)i;
1288 template<
class GammaF>
1290 m_subpixel_width(0),
1292 m_smoother_width(1.0)
1294 gamma(gamma_function);
1299 void min_width(
double w) { m_min_width = w; }
1300 void smoother_width(
double w) { m_smoother_width = w; }
1303 template<
class GammaF>
void gamma(
const GammaF& gamma_function)
1306 for(i = 0; i < aa_scale; i++)
1308 m_gamma[i] = value_type(
1309 uround(gamma_function(
double(i) / aa_mask) * aa_mask));
1313 void width(
double w);
1315 unsigned profile_size()
const {
return m_profile.size(); }
1316 int subpixel_width()
const {
return m_subpixel_width; }
1319 double min_width()
const {
return m_min_width; }
1320 double smoother_width()
const {
return m_smoother_width; }
1323 value_type value(
int dist)
const 1325 return m_profile[dist + subpixel_scale*2];
1332 value_type* profile(
double w);
1333 void set(
double center_width,
double smoother_width);
1337 value_type m_gamma[aa_scale];
1338 int m_subpixel_width;
1340 double m_smoother_width;
1349 typedef BaseRenderer base_ren_type;
1351 typedef typename base_ren_type::color_type color_type;
1357 m_clip_box(0,0,0,0),
1360 void attach(base_ren_type& ren) { m_ren = &ren; }
1363 void color(
const color_type& c) { m_color = c; }
1364 const color_type& color()
const {
return m_color; }
1372 int subpixel_width()
const {
return m_profile->subpixel_width(); }
1375 void reset_clipping() { m_clipping =
false; }
1376 void clip_box(
double x1,
double y1,
double x2,
double y2)
1378 m_clip_box.x1 = line_coord_sat::conv(x1);
1379 m_clip_box.y1 = line_coord_sat::conv(y1);
1380 m_clip_box.x2 = line_coord_sat::conv(x2);
1381 m_clip_box.y2 = line_coord_sat::conv(y2);
1386 int cover(
int d)
const 1388 return m_profile->value(d);
1392 void blend_solid_hspan(
int x,
int y,
unsigned len,
const cover_type* covers)
1394 m_ren->blend_solid_hspan(x, y, len, m_color, covers);
1398 void blend_solid_vspan(
int x,
int y,
unsigned len,
const cover_type* covers)
1400 m_ren->blend_solid_vspan(x, y, len, m_color, covers);
1404 static bool accurate_join_only() {
return false; }
1408 void semidot_hline(Cmp cmp,
1409 int xc1,
int yc1,
int xc2,
int yc2,
1410 int x1,
int y1,
int x2)
1413 cover_type* p0 = covers;
1414 cover_type* p1 = covers;
1415 int x = x1 << line_subpixel_shift;
1416 int y = y1 << line_subpixel_shift;
1417 int w = subpixel_width();
1419 x += line_subpixel_scale/2;
1420 y += line_subpixel_scale/2;
1427 int d = int(fast_sqrt(dx*dx + dy*dy));
1429 if(cmp(di.dist()) && d <= w)
1431 *p1 = (cover_type)cover(d);
1434 dx += line_subpixel_scale;
1438 m_ren->blend_solid_hspan(x0, y1,
1446 void semidot(Cmp cmp,
int xc1,
int yc1,
int xc2,
int yc2)
1448 if(m_clipping && clipping_flags(xc1, yc1, m_clip_box))
return;
1450 int r = ((subpixel_width() + line_subpixel_mask) >> line_subpixel_shift);
1457 int x = xc1 >> line_subpixel_shift;
1458 int y = yc1 >> line_subpixel_shift;
1467 semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y+dy0, x+dx0);
1468 semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y-dy0, x+dx0);
1475 semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y+dy0, x+dx0);
1479 void pie_hline(
int xc,
int yc,
int xp1,
int yp1,
int xp2,
int yp2,
1480 int xh1,
int yh1,
int xh2)
1482 if(m_clipping && clipping_flags(xc, yc, m_clip_box))
return;
1485 cover_type* p0 = covers;
1486 cover_type* p1 = covers;
1487 int x = xh1 << line_subpixel_shift;
1488 int y = yh1 << line_subpixel_shift;
1489 int w = subpixel_width();
1492 x += line_subpixel_scale/2;
1493 y += line_subpixel_scale/2;
1500 int d = int(fast_sqrt(dx*dx + dy*dy));
1502 if(di.dist1() <= 0 && di.dist2() > 0 && d <= w)
1504 *p1 = (cover_type)cover(d);
1507 dx += line_subpixel_scale;
1510 while(++xh1 <= xh2);
1511 m_ren->blend_solid_hspan(xh0, yh1,
1519 void pie(
int xc,
int yc,
int x1,
int y1,
int x2,
int y2)
1521 int r = ((subpixel_width() + line_subpixel_mask) >> line_subpixel_shift);
1528 int x = xc >> line_subpixel_shift;
1529 int y = yc >> line_subpixel_shift;
1538 pie_hline(xc, yc, x1, y1, x2, y2, x-dx0, y+dy0, x+dx0);
1539 pie_hline(xc, yc, x1, y1, x2, y2, x-dx0, y-dy0, x+dx0);
1546 pie_hline(xc, yc, x1, y1, x2, y2, x-dx0, y+dy0, x+dx0);
1552 if(lp.len > line_max_length)
1555 lp.divide(lp1, lp2);
1566 while(li.step_ver());
1570 while(li.step_hor());
1584 unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
1585 if((flags & 4) == 0)
1590 uround(calc_distance(x1, y1, x2, y2)));
1608 if(lp.len > line_max_length)
1611 lp.divide(lp1, lp2);
1612 line1_no_clip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1);
1613 line1_no_clip(lp2, lp1.x2 + (lp1.y2 - lp1.y1), lp1.y2 - (lp1.x2 - lp1.x1));
1617 fix_degenerate_bisectrix_start(lp, &sx, &sy);
1621 while(li.step_ver());
1625 while(li.step_hor());
1639 unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
1640 if((flags & 4) == 0)
1645 uround(calc_distance(x1, y1, x2, y2)));
1648 sx = x1 + (y2 - y1);
1649 sy = y1 - (x2 - x1);
1653 while(std::abs(sx - lp.x1) + std::abs(sy - lp.y1) > lp2.len)
1655 sx = (lp.x1 + sx) >> 1;
1656 sy = (lp.y1 + sy) >> 1;
1659 line1_no_clip(lp2, sx, sy);
1663 line1_no_clip(lp, sx, sy);
1669 line1_no_clip(lp, sx, sy);
1676 if(lp.len > line_max_length)
1679 lp.divide(lp1, lp2);
1680 line2_no_clip(lp1, lp1.x2 + (lp1.y2 - lp1.y1), lp1.y2 - (lp1.x2 - lp1.x1));
1681 line2_no_clip(lp2, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1);
1685 fix_degenerate_bisectrix_end(lp, &ex, &ey);
1689 while(li.step_ver());
1693 while(li.step_hor());
1706 unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
1707 if((flags & 4) == 0)
1712 uround(calc_distance(x1, y1, x2, y2)));
1715 ex = x2 + (y2 - y1);
1716 ey = y2 - (x2 - x1);
1720 while(std::abs(ex - lp.x2) + std::abs(ey - lp.y2) > lp2.len)
1722 ex = (lp.x2 + ex) >> 1;
1723 ey = (lp.y2 + ey) >> 1;
1726 line2_no_clip(lp2, ex, ey);
1730 line2_no_clip(lp, ex, ey);
1736 line2_no_clip(lp, ex, ey);
1742 int sx,
int sy,
int ex,
int ey)
1744 if(lp.len > line_max_length)
1747 lp.divide(lp1, lp2);
1748 int mx = lp1.x2 + (lp1.y2 - lp1.y1);
1749 int my = lp1.y2 - (lp1.x2 - lp1.x1);
1750 line3_no_clip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1, mx, my);
1751 line3_no_clip(lp2, mx, my, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1);
1755 fix_degenerate_bisectrix_start(lp, &sx, &sy);
1756 fix_degenerate_bisectrix_end(lp, &ex, &ey);
1760 while(li.step_ver());
1764 while(li.step_hor());
1770 int sx,
int sy,
int ex,
int ey)
1778 unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
1779 if((flags & 4) == 0)
1784 uround(calc_distance(x1, y1, x2, y2)));
1787 sx = x1 + (y2 - y1);
1788 sy = y1 - (x2 - x1);
1792 while(std::abs(sx - lp.x1) + std::abs(sy - lp.y1) > lp2.len)
1794 sx = (lp.x1 + sx) >> 1;
1795 sy = (lp.y1 + sy) >> 1;
1800 ex = x2 + (y2 - y1);
1801 ey = y2 - (x2 - x1);
1805 while(std::abs(ex - lp.x2) + std::abs(ey - lp.y2) > lp2.len)
1807 ex = (lp.x2 + ex) >> 1;
1808 ey = (lp.y2 + ey) >> 1;
1811 line3_no_clip(lp2, sx, sy, ex, ey);
1815 line3_no_clip(lp, sx, sy, ex, ey);
1821 line3_no_clip(lp, sx, sy, ex, ey);
1827 base_ren_type* m_ren;