/* -*- mode: c++; c-basic-offset: 4 -*- */
#include <Python.h>
#define NO_IMPORT_ARRAY
#include "numpy/arrayobject.h"
#include "py_converters.h"
#include "py_adaptors.h"
#include "agg_conv_transform.h"
#include "path_converters.h"
class PathCleanupIterator
{
typedef agg::conv_transform<py::PathIterator> transformed_path_t;
typedef PathNanRemover<transformed_path_t> nan_removal_t;
typedef PathClipper<nan_removal_t> clipped_t;
typedef PathSnapper<clipped_t> snapped_t;
typedef PathSimplifier<snapped_t> simplify_t;
typedef Sketch<simplify_t> sketch_t;
py::PathIterator m_path_iter;
agg::trans_affine m_transform;
transformed_path_t m_transformed;
nan_removal_t m_nan_removed;
clipped_t m_clipped;
snapped_t m_snapped;
simplify_t m_simplify;
sketch_t m_sketch;
public:
PathCleanupIterator(PyObject *path,
agg::trans_affine trans,
bool remove_nans,
bool do_clip,
const agg::rect_base<double> &rect,
e_snap_mode snap_mode,
double stroke_width,
bool do_simplify,
double sketch_scale,
double sketch_length,
double sketch_randomness)
: m_transform(trans),
m_transformed(m_path_iter, m_transform),
m_nan_removed(m_transformed, remove_nans, m_path_iter.has_curves()),
m_clipped(m_nan_removed, do_clip && !m_path_iter.has_curves(), rect),
m_snapped(m_clipped, snap_mode, m_path_iter.total_vertices(), stroke_width),
m_simplify(m_snapped,
do_simplify && m_path_iter.should_simplify(),
m_path_iter.simplify_threshold()),
m_sketch(m_simplify, sketch_scale, sketch_length, sketch_randomness)
{
convert_path(path, &m_path_iter);
Py_INCREF(path);
m_path_iter.rewind(0);
}
unsigned vertex(double *x, double *y)
{
return m_simplify.vertex(x, y);
}
};
extern "C" {
void *get_path_iterator(PyObject *path,
PyObject *trans,
int remove_nans,
int do_clip,
double rect[4],
e_snap_mode snap_mode,
double stroke_width,
int do_simplify,
double sketch_scale,
double sketch_length,
double sketch_randomness)
{
agg::trans_affine agg_trans;
if (!convert_trans_affine(trans, &agg_trans)) {
return NULL;
}
agg::rect_base<double> clip_rect(rect[0], rect[1], rect[2], rect[3]);
PathCleanupIterator *pipeline = new PathCleanupIterator(path,
agg_trans,
remove_nans != 0,
do_clip != 0,
clip_rect,
snap_mode,
stroke_width,
do_simplify != 0,
sketch_scale,
sketch_length,
sketch_randomness);
return (void *)pipeline;
}
unsigned get_vertex(void *pipeline, double *x, double *y)
{
PathCleanupIterator *pipeline_iter = (PathCleanupIterator *)pipeline;
unsigned code = pipeline_iter->vertex(x, y);
return code;
}
void free_path_iterator(void *pipeline)
{
PathCleanupIterator *pipeline_iter = (PathCleanupIterator *)pipeline;
delete pipeline_iter;
}
}