public void RenderScanline(
            IImageReaderWriter dest,
            ScanlineRasterizer sclineRas,
            Scanline scline,
            Color color)
        {
#if DEBUG
            int dbugMinScanlineCount = 0;
#endif

            //1. ensure single line buffer width
            _grayScaleLine.EnsureLineStride(dest.Width + 4);
            //2. setup vars
            byte[] dest_buffer = dest.GetBuffer();
            int    dest_w      = dest.Width;
            int    dest_h      = dest.Height;
            int    dest_stride = dest.Stride;
            int    src_w       = dest_w;
            int    src_stride  = dest_stride;
            //*** set color before call Blend()
            this._color = color;

            byte color_alpha = color.alpha;
            //---------------------------
            //3. loop, render single scanline with subpixel rendering

            byte[] lineBuff = _grayScaleLine.GetInternalBuffer();

            while (sclineRas.SweepScanline(scline))
            {
                //3.1. clear
                _grayScaleLine.Clear();
                //3.2. write grayscale span to temp buffer
                //3.3 convert to subpixel value and write to dest buffer
                //render solid single scanline
                int    num_spans = scline.SpanCount;
                byte[] covers    = scline.GetCovers();
                //render each span in the scanline
                for (int i = 1; i <= num_spans; ++i)
                {
                    ScanlineSpan span = scline.GetSpan(i);
                    if (span.len > 0)
                    {
                        //positive len
                        _grayScaleLine.SubPixBlendSolidHSpan(span.x, span.len, color_alpha, covers, span.cover_index);
                    }
                    else
                    {
                        //fill the line, same coverage area
                        int x  = span.x;
                        int x2 = (x - span.len - 1);
                        _grayScaleLine.SubPixBlendHL(x, x2, color_alpha, covers[span.cover_index]);
                    }
                }
                BlendScanline(dest_buffer, dest_stride, scline.Y, src_w, src_stride, lineBuff);
#if DEBUG
                dbugMinScanlineCount++;
#endif
            }
        }
        /// <summary>
        /// for fill shape
        /// </summary>
        /// <param name="sclineRas"></param>
        /// <param name="scline"></param>
        /// <param name="color"></param>
        /// <param name="shapeHint"></param>
        public void FillWithColor(GLScanlineRasterizer sclineRas,
                                  GLScanline scline,
                                  PixelFarm.Drawing.Color color)
        {
            //early exit
            if (color.A == 0)
            {
                return;
            }
            if (!sclineRas.RewindScanlines())
            {
                return;
            }
            //-----------------------------------------------

            scline.ResetSpans(sclineRas.MinX, sclineRas.MaxX);
            //-----------------------------------------------
            var lineBuff = this.myLineBuffer;

            lineBuff.Clear();

            while (sclineRas.SweepScanline(scline))
            {
                int y = scline.Y;
                lineBuff.BeginNewLine(y);

                int    num_spans = scline.SpanCount;
                byte[] covers    = scline.GetCovers();

                //copy data from scanline to lineBuff
                //TODO: move linebuf built into the scanline?

                for (int i = 1; i <= num_spans; ++i)
                {
                    ScanlineSpan span = scline.GetSpan(i);
                    if (span.len > 0)
                    {
                        //outline
                        GLBlendSolidHSpan(span.x, span.len, true, lineBuff, color.A, covers, span.cover_index);
                    }
                    else
                    {
                        //fill
                        int x  = span.x;
                        int x2 = (x - span.len - 1);
                        GLBlendHLine(x, x2, true, lineBuff, color.A, covers[span.cover_index]);
                    }
                }

                lineBuff.CloseLine();
            }
            //----------------------------------
            int nelements = myLineBuffer.Count;

            if (nelements > 0)
            {
                this.scanlineShader.AggDrawLines(myLineBuffer, nelements, color);
            }
        }
        public void RenderWithColor(IImageReaderWriter dest,
                                    ScanlineRasterizer sclineRas,
                                    Scanline scline,
                                    Color color)
        {
            if (!sclineRas.RewindScanlines())
            {
                return;
            }                                             //early exit
            //-----------------------------------------------
            scline.ResetSpans(sclineRas.MinX, sclineRas.MaxX);
            switch (this.ScanlineRenderMode)
            {
            default:
            {
                while (sclineRas.SweepScanline(scline))
                {
                    //render solid single scanline
                    int    y         = scline.Y;
                    int    num_spans = scline.SpanCount;
                    byte[] covers    = scline.GetCovers();
                    //render each span in the scanline
                    for (int i = 1; i <= num_spans; ++i)
                    {
                        ScanlineSpan span = scline.GetSpan(i);
                        if (span.len > 0)
                        {
                            //positive len
                            dest.BlendSolidHSpan(span.x, y, span.len, color, covers, span.cover_index);
                        }
                        else
                        {
                            //fill the line, same coverage area
                            int x  = span.x;
                            int x2 = (x - span.len - 1);
                            dest.BlendHL(x, y, x2, color, covers[span.cover_index]);
                        }
                    }
                }
            }
            break;

            case Agg.ScanlineRenderMode.SubPixelRendering:
            {
                scSubPixRas.RenderScanline(dest, sclineRas, scline, color);
            }
            break;

            case Agg.ScanlineRenderMode.Custom:
            {
                while (sclineRas.SweepScanline(scline))
                {
                    CustomRenderSingleScanLine(dest, scline, color);
                }
            }
            break;
            }
        }
        public void RenderWithSpan(IImageReaderWriter dest,
                                   ScanlineRasterizer sclineRas,
                                   Scanline scline,
                                   ISpanGenerator spanGenerator)
        {
            if (!sclineRas.RewindScanlines())
            {
                return;
            }                                             //early exit
            //-----------------------------------------------

            scline.ResetSpans(sclineRas.MinX, sclineRas.MaxX);

            spanGenerator.Prepare();


            if (dest.Stride / 4 > (tempSpanColors.AllocatedSize))
            {
                //if not enough -> alloc more
                tempSpanColors.Clear(dest.Stride / 4);
            }

            ColorRGBA[] colorArray = tempSpanColors.Array;

            while (sclineRas.SweepScanline(scline))
            {
                //render single scanline
                int    y         = scline.Y;
                int    num_spans = scline.SpanCount;
                byte[] covers    = scline.GetCovers();

                for (int i = 1; i <= num_spans; ++i)
                {
                    ScanlineSpan span             = scline.GetSpan(i);
                    int          x                = span.x;
                    int          span_len         = span.len;
                    bool         firstCoverForAll = false;

                    if (span_len < 0)
                    {
                        span_len         = -span_len;
                        firstCoverForAll = true;
                    } //make absolute value

                    //1. generate colors -> store in colorArray
                    spanGenerator.GenerateColors(colorArray, 0, x, y, span_len);

                    //2. blend color in colorArray to destination image
                    dest.BlendColorHSpan(x, y, span_len,
                                         colorArray, 0,
                                         covers, span.cover_index,
                                         firstCoverForAll);
                }
            }
        }
