⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 agg_path_storage.h

📁 windows ce 下的画各种b样条曲线
💻 H
📖 第 1 页 / 共 4 页
字号:
//----------------------------------------------------------------------------
// 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_PATH_STORAGE_INCLUDED
#define AGG_PATH_STORAGE_INCLUDED

#include <string.h>
#include <math.h>
#include "agg_math.h"
#include "agg_array.h"
#include "agg_bezier_arc.h"

namespace agg
{


    //----------------------------------------------------vertex_block_storage
    template<class T, unsigned BlockShift=8, unsigned BlockPool=256>
    class vertex_block_storage
    {
    public:
        // Allocation parameters
        enum block_scale_e
        {
            block_shift = BlockShift,
            block_size  = 1 << block_shift,
            block_mask  = block_size - 1,
            block_pool  = BlockPool
        };

        typedef T value_type;
        typedef vertex_block_storage<T, BlockShift, BlockPool> self_type;

        ~vertex_block_storage();
        vertex_block_storage();
        vertex_block_storage(const self_type& v);
        const self_type& operator = (const self_type& ps);

        void remove_all();
        void free_all();

        void add_vertex(double x, double y, unsigned cmd);
        void modify_vertex(unsigned idx, double x, double y);
        void modify_vertex(unsigned idx, double x, double y, unsigned cmd);
        void modify_command(unsigned idx, unsigned cmd);
        void swap_vertices(unsigned v1, unsigned v2);

        unsigned last_command() const;
        unsigned last_vertex(double* x, double* y) const;
        unsigned prev_vertex(double* x, double* y) const;

        double last_x() const;
        double last_y() const;

        unsigned total_vertices() const;
        unsigned vertex(unsigned idx, double* x, double* y) const;
        unsigned command(unsigned idx) const;

    private:
        void   allocate_block(unsigned nb);
        int8u* storage_ptrs(T** xy_ptr);

