//========================================================render_all_paths public static void RenderSolidAllPaths(IPixelFormat pixFormat, IRasterizer ras, IScanline sl, IVertexSource 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, IScanline scanLine, RGBA_Bytes color) { #if use_timers render_scanline_aa_solidTimer.Start(); #endif int y = scanLine.y(); uint num_spans = scanLine.NumberOfSpans; ScanlineSpan scanlineSpan = scanLine.Begin; byte[] ManagedCoversArray = scanLine.GetCovers(); 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.BlendSolidHorizontalSpan(x, y, (uint)scanlineSpan.len, color, &pCovers[scanlineSpan.cover_index]); #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.BlendHorizontalLine(x, y, (x - (int)scanlineSpan.len - 1), color, pCovers[scanlineSpan.cover_index]); #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 rasterizer, IScanline 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.RenderSolidSingleScanLine(pixFormat, scanLine, color); } } }
//======================================================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 }
public unsafe override void Generate(RGBA_Bytes *span, int x, int y, uint len) { #if use_timers Generate_Span.Start(); #endif base.interpolator().Begin(x + base.filter_dx_dbl(), y + base.filter_dy_dbl(), len); //uint[] fg = new uint[4]; uint *fg = stackalloc uint[4]; uint back_r = m_back_color.m_R; uint back_g = m_back_color.m_G; uint back_b = m_back_color.m_B; uint back_a = m_back_color.m_A; byte *fg_ptr; RasterBuffer pSourceRenderingBuffer = base.source().PixelFormat.RenderingBuffer; int maxx = (int)pSourceRenderingBuffer.Width() - 1; int maxy = (int)pSourceRenderingBuffer.Height() - 1; ISpanInterpolator spanInterpolator = base.interpolator(); unchecked { do { int x_hr; int y_hr; spanInterpolator.Coordinates(out x_hr, out y_hr); x_hr -= base.filter_dx_int(); y_hr -= base.filter_dy_int(); 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).m_R = (byte)fg[0]; (*span).m_G = (byte)fg[1]; (*span).m_B = (byte)fg[2]; (*span).m_A = (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(x + base.filter_dx_dbl(), y + base.filter_dy_dbl(), len); uint *fg = stackalloc uint[4]; byte *fg_ptr; RasterBuffer pSourceRenderingBuffer = base.source().PixelFormat.RenderingBuffer; int maxx = (int)pSourceRenderingBuffer.Width() - 1; int maxy = (int)pSourceRenderingBuffer.Height() - 1; ISpanInterpolator spanInterpolator = base.interpolator(); unchecked { do { int x_hr; int y_hr; spanInterpolator.Coordinates(out x_hr, out y_hr); x_hr -= base.filter_dx_int(); y_hr -= base.filter_dy_int(); 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).m_R = (byte)fg[OrderR]; (*span).m_G = (byte)fg[OrderG]; (*span).m_B = (byte)fg[OrderB]; (*span).m_A = (byte)fg[OrderA]; ++span; spanInterpolator.Next(); } while (--len != 0); } #if use_timers Generate_Span.Stop(); #endif }
//-------------------------------------------------------------------- public bool SweepScanline(IScanline 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); AntiAliasingCell[] cells; uint Offset; m_outline.ScanlineCells(scan_y_uint, out cells, out Offset); int cover = 0; while (num_cells != 0) { AntiAliasingCell 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.NumberOfSpans != 0) { break; } ++m_scan_y; } sl.Finalize(m_scan_y); ++m_scan_y; #if use_timers SweepSacanLine.Stop(); #endif return(true); }