예제 #5
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;
        }
예제 #6
0
        public override void ResetSpans(int min_x, int max_x)
        {
            int max_len = max_x - min_x + 3;
            if (max_len > m_spans.Length)
            {
                m_spans = new ScanlineSpan[max_len];
                m_covers = new byte[max_len];
            }

            last_x = 0x7FFFFFF0;
            m_cover_index = 0; //make it ready for next add
            last_span_index = 0;
            m_spans[last_span_index].len = 0;
        }
예제 #7
0
        /// <summary>
        /// for fill shape
        /// </summary>
        /// <param name="sclineRas"></param>
        /// <param name="scline"></param>
        /// <param name="color"></param>
        /// <param name="shapeHint"></param>
        public void FillWithColor(GLScanlineRasterizer sclineRas,
                                  GLScanline scline,
                                  PixelFarm.Drawing.Color color)
        {
            //early exit
            if (color.A == 0)
            {
                return;
            }
            if (!sclineRas.RewindScanlines())
            {
                return;
            }
            //-----------------------------------------------

            scline.ResetSpans(sclineRas.MinX, sclineRas.MaxX);
            //-----------------------------------------------



            this.mySinglePixelBuffer.Clear();
            this.myLineBuffer.Clear();

            while (sclineRas.SweepScanline(scline))
            {
                int    y         = scline.Y;
                int    num_spans = scline.SpanCount;
                byte[] covers    = scline.GetCovers();
                for (int i = 1; i <= num_spans; ++i)
                {
                    ScanlineSpan span = scline.GetSpan(i);
                    if (span.len > 0)
                    {
                        //outline
                        GLBlendSolidHSpan(span.x, y, span.len, color, covers, span.cover_index);
                    }
                    else
                    {
                        //fill
                        int x  = span.x;
                        int x2 = (x - span.len - 1);
                        GLBlendHLine(x, y, x2, color, covers[span.cover_index]);
                    }
                }
            }


            DrawPointAndLineWithVertices();
        }
예제 #8
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;
 }
예제 #9
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++;
 }
예제 #10
0
        public override void ResetSpans(int min_x, int max_x)
        {
            int max_len = max_x - min_x + 3;

            if (max_len > m_spans.Length)
            {
                m_spans  = new ScanlineSpan[max_len];
                m_covers = new byte[max_len];
            }

            last_x          = 0x7FFFFFF0;
            m_cover_index   = 0; //make it ready for next add
            last_span_index = 0;
            m_spans[last_span_index].len = 0;
        }
예제 #11
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)
     {
         //append to last cell
         m_spans[last_span_index].len++;
     }
     else
     {
         //start new  
         last_span_index++;
         m_spans[last_span_index] = new ScanlineSpan((short)x, m_cover_index);
     }
     last_x = x;
     m_cover_index++; //make it ready for next add
 }
예제 #12
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;
        }
예제 #13
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)
     {
         //append to last cell
         m_spans[last_span_index].len++;
     }
     else
     {
         //start new
         last_span_index++;
         m_spans[last_span_index] = new ScanlineSpan((short)x, m_cover_index);
     }
     last_x = x;
     m_cover_index++; //make it ready for next add
 }
