//------------------------------------------------------------------------
 void vcgen_contour::add_vertex(double x, double y, unsigned cmd)
 {
     m_status = initial;
     if(is_move_to(cmd))
     {
         m_src_vertices.modify_last(vertex_dist(x, y));
     }
     else
     {
         if(is_vertex(cmd))
         {
             m_src_vertices.add(vertex_dist(x, y));
         }
         else
         {
             if(is_end_poly(cmd))
             {
                 m_closed = get_close_flag(cmd);
                 if(m_orientation == path_flags_none) 
                 {
                     m_orientation = get_orientation(cmd);
                 }
             }
         }
     }
 }
 //------------------------------------------------------------------------
 void path_renderer::move_to(double x, double y, bool rel)          // M, m
 {
     if(rel && m_storage.total_vertices()) {
        double x2,y2;
        unsigned cmd = m_storage.last_vertex(&x2,&y2);
        if(is_end_poly(cmd)) {
            // rewind until we find a real vertex
            unsigned idx = m_storage.total_vertices()-1;
            while(idx && !is_vertex(m_storage.vertex(--idx,&x2,&y2)));
        }
        x += x2;
        y += y2;
     }
     m_storage.move_to(x, y);
 }
    unsigned conv_adaptor_vpgen<VertexSource, VPGen>::vertex(double* x, double* y)
    {
        unsigned cmd = path_cmd_stop;
        for(;;)
        {
            cmd = m_vpgen.vertex(x, y);
            if(!is_stop(cmd)) break;

            if(m_poly_flags && !m_vpgen.auto_unclose())
            {
                *x = 0.0;
                *y = 0.0;
                cmd = m_poly_flags;
                m_poly_flags = 0;
                break;
            }

            if(m_vertices < 0)
            {
                if(m_vertices < -1) 
                {
                    m_vertices = 0;
                    return path_cmd_stop;
                }
                m_vpgen.move_to(m_start_x, m_start_y);
                m_vertices = 1;
                continue;
            }

            double tx, ty;
            cmd = m_source->vertex(&tx, &ty);
            if(is_vertex(cmd))
            {
                if(is_move_to(cmd)) 
                {
                    if(m_vpgen.auto_close() && m_vertices > 2)
                    {
                        m_vpgen.line_to(m_start_x, m_start_y);
                        m_poly_flags = path_cmd_end_poly | path_flags_close;
                        m_start_x    = tx;
                        m_start_y    = ty;
                        m_vertices   = -1;
                        continue;
                    }
                    m_vpgen.move_to(tx, ty);
                    m_start_x  = tx;
                    m_start_y  = ty;
                    m_vertices = 1;
                }
                else 
                {
                    m_vpgen.line_to(tx, ty);
                    ++m_vertices;
                }
            }
            else
            {
                if(is_end_poly(cmd))
                {
                    m_poly_flags = cmd;
                    if(is_closed(cmd) || m_vpgen.auto_close())
                    {
                        if(m_vpgen.auto_close()) m_poly_flags |= path_flags_close;
                        if(m_vertices > 2)
                        {
                            m_vpgen.line_to(m_start_x, m_start_y);
                        }
                        m_vertices = 0;
                    }
                }
                else
                {
                    // path_cmd_stop
                    if(m_vpgen.auto_close() && m_vertices > 2)
                    {
                        m_vpgen.line_to(m_start_x, m_start_y);
                        m_poly_flags = path_cmd_end_poly | path_flags_close;
                        m_vertices   = -2;
                        continue;
                    }
                    break;
                }
            }
        }
        return cmd;
    }