agg_rasterizer_outline_aa.h

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

H
600
字号
//----------------------------------------------------------------------------// Anti-Grain Geometry - Version 2.4// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)//// Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied// warranty, and with no claim as to its suitability for any purpose.////----------------------------------------------------------------------------// Contact: mcseem@antigrain.com//          mcseemagg@yahoo.com//          http://www.antigrain.com//----------------------------------------------------------------------------#ifndef AGG_RASTERIZER_OUTLINE_AA_INCLUDED#define AGG_RASTERIZER_OUTLINE_AA_INCLUDED#include "agg_basics.h"#include "agg_line_aa_basics.h"#include "agg_vertex_sequence.h"namespace agg{    //-------------------------------------------------------------------------    inline bool cmp_dist_start(int d) { return d > 0;  }    inline bool cmp_dist_end(int d)   { return d <= 0; }    //-----------------------------------------------------------line_aa_vertex    // Vertex (x, y) with the distance to the next one. The last vertex has     // the distance between the last and the first points    struct line_aa_vertex    {        int x;        int y;        int len;        line_aa_vertex() {}        line_aa_vertex(int x_, int y_) :            x(x_),            y(y_),            len(0)        {        }        bool operator () (const line_aa_vertex& val)        {            double dx = val.x - x;            double dy = val.y - y;            return (len = uround(sqrt(dx * dx + dy * dy))) >                    (line_subpixel_scale + line_subpixel_scale / 2);        }    };    //----------------------------------------------------------outline_aa_join_e    enum outline_aa_join_e    {        outline_no_join,             //-----outline_no_join        outline_miter_join,          //-----outline_miter_join        outline_round_join,          //-----outline_round_join        outline_miter_accurate_join  //-----outline_accurate_join    };    //=======================================================rasterizer_outline_aa    template<class Renderer, class Coord=line_coord> class rasterizer_outline_aa    {    private:        //------------------------------------------------------------------------        struct draw_vars        {            unsigned idx;            int x1, y1, x2, y2;            line_parameters curr, next;            int lcurr, lnext;            int xb1, yb1, xb2, yb2;            unsigned flags;        };        void draw(draw_vars& dv, unsigned start, unsigned end);    public:        typedef line_aa_vertex                  vertex_type;        typedef vertex_sequence<vertex_type, 6> vertex_storage_type;        rasterizer_outline_aa(Renderer& ren) :             m_ren(&ren),             m_line_join(ren.accurate_join_only() ?                             outline_miter_accurate_join :                             outline_round_join),            m_round_cap(false),            m_start_x(0),            m_start_y(0)        {}        void attach(Renderer& ren) { m_ren = &ren; }        //------------------------------------------------------------------------        void line_join(outline_aa_join_e join)         {             m_line_join = m_ren->accurate_join_only() ?                 outline_miter_accurate_join :                 join;         }        bool line_join() const { return m_line_join; }        //------------------------------------------------------------------------        void round_cap(bool v) { m_round_cap = v; }        bool round_cap() const { return m_round_cap; }        //------------------------------------------------------------------------        void move_to(int x, int y)        {            m_src_vertices.modify_last(vertex_type(m_start_x = x, m_start_y = y));        }        //------------------------------------------------------------------------        void line_to(int x, int y)        {            m_src_vertices.add(vertex_type(x, y));        }        //------------------------------------------------------------------------        void move_to_d(double x, double y)        {            move_to(Coord::conv(x), Coord::conv(y));        }        //------------------------------------------------------------------------        void line_to_d(double x, double y)        {            line_to(Coord::conv(x), Coord::conv(y));        }        //------------------------------------------------------------------------        void render(bool close_polygon);        //------------------------------------------------------------------------        void add_vertex(double x, double y, unsigned cmd)        {            if(is_move_to(cmd))             {                render(false);                move_to_d(x, y);            }            else             {                if(is_end_poly(cmd))                {                    render(is_closed(cmd));                    if(is_closed(cmd))                     {                        move_to(m_start_x, m_start_y);                    }                }                else                {                    line_to_d(x, y);                }            }        }        //------------------------------------------------------------------------        template<class VertexSource>        void add_path(VertexSource& vs, unsigned path_id=0)        {            double x;            double y;            unsigned cmd;            vs.rewind(path_id);            while(!is_stop(cmd = vs.vertex(&x, &y)))            {                add_vertex(x, y, cmd);            }            render(false);        }        //------------------------------------------------------------------------        template<class VertexSource, class ColorStorage, class PathId>        void render_all_paths(VertexSource& vs,                               const ColorStorage& colors,                               const PathId& path_id,                              unsigned num_paths)        {            for(unsigned i = 0; i < num_paths; i++)            {                m_ren->color(colors[i]);                add_path(vs, path_id[i]);            }        }        //------------------------------------------------------------------------        template<class Ctrl> void render_ctrl(Ctrl& c)        {            unsigned i;            for(i = 0; i < c.num_paths(); i++)            {                m_ren->color(c.color(i));                add_path(c, i);            }        }    private:        rasterizer_outline_aa(const rasterizer_outline_aa<Renderer, Coord>&);        const rasterizer_outline_aa<Renderer, Coord>& operator =             (const rasterizer_outline_aa<Renderer, Coord>&);        Renderer*           m_ren;        vertex_storage_type m_src_vertices;        outline_aa_join_e   m_line_join;        bool                m_round_cap;        int                 m_start_x;        int                 m_start_y;    };    //----------------------------------------------------------------------------    template<class Renderer, class Coord>     void rasterizer_outline_aa<Renderer, Coord>::draw(draw_vars& dv,                                                       unsigned start,                                                       unsigned end)    {        unsigned i;        const vertex_storage_type::value_type* v;        for(i = start; i < end; i++)        {            if(m_line_join == outline_round_join)            {                dv.xb1 = dv.curr.x1 + (dv.curr.y2 - dv.curr.y1);                 dv.yb1 = dv.curr.y1 - (dv.curr.x2 - dv.curr.x1);                 dv.xb2 = dv.curr.x2 + (dv.curr.y2 - dv.curr.y1);                 dv.yb2 = dv.curr.y2 - (dv.curr.x2 - dv.curr.x1);            }            switch(dv.flags)            {            case 0: m_ren->line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2); break;            case 1: m_ren->line2(dv.curr, dv.xb2, dv.yb2); break;            case 2: m_ren->line1(dv.curr, dv.xb1, dv.yb1); break;            case 3: m_ren->line0(dv.curr); break;            }            if(m_line_join == outline_round_join && (dv.flags & 2) == 0)            {                m_ren->pie(dv.curr.x2, dv.curr.y2,                            dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),                           dv.curr.y2 - (dv.curr.x2 - dv.curr.x1),                           dv.curr.x2 + (dv.next.y2 - dv.next.y1),                           dv.curr.y2 - (dv.next.x2 - dv.next.x1));            }            dv.x1 = dv.x2;            dv.y1 = dv.y2;            dv.lcurr = dv.lnext;            dv.lnext = m_src_vertices[dv.idx].len;            ++dv.idx;            if(dv.idx >= m_src_vertices.size()) dv.idx = 0;             v = &m_src_vertices[dv.idx];            dv.x2 = v->x;            dv.y2 = v->y;            dv.curr = dv.next;            dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);            dv.xb1 = dv.xb2;            dv.yb1 = dv.yb2;            switch(m_line_join)            {            case outline_no_join:                dv.flags = 3;                break;            case outline_miter_join:                dv.flags >>= 1;                dv.flags |= ((dv.curr.diagonal_quadrant() ==                               dv.next.diagonal_quadrant()) << 1);                if((dv.flags & 2) == 0)                {                    bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);                }                break;            case outline_round_join:                dv.flags >>= 1;                dv.flags |= ((dv.curr.diagonal_quadrant() ==                               dv.next.diagonal_quadrant()) << 1);                break;

⌨️ 快捷键说明

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