📄 agg_path_storage.h
字号:
void rewind(unsigned)
{
m_ptr = m_data;
m_stop = false;
}
unsigned vertex(double* x, double* y)
{
if(m_ptr < m_end)
{
bool first = m_ptr == m_data;
*x = *m_ptr++;
*y = *m_ptr++;
return first ? path_cmd_move_to : path_cmd_line_to;
}
*x = *y = 0.0;
if(m_closed && !m_stop)
{
m_stop = true;
return path_cmd_end_poly | path_flags_close;
}
return path_cmd_stop;
}
private:
const T* m_data;
const T* m_ptr;
const T* m_end;
bool m_closed;
bool m_stop;
};
//-------------------------------------------------poly_container_adaptor
template<class Container> class poly_container_adaptor
{
public:
typedef typename Container::value_type vertex_type;
poly_container_adaptor() :
m_container(0),
m_index(0),
m_closed(false),
m_stop(false)
{}
poly_container_adaptor(const Container& data, bool closed) :
m_container(&data),
m_index(0),
m_closed(closed),
m_stop(false)
{}
void init(const Container& data, bool closed)
{
m_container = &data;
m_index = 0;
m_closed = closed;
m_stop = false;
}
void rewind(unsigned)
{
m_index = 0;
m_stop = false;
}
unsigned vertex(double* x, double* y)
{
if(m_index < m_container->size())
{
bool first = m_index == 0;
const vertex_type& v = (*m_container)[m_index++];
*x = v.x;
*y = v.y;
return first ? path_cmd_move_to : path_cmd_line_to;
}
*x = *y = 0.0;
if(m_closed && !m_stop)
{
m_stop = true;
return path_cmd_end_poly | path_flags_close;
}
return path_cmd_stop;
}
private:
const Container* m_container;
unsigned m_index;
bool m_closed;
bool m_stop;
};
//-----------------------------------------poly_container_reverse_adaptor
template<class Container> class poly_container_reverse_adaptor
{
public:
typedef typename Container::value_type vertex_type;
poly_container_reverse_adaptor() :
m_container(0),
m_index(-1),
m_closed(false),
m_stop(false)
{}
poly_container_reverse_adaptor(const Container& data, bool closed) :
m_container(&data),
m_index(-1),
m_closed(closed),
m_stop(false)
{}
void init(const Container& data, bool closed)
{
m_container = &data;
m_index = m_container->size() - 1;
m_closed = closed;
m_stop = false;
}
void rewind(unsigned)
{
m_index = m_container->size() - 1;
m_stop = false;
}
unsigned vertex(double* x, double* y)
{
if(m_index >= 0)
{
bool first = m_index == int(m_container->size() - 1);
const vertex_type& v = (*m_container)[m_index--];
*x = v.x;
*y = v.y;
return first ? path_cmd_move_to : path_cmd_line_to;
}
*x = *y = 0.0;
if(m_closed && !m_stop)
{
m_stop = true;
return path_cmd_end_poly | path_flags_close;
}
return path_cmd_stop;
}
private:
const Container* m_container;
int m_index;
bool m_closed;
bool m_stop;
};
//--------------------------------------------------------line_adaptor
class line_adaptor
{
public:
typedef double value_type;
line_adaptor() : m_line(m_coord, 2, false) {}
line_adaptor(double x1, double y1, double x2, double y2) :
m_line(m_coord, 2, false)
{
m_coord[0] = x1;
m_coord[1] = y1;
m_coord[2] = x2;
m_coord[3] = y2;
}
void init(double x1, double y1, double x2, double y2)
{
m_coord[0] = x1;
m_coord[1] = y1;
m_coord[2] = x2;
m_coord[3] = y2;
m_line.rewind(0);
}
void rewind(unsigned)
{
m_line.rewind(0);
}
unsigned vertex(double* x, double* y)
{
return m_line.vertex(x, y);
}
private:
double m_coord[4];
poly_plain_adaptor<double> m_line;
};
//---------------------------------------------------------------path_base
// A container to store vertices with their flags.
// A path consists of a number of contours separated with "move_to"
// commands. The path storage can keep and maintain more than one
// path.
// To navigate to the beginning of a particular path, use rewind(path_id);
// Where path_id is what start_new_path() returns. So, when you call
// start_new_path() you need to store its return value somewhere else
// to navigate to the path afterwards.
//
// See also: vertex_source concept
//------------------------------------------------------------------------
template<class VertexContainer> class path_base
{
public:
typedef VertexContainer container_type;
typedef path_base<VertexContainer> self_type;
//--------------------------------------------------------------------
path_base() : m_vertices(), m_iterator(0) {}
void remove_all() { m_vertices.remove_all(); m_iterator = 0; }
void free_all() { m_vertices.free_all(); m_iterator = 0; }
// Make path functions
//--------------------------------------------------------------------
unsigned start_new_path();
void move_to(double x, double y);
void move_rel(double dx, double dy);
void line_to(double x, double y);
void line_rel(double dx, double dy);
void hline_to(double x);
void hline_rel(double dx);
void vline_to(double y);
void vline_rel(double dy);
void arc_to(double rx, double ry,
double angle,
bool large_arc_flag,
bool sweep_flag,
double x, double y);
void arc_rel(double rx, double ry,
double angle,
bool large_arc_flag,
bool sweep_flag,
double dx, double dy);
void curve3(double x_ctrl, double y_ctrl,
double x_to, double y_to);
void curve3_rel(double dx_ctrl, double dy_ctrl,
double dx_to, double dy_to);
void curve3(double x_to, double y_to);
void curve3_rel(double dx_to, double dy_to);
void curve4(double x_ctrl1, double y_ctrl1,
double x_ctrl2, double y_ctrl2,
double x_to, double y_to);
void curve4_rel(double dx_ctrl1, double dy_ctrl1,
double dx_ctrl2, double dy_ctrl2,
double dx_to, double dy_to);
void curve4(double x_ctrl2, double y_ctrl2,
double x_to, double y_to);
void curve4_rel(double x_ctrl2, double y_ctrl2,
double x_to, double y_to);
void end_poly(unsigned flags = path_flags_close);
void close_polygon(unsigned flags = path_flags_none);
// Accessors
//--------------------------------------------------------------------
const container_type& vertices() const { return m_vertices; }
container_type& vertices() { return m_vertices; }
unsigned total_vertices() const;
void rel_to_abs(double* x, double* y) const;
unsigned last_vertex(double* x, double* y) const;
unsigned prev_vertex(double* x, double* y) const;
double last_x() const;
double last_y() const;
unsigned vertex(unsigned idx, double* x, double* y) const;
unsigned command(unsigned idx) const;
void modify_vertex(unsigned idx, double x, double y);
void modify_vertex(unsigned idx, double x, double y, unsigned cmd);
void modify_command(unsigned idx, unsigned cmd);
// VertexSource interface
//--------------------------------------------------------------------
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
// Arrange the orientation of a polygon, all polygons in a path,
// or in all paths. After calling arrange_orientations() or
// arrange_orientations_all_paths(), all the polygons will have
// the same orientation, i.e. path_flags_cw or path_flags_ccw
//--------------------------------------------------------------------
unsigned arrange_polygon_orientation(unsigned start, path_flags_e orientation);
unsigned arrange_orientations(unsigned path_id, path_flags_e orientation);
void arrange_orientations_all_paths(path_flags_e orientation);
void invert_polygon(unsigned start);
// Flip all vertices horizontally or vertically,
// between x1 and x2, or between y1 and y2 respectively
//--------------------------------------------------------------------
void flip_x(double x1, double x2);
void flip_y(double y1, double y2);
// Concatenate path. The path is added as is.
//--------------------------------------------------------------------
template<class VertexSource>
void concat_path(VertexSource& vs, unsigned path_id = 0)
{
double x, y;
unsigned cmd;
vs.rewind(path_id);
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
m_vertices.add_vertex(x, y, cmd);
}
}
//--------------------------------------------------------------------
// Join path. The path is joined with the existing one, that is,
// it behaves as if the pen of a plotter was always down (drawing)
template<class VertexSource>
void join_path(VertexSource& vs, unsigned path_id = 0)
{
double x, y;
unsigned cmd;
vs.rewind(path_id);
cmd = vs.vertex(&x, &y);
if(!is_stop(cmd))
{
if(is_vertex(cmd))
{
double x0, y0;
unsigned cmd0 = last_vertex(&x0, &y0);
if(is_vertex(cmd0))
{
if(calc_distance(x, y, x0, y0) > vertex_dist_epsilon)
{
if(is_move_to(cmd)) cmd = path_cmd_line_to;
m_vertices.add_vertex(x, y, cmd);
}
}
else
{
if(is_stop(cmd0))
{
cmd = path_cmd_move_to;
}
else
{
if(is_move_to(cmd)) cmd = path_cmd_line_to;
}
m_vertices.add_vertex(x, y, cmd);
}
}
while(!is_stop(cmd = vs.vertex(&x, &y)))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -