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
            }
        }
Beispiel #2
0
        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
            }
        }