incubator-ooo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From p..@apache.org
Subject svn commit: r1184758 [8/17] - in /incubator/ooo/trunk/main: ./ agg/inc/ agg/source/ solenv/config/
Date Sun, 16 Oct 2011 04:13:21 GMT
Added: incubator/ooo/trunk/main/agg/inc/agg_rasterizer_cells_aa.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_rasterizer_cells_aa.h?rev=1184758&view=auto
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_rasterizer_cells_aa.h (added)
+++ incubator/ooo/trunk/main/agg/inc/agg_rasterizer_cells_aa.h Sun Oct 16 04:13:16 2011
@@ -0,0 +1,754 @@
+//----------------------------------------------------------------------------
+// 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.
+//
+//----------------------------------------------------------------------------
+//
+// 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
+//----------------------------------------------------------------------------
+//
+// 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_RASTERIZER_CELLS_AA_INCLUDED
+#define AGG_RASTERIZER_CELLS_AA_INCLUDED
+
+#include <string.h>
+#include <math.h>
+#include "agg_math.h"
+#include "agg_array.h"
+
+
+namespace agg
+{
+
+    //-----------------------------------------------------rasterizer_cells_aa
+    // An internal class that implements the main rasterization algorithm.
+    // Used in the rasterizer. Should not be used direcly.
+    template<class Cell> class rasterizer_cells_aa
+    {
+        enum cell_block_scale_e
+        {
+            cell_block_shift = 12,
+            cell_block_size  = 1 << cell_block_shift,
+            cell_block_mask  = cell_block_size - 1,
+            cell_block_pool  = 256,
+            cell_block_limit = 1024
+        };
+
+        struct sorted_y
+        {
+            unsigned start;
+            unsigned num;
+        };
+
+    public:
+        typedef Cell cell_type;
+        typedef rasterizer_cells_aa<Cell> self_type;
+
+        ~rasterizer_cells_aa();
+        rasterizer_cells_aa();
+
+        void reset();
+        void style(const cell_type& style_cell);
+        void line(int x1, int y1, int x2, int y2);
+
+        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; }
+
+        void sort_cells();
+
+        unsigned total_cells() const 
+        {
+            return m_num_cells;
+        }
+
+        unsigned scanline_num_cells(unsigned y) const 
+        { 
+            return m_sorted_y[y - m_min_y].num; 
+        }
+
+        const cell_type* const* scanline_cells(unsigned y) const
+        { 
+            return m_sorted_cells.data() + m_sorted_y[y - m_min_y].start; 
+        }
+
+        bool sorted() const { return m_sorted; }
+
+    private:
+        rasterizer_cells_aa(const self_type&);
+        const self_type& operator = (const self_type&);
+
+        void set_curr_cell(int x, int y);
+        void add_curr_cell();
+        void render_hline(int ey, int x1, int y1, int x2, int y2);
+        void allocate_block();
+        
+    private:
+        unsigned                m_num_blocks;
+        unsigned                m_max_blocks;
+        unsigned                m_curr_block;
+        unsigned                m_num_cells;
+        cell_type**             m_cells;
+        cell_type*              m_curr_cell_ptr;
+        pod_vector<cell_type*>  m_sorted_cells;
+        pod_vector<sorted_y>    m_sorted_y;
+        cell_type               m_curr_cell;
+        cell_type               m_style_cell;
+        int                     m_min_x;
+        int                     m_min_y;
+        int                     m_max_x;
+        int                     m_max_y;
+        bool                    m_sorted;
+    };
+
+
+
+
+    //------------------------------------------------------------------------
+    template<class Cell> 
+    rasterizer_cells_aa<Cell>::~rasterizer_cells_aa()
+    {
+        if(m_num_blocks)
+        {
+            cell_type** ptr = m_cells + m_num_blocks - 1;
+            while(m_num_blocks--)
+            {
+                pod_allocator<cell_type>::deallocate(*ptr, cell_block_size);
+                ptr--;
+            }
+            pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks);
+        }
+    }
+
+    //------------------------------------------------------------------------
+    template<class Cell> 
+    rasterizer_cells_aa<Cell>::rasterizer_cells_aa() :
+        m_num_blocks(0),
+        m_max_blocks(0),
+        m_curr_block(0),
+        m_num_cells(0),
+        m_cells(0),
+        m_curr_cell_ptr(0),
+        m_sorted_cells(),
+        m_sorted_y(),
+        m_min_x(0x7FFFFFFF),
+        m_min_y(0x7FFFFFFF),
+        m_max_x(-0x7FFFFFFF),
+        m_max_y(-0x7FFFFFFF),
+        m_sorted(false)
+    {
+        m_style_cell.initial();
+        m_curr_cell.initial();
+    }
+
+    //------------------------------------------------------------------------
+    template<class Cell> 
+    void rasterizer_cells_aa<Cell>::reset()
+    {
+        m_num_cells = 0; 
+        m_curr_block = 0;
+        m_curr_cell.initial();
+        m_style_cell.initial();
+        m_sorted = false;
+        m_min_x =  0x7FFFFFFF;
+        m_min_y =  0x7FFFFFFF;
+        m_max_x = -0x7FFFFFFF;
+        m_max_y = -0x7FFFFFFF;
+    }
+
+    //------------------------------------------------------------------------
+    template<class Cell> 
+    AGG_INLINE void rasterizer_cells_aa<Cell>::add_curr_cell()
+    {
+        if(m_curr_cell.area | m_curr_cell.cover)
+        {
+            if((m_num_cells & cell_block_mask) == 0)
+            {
+                if(m_num_blocks >= cell_block_limit) return;
+                allocate_block();
+            }
+            *m_curr_cell_ptr++ = m_curr_cell;
+            ++m_num_cells;
+        }
+    }
+
+    //------------------------------------------------------------------------
+    template<class Cell> 
+    AGG_INLINE void rasterizer_cells_aa<Cell>::set_curr_cell(int x, int y)
+    {
+        if(m_curr_cell.not_equal(x, y, m_style_cell))
+        {
+            add_curr_cell();
+            m_curr_cell.style(m_style_cell);
+            m_curr_cell.x     = x;
+            m_curr_cell.y     = y;
+            m_curr_cell.cover = 0;
+            m_curr_cell.area  = 0;
+        }
+    }
+
+    //------------------------------------------------------------------------
+    template<class Cell> 
+    AGG_INLINE void rasterizer_cells_aa<Cell>::render_hline(int ey, 
+                                                            int x1, int y1, 
+                                                            int x2, int y2)
+    {
+        int ex1 = x1 >> poly_subpixel_shift;
+        int ex2 = x2 >> poly_subpixel_shift;
+        int fx1 = x1 & poly_subpixel_mask;
+        int fx2 = x2 & poly_subpixel_mask;
+
+        int delta, p, first, dx;
+        int incr, lift, mod, rem;
+
+        //trivial case. Happens often
+        if(y1 == y2)
+        {
+            set_curr_cell(ex2, ey);
+            return;
+        }
+
+        //everything is located in a single cell.  That is easy!
+        if(ex1 == ex2)
+        {
+            delta = y2 - y1;
+            m_curr_cell.cover += delta;
+            m_curr_cell.area  += (fx1 + fx2) * delta;
+            return;
+        }
+
+        //ok, we'll have to render a run of adjacent cells on the same
+        //hline...
+        p     = (poly_subpixel_scale - fx1) * (y2 - y1);
+        first = poly_subpixel_scale;
+        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_curr_cell.cover += delta;
+        m_curr_cell.area  += (fx1 + first) * delta;
+
+        ex1 += incr;
+        set_curr_cell(ex1, ey);
+        y1  += delta;
+
+        if(ex1 != ex2)
+        {
+            p     = poly_subpixel_scale * (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_curr_cell.cover += delta;
+                m_curr_cell.area  += poly_subpixel_scale * delta;
+                y1  += delta;
+                ex1 += incr;
+                set_curr_cell(ex1, ey);
+            }
+        }
+        delta = y2 - y1;
+        m_curr_cell.cover += delta;
+        m_curr_cell.area  += (fx2 + poly_subpixel_scale - first) * delta;
+    }
+
+    //------------------------------------------------------------------------
+    template<class Cell> 
+    AGG_INLINE void rasterizer_cells_aa<Cell>::style(const cell_type& style_cell)
+    { 
+        m_style_cell.style(style_cell); 
+    }
+
+    //------------------------------------------------------------------------
+    template<class Cell> 
+    void rasterizer_cells_aa<Cell>::line(int x1, int y1, int x2, int y2)
+    {
+        enum dx_limit_e { dx_limit = 16384 << poly_subpixel_shift };
+
+        int dx = x2 - x1;
+
+        if(dx >= dx_limit || dx <= -dx_limit)
+        {
+            int cx = (x1 + x2) >> 1;
+            int cy = (y1 + y2) >> 1;
+            line(x1, y1, cx, cy);
+            line(cx, cy, x2, y2);
+        }
+
+        int dy = y2 - y1;
+        int ex1 = x1 >> poly_subpixel_shift;
+        int ex2 = x2 >> poly_subpixel_shift;
+        int ey1 = y1 >> poly_subpixel_shift;
+        int ey2 = y2 >> poly_subpixel_shift;
+        int fy1 = y1 & poly_subpixel_mask;
+        int fy2 = y2 & poly_subpixel_mask;
+
+        int x_from, x_to;
+        int p, rem, mod, lift, delta, first, incr;
+
+        if(ex1 < m_min_x) m_min_x = ex1;
+        if(ex1 > m_max_x) m_max_x = ex1;
+        if(ey1 < m_min_y) m_min_y = ey1;
+        if(ey1 > m_max_y) m_max_y = ey1;
+        if(ex2 < m_min_x) m_min_x = ex2;
+        if(ex2 > m_max_x) m_max_x = ex2;
+        if(ey2 < m_min_y) m_min_y = ey2;
+        if(ey2 > m_max_y) m_max_y = ey2;
+
+        set_curr_cell(ex1, ey1);
+
+        //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_subpixel_shift;
+            int two_fx = (x1 - (ex << poly_subpixel_shift)) << 1;
+            int area;
+
+            first = poly_subpixel_scale;
+            if(dy < 0)
+            {
+                first = 0;
+                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 = 
+                    pod_allocator<cell_type*>::allocate(m_max_blocks + 
+                                                        cell_block_pool);
+
+                if(m_cells)
+                {
+                    memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_type*));
+                    pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks);
+                }
+                m_cells = new_cells;
+                m_max_blocks += cell_block_pool;
+            }
+
+            m_cells[m_num_blocks++] = 
+                pod_allocator<cell_type>::allocate(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

Added: incubator/ooo/trunk/main/agg/inc/agg_rasterizer_compound_aa.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_rasterizer_compound_aa.h?rev=1184758&view=auto
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_rasterizer_compound_aa.h (added)
+++ incubator/ooo/trunk/main/agg/inc/agg_rasterizer_compound_aa.h Sun Oct 16 04:13:16 2011
@@ -0,0 +1,698 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// 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_RASTERIZER_COMPOUND_AA_INCLUDED
+#define AGG_RASTERIZER_COMPOUND_AA_INCLUDED
+
+#include "agg_rasterizer_cells_aa.h"
+#include "agg_rasterizer_sl_clip.h"
+
+namespace agg
+{
+
+    //-----------------------------------------------------------cell_style_aa
+    // A pixel cell. There're no constructors defined and it was done 
+    // intentionally in order to avoid extra overhead when allocating an 
+    // array of cells.
+    struct cell_style_aa
+    {
+        int   x;
+        int   y;
+        int   cover;
+        int   area;
+        int16 left, right;
+
+        void initial()
+        {
+            x     = 0x7FFFFFFF;
+            y     = 0x7FFFFFFF;
+            cover = 0;
+            area  = 0;
+            left  = -1;
+            right = -1;
+        }
+
+        void style(const cell_style_aa& c)
+        {
+            left  = c.left;
+            right = c.right;
+        }
+
+        int not_equal(int ex, int ey, const cell_style_aa& c) const
+        {
+            return (ex - x) | (ey - y) | (left - c.left) | (right - c.right);
+        }
+    };
+
+
+    //===========================================================layer_order_e
+    enum layer_order_e
+    {
+        layer_unsorted, //------layer_unsorted
+        layer_direct,   //------layer_direct
+        layer_inverse   //------layer_inverse
+    };
+
+
+    //==================================================rasterizer_compound_aa
+    template<class Clip=rasterizer_sl_clip_int> class rasterizer_compound_aa
+    {
+        struct style_info 
+        { 
+            unsigned start_cell;
+            unsigned num_cells;
+            int      last_x;
+        };
+
+        struct cell_info
+        {
+            int x, area, cover; 
+        };
+
+    public:
+        typedef Clip                      clip_type;
+        typedef typename Clip::conv_type  conv_type;
+        typedef typename Clip::coord_type coord_type;
+
+        enum aa_scale_e
+        {
+            aa_shift  = 8,
+            aa_scale  = 1 << aa_shift,
+            aa_mask   = aa_scale - 1,
+            aa_scale2 = aa_scale * 2,
+            aa_mask2  = aa_scale2 - 1
+        };
+
+        //--------------------------------------------------------------------
+        rasterizer_compound_aa() : 
+            m_outline(),
+            m_clipper(),
+            m_filling_rule(fill_non_zero),
+            m_layer_order(layer_direct),
+            m_styles(),  // Active Styles
+            m_ast(),     // Active Style Table (unique values)
+            m_asm(),     // Active Style Mask 
+            m_cells(),
+            m_cover_buf(),
+            m_master_alpha(),
+            m_min_style(0x7FFFFFFF),
+            m_max_style(-0x7FFFFFFF),
+            m_start_x(0),
+            m_start_y(0),
+            m_scan_y(0x7FFFFFFF),
+            m_sl_start(0),
+            m_sl_len(0)
+        {}
+
+        //--------------------------------------------------------------------
+        void reset(); 
+        void reset_clipping();
+        void clip_box(double x1, double y1, double x2, double y2);
+        void filling_rule(filling_rule_e filling_rule);
+        void layer_order(layer_order_e order);
+        void master_alpha(int style, double alpha);
+
+        //--------------------------------------------------------------------
+        void styles(int left, int right);
+        void move_to(int x, int y);
+        void line_to(int x, int y);
+        void move_to_d(double x, double y);
+        void line_to_d(double x, double y);
+        void add_vertex(double x, double y, unsigned cmd);
+
+        void edge(int x1, int y1, int x2, int y2);
+        void edge_d(double x1, double y1, double x2, double y2);
+
+        //-------------------------------------------------------------------
+        template<class VertexSource>
+        void add_path(VertexSource& vs, unsigned path_id=0)
+        {
+            double x;
+            double y;
+
+            unsigned cmd;
+            vs.rewind(path_id);
+            if(m_outline.sorted()) reset();
+            while(!is_stop(cmd = vs.vertex(&x, &y)))
+            {
+                add_vertex(x, y, cmd);
+            }
+        }
+
+        
+        //--------------------------------------------------------------------
+        int min_x()     const { return m_outline.min_x(); }
+        int min_y()     const { return m_outline.min_y(); }
+        int max_x()     const { return m_outline.max_x(); }
+        int max_y()     const { return m_outline.max_y(); }
+        int min_style() const { return m_min_style; }
+        int max_style() const { return m_max_style; }
+
+        //--------------------------------------------------------------------
+        void sort();
+        bool rewind_scanlines();
+        unsigned sweep_styles();
+        int      scanline_start()  const { return m_sl_start; }
+        unsigned scanline_length() const { return m_sl_len;   }
+        unsigned style(unsigned style_idx) const;
+
+        cover_type* allocate_cover_buffer(unsigned len);
+
+        //--------------------------------------------------------------------
+        bool navigate_scanline(int y); 
+        bool hit_test(int tx, int ty);
+
+        //--------------------------------------------------------------------
+        AGG_INLINE unsigned calculate_alpha(int area, unsigned master_alpha) const
+        {
+            int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
+            if(cover < 0) cover = -cover;
+            if(m_filling_rule == fill_even_odd)
+            {
+                cover &= aa_mask2;
+                if(cover > aa_scale)
+                {
+                    cover = aa_scale2 - cover;
+                }
+            }
+            if(cover > aa_mask) cover = aa_mask;
+            return (cover * master_alpha + aa_mask) >> aa_shift;
+        }
+
+        //--------------------------------------------------------------------
+        // Sweeps one scanline with one style index. The style ID can be 
+        // determined by calling style(). 
+        template<class Scanline> bool sweep_scanline(Scanline& sl, int style_idx)
+        {
+            int scan_y = m_scan_y - 1;
+            if(scan_y > m_outline.max_y()) return false;
+
+            sl.reset_spans();
+
+            unsigned master_alpha = aa_mask;
+
+            if(style_idx < 0) 
+            {
+                style_idx = 0;
+            }
+            else 
+            {
+                style_idx++;
+                master_alpha = m_master_alpha[m_ast[style_idx] + m_min_style - 1];
+            }
+
+            const style_info& st = m_styles[m_ast[style_idx]];
+
+            unsigned num_cells = st.num_cells;
+            cell_info* cell = &m_cells[st.start_cell];
+
+            int cover = 0;
+            while(num_cells--)
+            {
+                unsigned alpha;
+                int x = cell->x;
+                int area = cell->area;
+
+                cover += cell->cover;
+
+                ++cell;
+
+                if(area)
+                {
+                    alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area,
+                                            master_alpha);
+                    sl.add_cell(x, alpha);
+                    x++;
+                }
+
+                if(num_cells && cell->x > x)
+                {
+                    alpha = calculate_alpha(cover << (poly_subpixel_shift + 1),
+                                            master_alpha);
+                    if(alpha)
+                    {
+                        sl.add_span(x, cell->x - x, alpha);
+                    }
+                }
+            }
+
+            if(sl.num_spans() == 0) return false;
+            sl.finalize(scan_y);
+            return true;
+        }
+
+    private:
+        void add_style(int style_id);
+        void allocate_master_alpha();
+
+        //--------------------------------------------------------------------
+        // Disable copying
+        rasterizer_compound_aa(const rasterizer_compound_aa<Clip>&);
+        const rasterizer_compound_aa<Clip>& 
+        operator = (const rasterizer_compound_aa<Clip>&);
+
+    private:
+        rasterizer_cells_aa<cell_style_aa> m_outline;
+        clip_type              m_clipper;
+        filling_rule_e         m_filling_rule;
+        layer_order_e          m_layer_order;
+        pod_vector<style_info> m_styles;  // Active Styles
+        pod_vector<unsigned>   m_ast;     // Active Style Table (unique values)
+        pod_vector<int8u>      m_asm;     // Active Style Mask 
+        pod_vector<cell_info>  m_cells;
+        pod_vector<cover_type> m_cover_buf;
+        pod_bvector<unsigned>  m_master_alpha;
+
+        int        m_min_style;
+        int        m_max_style;
+        coord_type m_start_x;
+        coord_type m_start_y;
+        int        m_scan_y;
+        int        m_sl_start;
+        unsigned   m_sl_len;
+    };
+
+
+
+
+
+
+
+
+
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::reset() 
+    { 
+        m_outline.reset(); 
+        m_min_style =  0x7FFFFFFF;
+        m_max_style = -0x7FFFFFFF;
+        m_scan_y    =  0x7FFFFFFF;
+        m_sl_start  =  0;
+        m_sl_len    = 0;
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::filling_rule(filling_rule_e filling_rule) 
+    { 
+        m_filling_rule = filling_rule; 
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::layer_order(layer_order_e order)
+    {
+        m_layer_order = order;
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::clip_box(double x1, double y1, 
+                                                double x2, double y2)
+    {
+        reset();
+        m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1), 
+                           conv_type::upscale(x2), conv_type::upscale(y2));
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::reset_clipping()
+    {
+        reset();
+        m_clipper.reset_clipping();
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::styles(int left, int right)
+    {
+        cell_style_aa cell;
+        cell.initial();
+        cell.left = (int16)left;
+        cell.right = (int16)right;
+        m_outline.style(cell);
+        if(left  >= 0 && left  < m_min_style) m_min_style = left;
+        if(left  >= 0 && left  > m_max_style) m_max_style = left;
+        if(right >= 0 && right < m_min_style) m_min_style = right;
+        if(right >= 0 && right > m_max_style) m_max_style = right;
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::move_to(int x, int y)
+    {
+        if(m_outline.sorted()) reset();
+        m_clipper.move_to(m_start_x = conv_type::downscale(x), 
+                          m_start_y = conv_type::downscale(y));
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::line_to(int x, int y)
+    {
+        m_clipper.line_to(m_outline, 
+                          conv_type::downscale(x), 
+                          conv_type::downscale(y));
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::move_to_d(double x, double y) 
+    { 
+        if(m_outline.sorted()) reset();
+        m_clipper.move_to(m_start_x = conv_type::upscale(x), 
+                          m_start_y = conv_type::upscale(y)); 
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::line_to_d(double x, double y) 
+    { 
+        m_clipper.line_to(m_outline, 
+                          conv_type::upscale(x), 
+                          conv_type::upscale(y)); 
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::add_vertex(double x, double y, unsigned cmd)
+    {
+        if(is_move_to(cmd)) 
+        {
+            move_to_d(x, y);
+        }
+        else 
+        if(is_vertex(cmd))
+        {
+            line_to_d(x, y);
+        }
+        else
+        if(is_close(cmd))
+        {
+            m_clipper.line_to(m_outline, m_start_x, m_start_y);
+        }
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::edge(int x1, int y1, int x2, int y2)
+    {
+        if(m_outline.sorted()) reset();
+        m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
+        m_clipper.line_to(m_outline, 
+                          conv_type::downscale(x2), 
+                          conv_type::downscale(y2));
+    }
+    
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::edge_d(double x1, double y1, 
+                                              double x2, double y2)
+    {
+        if(m_outline.sorted()) reset();
+        m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1)); 
+        m_clipper.line_to(m_outline, 
+                          conv_type::upscale(x2), 
+                          conv_type::upscale(y2)); 
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    AGG_INLINE void rasterizer_compound_aa<Clip>::sort()
+    {
+        m_outline.sort_cells();
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    AGG_INLINE bool rasterizer_compound_aa<Clip>::rewind_scanlines()
+    {
+        m_outline.sort_cells();
+        if(m_outline.total_cells() == 0) 
+        {
+            return false;
+        }
+        if(m_max_style < m_min_style)
+        {
+            return false;
+        }
+        m_scan_y = m_outline.min_y();
+        m_styles.allocate(m_max_style - m_min_style + 2, 128);
+        allocate_master_alpha();
+        return true;
+    }
+
+    //------------------------------------------------------------------------
+    template<class Clip> 
+    AGG_INLINE void rasterizer_compound_aa<Clip>::add_style(int style_id)
+    {
+        if(style_id < 0) style_id  = 0;
+        else             style_id -= m_min_style - 1;
+
+        unsigned nbyte = style_id >> 3;
+        unsigned mask = 1 << (style_id & 7);
+
+        style_info* style = &m_styles[style_id];
+        if((m_asm[nbyte] & mask) == 0)
+        {
+            m_ast.add(style_id);
+            m_asm[nbyte] |= mask;
+            style->start_cell = 0;
+            style->num_cells = 0;
+            style->last_x = -0x7FFFFFFF;
+        }
+        ++style->start_cell;
+    }
+
+    //------------------------------------------------------------------------
+    // Returns the number of styles
+    template<class Clip> 
+    unsigned rasterizer_compound_aa<Clip>::sweep_styles()
+    {
+        for(;;)
+        {
+            if(m_scan_y > m_outline.max_y()) return 0;
+            unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
+            const cell_style_aa* const* cells = m_outline.scanline_cells(m_scan_y);
+            unsigned num_styles = m_max_style - m_min_style + 2;
+            const cell_style_aa* curr_cell;
+            unsigned style_id;
+            style_info* style;
+            cell_info* cell;
+
+            m_cells.allocate(num_cells * 2, 256); // Each cell can have two styles
+            m_ast.capacity(num_styles, 64);
+            m_asm.allocate((num_styles + 7) >> 3, 8);
+            m_asm.zero();
+
+            if(num_cells)
+            {
+                // Pre-add zero (for no-fill style, that is, -1).
+                // We need that to ensure that the "-1 style" would go first.
+                m_asm[0] |= 1; 
+                m_ast.add(0);
+                style = &m_styles[0];
+                style->start_cell = 0;
+                style->num_cells = 0;
+                style->last_x = -0x7FFFFFFF;
+
+                m_sl_start = cells[0]->x;
+                m_sl_len   = cells[num_cells-1]->x - m_sl_start + 1;
+                while(num_cells--)
+                {
+                    curr_cell = *cells++;
+                    add_style(curr_cell->left);
+                    add_style(curr_cell->right);
+                }
+
+                // Convert the Y-histogram into the array of starting indexes
+                unsigned i;
+                unsigned start_cell = 0;
+                for(i = 0; i < m_ast.size(); i++)
+                {
+                    style_info& st = m_styles[m_ast[i]];
+                    unsigned v = st.start_cell;
+                    st.start_cell = start_cell;
+                    start_cell += v;
+                }
+
+                cells = m_outline.scanline_cells(m_scan_y);
+                num_cells = m_outline.scanline_num_cells(m_scan_y);
+
+                while(num_cells--)
+                {
+                    curr_cell = *cells++;
+                    style_id = (curr_cell->left < 0) ? 0 : 
+                                curr_cell->left - m_min_style + 1;
+
+                    style = &m_styles[style_id];
+                    if(curr_cell->x == style->last_x)
+                    {
+                        cell = &m_cells[style->start_cell + style->num_cells - 1];
+                        cell->area  += curr_cell->area;
+                        cell->cover += curr_cell->cover;
+                    }
+                    else
+                    {
+                        cell = &m_cells[style->start_cell + style->num_cells];
+                        cell->x       = curr_cell->x;
+                        cell->area    = curr_cell->area;
+                        cell->cover   = curr_cell->cover;
+                        style->last_x = curr_cell->x;
+                        style->num_cells++;
+                    }
+
+                    style_id = (curr_cell->right < 0) ? 0 : 
+                                curr_cell->right - m_min_style + 1;
+
+                    style = &m_styles[style_id];
+                    if(curr_cell->x == style->last_x)
+                    {
+                        cell = &m_cells[style->start_cell + style->num_cells - 1];
+                        cell->area  -= curr_cell->area;
+                        cell->cover -= curr_cell->cover;
+                    }
+                    else
+                    {
+                        cell = &m_cells[style->start_cell + style->num_cells];
+                        cell->x       =  curr_cell->x;
+                        cell->area    = -curr_cell->area;
+                        cell->cover   = -curr_cell->cover;
+                        style->last_x =  curr_cell->x;
+                        style->num_cells++;
+                    }
+                }
+            }
+            if(m_ast.size() > 1) break;
+            ++m_scan_y;
+        }
+        ++m_scan_y;
+
+        if(m_layer_order != layer_unsorted)
+        {
+            range_adaptor<pod_vector<unsigned> > ra(m_ast, 1, m_ast.size() - 1);
+            if(m_layer_order == layer_direct) quick_sort(ra, unsigned_greater);
+            else                              quick_sort(ra, unsigned_less);
+        }
+
+        return m_ast.size() - 1;
+    }
+
+    //------------------------------------------------------------------------
+    // Returns style ID depending of the existing style index
+    template<class Clip> 
+    AGG_INLINE 
+    unsigned rasterizer_compound_aa<Clip>::style(unsigned style_idx) const
+    {
+        return m_ast[style_idx + 1] + m_min_style - 1;
+    }
+
+    //------------------------------------------------------------------------ 
+    template<class Clip> 
+    AGG_INLINE bool rasterizer_compound_aa<Clip>::navigate_scanline(int y)
+    {
+        m_outline.sort_cells();
+        if(m_outline.total_cells() == 0) 
+        {
+            return false;
+        }
+        if(m_max_style < m_min_style)
+        {
+            return false;
+        }
+        if(y < m_outline.min_y() || y > m_outline.max_y()) 
+        {
+            return false;
+        }
+        m_scan_y = y;
+        m_styles.allocate(m_max_style - m_min_style + 2, 128);
+        allocate_master_alpha();
+        return true;
+    }
+    
+    //------------------------------------------------------------------------ 
+    template<class Clip> 
+    bool rasterizer_compound_aa<Clip>::hit_test(int tx, int ty)
+    {
+        if(!navigate_scanline(ty)) 
+        {
+            return false;
+        }
+
+        unsigned num_styles = sweep_styles(); 
+        if(num_styles <= 0)
+        {
+            return false;
+        }
+
+        scanline_hit_test sl(tx);
+        sweep_scanline(sl, -1);
+        return sl.hit();
+    }
+
+    //------------------------------------------------------------------------ 
+    template<class Clip> 
+    cover_type* rasterizer_compound_aa<Clip>::allocate_cover_buffer(unsigned len)
+    {
+        m_cover_buf.allocate(len, 256);
+        return &m_cover_buf[0];
+    }
+
+    //------------------------------------------------------------------------ 
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::allocate_master_alpha()
+    {
+        while((int)m_master_alpha.size() <= m_max_style)
+        {
+            m_master_alpha.add(aa_mask);
+        }
+    }
+
+    //------------------------------------------------------------------------ 
+    template<class Clip> 
+    void rasterizer_compound_aa<Clip>::master_alpha(int style, double alpha)
+    {
+        if(style >= 0)
+        {
+            while((int)m_master_alpha.size() <= style)
+            {
+                m_master_alpha.add(aa_mask);
+            }
+            m_master_alpha[style] = uround(alpha * aa_mask);
+        }
+    }
+
+}
+
+
+
+#endif
+

Modified: incubator/ooo/trunk/main/agg/inc/agg_rasterizer_outline.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_rasterizer_outline.h?rev=1184758&r1=1184757&r2=1184758&view=diff
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_rasterizer_outline.h (original)
+++ incubator/ooo/trunk/main/agg/inc/agg_rasterizer_outline.h Sun Oct 16 04:13:16 2011
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// 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 
@@ -23,13 +23,14 @@ namespace agg
     template<class Renderer> class rasterizer_outline
     {
     public:
-        rasterizer_outline(Renderer& ren) : 
+        explicit rasterizer_outline(Renderer& ren) : 
             m_ren(&ren), 
             m_start_x(0), 
             m_start_y(0), 
             m_vertices(0)
-        {
-        }
+        {}
+        void attach(Renderer& ren) { m_ren = &ren; }
+
 
         //--------------------------------------------------------------------
         void move_to(int x, int y)
@@ -90,13 +91,13 @@ namespace agg
 
         //--------------------------------------------------------------------
         template<class VertexSource>
-        void add_path(VertexSource& vs, unsigned id=0)
+        void add_path(VertexSource& vs, unsigned path_id=0)
         {
             double x;
             double y;
 
             unsigned cmd;
-            vs.rewind(id);
+            vs.rewind(path_id);
             while(!is_stop(cmd = vs.vertex(&x, &y)))
             {
                 add_vertex(x, y, cmd);
@@ -108,13 +109,13 @@ namespace agg
         template<class VertexSource, class ColorStorage, class PathId>
         void render_all_paths(VertexSource& vs, 
                               const ColorStorage& colors, 
-                              const PathId& id,
+                              const PathId& path_id,
                               unsigned num_paths)
         {
             for(unsigned i = 0; i < num_paths; i++)
             {
                 m_ren->line_color(colors[i]);
-                add_path(vs, id[i]);
+                add_path(vs, path_id[i]);
             }
         }
 

Modified: incubator/ooo/trunk/main/agg/inc/agg_rasterizer_outline_aa.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_rasterizer_outline_aa.h?rev=1184758&r1=1184757&r2=1184758&view=diff
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_rasterizer_outline_aa.h (original)
+++ incubator/ooo/trunk/main/agg/inc/agg_rasterizer_outline_aa.h Sun Oct 16 04:13:16 2011
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// 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 
@@ -49,16 +49,23 @@ namespace agg
         {
             double dx = val.x - x;
             double dy = val.y - y;
-            return (len = int(sqrt(dx * dx + dy * dy))) > 
-                   (line_subpixel_size + line_subpixel_size / 2);
+            return (len = uround(sqrt(dx * dx + dy * dy))) > 
+                   (line_subpixel_scale + line_subpixel_scale / 2);
         }
     };
 
 
-
+    //----------------------------------------------------------outline_aa_join_e
+    enum outline_aa_join_e
+    {
+        outline_no_join,             //-----outline_no_join
+        outline_miter_join,          //-----outline_miter_join
+        outline_round_join,          //-----outline_round_join
+        outline_miter_accurate_join  //-----outline_accurate_join
+    };
 
     //=======================================================rasterizer_outline_aa
-    template<class Renderer> class rasterizer_outline_aa
+    template<class Renderer, class Coord=line_coord> class rasterizer_outline_aa
     {
     private:
         //------------------------------------------------------------------------
@@ -78,21 +85,25 @@ namespace agg
         typedef line_aa_vertex                  vertex_type;
         typedef vertex_sequence<vertex_type, 6> vertex_storage_type;
 
-        rasterizer_outline_aa(Renderer& ren) : 
-            m_ren(ren), 
-            m_accurate_join(m_ren.accurate_join_only()),
+        explicit rasterizer_outline_aa(Renderer& ren) : 
+            m_ren(&ren), 
+            m_line_join(ren.accurate_join_only() ? 
+                            outline_miter_accurate_join : 
+                            outline_round_join),
             m_round_cap(false),
             m_start_x(0),
             m_start_y(0)
-        {
-        }
+        {}
+        void attach(Renderer& ren) { m_ren = &ren; }
 
         //------------------------------------------------------------------------
-        void accurate_join(bool v) 
+        void line_join(outline_aa_join_e join) 
         { 
-            m_accurate_join = m_ren.accurate_join_only() ? true : v; 
+            m_line_join = m_ren->accurate_join_only() ? 
+                outline_miter_accurate_join : 
+                join; 
         }
-        bool accurate_join() const { return m_accurate_join; }
+        bool line_join() const { return m_line_join; }
 
         //------------------------------------------------------------------------
         void round_cap(bool v) { m_round_cap = v; }
@@ -113,13 +124,13 @@ namespace agg
         //------------------------------------------------------------------------
         void move_to_d(double x, double y)
         {
-            move_to(line_coord(x), line_coord(y));
+            move_to(Coord::conv(x), Coord::conv(y));
         }
 
         //------------------------------------------------------------------------
         void line_to_d(double x, double y)
         {
-            line_to(line_coord(x), line_coord(y));
+            line_to(Coord::conv(x), Coord::conv(y));
         }
 
         //------------------------------------------------------------------------
@@ -152,13 +163,13 @@ namespace agg
 
         //------------------------------------------------------------------------
         template<class VertexSource>
-        void add_path(VertexSource& vs, unsigned id=0)
+        void add_path(VertexSource& vs, unsigned path_id=0)
         {
             double x;
             double y;
 
             unsigned cmd;
-            vs.rewind(id);
+            vs.rewind(path_id);
             while(!is_stop(cmd = vs.vertex(&x, &y)))
             {
                 add_vertex(x, y, cmd);
@@ -171,13 +182,13 @@ namespace agg
         template<class VertexSource, class ColorStorage, class PathId>
         void render_all_paths(VertexSource& vs, 
                               const ColorStorage& colors, 
-                              const PathId& id,
+                              const PathId& path_id,
                               unsigned num_paths)
         {
             for(unsigned i = 0; i < num_paths; i++)
             {
-                m_ren.color(colors[i]);
-                add_path(vs, id[i]);
+                m_ren->color(colors[i]);
+                add_path(vs, path_id[i]);
             }
         }
 
@@ -188,22 +199,22 @@ namespace agg
             unsigned i;
             for(i = 0; i < c.num_paths(); i++)
             {
-                m_ren.color(c.color(i));
+                m_ren->color(c.color(i));
                 add_path(c, i);
             }
         }
 
     private:
-        rasterizer_outline_aa(const rasterizer_outline_aa<Renderer>&);
-        const rasterizer_outline_aa<Renderer>& operator = 
-            (const rasterizer_outline_aa<Renderer>&);
+        rasterizer_outline_aa(const rasterizer_outline_aa<Renderer, Coord>&);
+        const rasterizer_outline_aa<Renderer, Coord>& operator = 
+            (const rasterizer_outline_aa<Renderer, Coord>&);
 
-        Renderer& m_ren;
+        Renderer*           m_ren;
         vertex_storage_type m_src_vertices;
-        bool m_accurate_join;
-        bool m_round_cap;
-        int  m_start_x;
-        int  m_start_y;
+        outline_aa_join_e   m_line_join;
+        bool                m_round_cap;
+        int                 m_start_x;
+        int                 m_start_y;
     };
 
 
@@ -214,20 +225,39 @@ namespace agg
 
 
     //----------------------------------------------------------------------------
-    template<class Renderer> 
-    void rasterizer_outline_aa<Renderer>::draw(draw_vars& dv, unsigned start, unsigned end)
+    template<class Renderer, class Coord> 
+    void rasterizer_outline_aa<Renderer, Coord>::draw(draw_vars& dv, 
+                                                      unsigned start, 
+                                                      unsigned end)
     {
         unsigned i;
         const vertex_storage_type::value_type* v;
 
         for(i = start; i < end; i++)
         {
+            if(m_line_join == outline_round_join)
+            {
+                dv.xb1 = dv.curr.x1 + (dv.curr.y2 - dv.curr.y1); 
+                dv.yb1 = dv.curr.y1 - (dv.curr.x2 - dv.curr.x1); 
+                dv.xb2 = dv.curr.x2 + (dv.curr.y2 - dv.curr.y1); 
+                dv.yb2 = dv.curr.y2 - (dv.curr.x2 - dv.curr.x1);
+            }
+
             switch(dv.flags)
             {
-            case 0: m_ren.line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2); break;
-            case 1: m_ren.line2(dv.curr, dv.xb2, dv.yb2); break;
-            case 2: m_ren.line1(dv.curr, dv.xb1, dv.yb1); break;
-            case 3: m_ren.line0(dv.curr); break;
+            case 0: m_ren->line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2); break;
+            case 1: m_ren->line2(dv.curr, dv.xb2, dv.yb2); break;
+            case 2: m_ren->line1(dv.curr, dv.xb1, dv.yb1); break;
+            case 3: m_ren->line0(dv.curr); break;
+            }
+
+            if(m_line_join == outline_round_join && (dv.flags & 2) == 0)
+            {
+                m_ren->pie(dv.curr.x2, dv.curr.y2, 
+                           dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
+                           dv.curr.y2 - (dv.curr.x2 - dv.curr.x1),
+                           dv.curr.x2 + (dv.next.y2 - dv.next.y1),
+                           dv.curr.y2 - (dv.next.x2 - dv.next.x1));
             }
 
             dv.x1 = dv.x2;
@@ -247,20 +277,32 @@ namespace agg
             dv.xb1 = dv.xb2;
             dv.yb1 = dv.yb2;
 
-            if(m_accurate_join)
-            {
-                dv.flags = 0;
-            }
-            else
+            switch(m_line_join)
             {
+            case outline_no_join:
+                dv.flags = 3;
+                break;
+
+            case outline_miter_join:
                 dv.flags >>= 1;
                 dv.flags |= ((dv.curr.diagonal_quadrant() == 
                               dv.next.diagonal_quadrant()) << 1);
-            }
+                if((dv.flags & 2) == 0)
+                {
+                    bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
+                }
+                break;
 
-            if((dv.flags & 2) == 0)
-            {
+            case outline_round_join:
+                dv.flags >>= 1;
+                dv.flags |= ((dv.curr.diagonal_quadrant() == 
+                              dv.next.diagonal_quadrant()) << 1);
+                break;
+
+            case outline_miter_accurate_join:
+                dv.flags = 0;
                 bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
+                break;
             }
         }
     }
@@ -269,8 +311,8 @@ namespace agg
 
 
     //----------------------------------------------------------------------------
-    template<class Renderer> 
-    void rasterizer_outline_aa<Renderer>::render(bool close_polygon)
+    template<class Renderer, class Coord> 
+    void rasterizer_outline_aa<Renderer, Coord>::render(bool close_polygon)
     {
         m_src_vertices.close(close_polygon);
         draw_vars dv;
@@ -314,23 +356,30 @@ namespace agg
                 dv.xb2 = 0;
                 dv.yb2 = 0;
 
-                if(m_accurate_join)
-                {
-                    dv.flags = 0;
-                }
-                else
+                switch(m_line_join)
                 {
+                case outline_no_join:
+                    dv.flags = 3;
+                    break;
+
+                case outline_miter_join:
+                case outline_round_join:
                     dv.flags = 
                             (prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
                         ((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
+                    break;
+
+                case outline_miter_accurate_join:
+                    dv.flags = 0;
+                    break;
                 }
 
-                if((dv.flags & 1) == 0)
+                if((dv.flags & 1) == 0 && m_line_join != outline_round_join)
                 {
                     bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
                 }
 
-                if((dv.flags & 2) == 0)
+                if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
                 {
                     bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
                 }
@@ -357,16 +406,16 @@ namespace agg
                     line_parameters lp(x1, y1, x2, y2, lprev);
                     if(m_round_cap) 
                     {
-                        m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
+                        m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
                     }
-                    m_ren.line3(lp, 
-                                x1 + (y2 - y1), 
-                                y1 - (x2 - x1),
-                                x2 + (y2 - y1), 
-                                y2 - (x2 - x1));
+                    m_ren->line3(lp, 
+                                 x1 + (y2 - y1), 
+                                 y1 - (x2 - x1),
+                                 x2 + (y2 - y1), 
+                                 y2 - (x2 - x1));
                     if(m_round_cap) 
                     {
-                        m_ren.semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1));
+                        m_ren->semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1));
                     }
                 }
                 break;
@@ -388,26 +437,35 @@ namespace agg
                     y3    = v->y;
                     line_parameters lp1(x1, y1, x2, y2, lprev);
                     line_parameters lp2(x2, y2, x3, y3, lnext);
-                    bisectrix(lp1, lp2, &dv.xb1, &dv.yb1);
 
                     if(m_round_cap) 
                     {
-                        m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
+                        m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
+                    }
+
+                    if(m_line_join == outline_round_join)
+                    {
+                        m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1), 
+                                          x2 + (y2 - y1), y2 - (x2 - x1));
+
+                        m_ren->pie(x2, y2, x2 + (y2 - y1), y2 - (x2 - x1),
+                                           x2 + (y3 - y2), y2 - (x3 - x2));
+
+                        m_ren->line3(lp2, x2 + (y3 - y2), y2 - (x3 - x2),
+                                          x3 + (y3 - y2), y3 - (x3 - x2));
+                    }
+                    else
+                    {
+                        bisectrix(lp1, lp2, &dv.xb1, &dv.yb1);
+                        m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1),
+                                          dv.xb1,         dv.yb1);
+
+                        m_ren->line3(lp2, dv.xb1,         dv.yb1,
+                                          x3 + (y3 - y2), y3 - (x3 - x2));
                     }
-                    m_ren.line3(lp1, 
-                                x1 + (y2 - y1), 
-                                y1 - (x2 - x1),
-                                dv.xb1, 
-                                dv.yb1);
-
-                    m_ren.line3(lp2, 
-                                dv.xb1,
-                                dv.yb1,
-                                x3 + (y3 - y2), 
-                                y3 - (x3 - x2));
                     if(m_round_cap) 
                     {
-                        m_ren.semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2));
+                        m_ren->semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2));
                     }
                 }
                 break;
