xref: /haiku/headers/libs/agg/agg_vcgen_vertex_sequence.h (revision 2e7da8455a92f61db667fdaf602308344c4426d6)
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 //          mcseemagg@yahoo.com
13 //          http://www.antigrain.com
14 //----------------------------------------------------------------------------
15 
16 #ifndef AGG_VCGEN_VERTEX_SEQUENCE_INCLUDED
17 #define AGG_VCGEN_VERTEX_SEQUENCE_INCLUDED
18 
19 #include "agg_basics.h"
20 #include "agg_vertex_sequence.h"
21 #include "agg_shorten_path.h"
22 
23 namespace agg
24 {
25 
26     //===================================================vcgen_vertex_sequence
27     class vcgen_vertex_sequence
28     {
29     public:
30         typedef vertex_dist_cmd                 vertex_type;
31         typedef vertex_sequence<vertex_type, 6> vertex_storage;
32 
vcgen_vertex_sequence()33         vcgen_vertex_sequence() :
34             m_flags(0),
35             m_cur_vertex(0),
36             m_shorten(0.0),
37             m_ready(false)
38         {
39         }
40 
41         // Vertex Generator Interface
42         void remove_all();
43         void add_vertex(double x, double y, unsigned cmd);
44 
45         // Vertex Source Interface
46         void     rewind(unsigned path_id);
47         unsigned vertex(double* x, double* y);
48 
shorten(double s)49         void shorten(double s) { m_shorten = s; }
shorten()50         double shorten() const { return m_shorten; }
51 
52     private:
53         vcgen_vertex_sequence(const vcgen_vertex_sequence&);
54         const vcgen_vertex_sequence& operator = (const vcgen_vertex_sequence&);
55 
56         vertex_storage m_src_vertices;
57         unsigned       m_flags;
58         unsigned       m_cur_vertex;
59         double         m_shorten;
60         bool           m_ready;
61     };
62 
63 
64     //------------------------------------------------------------------------
remove_all()65     inline void vcgen_vertex_sequence::remove_all()
66     {
67         m_ready = false;
68         m_src_vertices.remove_all();
69         m_cur_vertex = 0;
70         m_flags = 0;
71     }
72 
73     //------------------------------------------------------------------------
add_vertex(double x,double y,unsigned cmd)74     inline void vcgen_vertex_sequence::add_vertex(double x, double y, unsigned cmd)
75     {
76         m_ready = false;
77         if(is_move_to(cmd))
78         {
79             m_src_vertices.modify_last(vertex_dist_cmd(x, y, cmd));
80         }
81         else
82         {
83             if(is_vertex(cmd))
84             {
85                 m_src_vertices.add(vertex_dist_cmd(x, y, cmd));
86             }
87             else
88             {
89                 m_flags = cmd & path_flags_mask;
90             }
91         }
92     }
93 
94 
95     //------------------------------------------------------------------------
rewind(unsigned)96     inline void vcgen_vertex_sequence::rewind(unsigned)
97     {
98         if(!m_ready)
99         {
100             m_src_vertices.close(is_closed(m_flags));
101             shorten_path(m_src_vertices, m_shorten, get_close_flag(m_flags));
102         }
103         m_ready = true;
104         m_cur_vertex = 0;
105     }
106 
107     //------------------------------------------------------------------------
vertex(double * x,double * y)108     inline unsigned vcgen_vertex_sequence::vertex(double* x, double* y)
109     {
110         if(!m_ready)
111         {
112             rewind(0);
113         }
114 
115         if(m_cur_vertex == m_src_vertices.size())
116         {
117             ++m_cur_vertex;
118             return path_cmd_end_poly | m_flags;
119         }
120 
121         if(m_cur_vertex > m_src_vertices.size())
122         {
123             return path_cmd_stop;
124         }
125 
126         vertex_type& v = m_src_vertices[m_cur_vertex++];
127         *x = v.x;
128         *y = v.y;
129         return v.cmd;
130     }
131 
132 
133 }
134 
135 #endif
136