예제 #14
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;
        }
예제 #15
0
        public override void AddSpan(int x, int len, int cover)
        {
            int backupCover = cover;

            if (x == last_x + 1 &&
                m_spans[last_span_index].len < 0 &&
                cover == m_spans[last_span_index].cover_index)
            {
                //just append data to latest span ***
                m_spans[last_span_index].len -= (short)len;
            }
            else
            {
                m_covers[m_cover_index] = (byte)cover;
                last_span_index++;
                //---------------------------------------------------
                //start new
                m_spans[last_span_index] = new ScanlineSpan((short)x, (short)(-len), m_cover_index);
                m_cover_index++; //make it ready for next add
            }
            last_x = x + len - 1;
        }
예제 #16
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;
        }
예제 #17
0
 public override void AddSpan(int x, int len, int cover)
 {
     int backupCover = cover;
     if (x == last_x + 1
         && m_spans[last_span_index].len < 0
         && cover == m_spans[last_span_index].cover_index)
     {
         //just append data to latest span ***
         m_spans[last_span_index].len -= (short)len;
     }
     else
     {
         m_covers[m_cover_index] = (byte)cover;
         last_span_index++;
         //---------------------------------------------------
         //start new  
         m_spans[last_span_index] = new ScanlineSpan((short)x, (short)(-len), m_cover_index);
         m_cover_index++; //make it ready for next add
     }
     last_x = x + len - 1;
 }
        void SubPixRender(IImageReaderWriter dest, Scanline scanline, ColorRGBA color)
        {
            byte[] covers    = scanline.GetCovers();
            int    num_spans = scanline.SpanCount;
            int    y         = scanline.Y;

            byte[]        buffer       = dest.GetBuffer();
            IPixelBlender blender      = dest.GetRecieveBlender();
            int           last_x       = int.MinValue;
            int           prev_cover   = 0;
            int           bufferOffset = 0;
            ColorRGBA     prevColor    = ColorRGBA.White;

            for (int i = 1; i <= num_spans; ++i)
            {
                //render span by span

                ScanlineSpan span = scanline.GetSpan(i);
                if (span.x != last_x + 1)
                {
                    bufferOffset = dest.GetBufferOffsetXY(span.x, y);
                    //when skip  then reset
                    prev_cover = 0;
                    prevColor  = ColorRGBA.White;
                }

                last_x = span.x;
                int num_pix = span.len;
                if (num_pix < 0)
                {
                    //special encode***
                    num_pix = -num_pix; //make it positive value
                    last_x += (num_pix - 1);
                    //long span with coverage
                    int coverageValue = covers[span.cover_index];
                    //-------------------------------------------
                    if (coverageValue >= 255)
                    {
                        //100% cover
                        int       a           = ((coverageValue + 1) * color.Alpha0To255) >> 8;
                        ColorRGBA newc        = prevColor = new ColorRGBA(color.red, color.green, color.blue);
                        ColorRGBA todrawColor = new ColorRGBA(newc, a);
                        prev_cover = 255;//full
                        while (num_pix > 0)
                        {
                            blender.BlendPixel(buffer, bufferOffset, todrawColor);
                            bufferOffset += 4; //1 pixel 4 bytes
                            --num_pix;
                        }
                    }
                    else
                    {
                        prev_cover = coverageValue;
                        int       a           = ((coverageValue + 1) * color.Alpha0To255) >> 8;
                        ColorRGBA newc        = prevColor = new ColorRGBA(color.red, color.green, color.blue);
                        ColorRGBA todrawColor = new ColorRGBA(newc, a);
                        while (num_pix > 0)
                        {
                            blender.BlendPixel(buffer, bufferOffset, todrawColor);
                            bufferOffset += 4; //1 pixel 4 bytes
                            --num_pix;
                        }
                    }
                }
                else
                {
                    int coverIndex = span.cover_index;
                    last_x += (num_pix - 1);
                    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 + 1) * color.Alpha0To255) >> 8;
                            blender.BlendPixel(buffer, bufferOffset, new ColorRGBA(newc, a));
                            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 + 1) * color.Alpha0To255) >> 8;
                                blender.BlendPixel(buffer, bufferOffset, new ColorRGBA(newc, a));
                            }
                            else if (coverageValue < cover_2_3)
                            {
                                if (isLeftToRight)
                                {
                                    c_r = prevColor.blue;
                                    c_g = (byte)(255 - (255f * (subpix_percent)));
                                    c_b = color.blue;
                                }
                                else
                                {
                                    c_r = 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 + 1) * color.Alpha0To255) >> 8;
                                blender.BlendPixel(buffer, bufferOffset, new ColorRGBA(newc, a));
                            }
                            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 + 1) * color.Alpha0To255) >> 8;
                                blender.BlendPixel(buffer, bufferOffset, new ColorRGBA(newc, a));
                            }
                        }
                        bufferOffset += 4; //1 pixel 4 bits
                        --num_pix;
                    }
                }
            }
        }
예제 #19
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;
 }
예제 #20
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;
 }