agg_scanline_u.h

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

H
518
字号
//----------------------------------------------------------------------------// 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 (scanline32_u) 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_U_INCLUDED#define AGG_SCANLINE_U_INCLUDED#include "agg_array.h"namespace agg{    //=============================================================scanline_u8    //    // Unpacked scanline container class    //    // This class is used to transfer data from a scanline rasterizer     // to the rendering buffer. It's organized very simple. The class stores     // information of horizontal spans to render it into a pixel-map buffer.     // Each span has staring X, length, and an array of bytes that determine the     // cover-values for each pixel.     // Before using this class you should know the minimal and maximal pixel     // coordinates of your scanline. The protocol of using is:    // 1. reset(min_x, max_x)    // 2. add_cell() / add_span() - accumulate scanline.     //    When forming one scanline the next X coordinate must be always greater    //    than the last stored one, i.e. it works only with ordered coordinates.    // 3. Call finalize(y) and render the scanline.    // 3. Call reset_spans() to prepare for the new scanline.    //        // 4. Rendering:    //     // Scanline provides an iterator class that allows you to extract    // the spans and the cover values for each pixel. Be aware that clipping    // has not been done yet, so you should perform it yourself.    // Use scanline_u8::iterator to render spans:    //-------------------------------------------------------------------------    //    // int y = sl.y();                    // Y-coordinate of the scanline    //    // ************************************    // ...Perform vertical clipping here...    // ************************************    //    // scanline_u8::const_iterator span = sl.begin();    //     // unsigned char* row = m_rbuf->row(y); // The the address of the beginning     //                                      // of the current row    //     // unsigned num_spans = sl.num_spans(); // Number of spans. It's guaranteed that    //                                      // num_spans is always greater than 0.    //    // do    // {    //     const scanline_u8::cover_type* covers =    //         span->covers;                     // The array of the cover values    //    //     int num_pix = span->len;              // Number of pixels of the span.    //                                           // Always greater than 0, still it's    //                                           // better to use "int" instead of     //                                           // "unsigned" because it's more    //                                           // convenient for clipping    //     int x = span->x;    //    //     **************************************    //     ...Perform horizontal clipping here...    //     ...you have x, covers, and pix_count..    //     **************************************    //    //     unsigned char* dst = row + x;  // Calculate the start address of the row.    //                                    // In this case we assume a simple     //                                    // grayscale image 1-byte per pixel.    //     do    //     {    //         *dst++ = *covers++;        // Hypotetical rendering.     //     }    //     while(--num_pix);    //    //     ++span;    // }     // while(--num_spans);  // num_spans cannot be 0, so this loop is quite safe    //------------------------------------------------------------------------    //    // The question is: why should we accumulate the whole scanline when we    // could render just separate spans when they're ready?    // That's because using the scanline is generally faster. When is consists     // of more than one span the conditions for the processor cash system    // are better, because switching between two different areas of memory     // (that can be very large) occurs less frequently.    //------------------------------------------------------------------------    class scanline_u8    {    public:        typedef scanline_u8 self_type;        typedef int8u       cover_type;        typedef int16       coord_type;        //--------------------------------------------------------------------        struct span        {            coord_type  x;            coord_type  len;            cover_type* covers;        };        typedef span* iterator;        typedef const span* const_iterator;        //--------------------------------------------------------------------        ~scanline_u8()        {            delete [] m_spans;            delete [] m_covers;        }        scanline_u8() :            m_min_x(0),            m_max_len(0),            m_last_x(0x7FFFFFF0),            m_covers(0),            m_spans(0),            m_cur_span(0)        {}        //--------------------------------------------------------------------        void reset(int min_x, int max_x)        {            unsigned max_len = max_x - min_x + 2;            if(max_len > m_max_len)            {                delete [] m_spans;                delete [] m_covers;                m_covers  = new cover_type [max_len];                m_spans   = new span       [max_len];                m_max_len = max_len;            }            m_last_x        = 0x7FFFFFF0;            m_min_x         = min_x;            m_cur_span      = m_spans;        }        //--------------------------------------------------------------------        void add_cell(int x, unsigned cover)        {            x -= m_min_x;            m_covers[x] = (cover_type)cover;            if(x == m_last_x+1)            {                m_cur_span->len++;            }            else            {                m_cur_span++;                m_cur_span->x      = (coord_type)(x + m_min_x);                m_cur_span->len    = 1;                m_cur_span->covers = m_covers + x;            }            m_last_x = x;        }        //--------------------------------------------------------------------        void add_cells(int x, unsigned len, const cover_type* covers)        {            x -= m_min_x;            memcpy(m_covers + x, covers, len * sizeof(cover_type));            if(x == m_last_x+1)            {                m_cur_span->len += (coord_type)len;            }            else            {                m_cur_span++;                m_cur_span->x      = (coord_type)(x + m_min_x);                m_cur_span->len    = (coord_type)len;                m_cur_span->covers = m_covers + x;            }            m_last_x = x + len - 1;        }        //--------------------------------------------------------------------        void add_span(int x, unsigned len, unsigned cover)        {            x -= m_min_x;            memset(m_covers + x, cover, len);            if(x == m_last_x+1)            {                m_cur_span->len += (coord_type)len;            }            else            {                m_cur_span++;                m_cur_span->x      = (coord_type)(x + m_min_x);                m_cur_span->len    = (coord_type)len;                m_cur_span->covers = m_covers + x;            }            m_last_x = x + len - 1;        }        //--------------------------------------------------------------------        void finalize(int y)         {             m_y = y;         }        //--------------------------------------------------------------------        void reset_spans()        {            m_last_x    = 0x7FFFFFF0;            m_cur_span  = m_spans;        }        //--------------------------------------------------------------------        int      y()           const { return m_y; }        unsigned num_spans()   const { return unsigned(m_cur_span - m_spans); }        const_iterator begin() const { return m_spans + 1; }        iterator       begin()       { return m_spans + 1; }    private:        scanline_u8(const self_type&);        const self_type& operator = (const self_type&);    private:        int           m_min_x;        unsigned      m_max_len;        int           m_last_x;        int           m_y;        cover_type*   m_covers;        span*         m_spans;        span*         m_cur_span;    };    //==========================================================scanline_u8_am    //     // The scanline container with alpha-masking    //     //------------------------------------------------------------------------    template<class AlphaMask>     class scanline_u8_am : public scanline_u8

⌨️ 快捷键说明

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