agg_renderer_outline_aa.h

来自「这是VCF框架的代码」· C头文件 代码 · 共 1,846 行 · 第 1/5 页

H
1,846
字号
        //---------------------------------------------------------------------        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                    {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?