//---------------------------------------------------------------------------- // Anti-Grain Geometry (AGG) - Version 2.5 // A high quality rendering engine for C++ // Copyright (C) 2002-2006 Maxim Shemanarev // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://antigrain.com // // AGG is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // AGG is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with AGG; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, // MA 02110-1301, USA. //---------------------------------------------------------------------------- #ifndef AGG_RENDERER_OUTLINE_AA_INCLUDED #define AGG_RENDERER_OUTLINE_AA_INCLUDED #include "agg_array.h" #include "agg_math.h" #include "agg_line_aa_basics.h" #include "agg_dda_line.h" #include "agg_ellipse_bresenham.h" #include "agg_renderer_base.h" #include "agg_gamma_functions.h" #include "agg_clip_liang_barsky.h" namespace agg { //===================================================distance_interpolator0 class distance_interpolator0 { public: //--------------------------------------------------------------------- distance_interpolator0() {} distance_interpolator0(int x1, int y1, int x2, int y2, int x, int y) : m_dx(line_mr(x2) - line_mr(x1)), m_dy(line_mr(y2) - line_mr(y1)), m_dist((line_mr(x + line_subpixel_scale/2) - line_mr(x2)) * m_dy - (line_mr(y + line_subpixel_scale/2) - line_mr(y2)) * m_dx) { m_dx <<= line_mr_subpixel_shift; m_dy <<= line_mr_subpixel_shift; } //--------------------------------------------------------------------- void inc_x() { m_dist += m_dy; } int dist() const { return m_dist; } private: //--------------------------------------------------------------------- int m_dx; int m_dy; int m_dist; }; //==================================================distance_interpolator00 class distance_interpolator00 { public: //--------------------------------------------------------------------- distance_interpolator00() {} distance_interpolator00(int xc, int yc, int x1, int y1, int x2, int y2, int x, int y) : m_dx1(line_mr(x1) - line_mr(xc)), m_dy1(line_mr(y1) - line_mr(yc)), m_dx2(line_mr(x2) - line_mr(xc)), m_dy2(line_mr(y2) - line_mr(yc)), m_dist1((line_mr(x + line_subpixel_scale/2) - line_mr(x1)) * m_dy1 - (line_mr(y + line_subpixel_scale/2) - line_mr(y1)) * m_dx1), m_dist2((line_mr(x + line_subpixel_scale/2) - line_mr(x2)) * m_dy2 - (line_mr(y + line_subpixel_scale/2) - line_mr(y2)) * m_dx2) { m_dx1 <<= line_mr_subpixel_shift; m_dy1 <<= line_mr_subpixel_shift; m_dx2 <<= line_mr_subpixel_shift; m_dy2 <<= line_mr_subpixel_shift; } //--------------------------------------------------------------------- void inc_x() { m_dist1 += m_dy1; m_dist2 += m_dy2; } int dist1() const { return m_dist1; } int dist2() const { return m_dist2; } private: //--------------------------------------------------------------------- int m_dx1; int m_dy1; int m_dx2; int m_dy2; int m_dist1; int m_dist2; }; //===================================================distance_interpolator1 class distance_interpolator1 { public: //--------------------------------------------------------------------- distance_interpolator1() {} distance_interpolator1(int x1, int y1, int x2, int y2, int x, int y) : m_dx(x2 - x1), m_dy(y2 - y1), m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) - double(y + line_subpixel_scale/2 - y2) * double(m_dx))) { m_dx <<= line_subpixel_shift; m_dy <<= line_subpixel_shift; } //--------------------------------------------------------------------- void inc_x() { m_dist += m_dy; } void dec_x() { m_dist -= m_dy; } void inc_y() { m_dist -= m_dx; } void dec_y() { m_dist += m_dx; } //--------------------------------------------------------------------- void inc_x(int dy) { m_dist += m_dy; if(dy > 0) m_dist -= m_dx; if(dy < 0) m_dist += m_dx; } //--------------------------------------------------------------------- void dec_x(int dy) { m_dist -= m_dy; if(dy > 0) m_dist -= m_dx; if(dy < 0) m_dist += m_dx; } //--------------------------------------------------------------------- void inc_y(int dx) { m_dist -= m_dx; if(dx > 0) m_dist += m_dy; if(dx < 0) m_dist -= m_dy; } void dec_y(int dx) //--------------------------------------------------------------------- { m_dist += m_dx; if(dx > 0) m_dist += m_dy; if(dx < 0) m_dist -= m_dy; } //--------------------------------------------------------------------- int dist() const { return m_dist; } int dx() const { return m_dx; } int dy() const { return m_dy; } private: //--------------------------------------------------------------------- int m_dx; int m_dy; int m_dist; }; //===================================================distance_interpolator2 class distance_interpolator2 { public: //--------------------------------------------------------------------- distance_interpolator2() {} distance_interpolator2(int x1, int y1, int x2, int y2, int sx, int sy, int x, int y) : m_dx(x2 - x1), m_dy(y2 - y1), m_dx_start(line_mr(sx) - line_mr(x1)), m_dy_start(line_mr(sy) - line_mr(y1)), m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) - double(y + line_subpixel_scale/2 - y2) * double(m_dx))), m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(sx)) * m_dy_start - (line_mr(y + line_subpixel_scale/2) - line_mr(sy)) * m_dx_start) { m_dx <<= line_subpixel_shift; m_dy <<= line_subpixel_shift; m_dx_start <<= line_mr_subpixel_shift; m_dy_start <<= line_mr_subpixel_shift; } distance_interpolator2(int x1, int y1, int x2, int y2, int ex, int ey, int x, int y, int) : m_dx(x2 - x1), m_dy(y2 - y1), m_dx_start(line_mr(ex) - line_mr(x2)), m_dy_start(line_mr(ey) - line_mr(y2)), m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) - double(y + line_subpixel_scale/2 - y2) * double(m_dx))), m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(ex)) * m_dy_start - (line_mr(y + line_subpixel_scale/2) - line_mr(ey)) * m_dx_start) { m_dx <<= line_subpixel_shift; m_dy <<= line_subpixel_shift; m_dx_start <<= line_mr_subpixel_shift; m_dy_start <<= line_mr_subpixel_shift; } //--------------------------------------------------------------------- void inc_x() { m_dist += m_dy; m_dist_start += m_dy_start; } void dec_x() { m_dist -= m_dy; m_dist_start -= m_dy_start; } void inc_y() { m_dist -= m_dx; m_dist_start -= m_dx_start; } void dec_y() { m_dist += m_dx; m_dist_start += m_dx_start; } //--------------------------------------------------------------------- void inc_x(int dy) { m_dist += m_dy; m_dist_start += m_dy_start; if(dy > 0) { m_dist -= m_dx; m_dist_start -= m_dx_start; } if(dy < 0) { m_dist += m_dx; m_dist_start += m_dx_start; } } //--------------------------------------------------------------------- void dec_x(int dy) { m_dist -= m_dy; m_dist_start -= m_dy_start; if(dy > 0) { m_dist -= m_dx; m_dist_start -= m_dx_start; } if(dy < 0) { m_dist += m_dx; m_dist_start += m_dx_start; } } //--------------------------------------------------------------------- void inc_y(int dx) { m_dist -= m_dx; m_dist_start -= m_dx_start; if(dx > 0) { m_dist += m_dy; m_dist_start += m_dy_start; } if(dx < 0) { m_dist -= m_dy; m_dist_start -= m_dy_start; } } //--------------------------------------------------------------------- void dec_y(int dx) { m_dist += m_dx; m_dist_start += m_dx_start; if(dx > 0) { m_dist += m_dy; m_dist_start += m_dy_start; } if(dx < 0) { m_dist -= m_dy; m_dist_start -= m_dy_start; } } //--------------------------------------------------------------------- int dist() const { return m_dist; } int dist_start() const { return m_dist_start; } int dist_end() const { return m_dist_start; } //--------------------------------------------------------------------- int dx() const { return m_dx; } int dy() const { return m_dy; } int dx_start() const { return m_dx_start; } int dy_start() const { return m_dy_start; } int dx_end() const { return m_dx_start; } int dy_end() const { return m_dy_start; } private: //--------------------------------------------------------------------- int m_dx; int m_dy; int m_dx_start; int m_dy_start; int m_dist; int m_dist_start; }; //===================================================distance_interpolator3 class distance_interpolator3 { public: //--------------------------------------------------------------------- distance_interpolator3() {} distance_interpolator3(int x1, int y1, int x2, int y2, int sx, int sy, int ex, int ey, int x, int y) : m_dx(x2 - x1), m_dy(y2 - y1), m_dx_start(line_mr(sx) - line_mr(x1)), m_dy_start(line_mr(sy) - line_mr(y1)), m_dx_end(line_mr(ex) - line_mr(x2)), m_dy_end(line_mr(ey) - line_mr(y2)), m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) - double(y + line_subpixel_scale/2 - y2) * double(m_dx))), m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(sx)) * m_dy_start - (line_mr(y + line_subpixel_scale/2) - line_mr(sy)) * m_dx_start), m_dist_end((line_mr(x + line_subpixel_scale/2) - line_mr(ex)) * m_dy_end - (line_mr(y + line_subpixel_scale/2) - line_mr(ey)) * m_dx_end) { m_dx <<= line_subpixel_shift; m_dy <<= line_subpixel_shift; m_dx_start <<= line_mr_subpixel_shift; m_dy_start <<= line_mr_subpixel_shift; m_dx_end <<= line_mr_subpixel_shift; m_dy_end <<= line_mr_subpixel_shift; } //--------------------------------------------------------------------- void inc_x() { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_end += m_dy_end; } void dec_x() { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_end -= m_dy_end; } void inc_y() { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_end -= m_dx_end; } void dec_y() { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_end += m_dx_end; } //--------------------------------------------------------------------- void inc_x(int dy) { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_end += m_dy_end; if(dy > 0) { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_end -= m_dx_end; } if(dy < 0) { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_end += m_dx_end; } } //--------------------------------------------------------------------- void dec_x(int dy) { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_end -= m_dy_end; if(dy > 0) { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_end -= m_dx_end; } if(dy < 0) { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_end += m_dx_end; } } //--------------------------------------------------------------------- void inc_y(int dx) { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_end -= m_dx_end; if(dx > 0) { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_end += m_dy_end; } if(dx < 0) { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_end -= m_dy_end; } } //--------------------------------------------------------------------- void dec_y(int dx) { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_end += m_dx_end; if(dx > 0) { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_end += m_dy_end; } if(dx < 0) { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_end -= m_dy_end; } } //--------------------------------------------------------------------- int dist() const { return m_dist; } int dist_start() const { return m_dist_start; } int dist_end() const { return m_dist_end; } //--------------------------------------------------------------------- int dx() const { return m_dx; } int dy() const { return m_dy; } int dx_start() const { return m_dx_start; } int dy_start() const { return m_dy_start; } int dx_end() const { return m_dx_end; } int dy_end() const { return m_dy_end; } private: //--------------------------------------------------------------------- int m_dx; int m_dy; int m_dx_start; int m_dy_start; int m_dx_end; int m_dy_end; int m_dist; int m_dist_start; int m_dist_end; }; //================================================line_interpolator_aa_base template<class Renderer> class line_interpolator_aa_base { public: typedef Renderer renderer_type; typedef typename Renderer::color_type color_type; //--------------------------------------------------------------------- enum max_half_width_e { max_half_width = 64 }; //--------------------------------------------------------------------- line_interpolator_aa_base(renderer_type& ren, const line_parameters& lp) : m_lp(&lp), m_li(lp.vertical ? line_dbl_hr(lp.x2 - lp.x1) : line_dbl_hr(lp.y2 - lp.y1), lp.vertical ? abs(lp.y2 - lp.y1) : abs(lp.x2 - lp.x1) + 1), m_ren(ren), m_len((lp.vertical == (lp.inc > 0)) ? -lp.len : lp.len), m_x(lp.x1 >> line_subpixel_shift), m_y(lp.y1 >> line_subpixel_shift), m_old_x(m_x), m_old_y(m_y), m_count((lp.vertical ? abs((lp.y2 >> line_subpixel_shift) - m_y) : abs((lp.x2 >> line_subpixel_shift) - m_x))), m_width(ren.subpixel_width()), //m_max_extent(m_width >> (line_subpixel_shift - 2)), m_max_extent((m_width + line_subpixel_mask) >> line_subpixel_shift), m_step(0) { agg::dda2_line_interpolator li(0, lp.vertical ? (lp.dy << agg::line_subpixel_shift) : (lp.dx << agg::line_subpixel_shift), lp.len); unsigned i; int stop = m_width + line_subpixel_scale * 2; for(i = 0; i < max_half_width; ++i) { m_dist[i] = li.y(); if(m_dist[i] >= stop) break; ++li; } m_dist[i++] = 0x7FFF0000; } //--------------------------------------------------------------------- template<class DI> int step_hor_base(DI& di) { ++m_li; m_x += m_lp->inc; m_y = (m_lp->y1 + m_li.y()) >> line_subpixel_shift; if(m_lp->inc > 0) di.inc_x(m_y - m_old_y); else di.dec_x(m_y - m_old_y); m_old_y = m_y; return di.dist() / m_len; } //--------------------------------------------------------------------- template<class DI> int step_ver_base(DI& di) { ++m_li; m_y += m_lp->inc; m_x = (m_lp->x1 + m_li.y()) >> line_subpixel_shift; if(m_lp->inc > 0) di.inc_y(m_x - m_old_x); else di.dec_y(m_x - m_old_x); m_old_x = m_x; return di.dist() / m_len; } //--------------------------------------------------------------------- bool vertical() const { return m_lp->vertical; } int width() const { return m_width; } int count() const { return m_count; } private: line_interpolator_aa_base(const line_interpolator_aa_base<Renderer>&); const line_interpolator_aa_base<Renderer>& operator = (const line_interpolator_aa_base<Renderer>&); protected: const line_parameters* m_lp; dda2_line_interpolator m_li; renderer_type& m_ren; int m_len; int m_x; int m_y; int m_old_x; int m_old_y; int m_count; int m_width; int m_max_extent; int m_step; int m_dist[max_half_width + 1]; cover_type m_covers[max_half_width * 2 + 4]; }; //====================================================line_interpolator_aa0 template<class Renderer> class line_interpolator_aa0 : public line_interpolator_aa_base<Renderer> { public: typedef Renderer renderer_type; typedef typename Renderer::color_type color_type; typedef line_interpolator_aa_base<Renderer> base_type; //--------------------------------------------------------------------- line_interpolator_aa0(renderer_type& ren, const line_parameters& lp) : line_interpolator_aa_base<Renderer>(ren, lp), m_di(lp.x1, lp.y1, lp.x2, lp.y2, lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask) { base_type::m_li.adjust_forward(); } //--------------------------------------------------------------------- bool step_hor() { int dist; int dy; int s1 = base_type::step_hor_base(m_di); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; *p1++ = (cover_type)base_type::m_ren.cover(s1); dy = 1; while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) { *p1++ = (cover_type)base_type::m_ren.cover(dist); ++dy; } dy = 1; while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) { *--p0 = (cover_type)base_type::m_ren.cover(dist); ++dy; } base_type::m_ren.blend_solid_vspan(base_type::m_x, base_type::m_y - dy + 1, unsigned(p1 - p0), p0); return ++base_type::m_step < base_type::m_count; } //--------------------------------------------------------------------- bool step_ver() { int dist; int dx; int s1 = base_type::step_ver_base(m_di); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; *p1++ = (cover_type)base_type::m_ren.cover(s1); dx = 1; while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) { *p1++ = (cover_type)base_type::m_ren.cover(dist); ++dx; } dx = 1; while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) { *--p0 = (cover_type)base_type::m_ren.cover(dist); ++dx; } base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, base_type::m_y, unsigned(p1 - p0), p0); return ++base_type::m_step < base_type::m_count; } private: line_interpolator_aa0(const line_interpolator_aa0<Renderer>&); const line_interpolator_aa0<Renderer>& operator = (const line_interpolator_aa0<Renderer>&); //--------------------------------------------------------------------- distance_interpolator1 m_di; }; //====================================================line_interpolator_aa1 template<class Renderer> class line_interpolator_aa1 : public line_interpolator_aa_base<Renderer> { public: typedef Renderer renderer_type; typedef typename Renderer::color_type color_type; typedef line_interpolator_aa_base<Renderer> base_type; //--------------------------------------------------------------------- line_interpolator_aa1(renderer_type& ren, const line_parameters& lp, int sx, int sy) : line_interpolator_aa_base<Renderer>(ren, lp), m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask) { int dist1_start; int dist2_start; int npix = 1; if(lp.vertical) { do { --base_type::m_li; base_type::m_y -= lp.inc; base_type::m_x = (base_type::m_lp->x1 + base_type::m_li.y()) >> line_subpixel_shift; if(lp.inc > 0) m_di.dec_y(base_type::m_x - base_type::m_old_x); else m_di.inc_y(base_type::m_x - base_type::m_old_x); base_type::m_old_x = base_type::m_x; dist1_start = dist2_start = m_di.dist_start(); int dx = 0; if(dist1_start < 0) ++npix; do { dist1_start += m_di.dy_start(); dist2_start -= m_di.dy_start(); if(dist1_start < 0) ++npix; if(dist2_start < 0) ++npix; ++dx; } while(base_type::m_dist[dx] <= base_type::m_width); --base_type::m_step; if(npix == 0) break; npix = 0; } while(base_type::m_step >= -base_type::m_max_extent); } else { do { --base_type::m_li; base_type::m_x -= lp.inc; base_type::m_y = (base_type::m_lp->y1 + base_type::m_li.y()) >> line_subpixel_shift; if(lp.inc > 0) m_di.dec_x(base_type::m_y - base_type::m_old_y); else m_di.inc_x(base_type::m_y - base_type::m_old_y); base_type::m_old_y = base_type::m_y; dist1_start = dist2_start = m_di.dist_start(); int dy = 0; if(dist1_start < 0) ++npix; do { dist1_start -= m_di.dx_start(); dist2_start += m_di.dx_start(); if(dist1_start < 0) ++npix; if(dist2_start < 0) ++npix; ++dy; } while(base_type::m_dist[dy] <= base_type::m_width); --base_type::m_step; if(npix == 0) break; npix = 0; } while(base_type::m_step >= -base_type::m_max_extent); } base_type::m_li.adjust_forward(); } //--------------------------------------------------------------------- bool step_hor() { int dist_start; int dist; int dy; int s1 = base_type::step_hor_base(m_di); dist_start = m_di.dist_start(); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; *p1 = 0; if(dist_start <= 0) { *p1 = (cover_type)base_type::m_ren.cover(s1); } ++p1; dy = 1; while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) { dist_start -= m_di.dx_start(); *p1 = 0; if(dist_start <= 0) { *p1 = (cover_type)base_type::m_ren.cover(dist); } ++p1; ++dy; } dy = 1; dist_start = m_di.dist_start(); while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) { dist_start += m_di.dx_start(); *--p0 = 0; if(dist_start <= 0) { *p0 = (cover_type)base_type::m_ren.cover(dist); } ++dy; } base_type::m_ren.blend_solid_vspan(base_type::m_x, base_type::m_y - dy + 1, unsigned(p1 - p0), p0); return ++base_type::m_step < base_type::m_count; } //--------------------------------------------------------------------- bool step_ver() { int dist_start; int dist; int dx; int s1 = base_type::step_ver_base(m_di); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; dist_start = m_di.dist_start(); *p1 = 0; if(dist_start <= 0) { *p1 = (cover_type)base_type::m_ren.cover(s1); } ++p1; dx = 1; while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) { dist_start += m_di.dy_start(); *p1 = 0; if(dist_start <= 0) { *p1 = (cover_type)base_type::m_ren.cover(dist); } ++p1; ++dx; } dx = 1; dist_start = m_di.dist_start(); while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) { dist_start -= m_di.dy_start(); *--p0 = 0; if(dist_start <= 0) { *p0 = (cover_type)base_type::m_ren.cover(dist); } ++dx; } base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, base_type::m_y, unsigned(p1 - p0), p0); return ++base_type::m_step < base_type::m_count; } private: line_interpolator_aa1(const line_interpolator_aa1<Renderer>&); const line_interpolator_aa1<Renderer>& operator = (const line_interpolator_aa1<Renderer>&); //--------------------------------------------------------------------- distance_interpolator2 m_di; }; //====================================================line_interpolator_aa2 template<class Renderer> class line_interpolator_aa2 : public line_interpolator_aa_base<Renderer> { public: typedef Renderer renderer_type; typedef typename Renderer::color_type color_type; typedef line_interpolator_aa_base<Renderer> base_type; //--------------------------------------------------------------------- line_interpolator_aa2(renderer_type& ren, const line_parameters& lp, int ex, int ey) : line_interpolator_aa_base<Renderer>(ren, lp), m_di(lp.x1, lp.y1, lp.x2, lp.y2, ex, ey, lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask, 0) { base_type::m_li.adjust_forward(); base_type::m_step -= base_type::m_max_extent; } //--------------------------------------------------------------------- bool step_hor() { int dist_end; int dist; int dy; int s1 = base_type::step_hor_base(m_di); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; dist_end = m_di.dist_end(); int npix = 0; *p1 = 0; if(dist_end > 0) { *p1 = (cover_type)base_type::m_ren.cover(s1); ++npix; } ++p1; dy = 1; while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) { dist_end -= m_di.dx_end(); *p1 = 0; if(dist_end > 0) { *p1 = (cover_type)base_type::m_ren.cover(dist); ++npix; } ++p1; ++dy; } dy = 1; dist_end = m_di.dist_end(); while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) { dist_end += m_di.dx_end(); *--p0 = 0; if(dist_end > 0) { *p0 = (cover_type)base_type::m_ren.cover(dist); ++npix; } ++dy; } base_type::m_ren.blend_solid_vspan(base_type::m_x, base_type::m_y - dy + 1, unsigned(p1 - p0), p0); return npix && ++base_type::m_step < base_type::m_count; } //--------------------------------------------------------------------- bool step_ver() { int dist_end; int dist; int dx; int s1 = base_type::step_ver_base(m_di); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; dist_end = m_di.dist_end(); int npix = 0; *p1 = 0; if(dist_end > 0) { *p1 = (cover_type)base_type::m_ren.cover(s1); ++npix; } ++p1; dx = 1; while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) { dist_end += m_di.dy_end(); *p1 = 0; if(dist_end > 0) { *p1 = (cover_type)base_type::m_ren.cover(dist); ++npix; } ++p1; ++dx; } dx = 1; dist_end = m_di.dist_end(); while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) { dist_end -= m_di.dy_end(); *--p0 = 0; if(dist_end > 0) { *p0 = (cover_type)base_type::m_ren.cover(dist); ++npix; } ++dx; } base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, base_type::m_y, unsigned(p1 - p0), p0); return npix && ++base_type::m_step < base_type::m_count; } private: line_interpolator_aa2(const line_interpolator_aa2<Renderer>&); const line_interpolator_aa2<Renderer>& operator = (const line_interpolator_aa2<Renderer>&); //--------------------------------------------------------------------- distance_interpolator2 m_di; }; //====================================================line_interpolator_aa3 template<class Renderer> class line_interpolator_aa3 : public line_interpolator_aa_base<Renderer> { public: typedef Renderer renderer_type; typedef typename Renderer::color_type color_type; typedef line_interpolator_aa_base<Renderer> base_type; //--------------------------------------------------------------------- line_interpolator_aa3(renderer_type& ren, const line_parameters& lp, int sx, int sy, int ex, int ey) : line_interpolator_aa_base<Renderer>(ren, lp), m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask) { int dist1_start; int dist2_start; int npix = 1; |