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));
}
}
|