@@ -443,37 +501,53 @@ namespace agg
                     dv.xb2 = 0;
                     dv.yb2 = 0;
 
-                    if(m_accurate_join)
-                    {
-                        dv.flags = 0;
-                    }
-                    else
+                    switch(m_line_join)
                     {
+                    case outline_no_join:
+                        dv.flags = 3;
+                        break;
+
+                    case outline_miter_join:
+                    case outline_round_join:
                         dv.flags = 
                                 (prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
                             ((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
+                        break;
+
+                    case outline_miter_accurate_join:
+                        dv.flags = 0;
+                        break;
                     }
 
-                    if((dv.flags & 1) == 0)
+                    if(m_round_cap) 
                     {
-                        bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
-                        m_ren.line3(prev, 
-                                    x1 + (y2 - y1), 
-                                    y1 - (x2 - x1),
-                                    dv.xb1, 
-                                    dv.yb1);
+                        m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
                     }
-                    else
+                    if((dv.flags & 1) == 0)
                     {
-                        m_ren.line1(prev, 
-                                    x1 + (y2 - y1), 
-                                    y1 - (x2 - x1));
+                        if(m_line_join == outline_round_join)
+                        {
+                            m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1),
+                                               x2 + (y2 - y1), y2 - (x2 - x1));
+                            m_ren->pie(prev.x2, prev.y2, 
+                                       x2 + (y2 - y1), y2 - (x2 - x1),
+                                       dv.curr.x1 + (dv.curr.y2 - dv.curr.y1), 
+                                       dv.curr.y1 - (dv.curr.x2 - dv.curr.x1));
+                        }
+                        else
+                        {
+                            bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
+                            m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1),
+                                               dv.xb1,         dv.yb1);
+                        }
                     }
