agg_rasterizer_cells_aa.h

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

H
754
字号
                incr  = -1;            }            x_from = x1;            //render_hline(ey1, x_from, fy1, x_from, first);            delta = first - fy1;            m_curr_cell.cover += delta;            m_curr_cell.area  += two_fx * delta;            ey1 += incr;            set_curr_cell(ex, ey1);            delta = first + first - poly_subpixel_scale;            area = two_fx * delta;            while(ey1 != ey2)            {                //render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, first);                m_curr_cell.cover = delta;                m_curr_cell.area  = area;                ey1 += incr;                set_curr_cell(ex, ey1);            }            //render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, fy2);            delta = fy2 - poly_subpixel_scale + first;            m_curr_cell.cover += delta;            m_curr_cell.area  += two_fx * delta;            return;        }        //ok, we have to render several hlines        p     = (poly_subpixel_scale - fy1) * dx;        first = poly_subpixel_scale;        if(dy < 0)        {            p     = fy1 * dx;            first = 0;            incr  = -1;            dy    = -dy;        }        delta = p / dy;        mod   = p % dy;        if(mod < 0)        {            delta--;            mod += dy;        }        x_from = x1 + delta;        render_hline(ey1, x1, fy1, x_from, first);        ey1 += incr;        set_curr_cell(x_from >> poly_subpixel_shift, ey1);        if(ey1 != ey2)        {            p     = poly_subpixel_scale * dx;            lift  = p / dy;            rem   = p % dy;            if(rem < 0)            {                lift--;                rem += dy;            }            mod -= dy;            while(ey1 != ey2)            {                delta = lift;                mod  += rem;                if (mod >= 0)                {                    mod -= dy;                    delta++;                }                x_to = x_from + delta;                render_hline(ey1, x_from, poly_subpixel_scale - first, x_to, first);                x_from = x_to;                ey1 += incr;                set_curr_cell(x_from >> poly_subpixel_shift, ey1);            }        }        render_hline(ey1, x_from, poly_subpixel_scale - first, x2, fy2);    }    //------------------------------------------------------------------------    template<class Cell>     void rasterizer_cells_aa<Cell>::allocate_block()    {        if(m_curr_block >= m_num_blocks)        {            if(m_num_blocks >= m_max_blocks)            {                cell_type** new_cells = new cell_type* [m_max_blocks + cell_block_pool];                if(m_cells)                {                    memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_type*));                    delete [] m_cells;                }                m_cells = new_cells;                m_max_blocks += cell_block_pool;            }            m_cells[m_num_blocks++] = new cell_type [unsigned(cell_block_size)];        }        m_curr_cell_ptr = m_cells[m_curr_block++];    }    //------------------------------------------------------------------------    template <class T> static AGG_INLINE void swap_cells(T* a, T* b)    {        T temp = *a;        *a = *b;        *b = temp;    }    //------------------------------------------------------------------------    enum    {        qsort_threshold = 9    };    //------------------------------------------------------------------------    template<class Cell>    void qsort_cells(Cell** start, unsigned num)    {        Cell**  stack[80];        Cell*** top;         Cell**  limit;        Cell**  base;        limit = start + num;        base  = start;        top   = stack;        for (;;)        {            int len = int(limit - base);            Cell** i;            Cell** j;            Cell** pivot;            if(len > qsort_threshold)            {                // we use base + len/2 as the pivot                pivot = base + len / 2;                swap_cells(base, pivot);                i = base + 1;                j = limit - 1;                // now ensure that *i <= *base <= *j                 if((*j)->x < (*i)->x)                {                    swap_cells(i, j);                }                if((*base)->x < (*i)->x)                {                    swap_cells(base, i);                }                if((*j)->x < (*base)->x)                {                    swap_cells(base, j);                }                for(;;)                {                    int x = (*base)->x;                    do i++; while( (*i)->x < x );                    do j--; while( x < (*j)->x );                    if(i > j)                    {                        break;                    }                    swap_cells(i, j);                }                swap_cells(base, j);                // now, push the largest sub-array                if(j - base > limit - i)                {                    top[0] = base;                    top[1] = j;                    base   = i;                }                else                {                    top[0] = i;                    top[1] = limit;                    limit  = j;                }                top += 2;            }            else            {                // the sub-array is small, perform insertion sort                j = base;                i = j + 1;                for(; i < limit; j = i, i++)                {                    for(; j[1]->x < (*j)->x; j--)                    {                        swap_cells(j + 1, j);                        if (j == base)                        {                            break;                        }                    }                }                if(top > stack)                {                    top  -= 2;                    base  = top[0];                    limit = top[1];                }                else                {                    break;                }            }        }    }    //------------------------------------------------------------------------    template<class Cell>     void rasterizer_cells_aa<Cell>::sort_cells()    {        if(m_sorted) return; //Perform sort only the first time.        add_curr_cell();        m_curr_cell.x     = 0x7FFFFFFF;        m_curr_cell.y     = 0x7FFFFFFF;        m_curr_cell.cover = 0;        m_curr_cell.area  = 0;        if(m_num_cells == 0) return;// DBG: Check to see if min/max works well.//for(unsigned nc = 0; nc < m_num_cells; nc++)//{//    cell_type* cell = m_cells[nc >> cell_block_shift] + (nc & cell_block_mask);//    if(cell->x < m_min_x || //       cell->y < m_min_y || //       cell->x > m_max_x || //       cell->y > m_max_y)//    {//        cell = cell; // Breakpoint here//    }//}        // Allocate the array of cell pointers        m_sorted_cells.allocate(m_num_cells, 16);        // Allocate and zero the Y array        m_sorted_y.allocate(m_max_y - m_min_y + 1, 16);        m_sorted_y.zero();        // Create the Y-histogram (count the numbers of cells for each Y)        cell_type** block_ptr = m_cells;        cell_type*  cell_ptr;        unsigned nb = m_num_cells >> cell_block_shift;        unsigned i;        while(nb--)        {            cell_ptr = *block_ptr++;            i = cell_block_size;            while(i--)             {                m_sorted_y[cell_ptr->y - m_min_y].start++;                ++cell_ptr;            }        }        cell_ptr = *block_ptr++;        i = m_num_cells & cell_block_mask;        while(i--)         {            m_sorted_y[cell_ptr->y - m_min_y].start++;            ++cell_ptr;        }        // Convert the Y-histogram into the array of starting indexes        unsigned start = 0;        for(i = 0; i < m_sorted_y.size(); i++)        {            unsigned v = m_sorted_y[i].start;            m_sorted_y[i].start = start;            start += v;        }        // Fill the cell pointer array sorted by Y        block_ptr = m_cells;        nb = m_num_cells >> cell_block_shift;        while(nb--)        {            cell_ptr = *block_ptr++;            i = cell_block_size;            while(i--)             {                sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y];                m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr;                ++curr_y.num;                ++cell_ptr;            }        }                cell_ptr = *block_ptr++;        i = m_num_cells & cell_block_mask;        while(i--)         {            sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y];            m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr;            ++curr_y.num;            ++cell_ptr;        }        // Finally arrange the X-arrays        for(i = 0; i < m_sorted_y.size(); i++)        {            const sorted_y& curr_y = m_sorted_y[i];            if(curr_y.num)            {                qsort_cells(m_sorted_cells.data() + curr_y.start, curr_y.num);            }        }        m_sorted = true;    }    //------------------------------------------------------scanline_hit_test    class scanline_hit_test    {    public:        scanline_hit_test(int x) : m_x(x), m_hit(false) {}        void reset_spans() {}        void finalize(int) {}        void add_cell(int x, int)        {            if(m_x == x) m_hit = true;        }        void add_span(int x, int len, int)        {            if(m_x >= x && m_x < x+len) m_hit = true;        }        unsigned num_spans() const { return 1; }        bool hit() const { return m_hit; }    private:        int  m_x;        bool m_hit;    };}#endif

⌨️ 快捷键说明

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