//========================================================render_all_paths public static void RenderSolidAllPaths(IPixelFormat pixFormat, IRasterizer<T> ras, IScanlineCache sl, IVertexSource<T> vs, RGBA_Bytes[] color_storage, uint[] path_id, uint num_paths) { for (uint i = 0; i < num_paths; i++) { ras.Reset(); #if use_timers AddPathTimer.Start(); #endif ras.AddPath(vs, path_id[i]); #if use_timers AddPathTimer.Stop(); #endif #if use_timers RenderSLTimer.Start(); #endif RenderSolid(pixFormat, ras, sl, color_storage[i]); #if use_timers RenderSLTimer.Stop(); #endif } }
//================================================render_scanline_aa_solid private static void RenderSolidSingleScanLine(IPixelFormat pixFormat, IScanlineCache scanLine, RGBA_Bytes color) { #if use_timers render_scanline_aa_solidTimer.Start(); #endif int y = scanLine.Y; uint num_spans = scanLine.NumSpans; ScanlineSpan scanlineSpan = scanLine.Begin(); byte[] ManagedCoversArray = scanLine.Covers; unsafe { fixed (byte* pCovers = ManagedCoversArray) { for (; ; ) { int x = scanlineSpan.X; if (scanlineSpan.Len > 0) { #if use_timers render_scanline_aa_solid_blend_solid_hspan.Start(); #endif pixFormat.BlendSolidHSpan(x, y, (uint)scanlineSpan.Len, color, &pCovers[scanlineSpan.CoverIndex]); #if use_timers render_scanline_aa_solid_blend_solid_hspan.Stop(); #endif } else { #if use_timers render_scanline_aa_solid_blend_hline.Start(); #endif pixFormat.BlendHLine(x, y, (x - (int)scanlineSpan.Len - 1), color, pCovers[scanlineSpan.CoverIndex]); #if use_timers render_scanline_aa_solid_blend_hline.Stop(); #endif } if (--num_spans == 0) break; scanlineSpan = scanLine.GetNextScanlineSpan(); } } } #if use_timers render_scanline_aa_solidTimer.Stop(); #endif }
//========================================================render_scanlines public static void RenderSolid(IPixelFormat pixFormat, IRasterizer<T> rasterizer, IScanlineCache scanLine, RGBA_Bytes color) { if (rasterizer.RewindScanlines()) { scanLine.Reset(rasterizer.MinX, rasterizer.MaxX); #if use_timers PrepareTimer.Start(); #endif //renderer.prepare(); #if use_timers PrepareTimer.Stop(); #endif while (rasterizer.SweepScanline(scanLine)) { Renderer<T>.RenderSolidSingleScanLine(pixFormat, scanLine, color); } } }
//======================================================render_scanline_aa private static void GenerateAndRenderSingleScanline(IScanlineCache sl, IPixelFormat ren, SpanAllocator alloc, ISpanGenerator<T> span_gen) { int y = sl.Y; uint num_spans = sl.NumSpans; ScanlineSpan scanlineSpan = sl.Begin(); byte[] ManagedCoversArray = sl.Covers; 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.BlendColorHSpan(x, y, (uint)len, pColors, (scanlineSpan.Len < 0) ? null : &pCovers[scanlineSpan.CoverIndex], pCovers[scanlineSpan.CoverIndex]); #if use_timers blend_color_hspan.Stop(); #endif } if (--num_spans == 0) break; scanlineSpan = sl.GetNextScanlineSpan(); } } } }
public unsafe override void Generate(RGBA_Bytes *span, int x, int y, uint len) { #if use_timers Generate_Span.Start(); #endif base.Interpolator.Begin(M.New <T>(x).Add(base.FilterDxDbl()), M.New <T>(y).Add(base.FilterDyDbl()), len); //uint[] fg = new uint[4]; uint *fg = stackalloc uint[4]; uint back_r = m_back_color.R; uint back_g = m_back_color.G; uint back_b = m_back_color.B; uint back_a = m_back_color.A; byte *fg_ptr; RasterBuffer pSourceRenderingBuffer = base.Source().PixelFormat.GetRenderingBuffer(); int maxx = (int)pSourceRenderingBuffer.Width - 1; int maxy = (int)pSourceRenderingBuffer.Height - 1; ISpanInterpolator <T> spanInterpolator = base.Interpolator; unchecked { do { int x_hr; int y_hr; spanInterpolator.Coordinates(out x_hr, out y_hr); x_hr -= base.FilterDxInt(); y_hr -= base.FilterDyInt(); int x_lr = x_hr >> (int)image_subpixel_scale_e.Shift; int y_lr = y_hr >> (int)image_subpixel_scale_e.Shift; uint weight; if (x_lr >= 0 && y_lr >= 0 && x_lr < maxx && y_lr < maxy) { fg[0] = fg[1] = fg[2] = fg[3] = (int)image_subpixel_scale_e.Scale * (int)image_subpixel_scale_e.Scale / 2; x_hr &= (int)image_subpixel_scale_e.Mask; y_hr &= (int)image_subpixel_scale_e.Mask; fg_ptr = pSourceRenderingBuffer.GetPixelPointer(y_lr) + (x_lr << 2); weight = (uint)(((int)image_subpixel_scale_e.Scale - x_hr) * ((int)image_subpixel_scale_e.Scale - y_hr)); fg[0] += weight * fg_ptr[0]; fg[1] += weight * fg_ptr[1]; fg[2] += weight * fg_ptr[2]; fg[3] += weight * fg_ptr[3]; weight = (uint)(x_hr * ((int)image_subpixel_scale_e.Scale - y_hr)); fg[0] += weight * fg_ptr[4]; fg[1] += weight * fg_ptr[5]; fg[2] += weight * fg_ptr[6]; fg[3] += weight * fg_ptr[7]; ++y_lr; fg_ptr = pSourceRenderingBuffer.GetPixelPointer(y_lr) + (x_lr << 2); weight = (uint)(((int)image_subpixel_scale_e.Scale - x_hr) * y_hr); fg[0] += weight * fg_ptr[0]; fg[1] += weight * fg_ptr[1]; fg[2] += weight * fg_ptr[2]; fg[3] += weight * fg_ptr[3]; weight = (uint)(x_hr * y_hr); fg[0] += weight * fg_ptr[4]; fg[1] += weight * fg_ptr[5]; fg[2] += weight * fg_ptr[6]; fg[3] += weight * fg_ptr[7]; fg[0] >>= (int)image_subpixel_scale_e.Shift * 2; fg[1] >>= (int)image_subpixel_scale_e.Shift * 2; fg[2] >>= (int)image_subpixel_scale_e.Shift * 2; fg[3] >>= (int)image_subpixel_scale_e.Shift * 2; } else { if (x_lr < -1 || y_lr < -1 || x_lr > maxx || y_lr > maxy) { fg[OrderR] = back_r; fg[OrderG] = back_g; fg[OrderB] = back_b; fg[OrderA] = back_a; } else { fg[0] = fg[1] = fg[2] = fg[3] = (int)image_subpixel_scale_e.Scale * (int)image_subpixel_scale_e.Scale / 2; x_hr &= (int)image_subpixel_scale_e.Mask; y_hr &= (int)image_subpixel_scale_e.Mask; weight = (uint)(((int)image_subpixel_scale_e.Scale - x_hr) * ((int)image_subpixel_scale_e.Scale - y_hr)); BlendInFilterPixel(fg, back_r, back_g, back_b, back_a, pSourceRenderingBuffer, maxx, maxy, x_lr, y_lr, weight); x_lr++; weight = (uint)(x_hr * ((int)image_subpixel_scale_e.Scale - y_hr)); BlendInFilterPixel(fg, back_r, back_g, back_b, back_a, pSourceRenderingBuffer, maxx, maxy, x_lr, y_lr, weight); x_lr--; y_lr++; weight = (uint)(((int)image_subpixel_scale_e.Scale - x_hr) * y_hr); BlendInFilterPixel(fg, back_r, back_g, back_b, back_a, pSourceRenderingBuffer, maxx, maxy, x_lr, y_lr, weight); x_lr++; weight = (uint)(x_hr * y_hr); BlendInFilterPixel(fg, back_r, back_g, back_b, back_a, pSourceRenderingBuffer, maxx, maxy, x_lr, y_lr, weight); fg[0] >>= (int)image_subpixel_scale_e.Shift * 2; fg[1] >>= (int)image_subpixel_scale_e.Shift * 2; fg[2] >>= (int)image_subpixel_scale_e.Shift * 2; fg[3] >>= (int)image_subpixel_scale_e.Shift * 2; } } //(*span).R = (byte)fg[0]; //(*span).G = (byte)fg[1]; //(*span).B = (byte)fg[2]; //(*span).A = (byte)fg[3]; (*span) = new RGBA_Bytes((byte)fg[0], (byte)fg[1], (byte)fg[2], (byte)fg[3]); ++span; spanInterpolator.Next(); } while (--len != 0); } #if use_timers Generate_Span.Stop(); #endif }
public unsafe override void Generate(RGBA_Bytes *span, int x, int y, uint len) { #if use_timers Generate_Span.Start(); #endif base.Interpolator.Begin(M.New <T>(x).Add(base.FilterDxDbl()), M.New <T>(y).Add(base.FilterDyDbl()), len); uint *fg = stackalloc uint[4]; byte *fg_ptr; RasterBuffer pSourceRenderingBuffer = base.Source().PixelFormat.GetRenderingBuffer(); int maxx = (int)pSourceRenderingBuffer.Width - 1; int maxy = (int)pSourceRenderingBuffer.Height - 1; ISpanInterpolator <T> spanInterpolator = base.Interpolator; unchecked { do { int x_hr; int y_hr; spanInterpolator.Coordinates(out x_hr, out y_hr); x_hr -= base.FilterDxInt(); y_hr -= base.FilterDyInt(); int x_lr = x_hr >> (int)image_subpixel_scale_e.Shift; int y_lr = y_hr >> (int)image_subpixel_scale_e.Shift; uint weight; fg[0] = fg[1] = fg[2] = fg[3] = (int)image_subpixel_scale_e.Scale * (int)image_subpixel_scale_e.Scale / 2; x_hr &= (int)image_subpixel_scale_e.Mask; y_hr &= (int)image_subpixel_scale_e.Mask; fg_ptr = pSourceRenderingBuffer.GetPixelPointer(y_lr) + (x_lr << 2); weight = (uint)(((int)image_subpixel_scale_e.Scale - x_hr) * ((int)image_subpixel_scale_e.Scale - y_hr)); fg[0] += weight * fg_ptr[0]; fg[1] += weight * fg_ptr[1]; fg[2] += weight * fg_ptr[2]; fg[3] += weight * fg_ptr[3]; weight = (uint)(x_hr * ((int)image_subpixel_scale_e.Scale - y_hr)); fg[0] += weight * fg_ptr[4]; fg[1] += weight * fg_ptr[5]; fg[2] += weight * fg_ptr[6]; fg[3] += weight * fg_ptr[7]; ++y_lr; fg_ptr = pSourceRenderingBuffer.GetPixelPointer(y_lr) + (x_lr << 2); weight = (uint)(((int)image_subpixel_scale_e.Scale - x_hr) * y_hr); fg[0] += weight * fg_ptr[0]; fg[1] += weight * fg_ptr[1]; fg[2] += weight * fg_ptr[2]; fg[3] += weight * fg_ptr[3]; weight = (uint)(x_hr * y_hr); fg[0] += weight * fg_ptr[4]; fg[1] += weight * fg_ptr[5]; fg[2] += weight * fg_ptr[6]; fg[3] += weight * fg_ptr[7]; fg[0] >>= (int)image_subpixel_scale_e.Shift * 2; fg[1] >>= (int)image_subpixel_scale_e.Shift * 2; fg[2] >>= (int)image_subpixel_scale_e.Shift * 2; fg[3] >>= (int)image_subpixel_scale_e.Shift * 2; //(*span).R = (byte)fg[OrderR]; //(*span).G = (byte)fg[OrderG]; //(*span).B = (byte)fg[OrderB]; //(*span).A = (byte)fg[OrderA]; (*span) = new RGBA_Bytes((byte)fg[OrderR], (byte)fg[OrderG], (byte)fg[OrderB], (byte)fg[OrderA]); ++span; spanInterpolator.Next(); } while (--len != 0); } #if use_timers Generate_Span.Stop(); #endif }
//-------------------------------------------------------------------- public bool SweepScanline(IScanlineCache sl) { #if use_timers SweepSacanLine.Start(); #endif for (; ;) { if (m_scan_y > m_outline.MaxY) { #if use_timers SweepSacanLine.Stop(); #endif return(false); } sl.ResetSpans(); uint scan_y_uint = 0; // it is going to get initialize to 0 anyway so make it clear. if (m_scan_y > 0) { scan_y_uint = (uint)m_scan_y; } uint num_cells = m_outline.ScanlineNumCells(scan_y_uint); CellAA[] cells; uint Offset; m_outline.ScanlineCells(scan_y_uint, out cells, out Offset); int cover = 0; while (num_cells != 0) { CellAA cur_cell = cells[Offset]; int x = cur_cell.X; int area = cur_cell.Area; uint alpha; cover += cur_cell.Cover; //accumulate all cells with the same X while (--num_cells != 0) { Offset++; cur_cell = cells[Offset]; if (cur_cell.X != x) { break; } area += cur_cell.Area; cover += cur_cell.Cover; } if (area != 0) { alpha = CalculateAlpha((cover << ((int)poly_subpixel_scale_e.Shift + 1)) - area); if (alpha != 0) { sl.AddCell(x, alpha); } x++; } if ((num_cells != 0) && (cur_cell.X > x)) { alpha = CalculateAlpha(cover << ((int)poly_subpixel_scale_e.Shift + 1)); if (alpha != 0) { sl.AddSpan(x, (cur_cell.X - x), alpha); } } } if (sl.NumSpans != 0) { break; } ++m_scan_y; } sl.Finalize(m_scan_y); ++m_scan_y; #if use_timers SweepSacanLine.Stop(); #endif return(true); }
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 }