xref: /haiku/headers/libs/agg/agg_conv_marker.h (revision c90684742e7361651849be4116d0e5de3a817194)
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 // conv_marker
17 //
18 //----------------------------------------------------------------------------
19 #ifndef AGG_CONV_MARKER_INCLUDED
20 #define AGG_CONV_MARKER_INCLUDED
21 
22 #include "agg_basics.h"
23 #include "agg_trans_affine.h"
24 
25 namespace agg
26 {
27     //-------------------------------------------------------------conv_marker
28     template<class MarkerLocator, class MarkerShapes>
29     class conv_marker
30     {
31     public:
32         conv_marker(MarkerLocator& ml, MarkerShapes& ms);
33 
34         trans_affine& transform() { return m_transform; }
35         const trans_affine& transform() const { return m_transform; }
36 
37         void rewind(unsigned path_id);
38         unsigned vertex(double* x, double* y);
39 
40     private:
41         conv_marker(const conv_marker<MarkerLocator, MarkerShapes>&);
42         const conv_marker<MarkerLocator, MarkerShapes>&
43             operator = (const conv_marker<MarkerLocator, MarkerShapes>&);
44 
45         enum status_e
46         {
47             initial,
48             markers,
49             polygon,
50             stop
51         };
52 
53         MarkerLocator* m_marker_locator;
54         MarkerShapes*  m_marker_shapes;
55         trans_affine   m_transform;
56         trans_affine   m_mtx;
57         status_e       m_status;
58         unsigned       m_marker;
59         unsigned       m_num_markers;
60     };
61 
62 
63     //------------------------------------------------------------------------
64     template<class MarkerLocator, class MarkerShapes>
65     conv_marker<MarkerLocator, MarkerShapes>::conv_marker(MarkerLocator& ml, MarkerShapes& ms) :
66         m_marker_locator(&ml),
67         m_marker_shapes(&ms),
68         m_status(initial),
69         m_marker(0),
70         m_num_markers(1)
71     {
72     }
73 
74 
75     //------------------------------------------------------------------------
76     template<class MarkerLocator, class MarkerShapes>
77     void conv_marker<MarkerLocator, MarkerShapes>::rewind(unsigned)
78     {
79         m_status = initial;
80         m_marker = 0;
81         m_num_markers = 1;
82     }
83 
84 
85     //------------------------------------------------------------------------
86     template<class MarkerLocator, class MarkerShapes>
87     unsigned conv_marker<MarkerLocator, MarkerShapes>::vertex(double* x, double* y)
88     {
89         unsigned cmd = path_cmd_move_to;
90         double x1, y1, x2, y2;
91 
92         while(!is_stop(cmd))
93         {
94             switch(m_status)
95             {
96             case initial:
97                 if(m_num_markers == 0)
98                 {
99                    cmd = path_cmd_stop;
100                    break;
101                 }
102                 m_marker_locator->rewind(m_marker);
103                 ++m_marker;
104                 m_num_markers = 0;
105                 m_status = markers;
106 
107             case markers:
108                 if(is_stop(m_marker_locator->vertex(&x1, &y1)))
109                 {
110                     m_status = initial;
111                     break;
112                 }
113                 if(is_stop(m_marker_locator->vertex(&x2, &y2)))
114                 {
115                     m_status = initial;
116                     break;
117                 }
118                 ++m_num_markers;
119                 m_mtx = m_transform;
120                 m_mtx *= trans_affine_rotation(atan2(y2 - y1, x2 - x1));
121                 m_mtx *= trans_affine_translation(x1, y1);
122                 m_marker_shapes->rewind(m_marker - 1);
123                 m_status = polygon;
124 
125             case polygon:
126                 cmd = m_marker_shapes->vertex(x, y);
127                 if(is_stop(cmd))
128                 {
129                     cmd = path_cmd_move_to;
130                     m_status = markers;
131                     break;
132                 }
133                 m_mtx.transform(x, y);
134                 return cmd;
135 
136             case stop:
137                 cmd = path_cmd_stop;
138                 break;
139             }
140         }
141         return cmd;
142     }
143 
144 }
145 
146 
147 #endif
148 
149