-                    if(m_round_cap) 
+                    else
                     {
-                        m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
+                        m_ren->line1(prev, 
+                                     x1 + (y2 - y1), 
+                                     y1 - (x2 - x1));
                     }
-                    if((dv.flags & 2) == 0)
+                    if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
                     {
                         bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
                     }
@@ -482,23 +556,32 @@ namespace agg
 
                     if((dv.flags & 1) == 0)
                     {
-                        m_ren.line3(dv.curr, 
-                                    dv.xb1, 
-                                    dv.yb1,
-                                    dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), 
-                                    dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
+                        if(m_line_join == outline_round_join)
+                        {
+                            m_ren->line3(dv.curr, 
+                                         dv.curr.x1 + (dv.curr.y2 - dv.curr.y1), 
+                                         dv.curr.y1 - (dv.curr.x2 - dv.curr.x1),
+                                         dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), 
+                                         dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
+                        }
+                        else
+                        {
+                            m_ren->line3(dv.curr, dv.xb1, dv.yb1,
+                                         dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), 
+                                         dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
+                        }
                     }
                     else
                     {
-                        m_ren.line2(dv.curr, 
-                                    dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), 
-                                    dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
+                        m_ren->line2(dv.curr, 
+                                     dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), 
+                                     dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
                     }
                     if(m_round_cap) 
                     {
-                        m_ren.semidot(cmp_dist_end, dv.curr.x2, dv.curr.y2,
-                                      dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
-                                      dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
+                        m_ren->semidot(cmp_dist_end, dv.curr.x2, dv.curr.y2,
+                                       dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
+                                       dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
                     }
 
                 }



Mime
View raw message