//---------------------------------------------------------------------
        public line_interpolator_image(IPixelFormat ren, line_parameters lp,
                                       int sx, int sy, int ex, int ey,
                                       int pattern_start,
                                       double scale_x)
        {
            m_lp = (lp);
            m_li = new dda2_line_interpolator(lp.vertical ? line_dbl_hr(lp.x2 - lp.x1) :
                                              line_dbl_hr(lp.y2 - lp.y1),
                                              lp.vertical ? abs(lp.y2 - lp.y1) :
                                              abs(lp.x2 - lp.x1) + 1);
            m_di = new distance_interpolator4(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, lp.len, scale_x,
                                              lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask);
            m_ren   = (ren);
            m_x     = (lp.x1 >> line_subpixel_shift);
            m_y     = (lp.y1 >> line_subpixel_shift);
            m_old_x = (m_x);
            m_old_y = (m_y);
            m_count = ((lp.vertical ? abs((lp.y2 >> line_subpixel_shift) - m_y) :
                        abs((lp.x2 >> line_subpixel_shift) - m_x)));
            m_width = (ren.subpixel_width());
            //m_max_extent(m_width >> (line_subpixel_shift - 2));
            m_max_extent = ((m_width + LineAABasics.line_subpixel_scale) >> line_subpixel_shift);
            m_start      = (pattern_start + (m_max_extent + 2) * ren.pattern_width());
            m_step       = (0);

            dda2_line_interpolator li = new dda2_line_interpolator(0, lp.vertical ?
                                                                   (lp.dy << LineAABasics.line_subpixel_shift) :
                                                                   (lp.dx << LineAABasics.line_subpixel_shift),
                                                                   lp.len);

            uint i;
            int  stop = m_width + LineAABasics.line_subpixel_scale * 2;

            for (i = 0; i < max_half_width; ++i)
            {
                m_dist_pos[i] = li.y();
                if (m_dist_pos[i] >= stop)
                {
                    break;
                }
                ++li;
            }
            m_dist_pos[i] = 0x7FFF0000;

            int dist1_start;
            int dist2_start;
            int npix = 1;

            if (lp.vertical)
            {
                do
                {
                    --m_li;
                    m_y -= lp.inc;
                    m_x  = (m_lp.x1 + m_li.y()) >> line_subpixel_shift;

                    if (lp.inc > 0)
                    {
                        m_di.dec_y(m_x - m_old_x);
                    }
                    else
                    {
                        m_di.inc_y(m_x - m_old_x);
                    }

                    m_old_x = m_x;

                    dist1_start = dist2_start = m_di.dist_start();

                    int dx = 0;
                    if (dist1_start < 0)
                    {
                        ++npix;
                    }
                    do
                    {
                        dist1_start += m_di.dy_start();
                        dist2_start -= m_di.dy_start();
                        if (dist1_start < 0)
                        {
                            ++npix;
                        }
                        if (dist2_start < 0)
                        {
                            ++npix;
                        }
                        ++dx;
                    }while(m_dist_pos[dx] <= m_width);
                    if (npix == 0)
                    {
                        break;
                    }

                    npix = 0;
                }while(--m_step >= -m_max_extent);
            }
            else
            {
                do
                {
                    --m_li;

                    m_x -= lp.inc;
                    m_y  = (m_lp.y1 + m_li.y()) >> line_subpixel_shift;

                    if (lp.inc > 0)
                    {
                        m_di.dec_x(m_y - m_old_y);
                    }
                    else
                    {
                        m_di.inc_x(m_y - m_old_y);
                    }

                    m_old_y = m_y;

                    dist1_start = dist2_start = m_di.dist_start();

                    int dy = 0;
                    if (dist1_start < 0)
                    {
                        ++npix;
                    }
                    do
                    {
                        dist1_start -= m_di.dx_start();
                        dist2_start += m_di.dx_start();
                        if (dist1_start < 0)
                        {
                            ++npix;
                        }
                        if (dist2_start < 0)
                        {
                            ++npix;
                        }
                        ++dy;
                    }while(m_dist_pos[dy] <= m_width);
                    if (npix == 0)
                    {
                        break;
                    }

                    npix = 0;
                }while(--m_step >= -m_max_extent);
            }
            m_li.adjust_forward();
            m_step -= m_max_extent;
        }
        //---------------------------------------------------------------------
        public bool step_hor()
        {
            ++m_li;
            m_x += m_lp.inc;
            m_y  = (m_lp.y1 + m_li.y()) >> line_subpixel_shift;

            if (m_lp.inc > 0)
            {
                m_di.inc_x(m_y - m_old_y);
            }
            else
            {
                m_di.dec_x(m_y - m_old_y);
            }

            m_old_y = m_y;

            int s1 = m_di.dist() / m_lp.len;
            int s2 = -s1;

            if (m_lp.inc < 0)
            {
                s1 = -s1;
            }

            int dist_start;
            int dist_pict;
            int dist_end;
            int dy;
            int dist;

            dist_start = m_di.dist_start();
            dist_pict  = m_di.dist_pict() + m_start;
            dist_end   = m_di.dist_end();
            RGBA_Bytes *p0 = m_colors + max_half_width + 2;
            RGBA_Bytes *p1 = p0;

            int npix = 0;

            p1->clear();
            if (dist_end > 0)
            {
                if (dist_start <= 0)
                {
                    m_ren.pixel(p1, dist_pict, s2);
                }
                ++npix;
            }
            ++p1;

            dy = 1;
            while ((dist = m_dist_pos[dy]) - s1 <= m_width)
            {
                dist_start -= m_di.dx_start();
                dist_pict  -= m_di.dx_pict();
                dist_end   -= m_di.dx_end();
                p1->clear();
                if (dist_end > 0 && dist_start <= 0)
                {
                    if (m_lp.inc > 0)
                    {
                        dist = -dist;
                    }
                    m_ren.pixel(p1, dist_pict, s2 - dist);
                    ++npix;
                }
                ++p1;
                ++dy;
            }

            dy         = 1;
            dist_start = m_di.dist_start();
            dist_pict  = m_di.dist_pict() + m_start;
            dist_end   = m_di.dist_end();
            while ((dist = m_dist_pos[dy]) + s1 <= m_width)
            {
                dist_start += m_di.dx_start();
                dist_pict  += m_di.dx_pict();
                dist_end   += m_di.dx_end();
                --p0;
                p0->clear();
                if (dist_end > 0 && dist_start <= 0)
                {
                    if (m_lp.inc > 0)
                    {
                        dist = -dist;
                    }
                    m_ren.pixel(p0, dist_pict, s2 + dist);
                    ++npix;
                }
                ++dy;
            }
            m_ren.blend_color_vspan(m_x,
                                    m_y - dy + 1,
                                    (uint)(p1 - p0),
                                    p0);
            return(npix && ++m_step < m_count);
        }
        //---------------------------------------------------------------------
        public line_interpolator_image(IPixelFormat ren, line_parameters lp,
								int sx, int sy, int ex, int ey,
								int pattern_start,
								double scale_x)
        {
            m_lp=(lp);
            m_li = new dda2_line_interpolator(lp.vertical ? line_dbl_hr(lp.x2 - lp.x1) :
                               line_dbl_hr(lp.y2 - lp.y1),
                 lp.vertical ? abs(lp.y2 - lp.y1) :
                               abs(lp.x2 - lp.x1) + 1);
            m_di = new distance_interpolator4(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, lp.len, scale_x,
                 lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask);
            m_ren=(ren);
            m_x=(lp.x1 >> line_subpixel_shift);
            m_y=(lp.y1 >> line_subpixel_shift);
            m_old_x=(m_x);
            m_old_y=(m_y);
            m_count=((lp.vertical ? abs((lp.y2 >> line_subpixel_shift) - m_y) :
                                   abs((lp.x2 >> line_subpixel_shift) - m_x)));
            m_width=(ren.subpixel_width());

            //m_max_extent(m_width >> (line_subpixel_shift - 2));
            m_max_extent=((m_width + LineAABasics.line_subpixel_scale) >> line_subpixel_shift);
            m_start=(pattern_start + (m_max_extent + 2) * ren.pattern_width());
            m_step=(0);

            dda2_line_interpolator li = new dda2_line_interpolator(0, lp.vertical ?
                                              (lp.dy << LineAABasics.line_subpixel_shift) :
                                              (lp.dx << LineAABasics.line_subpixel_shift),
                                           lp.len);

            uint i;
            int stop = m_width + LineAABasics.line_subpixel_scale * 2;
            for(i = 0; i < max_half_width; ++i)
            {
                m_dist_pos[i] = li.y();
                if(m_dist_pos[i] >= stop) break;
                ++li;
            }
            m_dist_pos[i] = 0x7FFF0000;

            int dist1_start;
            int dist2_start;
            int npix = 1;

            if(lp.vertical)
            {
                do
                {
                    --m_li;
                    m_y -= lp.inc;
                    m_x = (m_lp.x1 + m_li.y()) >> line_subpixel_shift;

                    if(lp.inc > 0) m_di.dec_y(m_x - m_old_x);
                    else           m_di.inc_y(m_x - m_old_x);

                    m_old_x = m_x;

                    dist1_start = dist2_start = m_di.dist_start();

                    int dx = 0;
                    if(dist1_start < 0) ++npix;
                    do
                    {
                        dist1_start += m_di.dy_start();
                        dist2_start -= m_di.dy_start();
                        if(dist1_start < 0) ++npix;
                        if(dist2_start < 0) ++npix;
                        ++dx;
                    }
                    while(m_dist_pos[dx] <= m_width);
                    if(npix == 0) break;

                    npix = 0;
                }
                while(--m_step >= -m_max_extent);
            }
            else
            {
                do
                {
                    --m_li;

                    m_x -= lp.inc;
                    m_y = (m_lp.y1 + m_li.y()) >> line_subpixel_shift;

                    if(lp.inc > 0) m_di.dec_x(m_y - m_old_y);
                    else           m_di.inc_x(m_y - m_old_y);

                    m_old_y = m_y;

                    dist1_start = dist2_start = m_di.dist_start();

                    int dy = 0;
                    if(dist1_start < 0) ++npix;
                    do
                    {
                        dist1_start -= m_di.dx_start();
                        dist2_start += m_di.dx_start();
                        if(dist1_start < 0) ++npix;
                        if(dist2_start < 0) ++npix;
                        ++dy;
                    }
                    while(m_dist_pos[dy] <= m_width);
                    if(npix == 0) break;

                    npix = 0;
                }
                while(--m_step >= -m_max_extent);
            }
            m_li.adjust_forward();
            m_step -= m_max_extent;
        }