1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// XYQ: 2006-01-22 Copied from AGG project. 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This file uses only integer data, so it's suitable for all platforms. 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Anti-Grain Geometry - Version 2.3 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Permission to copy, use, modify, sell and distribute this software 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// is granted provided this copyright notice appears in all copies. 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This software is provided "as is" without express or implied 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// warranty, and with no claim as to its suitability for any purpose. 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The author gratefully acknowleges the support of David Turner, 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// libray - in producing this work. See http://www.freetype.org for details. 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Contact: mcseem@antigrain.com 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// mcseemagg@yahoo.com 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// http://www.antigrain.com 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Adaptation for 32-bit screen coordinates has been sponsored by 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Liberty Technology Systems, Inc., visit http://lib-sys.com 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Liberty Technology Systems, Inc. is the provider of 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// PostScript and PDF technology for software developers. 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Class outline_aa - implementation. 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Initially the rendering algorithm was designed by David Turner and the 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// other authors of the FreeType library - see the above notice. I nearly 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// created a similar renderer, but still I was far from David's work. 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// I completely redesigned the original code and adapted it for Anti-Grain 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ideas. Two functions - render_line and render_hline are the core of 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// the algorithm - they calculate the exact coverage of each pixel cell 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// of the polygon. I left these functions almost as is, because there's 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// no way to improve the perfection - hats off to David and his group! 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// All other code is very different from the original. 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../../include/fxcrt/fx_ext.h" 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <limits.h> 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "agg_rasterizer_scanline_aa.h" 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovnamespace agg 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovAGG_INLINE void cell_aa::set_cover(int c, int a) 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cover = c; 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov area = a; 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovAGG_INLINE void cell_aa::add_cover(int c, int a) 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cover += c; 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov area += a; 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovAGG_INLINE void cell_aa::set_coord(int cx, int cy) 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x = cx; 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = cy; 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovAGG_INLINE void cell_aa::set(int cx, int cy, int c, int a) 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x = cx; 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = cy; 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cover = c; 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov area = a; 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovoutline_aa::~outline_aa() 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_num_blocks) { 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_aa** ptr = m_cells + m_num_blocks - 1; 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(m_num_blocks--) { 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(*ptr); 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ptr--; 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(m_cells); 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovoutline_aa::outline_aa() : 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_num_blocks(0), 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_max_blocks(0), 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_block(0), 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_num_cells(0), 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cells(0), 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_cell_ptr(0), 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_x(0), 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_y(0), 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_min_x(0x7FFFFFFF), 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_min_y(0x7FFFFFFF), 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_max_x(-0x7FFFFFFF), 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_max_y(-0x7FFFFFFF), 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_sorted(false) 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_cell.set(0x7FFF, 0x7FFF, 0, 0); 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid outline_aa::reset() 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_num_cells = 0; 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_block = 0; 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_cell.set(0x7FFF, 0x7FFF, 0, 0); 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_sorted = false; 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_min_x = 0x7FFFFFFF; 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_min_y = 0x7FFFFFFF; 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_max_x = -0x7FFFFFFF; 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_max_y = -0x7FFFFFFF; 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid outline_aa::allocate_block() 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_cur_block >= m_num_blocks) { 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_num_blocks >= m_max_blocks) { 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_aa** new_cells = FX_Alloc( cell_aa*, m_max_blocks + cell_block_pool); 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!new_cells) { 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_cells) { 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXSYS_memcpy32(new_cells, m_cells, m_max_blocks * sizeof(cell_aa*)); 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(m_cells); 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cells = new_cells; 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_max_blocks += cell_block_pool; 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cells[m_num_blocks++] = FX_Alloc(cell_aa, cell_block_size); 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!m_cells[m_num_blocks - 1]) { 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_cell_ptr = m_cells[m_cur_block++]; 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovAGG_INLINE void outline_aa::add_cur_cell() 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_cur_cell.area | m_cur_cell.cover) { 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if((m_num_cells & cell_block_mask) == 0) { 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_num_blocks >= cell_block_limit) { 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov allocate_block(); 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *m_cur_cell_ptr++ = m_cur_cell; 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++m_num_cells; 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovAGG_INLINE void outline_aa::set_cur_cell(int x, int y) 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_cur_cell.x != x || m_cur_cell.y != y) { 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov add_cur_cell(); 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_cell.set(x, y, 0, 0); 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(x < m_min_x) { 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_min_x = x; 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(x > m_max_x) { 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_max_x = x; 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(y < m_min_y) { 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_min_y = y; 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(y > m_max_y) { 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_max_y = y; 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovAGG_INLINE void outline_aa::render_hline(int ey, int x1, int y1, int x2, int y2) 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int ex1 = x1 >> poly_base_shift; 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int ex2 = x2 >> poly_base_shift; 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int fx1 = x1 & poly_base_mask; 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int fx2 = x2 & poly_base_mask; 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int delta, p, first, dx; 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int incr, lift, mod, rem; 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(y1 == y2) { 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov set_cur_cell(ex2, ey); 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(ex1 == ex2) { 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = y2 - y1; 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_cell.add_cover(delta, (fx1 + fx2) * delta); 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = (poly_base_size - fx1) * (y2 - y1); 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = poly_base_size; 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov incr = 1; 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx = x2 - x1; 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(dx < 0) { 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = fx1 * (y2 - y1); 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = 0; 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov incr = -1; 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx = -dx; 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = p / dx; 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod = p % dx; 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(mod < 0) { 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta--; 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod += dx; 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_cell.add_cover(delta, (fx1 + first) * delta); 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ex1 += incr; 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov set_cur_cell(ex1, ey); 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y1 += delta; 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(ex1 != ex2) { 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = poly_base_size * (y2 - y1 + delta); 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov lift = p / dx; 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rem = p % dx; 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (rem < 0) { 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov lift--; 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rem += dx; 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod -= dx; 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while (ex1 != ex2) { 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = lift; 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod += rem; 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(mod >= 0) { 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod -= dx; 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta++; 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_cell.add_cover(delta, (poly_base_size) * delta); 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y1 += delta; 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ex1 += incr; 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov set_cur_cell(ex1, ey); 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = y2 - y1; 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_cell.add_cover(delta, (fx2 + poly_base_size - first) * delta); 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid outline_aa::render_line(int x1, int y1, int x2, int y2) 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov enum dx_limit_e { dx_limit = 16384 << poly_base_shift }; 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int dx = x2 - x1; 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(dx >= dx_limit || dx <= -dx_limit) { 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int cx = (x1 + x2) >> 1; 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int cy = (y1 + y2) >> 1; 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov render_line(x1, y1, cx, cy); 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov render_line(cx, cy, x2, y2); 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int dy = y2 - y1; 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int ey1 = y1 >> poly_base_shift; 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int ey2 = y2 >> poly_base_shift; 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int fy1 = y1 & poly_base_mask; 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int fy2 = y2 & poly_base_mask; 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int x_from, x_to; 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int p, rem, mod, lift, delta, first, incr; 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(ey1 == ey2) { 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov render_hline(ey1, x1, fy1, x2, fy2); 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov incr = 1; 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(dx == 0) { 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int ex = x1 >> poly_base_shift; 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int two_fx = (x1 - (ex << poly_base_shift)) << 1; 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int area; 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = poly_base_size; 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(dy < 0) { 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = 0; 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov incr = -1; 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_from = x1; 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = first - fy1; 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_cell.add_cover(delta, two_fx * delta); 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ey1 += incr; 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov set_cur_cell(ex, ey1); 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = first + first - poly_base_size; 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov area = two_fx * delta; 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(ey1 != ey2) { 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_cell.set_cover(delta, area); 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ey1 += incr; 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov set_cur_cell(ex, ey1); 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = fy2 - poly_base_size + first; 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_cell.add_cover(delta, two_fx * delta); 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = (poly_base_size - fy1) * dx; 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = poly_base_size; 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(dy < 0) { 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = fy1 * dx; 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = 0; 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov incr = -1; 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dy = -dy; 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = p / dy; 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod = p % dy; 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(mod < 0) { 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta--; 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod += dy; 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_from = x1 + delta; 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov render_hline(ey1, x1, fy1, x_from, first); 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ey1 += incr; 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov set_cur_cell(x_from >> poly_base_shift, ey1); 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(ey1 != ey2) { 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = poly_base_size * dx; 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov lift = p / dy; 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rem = p % dy; 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(rem < 0) { 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov lift--; 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rem += dy; 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod -= dy; 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(ey1 != ey2) { 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = lift; 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod += rem; 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mod >= 0) { 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod -= dy; 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta++; 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_to = x_from + delta; 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov render_hline(ey1, x_from, poly_base_size - first, x_to, first); 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_from = x_to; 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ey1 += incr; 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov set_cur_cell(x_from >> poly_base_shift, ey1); 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov render_hline(ey1, x_from, poly_base_size - first, x2, fy2); 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid outline_aa::move_to(int x, int y) 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_sorted) { 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov reset(); 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov set_cur_cell(x >> poly_base_shift, y >> poly_base_shift); 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_x = x; 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_y = y; 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid outline_aa::line_to(int x, int y) 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov render_line(m_cur_x, m_cur_y, x, y); 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_x = x; 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_cur_y = y; 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_sorted = false; 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtemplate <class T> static AGG_INLINE void swap_cells(T* a, T* b) 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T temp = *a; 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *a = *b; 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *b = temp; 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovenum { 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov qsort_threshold = 9 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}; 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void qsort_cells(cell_aa** start, unsigned num) 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_aa** stack[80]; 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_aa*** top; 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_aa** limit; 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_aa** base; 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = start + num; 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base = start; 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top = stack; 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (;;) { 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int len = int(limit - base); 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_aa** i; 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_aa** j; 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_aa** pivot; 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(len > qsort_threshold) { 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pivot = base + len / 2; 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov swap_cells(base, pivot); 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i = base + 1; 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov j = limit - 1; 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if((*j)->x < (*i)->x) { 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov swap_cells(i, j); 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if((*base)->x < (*i)->x) { 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov swap_cells(base, i); 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if((*j)->x < (*base)->x) { 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov swap_cells(base, j); 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for(;;) { 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int x = (*base)->x; 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do { 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i++; 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } while( (*i)->x < x ); 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do { 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov j--; 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } while( x < (*j)->x ); 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(i > j) { 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov swap_cells(i, j); 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov swap_cells(base, j); 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(j - base > limit - i) { 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top[0] = base; 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top[1] = j; 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base = i; 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top[0] = i; 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top[1] = limit; 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = j; 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top += 2; 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov j = base; 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i = j + 1; 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for(; i < limit; j = i, i++) { 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for(; j[1]->x < (*j)->x; j--) { 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov swap_cells(j + 1, j); 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (j == base) { 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(top > stack) { 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top -= 2; 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base = top[0]; 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = top[1]; 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid outline_aa::sort_cells() 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_sorted) { 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov add_cur_cell(); 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_num_cells == 0) { 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_sorted_cells.allocate(m_num_cells, 16); 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (m_max_y > 0 && m_min_y < 0 && -m_min_y > INT_MAX - m_max_y) { 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned size = m_max_y - m_min_y; 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (size + 1 < size) { 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size++; 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_sorted_y.allocate(size, 16); 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_sorted_y.zero(); 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_aa** block_ptr = m_cells; 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_aa* cell_ptr = NULL; 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned nb = m_num_cells >> cell_block_shift; 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned i; 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(nb--) { 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_ptr = *block_ptr++; 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i = cell_block_size; 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(i--) { 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_sorted_y[cell_ptr->y - m_min_y].start++; 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++cell_ptr; 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i = m_num_cells & cell_block_mask; 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (i) { 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_ptr = *block_ptr++; 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(i--) { 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_sorted_y[cell_ptr->y - m_min_y].start++; 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++cell_ptr; 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned start = 0; 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for(i = 0; i < m_sorted_y.size(); i++) { 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned v = m_sorted_y[i].start; 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_sorted_y[i].start = start; 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start += v; 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov block_ptr = m_cells; 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nb = m_num_cells >> cell_block_shift; 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(nb--) { 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_ptr = *block_ptr++; 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i = cell_block_size; 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(i--) { 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sorted_y& cur_y = m_sorted_y[cell_ptr->y - m_min_y]; 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_sorted_cells[cur_y.start + cur_y.num] = cell_ptr; 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++cur_y.num; 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++cell_ptr; 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i = m_num_cells & cell_block_mask; 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (i) { 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_ptr = *block_ptr++; 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(i--) { 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sorted_y& cur_y = m_sorted_y[cell_ptr->y - m_min_y]; 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_sorted_cells[cur_y.start + cur_y.num] = cell_ptr; 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++cur_y.num; 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++cell_ptr; 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for(i = 0; i < m_sorted_y.size(); i++) { 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const sorted_y& cur_y = m_sorted_y[i]; 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(cur_y.num) { 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov qsort_cells(m_sorted_cells.data() + cur_y.start, cur_y.num); 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_sorted = true; 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 496