///<summary>
 ///</summary>
 ///<returns></returns>
 public bool RewindScanlines()
 {
     _rasterizer.SortCells();
     if (_rasterizer.TotalCells == 0)
     {
         return(false);
     }
     if (_maxStyle < _minStyle)
     {
         return(false);
     }
     _scanY = _rasterizer.MinY();
     _activeStyles.Allocate((uint)(_maxStyle - _minStyle + 2), 128);
     AllocateMasterAlpha();
     return(true);
 }
Ejemplo n.º 2
0
        //======================================================render_scanline_aa
        private static void GenerateAndRenderSingleScanline(IScanline sl, IPixelFormat ren,
                                SpanAllocator alloc, ISpanGenerator span_gen)
        {
            int y = sl.y();
            uint num_spans = sl.NumberOfSpans;
            ScanlineSpan scanlineSpan = sl.Begin;

            byte[] ManagedCoversArray = sl.GetCovers();
            unsafe
            {
                fixed (byte* pCovers = ManagedCoversArray)
                {
                    for (; ; )
                    {
                        int x = scanlineSpan.x;
                        int len = scanlineSpan.len;
                        if(len < 0) len = -len;

                        if(tempSpanColors.Capacity() < len)
                        {
                            tempSpanColors.Allocate((uint)(len));
                        }

                        fixed (RGBA_Bytes* pColors = tempSpanColors.Array)
                        {
                            span_gen.Generate(pColors, x, y, (uint)len);
#if use_timers
                            blend_color_hspan.Start();
#endif
                            ren.BlendHorizontalColorSpan(x, y, (uint)len, pColors, (scanlineSpan.len < 0) ? null : &pCovers[scanlineSpan.cover_index], pCovers[scanlineSpan.cover_index]);
#if use_timers
                            blend_color_hspan.Stop();
#endif
                        }

                        if (--num_spans == 0) break;
                        scanlineSpan = sl.GetNextScanlineSpan();
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public void SortCells()
        {
            if (m_sorted)
            {
                return;                       //Perform Sort only the first time.
            }
            AddCurrentCell();
            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();
            AntiAliasingCell[] cells           = m_cells.Array;
            SortedY[]          sortedYData     = m_sorted_y.Array;
            AntiAliasingCell[] 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 IsSorted 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
        }
 byte[] AllocateCoverBuffer(uint len)
 {
     _coverBuffer.Allocate(len, 256);
     return(_coverBuffer.Array);
 }
        ///<summary>
        ///</summary>
        ///<returns></returns>
        ///<exception cref="NotImplementedException"></exception>
        public uint SweepStyles()
        {
            for (; ;)
            {
                if (_scanY > _rasterizer.MaxY())
                {
                    return(0);
                }
                int numCells = (int)_rasterizer.ScanlineNumCells((uint)_scanY);
                AntiAliasingCell[] cells;
                uint cellOffset;
                _rasterizer.ScanlineCells((uint)_scanY, out cells, out cellOffset);
                uint numStyles   = (uint)(_maxStyle - _minStyle + 2);
                int  styleOffset = 0;

                _cells.Allocate((uint)numCells * 2, 256);                 // Each cell can have two Styles
                _activeStyleTable.Capacity(numStyles, 64);
                _activeStyleMask.Allocate((numStyles + 7) >> 3, 8);
                _activeStyleMask.Zero();

                if (numCells > 0)
                {
                    // Pre-Add zero (for no-fill Style, that is, -1).
                    // We need that to ensure that the "-1 Style" would go first.
                    _activeStyleMask.Array[0] |= 1;
                    _activeStyleTable.Add(0);
                    _activeStyles.Array[styleOffset].StartCell = 0;
                    _activeStyles.Array[styleOffset].NumCells  = 0;
                    _activeStyles.Array[styleOffset].LastX     = -0x7FFFFFFF;

                    _scanlineStart  = cells[0].x;
                    _scanlineLength = (uint)(cells[numCells - 1].x - _scanlineStart + 1);
                    int curCellOffset;
                    while (numCells-- != 0)
                    {
                        curCellOffset = (int)cellOffset++;
                        AddStyle(cells[curCellOffset].left);
                        AddStyle(cells[curCellOffset].right);
                    }

                    // Convert the Y-histogram into the array of starting indexes
                    uint        i             = 0u;
                    uint        startCell     = 0;
                    StyleInfo[] stylesArray   = _activeStyles.Array;
                    int         indexToModify = (int)_activeStyleTable[i];
                    for (i = 0; i < _activeStyleTable.Size(); i++)
                    {
                        uint v = stylesArray[indexToModify].StartCell;
                        stylesArray[indexToModify].StartCell = startCell;
                        startCell += v;
                    }

                    numCells = (int)_rasterizer.ScanlineNumCells((uint)_scanY);
                    _rasterizer.ScanlineCells((uint)_scanY, out cells, out cellOffset);

                    while (numCells-- > 0)
                    {
                        curCellOffset = (int)cellOffset;
                        uint styleId = (uint)((cells[curCellOffset].left < 0) ? 0 :
                                              cells[curCellOffset].left - _minStyle + 1);

                        styleOffset = (int)styleId;
                        if (cells[curCellOffset].x == stylesArray[styleOffset].LastX)
                        {
                            cellOffset = stylesArray[styleOffset].StartCell + stylesArray[styleOffset].NumCells - 1;
                            unchecked
                            {
                                cells[cellOffset].area  += cells[curCellOffset].area;
                                cells[cellOffset].cover += cells[curCellOffset].cover;
                            }
                        }
                        else
                        {
                            cellOffset                     = stylesArray[styleOffset].StartCell + stylesArray[styleOffset].NumCells;
                            cells[cellOffset].x            = cells[curCellOffset].x;
                            cells[cellOffset].area         = cells[curCellOffset].area;
                            cells[cellOffset].cover        = cells[curCellOffset].cover;
                            stylesArray[styleOffset].LastX = cells[curCellOffset].x;
                            stylesArray[styleOffset].NumCells++;
                        }

                        styleId = (uint)((cells[curCellOffset].right < 0) ? 0 :
                                         cells[curCellOffset].right - _minStyle + 1);

                        styleOffset = (int)styleId;
                        if (cells[curCellOffset].x == stylesArray[styleOffset].LastX)
                        {
                            cellOffset = stylesArray[styleOffset].StartCell + stylesArray[styleOffset].NumCells - 1;
                            unchecked
                            {
                                cells[cellOffset].area  -= cells[curCellOffset].area;
                                cells[cellOffset].cover -= cells[curCellOffset].cover;
                            }
                        }
                        else
                        {
                            cellOffset                     = stylesArray[styleOffset].StartCell + stylesArray[styleOffset].NumCells;
                            cells[cellOffset].x            = cells[curCellOffset].x;
                            cells[cellOffset].area         = -cells[curCellOffset].area;
                            cells[cellOffset].cover        = -cells[curCellOffset].cover;
                            stylesArray[styleOffset].LastX = cells[curCellOffset].x;
                            stylesArray[styleOffset].NumCells++;
                        }
                    }
                }
                if (_activeStyleTable.Size() > 1)
                {
                    break;
                }
                ++_scanY;
            }
            ++_scanY;

            if (_layerOrder != ELayerOrder.LayerUnsorted)
            {
                VectorPOD_RangeAdaptor ra = new VectorPOD_RangeAdaptor(_activeStyleTable, 1, _activeStyleTable.Size() - 1);
                if (_layerOrder == ELayerOrder.LayerDirect)
                {
                    QuickSortRangeAdaptorUint mQSorter = new QuickSortRangeAdaptorUint();
                    mQSorter.Sort(ra);
                    //quick_sort(ra, uint_greater);
                }
                else
                {
                    throw new NotImplementedException();
                    //QuickSortRangeAdaptorUint m_QSorter = new QuickSortRangeAdaptorUint();
                    //m_QSorter.Sort(ra);
                    //quick_sort(ra, uint_less);
                }
            }

            return(_activeStyleTable.Size() - 1);
        }
Ejemplo n.º 6
0
Archivo: Blur.cs Proyecto: djlw78/Mosa
        public void BlurX(IPixelFormat img, double radius)
        {
            if (radius < 0.62)
            {
                return;
            }
            if (img.Width < 3)
            {
                return;
            }

            double s = (double)(radius * 0.5);
            double q = (double)((s < 2.5) ?
                                3.97156 - 4.14554 * Math.Sqrt(1 - 0.26891 * s) :
                                0.98711 * s - 0.96330);

            double q2 = (double)(q * q);
            double q3 = (double)(q2 * q);

            double b0 = (double)(1.0 / (1.578250 +
                                        2.444130 * q +
                                        1.428100 * q2 +
                                        0.422205 * q3));

            double b1 = (double)(2.44413 * q +
                                 2.85619 * q2 +
                                 1.26661 * q3);

            double b2 = (double)(-1.42810 * q2 +
                                 -1.26661 * q3);

            double b3 = (double)(0.422205 * q3);

            double b = (double)(1 - (b1 + b2 + b3) * b0);

            b1 *= b0;
            b2 *= b0;
            b3 *= b0;

            uint w = img.Width;
            uint h = img.Height;
            int  wm = (int)w - 1;
            int  x, y;

            int StartCreatingAt = (int)m_sum1.Size();

            m_sum1.Resize(w);
            m_sum2.Resize(w);
            m_buf.Allocate(w);

            RecursizeBlurCalculator[] Sum1Array = m_sum1.Array;
            RecursizeBlurCalculator[] Sum2Array = m_sum2.Array;
            RGBA_Bytes[] BufferArray            = m_buf.Array;

            for (int i = StartCreatingAt; i < w; i++)
            {
                Sum1Array[i] = m_RecursizeBlurCalculatorFactory.CreateNew();
                Sum2Array[i] = m_RecursizeBlurCalculatorFactory.CreateNew();
            }

            for (y = 0; y < h; y++)
            {
                RecursizeBlurCalculator c = m_RecursizeBlurCalculatorFactory;
                c.FromPixel(img.Pixel(0, y));
                Sum1Array[0].Calculate(b, b1, b2, b3, c, c, c, c);
                c.FromPixel(img.Pixel(1, y));
                Sum1Array[1].Calculate(b, b1, b2, b3, c, Sum1Array[0], Sum1Array[0], Sum1Array[0]);
                c.FromPixel(img.Pixel(2, y));
                Sum1Array[2].Calculate(b, b1, b2, b3, c, Sum1Array[1], Sum1Array[0], Sum1Array[0]);

                for (x = 3; x < w; ++x)
                {
                    c.FromPixel(img.Pixel(x, y));
                    Sum1Array[x].Calculate(b, b1, b2, b3, c, Sum1Array[x - 1], Sum1Array[x - 2], Sum1Array[x - 3]);
                }

                Sum2Array[wm].Calculate(b, b1, b2, b3, Sum1Array[wm], Sum1Array[wm], Sum1Array[wm], Sum1Array[wm]);
                Sum2Array[wm - 1].Calculate(b, b1, b2, b3, Sum1Array[wm - 1], Sum2Array[wm], Sum2Array[wm], Sum2Array[wm]);
                Sum2Array[wm - 2].Calculate(b, b1, b2, b3, Sum1Array[wm - 2], Sum2Array[wm - 1], Sum2Array[wm], Sum2Array[wm]);
                Sum2Array[wm].ToPixel(ref BufferArray[wm]);
                Sum2Array[wm - 1].ToPixel(ref BufferArray[wm - 1]);
                Sum2Array[wm - 2].ToPixel(ref BufferArray[wm - 2]);

                for (x = wm - 3; x >= 0; --x)
                {
                    Sum2Array[x].Calculate(b, b1, b2, b3, Sum1Array[x], Sum2Array[x + 1], Sum2Array[x + 2], Sum2Array[x + 3]);
                    Sum2Array[x].ToPixel(ref BufferArray[x]);
                }

                unsafe
                {
                    fixed(RGBA_Bytes *pBuffer = BufferArray)
                    {
                        img.CopyHorizontalColorSpan(0, y, w, pBuffer);
                    }
                }
            }
        }