    private:
        unsigned m_total_vertices;
        unsigned m_total_blocks;
        unsigned m_max_blocks;
        T**      m_coord_blocks;
        int8u**  m_cmd_blocks;
    };


    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    void vertex_block_storage<T,S,P>::free_all()
    {
        if(m_total_blocks)
        {
            T** coord_blk = m_coord_blocks + m_total_blocks - 1;
            while(m_total_blocks--)
            {
                pod_allocator<T>::deallocate(
                    *coord_blk,
                    block_size * 2 + 
                    block_size / (sizeof(T) / sizeof(unsigned char)));
                --coord_blk;
            }
            pod_allocator<T*>::deallocate(m_coord_blocks, m_max_blocks * 2);
            m_total_blocks   = 0;
            m_max_blocks     = 0;
            m_coord_blocks   = 0;
            m_cmd_blocks     = 0;
            m_total_vertices = 0;
        }
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    vertex_block_storage<T,S,P>::~vertex_block_storage()
    {
        free_all();
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    vertex_block_storage<T,S,P>::vertex_block_storage() :
        m_total_vertices(0),
        m_total_blocks(0),
        m_max_blocks(0),
        m_coord_blocks(0),
        m_cmd_blocks(0)
    {
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    vertex_block_storage<T,S,P>::vertex_block_storage(const vertex_block_storage<T,S,P>& v) :
        m_total_vertices(0),
        m_total_blocks(0),
        m_max_blocks(0),
        m_coord_blocks(0),
        m_cmd_blocks(0)
    {
        *this = v;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    const vertex_block_storage<T,S,P>& 
    vertex_block_storage<T,S,P>::operator = (const vertex_block_storage<T,S,P>& v)
    {
        remove_all();
        unsigned i;
        for(i = 0; i < v.total_vertices(); i++)
        {
            double x, y;
            unsigned cmd = v.vertex(i, &x, &y);
            add_vertex(x, y, cmd);
        }
	    return *this;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline void vertex_block_storage<T,S,P>::remove_all()
    {
        m_total_vertices = 0;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline void vertex_block_storage<T,S,P>::add_vertex(double x, double y, 
                                                        unsigned cmd)
    {
        T* coord_ptr = 0;
        *storage_ptrs(&coord_ptr) = (int8u)cmd;
        coord_ptr[0] = T(x);
        coord_ptr[1] = T(y);
        m_total_vertices++;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx, 
                                                           double x, double y)
    {
        T* pv = m_coord_blocks[idx >> block_shift] + ((idx & block_mask) << 1);
        pv[0] = T(x);
        pv[1] = T(y);
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx, 
                                                           double x, double y, 
                                                           unsigned cmd)
    {
        unsigned block = idx >> block_shift;
        unsigned offset = idx & block_mask;
        T* pv = m_coord_blocks[block] + (offset << 1);
        pv[0] = T(x);
        pv[1] = T(y);
        m_cmd_blocks[block][offset] = (int8u)cmd;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline void vertex_block_storage<T,S,P>::modify_command(unsigned idx, 
                                                            unsigned cmd)
    {
        m_cmd_blocks[idx >> block_shift][idx & block_mask] = (int8u)cmd;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline void vertex_block_storage<T,S,P>::swap_vertices(unsigned v1, unsigned v2)
    {
        unsigned b1 = v1 >> block_shift;
        unsigned b2 = v2 >> block_shift;
        unsigned o1 = v1 & block_mask;
        unsigned o2 = v2 & block_mask;
        T* pv1 = m_coord_blocks[b1] + (o1 << 1);
        T* pv2 = m_coord_blocks[b2] + (o2 << 1);
        T  val;
        val = pv1[0]; pv1[0] = pv2[0]; pv2[0] = val;
        val = pv1[1]; pv1[1] = pv2[1]; pv2[1] = val;
        int8u cmd = m_cmd_blocks[b1][o1];
        m_cmd_blocks[b1][o1] = m_cmd_blocks[b2][o2];
        m_cmd_blocks[b2][o2] = cmd;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline unsigned vertex_block_storage<T,S,P>::last_command() const
    {
        if(m_total_vertices) return command(m_total_vertices - 1);
        return path_cmd_stop;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline unsigned vertex_block_storage<T,S,P>::last_vertex(double* x, double* y) const
    {
        if(m_total_vertices) return vertex(m_total_vertices - 1, x, y);
        return path_cmd_stop;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline unsigned vertex_block_storage<T,S,P>::prev_vertex(double* x, double* y) const
    {
        if(m_total_vertices > 1) return vertex(m_total_vertices - 2, x, y);
        return path_cmd_stop;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline double vertex_block_storage<T,S,P>::last_x() const
    {
        if(m_total_vertices)
        {
            unsigned idx = m_total_vertices - 1;
            return m_coord_blocks[idx >> block_shift][(idx & block_mask) << 1];
        }
        return 0.0;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline double vertex_block_storage<T,S,P>::last_y() const
    {
        if(m_total_vertices)
        {
            unsigned idx = m_total_vertices - 1;
            return m_coord_blocks[idx >> block_shift][((idx & block_mask) << 1) + 1];
        }
        return 0.0;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline unsigned vertex_block_storage<T,S,P>::total_vertices() const
    {
        return m_total_vertices;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline unsigned vertex_block_storage<T,S,P>::vertex(unsigned idx, 
                                                        double* x, double* y) const
    {
        unsigned nb = idx >> block_shift;
        const T* pv = m_coord_blocks[nb] + ((idx & block_mask) << 1);
        *x = pv[0];
        *y = pv[1];
        return m_cmd_blocks[nb][idx & block_mask];
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    inline unsigned vertex_block_storage<T,S,P>::command(unsigned idx) const
    {
        return m_cmd_blocks[idx >> block_shift][idx & block_mask];
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    void vertex_block_storage<T,S,P>::allocate_block(unsigned nb)
    {
        if(nb >= m_max_blocks) 
        {
            T** new_coords = 
                pod_allocator<T*>::allocate((m_max_blocks + block_pool) * 2);

            unsigned char** new_cmds = 
                (unsigned char**)(new_coords + m_max_blocks + block_pool);

            if(m_coord_blocks)
            {
                memcpy(new_coords, 
                       m_coord_blocks, 
                       m_max_blocks * sizeof(T*));

                memcpy(new_cmds, 
                       m_cmd_blocks, 
                       m_max_blocks * sizeof(unsigned char*));

                pod_allocator<T*>::deallocate(m_coord_blocks, m_max_blocks * 2);
            }
            m_coord_blocks = new_coords;
            m_cmd_blocks   = new_cmds;
            m_max_blocks  += block_pool;
        }
        m_coord_blocks[nb] = 
            pod_allocator<T>::allocate(block_size * 2 + 
                   block_size / (sizeof(T) / sizeof(unsigned char)));

        m_cmd_blocks[nb]  = 
            (unsigned char*)(m_coord_blocks[nb] + block_size * 2);

        m_total_blocks++;
    }

    //------------------------------------------------------------------------
    template<class T, unsigned S, unsigned P>
    int8u* vertex_block_storage<T,S,P>::storage_ptrs(T** xy_ptr)
    {
        unsigned nb = m_total_vertices >> block_shift;
        if(nb >= m_total_blocks)
        {
            allocate_block(nb);
        }
        *xy_ptr = m_coord_blocks[nb] + ((m_total_vertices & block_mask) << 1);
        return m_cmd_blocks[nb] + (m_total_vertices & block_mask);
    }




    //-----------------------------------------------------poly_plain_adaptor
    template<class T> class poly_plain_adaptor
    {
    public:
        typedef T value_type;

        poly_plain_adaptor() : 
            m_data(0), 
            m_ptr(0),
            m_end(0),
            m_closed(false),
            m_stop(false)
        {}

        poly_plain_adaptor(const T* data, unsigned num_points, bool closed) :
            m_data(data), 
            m_ptr(data),
            m_end(data + num_points * 2),
            m_closed(closed),
            m_stop(false)
        {}

        void init(const T* data, unsigned num_points, bool closed)
        {
            m_data = data;
            m_ptr = data;
            m_end = data + num_points * 2;
            m_closed = closed;
            m_stop = false;
        }

⌨️ 快捷键说明

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