public void SortCells() { if (m_sorted) { return; //Perform sort only the first time. } AddCurrCell(); m_curr_cell.X = 0x7FFFFFFF; m_curr_cell.Y = 0x7FFFFFFF; m_curr_cell.Cover = 0; m_curr_cell.Area = 0; if (m_num_used_cells == 0) { return; } #if use_timers SortCellsTimer.Start(); #endif // Allocate the array of cell pointers m_sorted_cells.Allocate(m_num_used_cells); // Allocate and zero the Y array m_sorted_y.Allocate((uint)(m_max_y - m_min_y + 1)); m_sorted_y.Zero(); CellAA[] cells = m_cells.Array; sorted_y[] sortedYData = m_sorted_y.Array; CellAA[] sortedCellsData = m_sorted_cells.Array; // Create the Y-histogram (count the numbers of cells for each Y) for (uint i = 0; i < m_num_used_cells; i++) { int Index = cells[i].Y - m_min_y; sortedYData[Index].start++; } // Convert the Y-histogram into the array of starting indexes uint start = 0; uint SortedYSize = m_sorted_y.Size(); for (uint i = 0; i < SortedYSize; i++) { uint v = sortedYData[i].start; sortedYData[i].start = start; start += v; } // Fill the cell pointer array sorted by Y for (uint i = 0; i < m_num_used_cells; i++) { int SortedIndex = cells[i].Y - m_min_y; uint curr_y_start = sortedYData[SortedIndex].start; uint curr_y_num = sortedYData[SortedIndex].num; sortedCellsData[curr_y_start + curr_y_num] = cells[i]; ++sortedYData[SortedIndex].num; } #if use_timers QSortTimer.Start(); #endif // Finally arrange the X-arrays for (uint i = 0; i < SortedYSize; i++) { if (sortedYData[i].num != 0) { m_QSorter.Sort(sortedCellsData, sortedYData[i].start, sortedYData[i].start + sortedYData[i].num - 1); } } #if use_timers QSortTimer.Stop(); #endif m_sorted = true; #if use_timers SortCellsTimer.Stop(); #endif }
// Returns the number of styles public uint SweepStyles() { for (; ;) { if (m_scan_y > m_Rasterizer.MaxY) { return(0); } int num_cells = (int)m_Rasterizer.ScanlineNumCells((uint)m_scan_y); CellAA[] cells; uint cellOffset = 0; int curCellOffset; m_Rasterizer.ScanlineCells((uint)m_scan_y, out cells, out cellOffset); uint num_styles = (uint)(m_max_style - m_min_style + 2); uint style_id; int styleOffset = 0; m_cells.Allocate((uint)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 > 0) { // Pre-add zero (for no-fill style, that is, -1). // We need that to ensure that the "-1 style" would go first. m_asm.Array[0] |= 1; m_ast.Add(0); m_styles.Array[styleOffset].start_cell = 0; m_styles.Array[styleOffset].num_cells = 0; m_styles.Array[styleOffset].last_x = -0x7FFFFFFF; m_sl_start = cells[0].X; m_sl_len = (uint)(cells[num_cells - 1].X - m_sl_start + 1); while (num_cells-- != 0) { curCellOffset = (int)cellOffset++; AddStyle(cells[curCellOffset].Left); AddStyle(cells[curCellOffset].Right); } // Convert the Y-histogram into the array of starting indexes uint i; uint start_cell = 0; StyleInfo[] stylesArray = m_styles.Array; for (i = 0; i < m_ast.Size(); i++) { int IndexToModify = (int)m_ast[i]; uint v = stylesArray[IndexToModify].start_cell; stylesArray[IndexToModify].start_cell = start_cell; start_cell += v; } num_cells = (int)m_Rasterizer.ScanlineNumCells((uint)m_scan_y); m_Rasterizer.ScanlineCells((uint)m_scan_y, out cells, out cellOffset); while (num_cells-- > 0) { curCellOffset = (int)cellOffset++; style_id = (uint)((cells[curCellOffset].Left < 0) ? 0 : cells[curCellOffset].Left - m_min_style + 1); styleOffset = (int)style_id; if (cells[curCellOffset].X == stylesArray[styleOffset].last_x) { cellOffset = stylesArray[styleOffset].start_cell + stylesArray[styleOffset].num_cells - 1; unchecked { cells[cellOffset].Area += cells[curCellOffset].Area; cells[cellOffset].Cover += cells[curCellOffset].Cover; } } else { cellOffset = stylesArray[styleOffset].start_cell + stylesArray[styleOffset].num_cells; cells[cellOffset].X = cells[curCellOffset].X; cells[cellOffset].Area = cells[curCellOffset].Area; cells[cellOffset].Cover = cells[curCellOffset].Cover; stylesArray[styleOffset].last_x = cells[curCellOffset].X; stylesArray[styleOffset].num_cells++; } style_id = (uint)((cells[curCellOffset].Right < 0) ? 0 : cells[curCellOffset].Right - m_min_style + 1); styleOffset = (int)style_id; if (cells[curCellOffset].X == stylesArray[styleOffset].last_x) { cellOffset = stylesArray[styleOffset].start_cell + stylesArray[styleOffset].num_cells - 1; unchecked { cells[cellOffset].Area -= cells[curCellOffset].Area; cells[cellOffset].Cover -= cells[curCellOffset].Cover; } } else { cellOffset = stylesArray[styleOffset].start_cell + stylesArray[styleOffset].num_cells; cells[cellOffset].X = cells[curCellOffset].X; cells[cellOffset].Area = -cells[curCellOffset].Area; cells[cellOffset].Cover = -cells[curCellOffset].Cover; stylesArray[styleOffset].last_x = cells[curCellOffset].X; stylesArray[styleOffset].num_cells++; } } } if (m_ast.Size() > 1) { break; } ++m_scan_y; } ++m_scan_y; if (m_layer_order != LayerOrder.Unsorted) { VectorPODRangeAdaptor ra = new VectorPODRangeAdaptor(m_ast, 1, m_ast.Size() - 1); if (m_layer_order == LayerOrder.Direct) { QuickSortRangeAdaptorUint m_QSorter = new QuickSortRangeAdaptorUint(); m_QSorter.Sort(ra); //quick_sort(ra, uint_greater); } else { throw new System.NotImplementedException(); //QuickSort_range_adaptor_uint m_QSorter = new QuickSort_range_adaptor_uint(); //m_QSorter.Sort(ra); //quick_sort(ra, uint_less); } } return(m_ast.Size() - 1); }