Пример #1
0
        public override void ResetSpans(int min_x, int max_x)
        {
            int max_len = max_x - min_x + 2;

            if (max_len > m_spans.Length)
            {
                m_spans  = new ScanlineSpan[max_len];
                m_covers = new byte[max_len];
            }
            last_x          = 0x7FFFFFF0;
            minX            = min_x;
            last_span_index = 0;
        }
 public override void AddCell(int x, int cover)
 {
     x          -= minX;
     m_covers[x] = (byte)cover;
     if (x == last_x + 1)
     {
         m_spans[last_span_index].len++;
     }
     else
     {
         last_span_index++;
         m_spans[last_span_index] = new ScanlineSpan(x + minX, x);
     }
     last_x = x;
 }
Пример #3
0
 public override void AddCell(int x, int cover)
 {
     m_covers[m_cover_index] = (byte)cover;
     if (x == last_x + 1 && m_spans[last_span_index].len > 0)
     {
         m_spans[last_span_index].len++;
     }
     else
     {
         last_span_index++;
         m_spans[last_span_index] = new ScanlineSpan((short)x, m_cover_index);
     }
     last_x = x;
     m_cover_index++;
 }
Пример #4
0
 public override void AddSpan(int x, int len, int cover)
 {
     if (x == last_x + 1 &&
         m_spans[last_span_index].len < 0 &&
         cover == m_spans[last_span_index].cover_index)
     {
         m_spans[last_span_index].len -= (short)len;
     }
     else
     {
         m_covers[m_cover_index] = (byte)cover;
         last_span_index++;
         m_spans[last_span_index] = new ScanlineSpan((short)x, (short)(-len), m_cover_index++);
     }
     last_x = x + len - 1;
 }
Пример #5
0
        //================================================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
        }
Пример #6
0
        public override void AddSpan(int x, int len, int cover)
        {
            x -= minX;
            for (int i = 0; i < len; i++)
            {
                m_covers[x + i] = (byte)cover;
            }

            if (x == last_x + 1)
            {
                m_spans[last_span_index].len += (short)len;
            }
            else
            {
                last_span_index++;
                m_spans[last_span_index] = new ScanlineSpan(x + minX, len, x);
            }
            last_x = x + (int)len - 1;
        }
Пример #7
0
        //======================================================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();
                    }
                }
            }
        }
