• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@antigrain.com
13 //          mcseemagg@yahoo.com
14 //          http://www.antigrain.com
15 //----------------------------------------------------------------------------
16 #ifndef AGG_PATH_STORAGE_INCLUDED
17 #define AGG_PATH_STORAGE_INCLUDED
18 #include "agg_basics.h"
19 namespace pdfium
20 {
21 namespace agg
22 {
23 class path_storage
24 {
25     enum block_scale_e {
26         block_shift = 8,
27         block_size  = 1 << block_shift,
28         block_mask  = block_size - 1,
29         block_pool  = 256
30     };
31 public:
32     class vertex_source
33     {
34     public:
vertex_source()35         vertex_source() {}
vertex_source(const path_storage & p)36         vertex_source(const path_storage& p) : m_path(&p), m_vertex_idx(0) {}
rewind(unsigned path_id)37         void rewind(unsigned path_id)
38         {
39             m_vertex_idx = path_id;
40         }
vertex(float * x,float * y)41         unsigned vertex(float* x, float* y)
42         {
43           return (m_vertex_idx < m_path->total_vertices())
44                      ? m_path->vertex(m_vertex_idx++, x, y)
45                      : static_cast<unsigned>(path_cmd_stop);
46         }
47     private:
48         const path_storage* m_path;
49         unsigned            m_vertex_idx;
50     };
51     ~path_storage();
52     path_storage();
53     path_storage(path_storage&& other);
54     path_storage& operator=(path_storage&&) = delete;
55     path_storage(const path_storage&) = delete;
56     path_storage& operator=(const path_storage&) = delete;
57     unsigned last_vertex(float* x, float* y) const;
58     unsigned prev_vertex(float* x, float* y) const;
59     void move_to(float x, float y);
60     void line_to(float x, float y);
61     void curve4(float x_ctrl1, float y_ctrl1,
62                 float x_ctrl2, float y_ctrl2,
63                 float x_to,    float y_to);
64     template<class VertexSource>
65     void add_path(VertexSource& vs,
66                   unsigned path_id = 0,
67                   bool solid_path = true)
68     {
69         float x, y;
70         unsigned cmd;
71         vs.rewind(path_id);
72         while(!is_stop(cmd = vs.vertex(&x, &y))) {
73             if(is_move_to(cmd) && solid_path && m_total_vertices) {
74                 cmd = path_cmd_line_to;
75             }
76             add_vertex(x, y, cmd);
77         }
78     }
total_vertices()79     unsigned total_vertices() const
80     {
81         return m_total_vertices;
82     }
vertex(unsigned idx,float * x,float * y)83     unsigned vertex(unsigned idx, float* x, float* y) const
84     {
85         unsigned nb = idx >> block_shift;
86         const float* pv = m_coord_blocks[nb] + ((idx & block_mask) << 1);
87         *x = *pv++;
88         *y = *pv;
89         return m_cmd_blocks[nb][idx & block_mask];
90     }
command(unsigned idx)91     unsigned command(unsigned idx) const
92     {
93         return m_cmd_blocks[idx >> block_shift][idx & block_mask];
94     }
getflag(unsigned idx)95     unsigned getflag(unsigned idx) const
96     {
97         return m_cmd_blocks[idx >> block_shift][idx & block_mask] & path_flags_jr;
98     }
99     void     rewind(unsigned path_id);
100     unsigned vertex(float* x, float* y);
101     void add_vertex(float x, float y, unsigned cmd);
102     void end_poly();
103 private:
104     void allocate_block(unsigned nb);
105     unsigned char* storage_ptrs(float** xy_ptr);
106 private:
107     unsigned        m_total_vertices = 0;
108     unsigned        m_total_blocks = 0;
109     unsigned        m_max_blocks = 0;
110     float**         m_coord_blocks = nullptr;
111     unsigned char** m_cmd_blocks = nullptr;
112     unsigned        m_iterator = 0;
113 };
vertex(float * x,float * y)114 inline unsigned path_storage::vertex(float* x, float* y)
115 {
116     if(m_iterator >= m_total_vertices) {
117         return path_cmd_stop;
118     }
119     return vertex(m_iterator++, x, y);
120 }
prev_vertex(float * x,float * y)121 inline unsigned path_storage::prev_vertex(float* x, float* y) const
122 {
123     if(m_total_vertices > 1) {
124         return vertex(m_total_vertices - 2, x, y);
125     }
126     return path_cmd_stop;
127 }
last_vertex(float * x,float * y)128 inline unsigned path_storage::last_vertex(float* x, float* y) const
129 {
130     if(m_total_vertices) {
131         return vertex(m_total_vertices - 1, x, y);
132     }
133     return path_cmd_stop;
134 }
storage_ptrs(float ** xy_ptr)135 inline unsigned char* path_storage::storage_ptrs(float** xy_ptr)
136 {
137     unsigned nb = m_total_vertices >> block_shift;
138     if(nb >= m_total_blocks) {
139         allocate_block(nb);
140     }
141     *xy_ptr = m_coord_blocks[nb] + ((m_total_vertices & block_mask) << 1);
142     return m_cmd_blocks[nb] + (m_total_vertices & block_mask);
143 }
add_vertex(float x,float y,unsigned cmd)144 inline void path_storage::add_vertex(float x, float y, unsigned cmd)
145 {
146     float* coord_ptr = 0;
147     unsigned char* cmd_ptr = storage_ptrs(&coord_ptr);
148     *cmd_ptr = (unsigned char)cmd;
149     *coord_ptr++ = x;
150     *coord_ptr   = y;
151     m_total_vertices++;
152 }
move_to(float x,float y)153 inline void path_storage::move_to(float x, float y)
154 {
155     add_vertex(x, y, path_cmd_move_to);
156 }
line_to(float x,float y)157 inline void path_storage::line_to(float x, float y)
158 {
159     add_vertex(x, y, path_cmd_line_to);
160 }
161 }
162 }  // namespace pdfium
163 #endif
164