Exemplo n.º 1
0
        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);
        }