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

📄 agg_scanline_storage_aa.h

📁 这是VCF框架的代码
💻 H
📖 第 1 页 / 共 2 页
字号:
//----------------------------------------------------------------------------// 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//----------------------------------------------------------------------------//// Adaptation for 32-bit screen coordinates has been sponsored by // Liberty Technology Systems, Inc., visit http://lib-sys.com//// Liberty Technology Systems, Inc. is the provider of// PostScript and PDF technology for software developers.// //----------------------------------------------------------------------------#ifndef AGG_SCANLINE_STORAGE_AA_INCLUDED#define AGG_SCANLINE_STORAGE_AA_INCLUDED#include <string.h>#include <stdlib.h>#include <math.h>#include "agg_array.h"namespace agg{    //----------------------------------------------scanline_cell_storage    template<class T> class scanline_cell_storage    {        struct extra_span        {            unsigned len;            T*       ptr;        };    public:        typedef T value_type;        //---------------------------------------------------------------        ~scanline_cell_storage()        {            remove_all();        }        //---------------------------------------------------------------        scanline_cell_storage() :            m_cells(128-2),            m_extra_storage()        {}        // Copying        //---------------------------------------------------------------        scanline_cell_storage(const scanline_cell_storage<T>& v) :            m_cells(v.m_cells),            m_extra_storage()        {            copy_extra_storage(v);        }        //---------------------------------------------------------------        const scanline_cell_storage<T>&         operator = (const scanline_cell_storage<T>& v)        {            remove_all();            m_cells = v.m_cells;            copy_extra_storage(v);            return *this;        }        //---------------------------------------------------------------        void remove_all()        {            int i;            for(i = m_extra_storage.size()-1; i >= 0; --i)            {                delete [] m_extra_storage[(unsigned)i].ptr;            }            m_extra_storage.remove_all();            m_cells.remove_all();        }        //---------------------------------------------------------------        int add_cells(const T* cells, unsigned num_cells)        {            int idx = m_cells.allocate_continuous_block(num_cells);            if(idx >= 0)            {                T* ptr = &m_cells[idx];                memcpy(ptr, cells, sizeof(T) * num_cells);                return idx;            }            extra_span s;            s.len = num_cells;            s.ptr = new T [num_cells];            memcpy(s.ptr, cells, sizeof(T) * num_cells);            m_extra_storage.add(s);            return -int(m_extra_storage.size());        }        //---------------------------------------------------------------        const T* operator [] (int idx) const        {            if(idx >= 0)            {                if((unsigned)idx >= m_cells.size()) return 0;                return &m_cells[(unsigned)idx];            }            unsigned i = unsigned(-idx - 1);            if(i >= m_extra_storage.size()) return 0;            return m_extra_storage[i].ptr;        }        //---------------------------------------------------------------        T* operator [] (int idx)        {            if(idx >= 0)            {                if((unsigned)idx >= m_cells.size()) return 0;                return &m_cells[(unsigned)idx];            }            unsigned i = unsigned(-idx - 1);            if(i >= m_extra_storage.size()) return 0;            return m_extra_storage[i].ptr;        }    private:        void copy_extra_storage(const scanline_cell_storage<T>& v)        {            unsigned i;            for(i = 0; i < v.m_extra_storage.size(); ++i)            {                const extra_span& src = v.m_extra_storage[i];                extra_span dst;                dst.len = src.len;                dst.ptr = new T [dst.len];                memcpy(dst.ptr, src.ptr, dst.len * sizeof(T));                m_extra_storage.add(dst);            }        }        pod_bvector<T, 12>         m_cells;        pod_bvector<extra_span, 6> m_extra_storage;    };    //-----------------------------------------------scanline_storage_aa    template<class T> class scanline_storage_aa    {    public:        typedef T cover_type;        //---------------------------------------------------------------        struct span_data        {            int32 x;            int32 len;       // If negative, it's a solid span, covers is valid            int   covers_id; // The index of the cells in the scanline_cell_storage        };        //---------------------------------------------------------------        struct scanline_data        {            int      y;            unsigned num_spans;            unsigned start_span;        };        //---------------------------------------------------------------        class embedded_scanline        {        public:            //-----------------------------------------------------------            class const_iterator            {            public:                struct span                {                    int32    x;                    int32    len; // If negative, it's a solid span, covers is valid                    const T* covers;                };                const_iterator() : m_storage(0) {}                const_iterator(const embedded_scanline& sl) :                    m_storage(sl.m_storage),                    m_span_idx(sl.m_scanline.start_span)                {                    init_span();                }                const span& operator*()  const { return m_span;  }                const span* operator->() const { return &m_span; }                void operator ++ ()                {                    ++m_span_idx;                    init_span();                }            private:                void init_span()                {                    const span_data& s = m_storage->span_by_index(m_span_idx);                    m_span.x      = s.x;                    m_span.len    = s.len;                    m_span.covers = m_storage->covers_by_index(s.covers_id);                }                const scanline_storage_aa* m_storage;                unsigned                   m_span_idx;                span                       m_span;            };            friend class const_iterator;            //-----------------------------------------------------------            embedded_scanline(const scanline_storage_aa& storage) :                m_storage(&storage)            {                init(0);            }            //-----------------------------------------------------------            void     reset(int, int)     {}            unsigned num_spans()   const { return m_scanline.num_spans;  }            int      y()           const { return m_scanline.y;          }            const_iterator begin() const { return const_iterator(*this); }            //-----------------------------------------------------------            void init(unsigned scanline_idx)            {                m_scanline_idx = scanline_idx;                m_scanline = m_storage->scanline_by_index(m_scanline_idx);            }        private:            const scanline_storage_aa* m_storage;            scanline_data              m_scanline;            unsigned                   m_scanline_idx;        };        //---------------------------------------------------------------        scanline_storage_aa() :            m_covers(),            m_spans(256-2),         // Block increment size            m_scanlines(),            m_min_x( 0x7FFFFFFF),            m_min_y( 0x7FFFFFFF),            m_max_x(-0x7FFFFFFF),            m_max_y(-0x7FFFFFFF),            m_cur_scanline(0)        {            m_fake_scanline.y = 0;            m_fake_scanline.num_spans = 0;            m_fake_scanline.start_span = 0;            m_fake_span.x = 0;            m_fake_span.len = 0;            m_fake_span.covers_id = 0;        }        // Renderer Interface        //---------------------------------------------------------------        void prepare()        {            m_covers.remove_all();            m_scanlines.remove_all();            m_spans.remove_all();            m_min_x =  0x7FFFFFFF;            m_min_y =  0x7FFFFFFF;            m_max_x = -0x7FFFFFFF;            m_max_y = -0x7FFFFFFF;            m_cur_scanline = 0;        }        //---------------------------------------------------------------        template<class Scanline> void render(const Scanline& sl)        {            scanline_data sl_this;            int y = sl.y();            if(y < m_min_y) m_min_y = y;            if(y > m_max_y) m_max_y = y;            sl_this.y = y;            sl_this.num_spans = sl.num_spans();            sl_this.start_span = m_spans.size();            typename Scanline::const_iterator span_iterator = sl.begin();            unsigned num_spans = sl_this.num_spans;            for(;;)            {                span_data sp;                sp.x         = span_iterator->x;                sp.len       = span_iterator->len;                int len      = abs(int(sp.len));                sp.covers_id =                     m_covers.add_cells(span_iterator->covers,                                        unsigned(len));                m_spans.add(sp);                int x1 = sp.x;                int x2 = sp.x + len - 1;                if(x1 < m_min_x) m_min_x = x1;                if(x2 > m_max_x) m_max_x = x2;                if(--num_spans == 0) break;                ++span_iterator;            }            m_scanlines.add(sl_this);        }        //---------------------------------------------------------------        // Iterate scanlines interface        int min_x() const { return m_min_x; }        int min_y() const { return m_min_y; }        int max_x() const { return m_max_x; }        int max_y() const { return m_max_y; }        //---------------------------------------------------------------        bool rewind_scanlines()        {            m_cur_scanline = 0;            return m_scanlines.size() > 0;        }        //---------------------------------------------------------------        template<class Scanline> bool sweep_scanline(Scanline& sl)        {            sl.reset_spans();            for(;;)            {                if(m_cur_scanline >= m_scanlines.size()) return false;                const scanline_data& sl_this = m_scanlines[m_cur_scanline];                unsigned num_spans = sl_this.num_spans;                unsigned span_idx  = sl_this.start_span;                do                {                    const span_data& sp = m_spans[span_idx++];                    const T* covers = covers_by_index(sp.covers_id);                    if(sp.len < 0)                    {                        sl.add_span(sp.x, unsigned(-sp.len), *covers);                    }                    else                    {                        sl.add_cells(sp.x, sp.len, covers);                    }                }                while(--num_spans);                ++m_cur_scanline;                if(sl.num_spans())                {                    sl.finalize(sl_this.y);                    break;                }            }            return true;        }        //---------------------------------------------------------------        // Specialization for embedded_scanline        bool sweep_scanline(embedded_scanline& sl)        {            do            {                if(m_cur_scanline >= m_scanlines.size()) return false;                sl.init(m_cur_scanline);                ++m_cur_scanline;            }            while(sl.num_spans() == 0);            return true;        }        //---------------------------------------------------------------        unsigned byte_size() const        {            unsigned i;            unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y            for(i = 0; i < m_scanlines.size(); ++i)            {                size += sizeof(int32) * 3; // scanline size in bytes, Y, num_spans                const scanline_data& sl_this = m_scanlines[i];                unsigned num_spans = sl_this.num_spans;                unsigned span_idx  = sl_this.start_span;

⌨️ 快捷键说明

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