void 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.Array[style] = agg_basics.uround(alpha * aa_mask);
     }
 }
        // Returns the number of styles
        public int sweep_styles()
        {
            for (;;)
            {
                if (m_scan_y > m_Rasterizer.max_y())
                {
                    return(0);
                }
                int       num_cells = (int)m_Rasterizer.scanline_num_cells(m_scan_y);
                cell_aa[] cells;
                int       cellOffset = 0;
                int       curCellOffset;
                m_Rasterizer.scanline_cells(m_scan_y, out cells, out cellOffset);
                int num_styles = (int)(m_max_style - m_min_style + 2);
                int style_id;
                int styleOffset = 0;

                m_cells.Allocate((int)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   = (int)(cells[num_cells - 1].x - m_sl_start + 1);
                    while (num_cells-- != 0)
                    {
                        curCellOffset = (int)cellOffset++;
                        add_style(cells[curCellOffset].left);
                        add_style(cells[curCellOffset].right);
                    }

                    // Convert the Y-histogram into the array of starting indexes
                    int          i;
                    int          start_cell  = 0;
                    style_info[] stylesArray = m_styles.Array;
                    for (i = 0; i < m_ast.size(); i++)
                    {
                        int IndexToModify = (int)m_ast[i];
                        int v             = stylesArray[IndexToModify].start_cell;
                        stylesArray[IndexToModify].start_cell = start_cell;
                        start_cell += v;
                    }

                    num_cells = (int)m_Rasterizer.scanline_num_cells(m_scan_y);
                    m_Rasterizer.scanline_cells(m_scan_y, out cells, out cellOffset);

                    while (num_cells-- > 0)
                    {
                        curCellOffset = (int)cellOffset++;
                        style_id      = (int)((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 = (int)((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 != layer_order_e.layer_unsorted)
            {
                VectorPOD_RangeAdaptor ra = new VectorPOD_RangeAdaptor(m_ast, 1, m_ast.size() - 1);
                if (m_layer_order == layer_order_e.layer_direct)
                {
                    QuickSort_range_adaptor_uint m_QSorter = new QuickSort_range_adaptor_uint();
                    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);
        }
            public void generate(int cols, int rows,
                                 double cell_w, double cell_h,
                                 double start_x, double start_y)
            {
                m_cols    = cols;
                m_rows    = rows;
                m_cell_w  = cell_w;
                m_cell_h  = cell_h;
                m_start_x = start_x;
                m_start_y = start_y;

                m_vertices.remove_all();
                for (int i = 0; i < m_rows; i++)
                {
                    double x = start_x;
                    for (int j = 0; j < m_cols; j++)
                    {
                        double     dx = random(-0.5, 0.5);
                        double     dy = random(-0.5, 0.5);
                        RGBA_Bytes c  = new RGBA_Bytes(rand.Next() & 0xFF, rand.Next() & 0xFF, rand.Next() & 0xFF);
                        RGBA_Bytes dc = new RGBA_Bytes(rand.Next() & 1, rand.Next() & 1, rand.Next() & 1);
                        m_vertices.add(new mesh_point(x, start_y, dx, dy, c, dc));
                        x += cell_w;
                    }
                    start_y += cell_h;
                }

                //  4---3
                //  |t2/|
                //  | / |
                //  |/t1|
                //  1---2
                m_triangles.remove_all();
                m_edges.remove_all();
                for (int i = 0; i < m_rows - 1; i++)
                {
                    for (int j = 0; j < m_cols - 1; j++)
                    {
                        int p1 = i * m_cols + j;
                        int p2 = p1 + 1;
                        int p3 = p2 + m_cols;
                        int p4 = p1 + m_cols;
                        m_triangles.add(new mesh_triangle((int)p1, (int)p2, (int)p3));
                        m_triangles.add(new mesh_triangle((int)p3, (int)p4, (int)p1));

                        int curr_cell = i * (m_cols - 1) + j;
                        int left_cell = j != 0 ? (int)(curr_cell - 1) : -1;
                        int bott_cell = i != 0 ? (int)(curr_cell - (m_cols - 1)) : -1;

                        int curr_t1 = curr_cell * 2;
                        int curr_t2 = curr_t1 + 1;

                        int left_t1 = (left_cell >= 0) ? left_cell * 2 : -1;
                        int left_t2 = (left_cell >= 0) ? left_t1 + 1 : -1;

                        int bott_t1 = (bott_cell >= 0) ? bott_cell * 2 : -1;
                        int bott_t2 = (bott_cell >= 0) ? bott_t1 + 1 : -1;

                        m_edges.add(new mesh_edge((int)p1, (int)p2, curr_t1, bott_t2));
                        m_edges.add(new mesh_edge((int)p1, (int)p3, curr_t2, curr_t1));
                        m_edges.add(new mesh_edge((int)p1, (int)p4, left_t1, curr_t2));

                        if (j == m_cols - 2)                         // Last column
                        {
                            m_edges.add(new mesh_edge((int)p2, (int)p3, curr_t1, -1));
                        }

                        if (i == m_rows - 2)                         // Last row
                        {
                            m_edges.add(new mesh_edge((int)p3, (int)p4, curr_t2, -1));
                        }
                    }
                }
            }