///<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); }
//======================================================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(); } } } }
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); }
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); } } } }