Home | History | Annotate | Download | only in agg23
      1 
      2 //----------------------------------------------------------------------------
      3 // Anti-Grain Geometry - Version 2.3
      4 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
      5 //
      6 // Permission to copy, use, modify, sell and distribute this software
      7 // is granted provided this copyright notice appears in all copies.
      8 // This software is provided "as is" without express or implied
      9 // warranty, and with no claim as to its suitability for any purpose.
     10 //
     11 //----------------------------------------------------------------------------
     12 // Contact: mcseem (at) antigrain.com
     13 //          mcseemagg (at) yahoo.com
     14 //          http://www.antigrain.com
     15 //----------------------------------------------------------------------------
     16 #ifndef AGG_CONV_ADAPTOR_VCGEN_INCLUDED
     17 #define AGG_CONV_ADAPTOR_VCGEN_INCLUDED
     18 #include "agg_basics.h"
     19 namespace agg
     20 {
     21 struct null_markers  {
     22     void remove_all() {}
     23     void add_vertex(FX_FLOAT, FX_FLOAT, unsigned) {}
     24     void prepare_src() {}
     25     void rewind(unsigned) {}
     26     unsigned vertex(FX_FLOAT*, FX_FLOAT*)
     27     {
     28         return path_cmd_stop;
     29     }
     30 };
     31 template<class VertexSource,
     32          class Generator,
     33          class Markers = null_markers> class conv_adaptor_vcgen
     34 {
     35     enum status {
     36         initial,
     37         accumulate,
     38         generate
     39     };
     40 public:
     41     conv_adaptor_vcgen(VertexSource& source) :
     42         m_source(&source),
     43         m_status(initial)
     44     {}
     45     void set_source(VertexSource& source)
     46     {
     47         m_source = &source;
     48     }
     49     Generator& generator()
     50     {
     51         return m_generator;
     52     }
     53     const Generator& generator() const
     54     {
     55         return m_generator;
     56     }
     57     Markers& markers()
     58     {
     59         return m_markers;
     60     }
     61     const Markers& markers() const
     62     {
     63         return m_markers;
     64     }
     65     void rewind(unsigned path_id)
     66     {
     67         m_source->rewind(path_id);
     68         m_status = initial;
     69     }
     70     unsigned vertex(FX_FLOAT* x, FX_FLOAT* y);
     71 private:
     72     conv_adaptor_vcgen(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
     73     const conv_adaptor_vcgen<VertexSource, Generator, Markers>&
     74     operator = (const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
     75     VertexSource* m_source;
     76     Generator     m_generator;
     77     Markers       m_markers;
     78     status        m_status;
     79     unsigned      m_last_cmd;
     80     FX_FLOAT        m_start_x;
     81     FX_FLOAT        m_start_y;
     82 };
     83 template<class VertexSource, class Generator, class Markers>
     84 unsigned conv_adaptor_vcgen<VertexSource, Generator, Markers>::vertex(FX_FLOAT* x, FX_FLOAT* y)
     85 {
     86     unsigned cmd = path_cmd_stop;
     87     bool done = false;
     88     while(!done) {
     89         switch(m_status) {
     90             case initial:
     91                 m_markers.remove_all();
     92                 m_last_cmd = m_source->vertex(&m_start_x, &m_start_y);
     93                 m_status = accumulate;
     94             case accumulate:
     95                 if(is_stop(m_last_cmd)) {
     96                     return path_cmd_stop;
     97                 }
     98                 m_generator.remove_all();
     99                 m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
    100                 m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
    101                 for(;;) {
    102                     cmd = m_source->vertex(x, y);
    103                     if(is_vertex(cmd)) {
    104                         m_last_cmd = cmd;
    105                         if(is_move_to(cmd)) {
    106                             m_start_x = *x;
    107                             m_start_y = *y;
    108                             break;
    109                         }
    110                         m_generator.add_vertex(*x, *y, cmd);
    111                         m_markers.add_vertex(*x, *y, path_cmd_line_to);
    112                     } else {
    113                         if(is_stop(cmd)) {
    114                             m_last_cmd = path_cmd_stop;
    115                             break;
    116                         }
    117                         if(is_end_poly(cmd)) {
    118                             m_generator.add_vertex(*x, *y, cmd);
    119                             break;
    120                         }
    121                     }
    122                 }
    123                 m_generator.rewind(0);
    124                 m_status = generate;
    125             case generate:
    126                 cmd = m_generator.vertex(x, y);
    127                 if(is_stop(cmd)) {
    128                     m_status = accumulate;
    129                     break;
    130                 }
    131                 done = true;
    132                 break;
    133         }
    134     }
    135     return cmd;
    136 }
    137 }
    138 #endif
    139