agg_renderer_outline_aa.h

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

H
1,846
字号
            base_type::m_step -= base_type::m_max_extent;        }        //---------------------------------------------------------------------        bool step_hor()        {            int dist_start;            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_start = m_di.dist_start();            dist_end   = m_di.dist_end();            int npix = 0;            *p1 = 0;            if(dist_end > 0)            {                if(dist_start <= 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_start -= m_di.dx_start();                dist_end   -= m_di.dx_end();                *p1 = 0;                if(dist_end > 0 && dist_start <= 0)                {                       *p1 = (cover_type)base_type::m_ren.cover(dist);                    ++npix;                }                ++p1;                ++dy;            }            dy = 1;            dist_start = m_di.dist_start();            dist_end   = m_di.dist_end();            while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width)            {                dist_start += m_di.dx_start();                dist_end   += m_di.dx_end();                *--p0 = 0;                if(dist_end > 0 && dist_start <= 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_start;            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_start = m_di.dist_start();            dist_end   = m_di.dist_end();            int npix = 0;            *p1 = 0;            if(dist_end > 0)            {                if(dist_start <= 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_start += m_di.dy_start();                dist_end   += m_di.dy_end();                *p1 = 0;                if(dist_end > 0 && dist_start <= 0)                {                       *p1 = (cover_type)base_type::m_ren.cover(dist);                    ++npix;                }                ++p1;                ++dx;            }            dx = 1;            dist_start = m_di.dist_start();            dist_end   = m_di.dist_end();            while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width)            {                dist_start -= m_di.dy_start();                dist_end   -= m_di.dy_end();                *--p0 = 0;                if(dist_end > 0 && dist_start <= 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_aa3(const line_interpolator_aa3<Renderer>&);        const line_interpolator_aa3<Renderer>&             operator = (const line_interpolator_aa3<Renderer>&);        //---------------------------------------------------------------------        distance_interpolator3 m_di;     };    //==========================================================line_profile_aa    //    // See Implementation agg_line_profile_aa.cpp     //     class line_profile_aa    {    public:        //---------------------------------------------------------------------        typedef int8u value_type;        enum subpixel_scale_e        {            subpixel_shift = line_subpixel_shift,            subpixel_scale = 1 << subpixel_shift,            subpixel_mask  = subpixel_scale - 1        };        enum aa_scale_e        {            aa_shift = 8,            aa_scale = 1 << aa_shift,            aa_mask  = aa_scale - 1        };                //---------------------------------------------------------------------        ~line_profile_aa() { delete [] m_profile; }        //---------------------------------------------------------------------        line_profile_aa() :             m_size(0),             m_profile(0),             m_subpixel_width(0),            m_min_width(1.0),            m_smoother_width(1.0)        {            int i;            for(i = 0; i < aa_scale; i++) m_gamma[i] = (value_type)i;        }        //---------------------------------------------------------------------        template<class GammaF>         line_profile_aa(double w, const GammaF& gamma_function) :             m_size(0),             m_profile(0),             m_subpixel_width(0),            m_min_width(1.0),            m_smoother_width(1.0)        {            gamma(gamma_function);            width(w);        }        //---------------------------------------------------------------------        void min_width(double w) { m_min_width = w; }        void smoother_width(double w) { m_smoother_width = w; }        //---------------------------------------------------------------------        template<class GammaF> void gamma(const GammaF& gamma_function)        {             int i;            for(i = 0; i < aa_scale; i++)            {                m_gamma[i] = value_type(                    uround(gamma_function(double(i) / aa_mask) * aa_mask));            }        }        void width(double w);        unsigned profile_size() const { return m_size; }        int subpixel_width() const { return m_subpixel_width; }        //---------------------------------------------------------------------        double min_width() const { return m_min_width; }        double smoother_width() const { return m_smoother_width; }        //---------------------------------------------------------------------        value_type value(int dist) const        {            return m_profile[dist + subpixel_scale*2];        }    private:        line_profile_aa(const line_profile_aa&);        const line_profile_aa& operator = (const line_profile_aa&);        value_type* profile(double w);        void set(double center_width, double smoother_width);        //---------------------------------------------------------------------        unsigned    m_size;        value_type* m_profile;        value_type  m_gamma[aa_scale];        int         m_subpixel_width;        double      m_min_width;        double      m_smoother_width;    };    //======================================================renderer_outline_aa    template<class BaseRenderer> class renderer_outline_aa    {    public:        //---------------------------------------------------------------------        typedef BaseRenderer base_ren_type;        typedef renderer_outline_aa<base_ren_type> self_type;        typedef typename base_ren_type::color_type color_type;        //---------------------------------------------------------------------        renderer_outline_aa(base_ren_type& ren, const line_profile_aa& prof) :            m_ren(&ren),            m_profile(&prof),            m_clip_box(0,0,0,0),            m_clipping(false)        {}        void attach(base_ren_type& ren) { m_ren = &ren; }        //---------------------------------------------------------------------        void color(const color_type& c) { m_color = c; }        const color_type& color() const { return m_color; }        //---------------------------------------------------------------------        void profile(const line_profile_aa& prof) { m_profile = &prof; }        const line_profile_aa& profile() const { return *m_profile; }        line_profile_aa& profile() { return *m_profile; }        //---------------------------------------------------------------------        int subpixel_width() const { return m_profile->subpixel_width(); }        //---------------------------------------------------------------------        void reset_clipping() { m_clipping = false; }        void clip_box(double x1, double y1, double x2, double y2)        {            m_clip_box.x1 = line_coord_sat::conv(x1);            m_clip_box.y1 = line_coord_sat::conv(y1);            m_clip_box.x2 = line_coord_sat::conv(x2);            m_clip_box.y2 = line_coord_sat::conv(y2);            m_clipping = true;        }        //---------------------------------------------------------------------        int cover(int d) const        {            return m_profile->value(d);        }        //-------------------------------------------------------------------------        void blend_solid_hspan(int x, int y, unsigned len, const cover_type* covers)        {            m_ren->blend_solid_hspan(x, y, len, m_color, covers);        }        //-------------------------------------------------------------------------        void blend_solid_vspan(int x, int y, unsigned len, const cover_type* covers)        {            m_ren->blend_solid_vspan(x, y, len, m_color, covers);        }        //-------------------------------------------------------------------------        static bool accurate_join_only() { return false; }        //-------------------------------------------------------------------------        template<class Cmp>        void semidot_hline(Cmp cmp,                           int xc1, int yc1, int xc2, int yc2,                            int x1,  int y1,  int x2)        {            cover_type covers[line_interpolator_aa_base<self_type>::max_half_width * 2 + 4];            cover_type* p0 = covers;            cover_type* p1 = covers;            int x = x1 << line_subpixel_shift;            int y = y1 << line_subpixel_shift;            int w = subpixel_width();            distance_interpolator0 di(xc1, yc1, xc2, yc2, x, y);            x += line_subpixel_scale/2;            y += line_subpixel_scale/2;            int x0 = x1;            int dx = x - xc1;            int dy = y - yc1;            do            {                int d = int(fast_sqrt(dx*dx + dy*dy));                *p1 = 0;                if(cmp(di.dist()) && d <= w)                {                    *p1 = (cover_type)cover(d);                }                ++p1;                dx += line_subpixel_scale;                di.inc_x();            }            while(++x1 <= x2);            m_ren->blend_solid_hspan(x0, y1,                                      unsigned(p1 - p0),                                      color(),                                      p0);        }        //-------------------------------------------------------------------------        template<class Cmp>         void semidot(Cmp cmp, int xc1, int yc1, int xc2, int yc2)        {            if(m_clipping && clipping_flags(xc1, yc1, m_clip_box)) return;            int r = ((subpixel_width() + line_subpixel_mask) >> line_subpixel_shift);            if(r < 1) r = 1;            ellipse_bresenham_interpolator ei(r, r);            int dx = 0;            int dy = -r;            int dy0 = dy;            int dx0 = dx;            int x = xc1 >> line_subpixel_shift;            int y = yc1 >> line_subpixel_shift;            do            {                dx += ei.dx();                dy += ei.dy();                if(dy != dy0)                {                    semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y+dy0, x+dx0);                    semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y-dy0, x+dx0);                }                dx0 = dx;                dy0 = dy;                ++ei;            }

⌨️ 快捷键说明

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