Пример #1
0
        //========================================================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
            }
        }
Пример #2
0
        /// <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());
        }
Пример #3
0
        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());
            }
        }
Пример #4
0
 //=====================================================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);
         }
     }
 }
Пример #5
0
        //================================================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
        }
Пример #6
0
		//========================================================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);
				}
			}
		}
Пример #7
0
        //======================================================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();
                    }
                }
            }
        }
Пример #8
0
 //========================================================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);
         }
     }
 }
Пример #9
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
            }
        }
Пример #10
0
 //=====================================================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);
         }
     }
 }
Пример #11
0
        /// <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());
        }
Пример #12
0
        //================================================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
        }
        //--------------------------------------------------------------------
        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;
        }
Пример #14
0
        ///<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;
        }
Пример #15
0
 ///<summary>
 ///</summary>
 ///<param name="sl"></param>
 ///<returns></returns>
 ///<exception cref="NotImplementedException"></exception>
 public bool SweepScanline(IScanline sl)
 {
     throw new NotImplementedException();
 }
Пример #16
0
        //========================================================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
            }
        }
Пример #17
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
            }
        }
 ///<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);
        }
Пример #20
0
        //======================================================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 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);
        }