xref: /haiku/src/libs/agg/src/agg_vcgen_stroke.cpp (revision e39da397f5ff79f2db9f9a3ddf1852b6710578af)
139241fe2SDarkWyrm //----------------------------------------------------------------------------
2*e39da397SStephan Aßmus // Anti-Grain Geometry - Version 2.4
3*e39da397SStephan Aßmus // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
439241fe2SDarkWyrm //
539241fe2SDarkWyrm // Permission to copy, use, modify, sell and distribute this software
639241fe2SDarkWyrm // is granted provided this copyright notice appears in all copies.
739241fe2SDarkWyrm // This software is provided "as is" without express or implied
839241fe2SDarkWyrm // warranty, and with no claim as to its suitability for any purpose.
939241fe2SDarkWyrm //
1039241fe2SDarkWyrm //----------------------------------------------------------------------------
1139241fe2SDarkWyrm // Contact: mcseem@antigrain.com
1239241fe2SDarkWyrm //          mcseemagg@yahoo.com
1339241fe2SDarkWyrm //          http://www.antigrain.com
1439241fe2SDarkWyrm //----------------------------------------------------------------------------
1539241fe2SDarkWyrm //
1639241fe2SDarkWyrm // Stroke generator
1739241fe2SDarkWyrm //
1839241fe2SDarkWyrm //----------------------------------------------------------------------------
1939241fe2SDarkWyrm #include <math.h>
2039241fe2SDarkWyrm #include "agg_vcgen_stroke.h"
2139241fe2SDarkWyrm #include "agg_shorten_path.h"
2239241fe2SDarkWyrm 
2339241fe2SDarkWyrm namespace agg
2439241fe2SDarkWyrm {
2539241fe2SDarkWyrm 
2639241fe2SDarkWyrm     //------------------------------------------------------------------------
vcgen_stroke()2739241fe2SDarkWyrm     vcgen_stroke::vcgen_stroke() :
28*e39da397SStephan Aßmus         m_stroker(),
2939241fe2SDarkWyrm         m_src_vertices(),
3039241fe2SDarkWyrm         m_out_vertices(),
3139241fe2SDarkWyrm         m_shorten(0.0),
3239241fe2SDarkWyrm         m_closed(0),
3339241fe2SDarkWyrm         m_status(initial),
3439241fe2SDarkWyrm         m_src_vertex(0),
3539241fe2SDarkWyrm         m_out_vertex(0)
3639241fe2SDarkWyrm     {
3739241fe2SDarkWyrm     }
3839241fe2SDarkWyrm 
3939241fe2SDarkWyrm     //------------------------------------------------------------------------
remove_all()4039241fe2SDarkWyrm     void vcgen_stroke::remove_all()
4139241fe2SDarkWyrm     {
4239241fe2SDarkWyrm         m_src_vertices.remove_all();
4339241fe2SDarkWyrm         m_closed = 0;
4439241fe2SDarkWyrm         m_status = initial;
4539241fe2SDarkWyrm     }
4639241fe2SDarkWyrm 
4739241fe2SDarkWyrm 
4839241fe2SDarkWyrm     //------------------------------------------------------------------------
add_vertex(double x,double y,unsigned cmd)4939241fe2SDarkWyrm     void vcgen_stroke::add_vertex(double x, double y, unsigned cmd)
5039241fe2SDarkWyrm     {
5139241fe2SDarkWyrm         m_status = initial;
5239241fe2SDarkWyrm         if(is_move_to(cmd))
5339241fe2SDarkWyrm         {
5439241fe2SDarkWyrm             m_src_vertices.modify_last(vertex_dist(x, y));
5539241fe2SDarkWyrm         }
5639241fe2SDarkWyrm         else
5739241fe2SDarkWyrm         {
5839241fe2SDarkWyrm             if(is_vertex(cmd))
5939241fe2SDarkWyrm             {
6039241fe2SDarkWyrm                 m_src_vertices.add(vertex_dist(x, y));
6139241fe2SDarkWyrm             }
6239241fe2SDarkWyrm             else
6339241fe2SDarkWyrm             {
6439241fe2SDarkWyrm                 m_closed = get_close_flag(cmd);
6539241fe2SDarkWyrm             }
6639241fe2SDarkWyrm         }
6739241fe2SDarkWyrm     }
6839241fe2SDarkWyrm 
6939241fe2SDarkWyrm     //------------------------------------------------------------------------
rewind(unsigned)7039241fe2SDarkWyrm     void vcgen_stroke::rewind(unsigned)
7139241fe2SDarkWyrm     {
7239241fe2SDarkWyrm         if(m_status == initial)
7339241fe2SDarkWyrm         {
7439241fe2SDarkWyrm             m_src_vertices.close(m_closed != 0);
7539241fe2SDarkWyrm             shorten_path(m_src_vertices, m_shorten, m_closed);
76d1d811ecSDarkWyrm             if(m_src_vertices.size() < 3) m_closed = 0;
7739241fe2SDarkWyrm         }
7839241fe2SDarkWyrm         m_status = ready;
7939241fe2SDarkWyrm         m_src_vertex = 0;
8039241fe2SDarkWyrm         m_out_vertex = 0;
8139241fe2SDarkWyrm     }
8239241fe2SDarkWyrm 
8339241fe2SDarkWyrm 
8439241fe2SDarkWyrm     //------------------------------------------------------------------------
vertex(double * x,double * y)8539241fe2SDarkWyrm     unsigned vcgen_stroke::vertex(double* x, double* y)
8639241fe2SDarkWyrm     {
8739241fe2SDarkWyrm         unsigned cmd = path_cmd_line_to;
8839241fe2SDarkWyrm         while(!is_stop(cmd))
8939241fe2SDarkWyrm         {
9039241fe2SDarkWyrm             switch(m_status)
9139241fe2SDarkWyrm             {
9239241fe2SDarkWyrm             case initial:
9339241fe2SDarkWyrm                 rewind(0);
9439241fe2SDarkWyrm 
9539241fe2SDarkWyrm             case ready:
9639241fe2SDarkWyrm                 if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
9739241fe2SDarkWyrm                 {
9839241fe2SDarkWyrm                     cmd = path_cmd_stop;
9939241fe2SDarkWyrm                     break;
10039241fe2SDarkWyrm                 }
10139241fe2SDarkWyrm                 m_status = m_closed ? outline1 : cap1;
10239241fe2SDarkWyrm                 cmd = path_cmd_move_to;
10339241fe2SDarkWyrm                 m_src_vertex = 0;
10439241fe2SDarkWyrm                 m_out_vertex = 0;
10539241fe2SDarkWyrm                 break;
10639241fe2SDarkWyrm 
10739241fe2SDarkWyrm             case cap1:
108*e39da397SStephan Aßmus                 m_stroker.calc_cap(m_out_vertices,
109d1d811ecSDarkWyrm                                    m_src_vertices[0],
11039241fe2SDarkWyrm                                    m_src_vertices[1],
111*e39da397SStephan Aßmus                                    m_src_vertices[0].dist);
11239241fe2SDarkWyrm                 m_src_vertex = 1;
11339241fe2SDarkWyrm                 m_prev_status = outline1;
11439241fe2SDarkWyrm                 m_status = out_vertices;
11539241fe2SDarkWyrm                 m_out_vertex = 0;
11639241fe2SDarkWyrm                 break;
11739241fe2SDarkWyrm 
11839241fe2SDarkWyrm             case cap2:
119*e39da397SStephan Aßmus                 m_stroker.calc_cap(m_out_vertices,
120d1d811ecSDarkWyrm                                    m_src_vertices[m_src_vertices.size() - 1],
12139241fe2SDarkWyrm                                    m_src_vertices[m_src_vertices.size() - 2],
122*e39da397SStephan Aßmus                                    m_src_vertices[m_src_vertices.size() - 2].dist);
12339241fe2SDarkWyrm                 m_prev_status = outline2;
12439241fe2SDarkWyrm                 m_status = out_vertices;
12539241fe2SDarkWyrm                 m_out_vertex = 0;
12639241fe2SDarkWyrm                 break;
12739241fe2SDarkWyrm 
12839241fe2SDarkWyrm             case outline1:
12939241fe2SDarkWyrm                 if(m_closed)
13039241fe2SDarkWyrm                 {
13139241fe2SDarkWyrm                     if(m_src_vertex >= m_src_vertices.size())
13239241fe2SDarkWyrm                     {
13339241fe2SDarkWyrm                         m_prev_status = close_first;
13439241fe2SDarkWyrm                         m_status = end_poly1;
13539241fe2SDarkWyrm                         break;
13639241fe2SDarkWyrm                     }
13739241fe2SDarkWyrm                 }
13839241fe2SDarkWyrm                 else
13939241fe2SDarkWyrm                 {
14039241fe2SDarkWyrm                     if(m_src_vertex >= m_src_vertices.size() - 1)
14139241fe2SDarkWyrm                     {
14239241fe2SDarkWyrm                         m_status = cap2;
14339241fe2SDarkWyrm                         break;
14439241fe2SDarkWyrm                     }
14539241fe2SDarkWyrm                 }
146*e39da397SStephan Aßmus                 m_stroker.calc_join(m_out_vertices,
147d1d811ecSDarkWyrm                                     m_src_vertices.prev(m_src_vertex),
14839241fe2SDarkWyrm                                     m_src_vertices.curr(m_src_vertex),
14939241fe2SDarkWyrm                                     m_src_vertices.next(m_src_vertex),
15039241fe2SDarkWyrm                                     m_src_vertices.prev(m_src_vertex).dist,
151*e39da397SStephan Aßmus                                     m_src_vertices.curr(m_src_vertex).dist);
15239241fe2SDarkWyrm                 ++m_src_vertex;
15339241fe2SDarkWyrm                 m_prev_status = m_status;
15439241fe2SDarkWyrm                 m_status = out_vertices;
15539241fe2SDarkWyrm                 m_out_vertex = 0;
15639241fe2SDarkWyrm                 break;
15739241fe2SDarkWyrm 
15839241fe2SDarkWyrm             case close_first:
15939241fe2SDarkWyrm                 m_status = outline2;
16039241fe2SDarkWyrm                 cmd = path_cmd_move_to;
16139241fe2SDarkWyrm 
16239241fe2SDarkWyrm             case outline2:
16339241fe2SDarkWyrm                 if(m_src_vertex <= unsigned(m_closed == 0))
16439241fe2SDarkWyrm                 {
16539241fe2SDarkWyrm                     m_status = end_poly2;
16639241fe2SDarkWyrm                     m_prev_status = stop;
16739241fe2SDarkWyrm                     break;
16839241fe2SDarkWyrm                 }
16939241fe2SDarkWyrm 
17039241fe2SDarkWyrm                 --m_src_vertex;
171*e39da397SStephan Aßmus                 m_stroker.calc_join(m_out_vertices,
172d1d811ecSDarkWyrm                                     m_src_vertices.next(m_src_vertex),
17339241fe2SDarkWyrm                                     m_src_vertices.curr(m_src_vertex),
17439241fe2SDarkWyrm                                     m_src_vertices.prev(m_src_vertex),
17539241fe2SDarkWyrm                                     m_src_vertices.curr(m_src_vertex).dist,
176*e39da397SStephan Aßmus                                     m_src_vertices.prev(m_src_vertex).dist);
17739241fe2SDarkWyrm 
17839241fe2SDarkWyrm                 m_prev_status = m_status;
17939241fe2SDarkWyrm                 m_status = out_vertices;
18039241fe2SDarkWyrm                 m_out_vertex = 0;
18139241fe2SDarkWyrm                 break;
18239241fe2SDarkWyrm 
18339241fe2SDarkWyrm             case out_vertices:
18439241fe2SDarkWyrm                 if(m_out_vertex >= m_out_vertices.size())
18539241fe2SDarkWyrm                 {
18639241fe2SDarkWyrm                     m_status = m_prev_status;
18739241fe2SDarkWyrm                 }
18839241fe2SDarkWyrm                 else
18939241fe2SDarkWyrm                 {
190*e39da397SStephan Aßmus                     const point_d& c = m_out_vertices[m_out_vertex++];
19139241fe2SDarkWyrm                     *x = c.x;
19239241fe2SDarkWyrm                     *y = c.y;
19339241fe2SDarkWyrm                     return cmd;
19439241fe2SDarkWyrm                 }
19539241fe2SDarkWyrm                 break;
19639241fe2SDarkWyrm 
19739241fe2SDarkWyrm             case end_poly1:
19839241fe2SDarkWyrm                 m_status = m_prev_status;
19939241fe2SDarkWyrm                 return path_cmd_end_poly | path_flags_close | path_flags_ccw;
20039241fe2SDarkWyrm 
20139241fe2SDarkWyrm             case end_poly2:
20239241fe2SDarkWyrm                 m_status = m_prev_status;
20339241fe2SDarkWyrm                 return path_cmd_end_poly | path_flags_close | path_flags_cw;
20439241fe2SDarkWyrm 
20539241fe2SDarkWyrm             case stop:
20639241fe2SDarkWyrm                 cmd = path_cmd_stop;
20739241fe2SDarkWyrm                 break;
20839241fe2SDarkWyrm             }
20939241fe2SDarkWyrm         }
21039241fe2SDarkWyrm         return cmd;
21139241fe2SDarkWyrm     }
21239241fe2SDarkWyrm 
21339241fe2SDarkWyrm }
214