Пример #8
0
        void SubPixRender(IImageReaderWriter destImage, Scanline scanline, ColorRGBA color)
        {
            int y         = scanline.Y;
            int num_spans = scanline.SpanCount;

            byte[]             covers = scanline.GetCovers();
            ScanlineRasterizer ras    = gfx.ScanlineRasterizer;
            var       rasToBmp        = gfx.ScanlineRasToDestBitmap;
            ColorRGBA prevColor       = ColorRGBA.White;

            for (int i = 0; i <= num_spans; ++i)
            {
                //render span by span
                ScanlineSpan span       = scanline.GetSpan(i);
                int          x          = span.x;
                int          num_pix    = span.len;
                int          coverIndex = span.cover_index;
                //test subpixel rendering concept
                //----------------------------------------------------

                int prev_cover = 0;
                while (num_pix > 0)
                {
                    int coverageValue = covers[coverIndex++];
                    if (coverageValue >= 255)
                    {
                        //100% cover
                        ColorRGBA newc = new ColorRGBA(color.red, color.green, color.blue);
                        prevColor = newc;
                        int a = (coverageValue * color.Alpha0To255) >> 8;
                        m_square.Draw(rasToBmp,
                                      ras, m_sl, destImage,
                                      new ColorRGBA(newc, a),
                                      x, y);
                        prev_cover = 255;//full
                    }
                    else
                    {
                        //check direction :
                        bool isLeftToRight = coverageValue >= prev_cover;
                        prev_cover = coverageValue;
                        byte  c_r, c_g, c_b;
                        float subpix_percent = ((float)(coverageValue) / 256f);
                        if (coverageValue < cover_1_3)
                        {
                            if (isLeftToRight)
                            {
                                c_r = 255;
                                c_g = 255;
                                c_b = (byte)(255 - (255f * (subpix_percent)));
                            }
                            else
                            {
                                c_r = (byte)(255 - (255f * (subpix_percent)));
                                c_g = 255;
                                c_b = 255;
                            }

                            ColorRGBA newc = prevColor = new ColorRGBA(c_r, c_g, c_b);
                            int       a    = (coverageValue * color.Alpha0To255) >> 8;
                            m_square.Draw(rasToBmp,
                                          ras, m_sl, destImage,
                                          new ColorRGBA(newc, a),
                                          x, y);
                        }
                        else if (coverageValue < cover_2_3)
                        {
                            if (isLeftToRight)
                            {
                                c_r = prevColor.blue;
                                c_g = (byte)(255 - (255f * (subpix_percent)));
                                c_b = color.blue;// (byte)(255 - (255f * (subpix_percent)));// color.blue;
                            }
                            else
                            {
                                c_r = color.blue;// (byte)(255 - (255f * (subpix_percent))); //color.blue;
                                c_g = (byte)(255 - (255f * (subpix_percent)));
                                c_b = 255;
                            }


                            ColorRGBA newc = prevColor = new ColorRGBA(c_r, c_g, c_b);
                            int       a    = (coverageValue * color.Alpha0To255) >> 8;
                            m_square.Draw(rasToBmp,
                                          ras, m_sl, destImage,
                                          new ColorRGBA(newc, a),
                                          x, y);
                        }
                        else
                        {
                            //cover > 2/3 but not full
                            if (isLeftToRight)
                            {
                                c_r = (byte)(255 - (255f * (subpix_percent)));
                                c_g = color.green;
                                c_b = color.blue;
                            }
                            else
                            {
                                c_r = prevColor.green;
                                c_g = prevColor.blue;
                                c_b = (byte)(255 - (255f * (subpix_percent)));
                            }

                            ColorRGBA newc = prevColor = new ColorRGBA(c_r, c_g, c_b);
                            int       a    = (coverageValue * color.Alpha0To255) >> 8;
                            m_square.Draw(rasToBmp,
                                          ras, m_sl, destImage,
                                          new ColorRGBA(newc, a),
                                          x, y);
                        }
                    }



                    ++x;
                    --num_pix;
                }
            }
        }
