//========================================================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 } }
/// <summary> /// /// </summary> /// <param name="PixelFormat"></param> /// <param name="Rasterizer"></param> /// <param name="Scanline"></param> public Renderer(IPixelFormat PixelFormat, AntiAliasedScanlineRasterizer Rasterizer, IScanline Scanline) { m_PixelFormat = PixelFormat; m_Rasterizer = Rasterizer; m_Scanline = Scanline; TextPath = new GsvText(); StrockedText = new StrokeConverter(TextPath); m_AffineTransformStack.Push(Affine.NewIdentity()); }
public void Render(IRasterizer rasterizer, IScanline scanline, IPixelFormat rendererBase) { uint i; for (i = 0; i < num_paths(); i++) { rasterizer.reset(); rasterizer.add_path(this, i); Renderer.RenderSolid(rendererBase, rasterizer, scanline, color(i).Get_rgba8()); } }
//=====================================================render_scanlines_aa public static void GenerateAndRender(IRasterizer ras, IScanline sl, IPixelFormat ren, SpanAllocator alloc, ISpanGenerator span_gen) { if(ras.RewindScanlines()) { sl.Reset(ras.MinX(), ras.MaxX()); span_gen.Prepare(); while(ras.SweepScanline(sl)) { GenerateAndRenderSingleScanline(sl, ren, alloc, span_gen); } } }
//================================================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(); } } } }
//========================================================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); } } }
public static void RenderCompound(AntiAliasedCompundRasterizer ras, IScanline sl_aa, IScanline sl_bin, IPixelFormat pixelFormat, SpanAllocator alloc, IStyleHandler sh) { #if true unsafe { if (ras.RewindScanlines()) { int min_x = ras.MinX(); int len = ras.MaxX() - min_x + 2; sl_aa.Reset(min_x, ras.MaxX()); sl_bin.Reset(min_x, ras.MaxX()); //typedef typename BaseRenderer::color_type color_type; ArrayPOD<RGBA_Bytes> color_span = alloc.Allocate((uint)len * 2); byte[] ManagedCoversArray = sl_aa.GetCovers(); fixed (byte* pCovers = ManagedCoversArray) { fixed (RGBA_Bytes* pColorSpan = color_span.Array) { int mix_bufferOffset = len; uint num_spans; uint num_styles; uint style; bool solid; while ((num_styles = ras.SweepStyles()) > 0) { if (num_styles == 1) { // Optimization for a single Style. Happens often //------------------------- if (ras.SweepScanline(sl_aa, 0)) { style = ras.Style(0); if (sh.IsSolid(style)) { // Just solid fill //----------------------- RenderSolidSingleScanLine(pixelFormat, sl_aa, sh.Color(style)); } else { // Arbitrary Span Generator //----------------------- ScanlineSpan span_aa = sl_aa.Begin; num_spans = sl_aa.NumberOfSpans; for (; ; ) { len = span_aa.len; sh.GenerateSpan(pColorSpan, span_aa.x, sl_aa.y(), (uint)len, style); pixelFormat.BlendHorizontalColorSpan(span_aa.x, sl_aa.y(), (uint)span_aa.len, pColorSpan, &pCovers[span_aa.cover_index], 0); if (--num_spans == 0) break; span_aa = sl_aa.GetNextScanlineSpan(); } } } } else // there are multiple Styles { if (ras.SweepScanline(sl_bin, -1)) { // Clear the spans of the mix_buffer //-------------------- ScanlineSpan span_bin = sl_bin.Begin; num_spans = sl_bin.NumberOfSpans; for (; ; ) { Basics.MemClear((byte*)&pColorSpan[mix_bufferOffset + span_bin.x - min_x], span_bin.len * sizeof(RGBA_Bytes)); if (--num_spans == 0) break; span_bin = sl_bin.GetNextScanlineSpan(); } for (uint i = 0; i < num_styles; i++) { style = ras.Style(i); solid = sh.IsSolid(style); if (ras.SweepScanline(sl_aa, (int)i)) { //IColorType* Colors; //IColorType* cspan; //typename ScanlineAA::cover_type* covers; ScanlineSpan span_aa = sl_aa.Begin; num_spans = sl_aa.NumberOfSpans; if (solid) { // Just solid fill //----------------------- for (; ; ) { RGBA_Bytes c = sh.Color(style); len = span_aa.len; RGBA_Bytes* colors = &pColorSpan[mix_bufferOffset + span_aa.x - min_x]; byte* covers = &pCovers[span_aa.cover_index]; do { if (*covers == cover_full) { *colors = c; } else { colors->add(c, *covers); } ++colors; ++covers; } while (--len != 0); if (--num_spans == 0) break; span_aa = sl_aa.GetNextScanlineSpan(); } } else { // Arbitrary Span Generator //----------------------- for (; ; ) { len = span_aa.len; RGBA_Bytes* colors = &pColorSpan[mix_bufferOffset + span_aa.x - min_x]; RGBA_Bytes* cspan = pColorSpan; sh.GenerateSpan(cspan, span_aa.x, sl_aa.y(), (uint)len, style); byte* covers = &pCovers[span_aa.cover_index]; do { if (*covers == cover_full) { *colors = *cspan; } else { colors->add(*cspan, *covers); } ++cspan; ++colors; ++covers; } while (--len != 0); if (--num_spans == 0) break; span_aa = sl_aa.GetNextScanlineSpan(); } } } } // Emit the blended result as a Color hspan //------------------------- span_bin = sl_bin.Begin; num_spans = sl_bin.NumberOfSpans; for (; ; ) { pixelFormat.BlendHorizontalColorSpan(span_bin.x, sl_bin.y(), (uint)span_bin.len, &pColorSpan[mix_bufferOffset + span_bin.x - min_x], null, cover_full); if (--num_spans == 0) break; span_bin = sl_bin.GetNextScanlineSpan(); } } // if(ras.SweepScanline(sl_bin, -1)) } // if(num_styles == 1) ... else } // while((num_styles = ras.SweepStyles()) > 0) } } } // if(ras.RewindScanlines()) #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; }
///<summary> ///</summary> ///<param name="sl"></param> ///<param name="styleIdx"></param> ///<returns></returns> public bool SweepScanline(IScanline sl, int styleIdx) { int scanY = _scanY - 1; if (scanY > _rasterizer.MaxY()) return false; sl.ResetSpans(); uint masterAlpha = AntiAliasingMask; if (styleIdx < 0) { styleIdx = 0; } else { styleIdx++; masterAlpha = _masterAlpha[(uint)(_activeStyleTable[(uint)styleIdx] + _minStyle - 1)]; } StyleInfo st = _activeStyles[_activeStyleTable[styleIdx]]; int numCells = (int)st.NumCells; uint cellOffset = st.StartCell; AntiAliasingCell cell = _cells[cellOffset]; int cover = 0; while (numCells-- != 0) { uint alpha; int x = cell.x; int area = cell.area; cover += cell.cover; cell = _cells[++cellOffset]; if (area != 0) { alpha = CalculateAlpha((cover << (PolygonSubpixelShift + 1)) - area, masterAlpha); sl.AddCell(x, alpha); x++; } if (numCells == 0 || cell.x <= x) continue; alpha = CalculateAlpha(cover << (PolygonSubpixelShift + 1), masterAlpha); if (alpha != 0) { sl.AddSpan(x, cell.x - x, alpha); } } if (sl.NumberOfSpans == 0) return false; sl.Finalize(scanY); return true; }
///<summary> ///</summary> ///<param name="sl"></param> ///<returns></returns> ///<exception cref="NotImplementedException"></exception> public bool SweepScanline(IScanline sl) { throw new NotImplementedException(); }
///<summary> ///</summary> ///<param name="sl"></param> ///<param name="styleIdx"></param> ///<returns></returns> public bool SweepScanline(IScanline sl, int styleIdx) { int scanY = _scanY - 1; if (scanY > _rasterizer.MaxY()) { return(false); } sl.ResetSpans(); uint masterAlpha = AntiAliasingMask; if (styleIdx < 0) { styleIdx = 0; } else { styleIdx++; masterAlpha = _masterAlpha[(uint)(_activeStyleTable[(uint)styleIdx] + _minStyle - 1)]; } StyleInfo st = _activeStyles[_activeStyleTable[styleIdx]]; int numCells = (int)st.NumCells; uint cellOffset = st.StartCell; AntiAliasingCell cell = _cells[cellOffset]; int cover = 0; while (numCells-- != 0) { uint alpha; int x = cell.x; int area = cell.area; cover += cell.cover; cell = _cells[++cellOffset]; if (area != 0) { alpha = CalculateAlpha((cover << (PolygonSubpixelShift + 1)) - area, masterAlpha); sl.AddCell(x, alpha); x++; } if (numCells == 0 || cell.x <= x) { continue; } alpha = CalculateAlpha(cover << (PolygonSubpixelShift + 1), masterAlpha); if (alpha != 0) { sl.AddSpan(x, cell.x - x, alpha); } } if (sl.NumberOfSpans == 0) { return(false); } sl.Finalize(scanY); return(true); }
//-------------------------------------------------------------------- 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); }