Esempio n. 1
0
        VertexCmd GetNextVertex(out double x, out double y)
        {
            x = 0; y = 0;
            VertexCmd cmd = VertexCmd.LineTo;

            do
            {
                switch (m_status)
                {
                case Status.Init:
                    this.Rewind();
                    goto case Status.Ready;

                case Status.Ready:

                    if (multipartVertexDistanceList.CurrentRangeLen < 2 + (m_closed ? 1 : 0))
                    {
                        cmd = VertexCmd.NoMore;
                        break;
                    }
                    m_status     = m_closed ? Status.Outline1 : Status.Cap1;
                    cmd          = VertexCmd.MoveTo;
                    m_src_vertex = 0;
                    m_out_vertex = 0;
                    break;

                case Status.CloseFirst:
                    m_status = Status.Outline2;
                    cmd      = VertexCmd.MoveTo;
                    goto case Status.Outline2;

                case Status.Cap1:
                {
                    Vertex2d v0, v1;

                    multipartVertexDistanceList.GetFirst2(out v0, out v1);
                    m_stroker.CreateCap(
                        m_out_vertices,
                        v0,
                        v1,
                        v0.CalLen(v1));

                    m_src_vertex  = 1;
                    m_prev_status = Status.Outline1;
                    m_status      = Status.OutVertices;
                    m_out_vertex  = 0;
                }
                break;

                case Status.Cap2:
                {
                    Vertex2d beforeLast, last;
                    multipartVertexDistanceList.GetLast2(out beforeLast, out last);
                    m_stroker.CreateCap(m_out_vertices,
                                        last,
                                        beforeLast,
                                        beforeLast.CalLen(last));
                    m_prev_status = Status.Outline2;
                    m_status      = Status.OutVertices;
                    m_out_vertex  = 0;
                }
                break;

                case Status.Outline1:
                {
                    if (m_closed)
                    {
                        if (m_src_vertex >= multipartVertexDistanceList.CurrentRangeLen)
                        {
                            m_prev_status = Status.CloseFirst;
                            m_status      = Status.EndPoly1;
                            break;
                        }
                    }
                    else
                    {
                        if (m_src_vertex >= multipartVertexDistanceList.CurrentRangeLen - 1)
                        {
                            m_status = Status.Cap2;
                            break;
                        }
                    }

                    Vertex2d prev, cur, next;
                    multipartVertexDistanceList.GetTripleVertices(m_src_vertex,
                                                                  out prev,
                                                                  out cur,
                                                                  out next);
                    //check if we should join or not ?

                    //don't join it
                    m_stroker.CreateJoin(m_out_vertices,
                                         prev,
                                         cur,
                                         next,
                                         prev.CalLen(cur),
                                         cur.CalLen(next));

                    ++m_src_vertex;
                    m_prev_status = m_status;
                    m_status      = Status.OutVertices;
                    m_out_vertex  = 0;
                }
                break;

                case Status.Outline2:
                {
                    if (m_src_vertex <= (!m_closed ? 1 : 0))
                    {
                        m_status      = Status.EndPoly2;
                        m_prev_status = Status.Stop;
                        break;
                    }

                    --m_src_vertex;

                    Vertex2d prev, cur, next;
                    multipartVertexDistanceList.GetTripleVertices(m_src_vertex,
                                                                  out prev,
                                                                  out cur,
                                                                  out next);

                    m_stroker.CreateJoin(m_out_vertices,
                                         next,
                                         cur,
                                         prev,
                                         cur.CalLen(next),
                                         prev.CalLen(cur));
                    m_prev_status = m_status;
                    m_status      = Status.OutVertices;
                    m_out_vertex  = 0;
                }
                break;

                case Status.OutVertices:
                    if (m_out_vertex >= m_out_vertices.Count)
                    {
                        m_status = m_prev_status;
                    }
                    else
                    {
                        m_out_vertices.GetVertex(m_out_vertex++, out x, out y);
                        return(cmd);
                    }
                    break;

                case Status.EndPoly1:
                    m_status = m_prev_status;
                    x        = (int)EndVertexOrientation.CCW;
                    y        = 0;
                    return(VertexCmd.Close);

                case Status.EndPoly2:
                    m_status = m_prev_status;
                    x        = (int)EndVertexOrientation.CW;
                    y        = 0;
                    return(VertexCmd.Close);

                case Status.Stop:
                    cmd = VertexCmd.NoMore;
                    break;
                }
            } while (!VertexHelper.IsEmpty(cmd));
            return(cmd);
        }