Пример #9
0
        void SubPixRender(IImageReaderWriter destImage, Scanline scanline, Color color)
        {
            int y         = scanline.Y;
            int num_spans = scanline.SpanCount;

            byte[]             covers = scanline.GetCovers();
            ScanlineRasterizer ras    = gfx.ScanlineRasterizer;
            var rasToBmp = gfx.ScanlineRasToDestBitmap;
            //------------------------------------------
            Color bgColor = Color.White;
            float cb_R    = bgColor.R / 255f;
            float cb_G    = bgColor.G / 255f;
            float cb_B    = bgColor.B / 255f;
            float cf_R    = color.R / 255f;
            float cf_G    = color.G / 255f;
            float cf_B    = color.B / 255f;

            //------------------------------------------

            for (int i = 0; i <= num_spans; ++i)
            {
                //render span by span
                ScanlineSpan span       = scanline.GetSpan(i);
                int          x          = span.x;
                int          num_pix    = span.len;
                int          coverIndex = span.cover_index;
                //test subpixel rendering concept
                //----------------------------------------------------

                int prev_cover = 0;
                while (num_pix > 0)
                {
                    byte coverageValue = covers[coverIndex++];
                    if (coverageValue >= 255)
                    {
                        //100% cover
                        int a = (coverageValue * color.Alpha0To255) >> 8;
                        m_square.Draw(rasToBmp,
                                      ras, m_sl, destImage,
                                      Color.FromArgb(a, Color.FromArgb(color.red, color.green, color.blue)),
                                      x, y);
                        prev_cover = 255;//full
                    }
                    else
                    {
                        //check direction :
                        bool isUpHill = (coverageValue % 2) > 0;
                        //--------------------------------------------------------------------
                        //TODO: review here
                        //in somecase, demo3, isUpHill2 != isUpHill
                        //but we skip it, because we don't want context color around the point
                        //so when we use in fragment shader we can pick up a single color
                        //and determine what color it should be
                        bool isUpHill2 = coverageValue > prev_cover;
                        if (isUpHill != isUpHill2)
                        {
                        }
                        //--------------------------------------------------------------------
                        prev_cover = coverageValue;
                        byte  c_r, c_g, c_b;
                        float subpix_percent = ((float)(coverageValue) / 256f);
                        if (coverageValue < cover_1_3)
                        {
                            //assume LCD color arrangement is RGB
                            if (isUpHill)
                            {
                                c_r = bgColor.R;
                                c_g = bgColor.G;
                                c_b = (byte)(mix(cb_B, cf_B, subpix_percent) * 255);
                            }
                            else
                            {
                                c_r = (byte)(mix(cb_R, cf_R, subpix_percent) * 255);
                                c_g = bgColor.G;
                                c_b = bgColor.B;
                            }


                            int a = (coverageValue * color.Alpha0To255) >> 8;
                            m_square.Draw(rasToBmp,
                                          ras, m_sl, destImage,
                                          Color.FromArgb(a, Color.FromArgb(c_r, c_g, c_b)),
                                          x, y);
                        }
                        else if (coverageValue < cover_2_3)
                        {
                            if (isUpHill)
                            {
                                c_r = bgColor.R;
                                c_g = (byte)(mix(cb_G, cf_G, subpix_percent) * 255);
                                c_b = (byte)(mix(cb_B, cf_B, 1) * 255);
                            }
                            else
                            {
                                c_r = (byte)(mix(cb_R, cf_R, 1) * 255);
                                c_g = (byte)(mix(cb_G, cf_G, subpix_percent) * 255);
                                c_b = bgColor.B;
                            }



                            int a = (coverageValue * color.Alpha0To255) >> 8;
                            m_square.Draw(rasToBmp,
                                          ras, m_sl, destImage,
                                          Color.FromArgb(a, Color.FromArgb(c_r, c_g, c_b)),
                                          x, y);
                        }
                        else
                        {
                            //cover > 2/3 but not full
                            if (isUpHill)
                            {
                                c_r = (byte)(mix(cb_R, cf_R, subpix_percent) * 255);
                                c_g = (byte)(mix(cb_G, cf_G, 1) * 255);
                                c_b = (byte)(mix(cb_B, cf_B, 1) * 255);
                            }
                            else
                            {
                                c_r = (byte)(mix(cb_R, cf_R, 1) * 255);
                                c_g = (byte)(mix(cb_G, cf_G, 1) * 255);
                                c_b = (byte)(mix(cb_B, cf_B, subpix_percent) * 255);
                            }


                            int a = (coverageValue * color.Alpha0To255) >> 8;
                            m_square.Draw(rasToBmp,
                                          ras, m_sl, destImage,
                                          Color.FromArgb(a, Color.FromArgb(c_r, c_g, c_b)),
                                          x, y);
                        }
                    }


                    ++x;
                    --num_pix;
                }
            }
        }
Пример #10
0
        public static void RenderCompound(RasterizerCompoundAA<T> ras,
                                       IScanlineCache sl_aa,
                                       IScanlineCache 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.Covers;
                    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.NumSpans;
                                            for (; ; )
                                            {
                                                len = span_aa.Len;
                                                sh.GenerateSpan(pColorSpan,
                                                                 span_aa.X,
                                                                 sl_aa.Y,
                                                                 (uint)len,
                                                                 style);

                                                pixelFormat.BlendColorHSpan(span_aa.X,
                                                                      sl_aa.Y,
                                                                      (uint)span_aa.Len,
                                                                      pColorSpan,
                                                                      &pCovers[span_aa.CoverIndex], 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.NumSpans;
                                        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.NumSpans;
                                                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.CoverIndex];
                                                        do
                                                        {
                                                            if (*covers == CoverFull)
                                                            {
                                                                *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.CoverIndex];
                                                        do
                                                        {
                                                            if (*covers == CoverFull)
                                                            {
                                                                *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.NumSpans;
                                        for (; ; )
                                        {
                                            pixelFormat.BlendColorHSpan(span_bin.X,
                                                                  sl_bin.Y,
                                                                  (uint)span_bin.Len,
                                                                  &pColorSpan[mix_bufferOffset + span_bin.X - min_x],
                                                                  null,
                                                                  CoverFull);
                                            if (--num_spans == 0) break;
                                            span_bin = sl_bin.GetNextScanlineSpan();
                                        }
                                    } // if(ras.sweep_scanline(sl_bin, -1))
                                } // if(num_styles == 1) ... else
                            } // while((num_styles = ras.sweep_styles()) > 0)
                        }
                    }
                } // if(ras.rewind_scanlines())
#endif
            }
        }