forked from matplotlib/matplotlib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
_backend_agg.h
266 lines (211 loc) · 7.56 KB
/
_backend_agg.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
/* _backend_agg.h - A rewrite of _backend_agg using PyCXX to handle
ref counting, etc..
*/
#ifndef __BACKEND_AGG_H
#define __BACKEND_AGG_H
#include <utility>
#include "CXX/Extensions.hxx"
#include "agg_buffer.h" // a swig wrapper
#include "agg_arrowhead.h"
#include "agg_basics.h"
#include "agg_bezier_arc.h"
#include "agg_color_rgba.h"
#include "agg_conv_concat.h"
#include "agg_conv_contour.h"
#include "agg_conv_curve.h"
#include "agg_conv_dash.h"
#include "agg_conv_marker.h"
#include "agg_conv_marker_adaptor.h"
#include "agg_math_stroke.h"
#include "agg_conv_stroke.h"
#include "agg_ellipse.h"
#include "agg_embedded_raster_fonts.h"
#include "agg_path_storage.h"
#include "agg_pixfmt_rgb.h"
#include "agg_pixfmt_rgba.h"
#include "agg_pixfmt_gray.h"
#include "agg_alpha_mask_u8.h"
#include "agg_pixfmt_amask_adaptor.h"
#include "agg_rasterizer_outline.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_renderer_outline_aa.h"
#include "agg_renderer_raster_text.h"
#include "agg_renderer_scanline.h"
#include "agg_rendering_buffer.h"
#include "agg_scanline_bin.h"
#include "agg_scanline_u.h"
#include "agg_scanline_p.h"
#include "agg_vcgen_markers_term.h"
typedef agg::pixfmt_rgba32 pixfmt;
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_aa;
typedef agg::renderer_scanline_bin_solid<renderer_base> renderer_bin;
typedef agg::rasterizer_scanline_aa<> rasterizer;
typedef agg::scanline_p8 scanline_p8;
typedef agg::scanline_bin scanline_bin;
//yypedef agg::scanline_u8_am<agg::alpha_mask_gray8> scanline_alphamask;
typedef agg::amask_no_clip_gray8 alpha_mask_type;
typedef agg::renderer_base<agg::pixfmt_gray8> renderer_base_alpha_mask_type;
typedef agg::renderer_scanline_aa_solid<renderer_base_alpha_mask_type> renderer_alpha_mask_type;
struct SnapData {
SnapData(const bool& newpoint, const float& xsnap, const float& ysnap) :
newpoint(newpoint), xsnap(xsnap), ysnap(ysnap) {}
bool newpoint;
float xsnap, ysnap;
};
class SafeSnap {
// snap to pixel center, avoiding 0 path length rounding errors.
public:
SafeSnap() : first(true), xsnap(0.0), lastx(0.0), lastxsnap(0.0),
ysnap(0.0), lasty(0.0), lastysnap(0.0) {}
SnapData snap (const float& x, const float& y);
private:
bool first;
float xsnap, lastx, lastxsnap, ysnap, lasty, lastysnap;
};
// a helper class to pass agg::buffer objects around. agg::buffer is
// a class in the swig wrapper
class BufferRegion : public Py::PythonExtension<BufferRegion> {
public:
BufferRegion( agg::buffer& aggbuf, const agg::rect &r, bool freemem=true) : aggbuf(aggbuf), rect(r), freemem(freemem) {
//std::cout << "buffer region" << std::endl;
}
agg::buffer aggbuf;
agg::rect rect;
bool freemem;
Py::Object to_string(const Py::Tuple &args);
static void init_type(void);
virtual ~BufferRegion() {
//std::cout << "buffer region bye bye" << std::endl;
if (freemem) {
delete [] aggbuf.data;
aggbuf.data = NULL;
}
};
};
class GCAgg {
public:
GCAgg(const Py::Object& gc, double dpi, bool snapto=false);
~GCAgg() {
delete [] dasha;
delete [] cliprect;
delete clippath;
}
double dpi;
bool snapto;
bool isaa;
agg::line_cap_e cap;
agg::line_join_e join;
double linewidth;
double alpha;
agg::rgba color;
double *cliprect;
agg::path_storage *clippath;
//dashes
size_t Ndash;
double dashOffset;
double *dasha;
protected:
agg::rgba get_color(const Py::Object& gc);
double points_to_pixels( const Py::Object& points);
void _set_linecap(const Py::Object& gc) ;
void _set_joinstyle(const Py::Object& gc) ;
void _set_dashes(const Py::Object& gc) ;
void _set_clip_rectangle( const Py::Object& gc);
void _set_clip_path( const Py::Object& gc);
void _set_antialiased( const Py::Object& gc);
};
//struct AMRenderer {
//
//}
// the renderer
class RendererAgg: public Py::PythonExtension<RendererAgg> {
typedef std::pair<bool, agg::rgba> facepair_t;
public:
RendererAgg(unsigned int width, unsigned int height, double dpi, int debug);
static void init_type(void);
unsigned int get_width() { return width;}
unsigned int get_height() { return height;}
// the drawing methods
Py::Object draw_rectangle(const Py::Tuple & args);
Py::Object draw_ellipse(const Py::Tuple & args);
Py::Object draw_polygon(const Py::Tuple & args);
Py::Object draw_line_collection(const Py::Tuple& args);
Py::Object draw_quad_mesh(const Py::Tuple& args);
Py::Object draw_poly_collection(const Py::Tuple& args);
Py::Object draw_regpoly_collection(const Py::Tuple& args);
Py::Object draw_lines(const Py::Tuple & args);
Py::Object draw_path(const Py::Tuple & args);
//Py::Object _draw_markers_nocache(const Py::Tuple & args);
//Py::Object _draw_markers_cache(const Py::Tuple & args);
Py::Object draw_markers(const Py::Tuple & args);
Py::Object draw_text_image(const Py::Tuple & args);
Py::Object draw_image(const Py::Tuple & args);
Py::Object write_rgba(const Py::Tuple & args);
Py::Object write_png(const Py::Tuple & args);
Py::Object tostring_rgb(const Py::Tuple & args);
Py::Object tostring_argb(const Py::Tuple & args);
Py::Object tostring_bgra(const Py::Tuple & args);
Py::Object buffer_rgba(const Py::Tuple & args);
Py::Object clear(const Py::Tuple & args);
Py::Object copy_from_bbox(const Py::Tuple & args);
Py::Object restore_region(const Py::Tuple & args);
virtual ~RendererAgg();
static const size_t PIXELS_PER_INCH;
unsigned int width, height;
double dpi;
size_t NUMBYTES; //the number of bytes in buffer
agg::int8u *pixBuffer;
agg::rendering_buffer *renderingBuffer;
agg::int8u *alphaBuffer;
agg::rendering_buffer *alphaMaskRenderingBuffer;
alpha_mask_type *alphaMask;
agg::pixfmt_gray8 *pixfmtAlphaMask;
renderer_base_alpha_mask_type *rendererBaseAlphaMask;
renderer_alpha_mask_type *rendererAlphaMask;
agg::scanline_p8 *scanlineAlphaMask;
scanline_p8* slineP8;
scanline_bin* slineBin;
pixfmt *pixFmt;
renderer_base *rendererBase;
renderer_aa *rendererAA;
renderer_bin *rendererBin;
rasterizer *theRasterizer;
const int debug;
protected:
agg::rect bbox_to_rect( const Py::Object& o);
double points_to_pixels( const Py::Object& points);
double points_to_pixels_snapto( const Py::Object& points);
void DrawQuadMesh(int, int, void* colors, const double[], const double[]);
void DrawQuadMeshEdges(int, int, const double[], const double[]);
int intersectCheck(double, double, double, double, double, int*);
int inPolygon(int, const double[4], const double[4], int[4]);
void set_clip_from_bbox(const Py::Object& o);
agg::rgba rgb_to_color(const Py::SeqBase<Py::Object>& rgb, double alpha);
facepair_t _get_rgba_face(const Py::Object& rgbFace, double alpha);
void set_clipbox_rasterizer( double *cliprect);
bool _process_alpha_mask(const GCAgg& gc);
template <class VS> void _fill_and_stroke(VS&, const GCAgg&, const facepair_t&, bool curvy=true);
template<class PathSource>
void _render_lines_path(PathSource &ps, const GCAgg& gc);
private:
agg::path_storage *lastclippath;
};
// the extension module
class _backend_agg_module : public Py::ExtensionModule<_backend_agg_module>
{
public:
_backend_agg_module()
: Py::ExtensionModule<_backend_agg_module>( "_backend_agg" )
{
BufferRegion::init_type();
RendererAgg::init_type();
add_keyword_method("RendererAgg", &_backend_agg_module::new_renderer,
"RendererAgg(width, height, dpi)");
initialize( "The agg rendering backend" );
}
virtual ~_backend_agg_module() {}
private:
Py::Object new_renderer (const Py::Tuple &args, const Py::Dict &kws);
};
#endif