//=====================================================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 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 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 } }