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

📄 agg_rasterizer_scanline_aa.cpp

📁 okular
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//----------------------------------------------------------------------------// Anti-Grain Geometry - Version 2.3// 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.//// The author gratefully acknowleges the support of David Turner, // Robert Wilhelm, and Werner Lemberg - the authors of the FreeType // libray - in producing this work. See http://www.freetype.org for details.////----------------------------------------------------------------------------// Contact: mcseem@antigrain.com//          mcseemagg@yahoo.com//          http://www.antigrain.com//----------------------------------------------------------------------------//// Class outline_aa - implementation.//// Initially the rendering algorithm was designed by David Turner and the // other authors of the FreeType library - see the above notice. I nearly // created a similar renderer, but still I was far from David's work. // I completely redesigned the original code and adapted it for Anti-Grain // ideas. Two functions - render_line and render_hline are the core of // the algorithm - they calculate the exact coverage of each pixel cell// of the polygon. I left these functions almost as is, because there's // no way to improve the perfection - hats off to David and his group!//// All other code is very different from the original. // //----------------------------------------------------------------------------#include <string.h>#include "agg_rasterizer_scanline_aa.h"namespace agg{    //------------------------------------------------------------------------    AGG_INLINE void cell_aa::set_cover(int c, int a)    {        cover = c;        area = a;    }    //------------------------------------------------------------------------    AGG_INLINE void cell_aa::add_cover(int c, int a)    {        cover += c;        area += a;    }    //------------------------------------------------------------------------    AGG_INLINE void cell_aa::set_coord(int cx, int cy)    {        x = int16(cx);        y = int16(cy);        packed_coord = (cy << 16) + cx;    }    //------------------------------------------------------------------------    AGG_INLINE void cell_aa::set(int cx, int cy, int c, int a)    {        x = int16(cx);        y = int16(cy);        packed_coord = (cy << 16) + cx;        cover = c;        area = a;    }    //------------------------------------------------------------------------    outline_aa::~outline_aa()    {        delete [] m_sorted_cells;        if(m_num_blocks)        {            cell_aa** ptr = m_cells + m_num_blocks - 1;            while(m_num_blocks--)            {                delete [] *ptr;                ptr--;            }            delete [] m_cells;        }    }    //------------------------------------------------------------------------    outline_aa::outline_aa() :        m_num_blocks(0),        m_max_blocks(0),        m_cur_block(0),        m_num_cells(0),        m_cells(0),        m_cur_cell_ptr(0),        m_sorted_cells(0),        m_sorted_size(0),        m_cur_x(0),        m_cur_y(0),        m_min_x(0x7FFFFFFF),        m_min_y(0x7FFFFFFF),        m_max_x(-0x7FFFFFFF),        m_max_y(-0x7FFFFFFF),        m_sorted(false)    {        m_cur_cell.set(0x7FFF, 0x7FFF, 0, 0);    }    //------------------------------------------------------------------------    void outline_aa::reset()    {         m_num_cells = 0;         m_cur_block = 0;        m_cur_cell.set(0x7FFF, 0x7FFF, 0, 0);        m_sorted = false;        m_min_x =  0x7FFFFFFF;        m_min_y =  0x7FFFFFFF;        m_max_x = -0x7FFFFFFF;        m_max_y = -0x7FFFFFFF;    }    //------------------------------------------------------------------------    void outline_aa::allocate_block()    {        if(m_cur_block >= m_num_blocks)        {            if(m_num_blocks >= m_max_blocks)            {                cell_aa** new_cells = new cell_aa* [m_max_blocks + cell_block_pool];                if(m_cells)                {                    memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_aa*));                    delete [] m_cells;                }                m_cells = new_cells;                m_max_blocks += cell_block_pool;            }            m_cells[m_num_blocks++] = new cell_aa [unsigned(cell_block_size)];        }        m_cur_cell_ptr = m_cells[m_cur_block++];    }    //------------------------------------------------------------------------    AGG_INLINE void outline_aa::add_cur_cell()    {        if(m_cur_cell.area | m_cur_cell.cover)        {            if((m_num_cells & cell_block_mask) == 0)            {                if(m_num_blocks >= cell_block_limit) return;                allocate_block();            }            *m_cur_cell_ptr++ = m_cur_cell;            ++m_num_cells;            if(m_cur_cell.x < m_min_x) m_min_x = m_cur_cell.x;            if(m_cur_cell.x > m_max_x) m_max_x = m_cur_cell.x;        }    }    //------------------------------------------------------------------------    AGG_INLINE void outline_aa::set_cur_cell(int x, int y)    {        if(m_cur_cell.packed_coord != (y << 16) + x)        {            add_cur_cell();            m_cur_cell.set(x, y, 0, 0);        }    }    //------------------------------------------------------------------------    AGG_INLINE void outline_aa::render_hline(int ey, int x1, int y1, int x2, int y2)    {        int ex1 = x1 >> poly_base_shift;        int ex2 = x2 >> poly_base_shift;        int fx1 = x1 & poly_base_mask;        int fx2 = x2 & poly_base_mask;        int delta, p, first, dx;        int incr, lift, mod, rem;        //trivial case. Happens often        if(y1 == y2)        {            set_cur_cell(ex2, ey);            return;        }        //everything is located in a single cell.  That is easy!        if(ex1 == ex2)        {            delta = y2 - y1;            m_cur_cell.add_cover(delta, (fx1 + fx2) * delta);            return;        }        //ok, we'll have to render a run of adjacent cells on the same        //hline...        p     = (poly_base_size - fx1) * (y2 - y1);        first = poly_base_size;        incr  = 1;        dx = x2 - x1;        if(dx < 0)        {            p     = fx1 * (y2 - y1);            first = 0;            incr  = -1;            dx    = -dx;        }        delta = p / dx;        mod   = p % dx;        if(mod < 0)        {            delta--;            mod += dx;        }        m_cur_cell.add_cover(delta, (fx1 + first) * delta);        ex1 += incr;        set_cur_cell(ex1, ey);        y1  += delta;        if(ex1 != ex2)        {            p     = poly_base_size * (y2 - y1 + delta);            lift  = p / dx;            rem   = p % dx;            if (rem < 0)            {                lift--;                rem += dx;            }            mod -= dx;            while (ex1 != ex2)            {                delta = lift;                mod  += rem;                if(mod >= 0)                {                    mod -= dx;                    delta++;                }                m_cur_cell.add_cover(delta, (poly_base_size) * delta);                y1  += delta;                ex1 += incr;                set_cur_cell(ex1, ey);            }        }        delta = y2 - y1;        m_cur_cell.add_cover(delta, (fx2 + poly_base_size - first) * delta);    }    //------------------------------------------------------------------------    void outline_aa::render_line(int x1, int y1, int x2, int y2)    {        int ey1 = y1 >> poly_base_shift;        int ey2 = y2 >> poly_base_shift;        int fy1 = y1 & poly_base_mask;        int fy2 = y2 & poly_base_mask;        int dx, dy, x_from, x_to;        int p, rem, mod, lift, delta, first, incr;        dx = x2 - x1;        dy = y2 - y1;        //everything is on a single hline        if(ey1 == ey2)        {            render_hline(ey1, x1, fy1, x2, fy2);            return;        }        //Vertical line - we have to calculate start and end cells,        //and then - the common values of the area and coverage for        //all cells of the line. We know exactly there's only one         //cell, so, we don't have to call render_hline().        incr  = 1;        if(dx == 0)        {            int ex = x1 >> poly_base_shift;            int two_fx = (x1 - (ex << poly_base_shift)) << 1;            int area;            first = poly_base_size;            if(dy < 0)            {

⌨️ 快捷键说明

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