1- #include " _backend_agg.h"
1+ // font and text handling was lifted almost verbatim from module
2+ // paint. The paint license is in LICENSE_PAINT that accompanies the
3+ // matplotlib src distribution
24
35#include < cstring>
4-
5-
6- // font stuff from paint
6+ #include " _backend_agg.h"
77
88static char agg_font__doc__[] =
99" Font(filename, size = 12, rotate = 0)\n "
@@ -299,20 +299,18 @@ extern "C" staticforward PyTypeObject RendererAgg_Type;
299299static RendererAggObject *
300300newRendererAggObject (PyObject *args)
301301{
302- printf (" newRendererAggObject start\n " );
302+ // printf("newRendererAggObject start\n");
303303 RendererAggObject *self;
304304 int width, height;
305305 double dpi;
306306 if (!PyArg_ParseTuple (args, " iid:RendererAgg" , &width, &height, &dpi))
307307 return NULL ;
308308
309- printf (" newRendererAggObject 1\n " );
310309
311310 self = PyObject_New (RendererAggObject, &RendererAgg_Type);
312311 if (self == NULL )
313312 return NULL ;
314313
315- printf (" newRendererAggObject 2\n " );
316314
317315 unsigned stride (width*4 ); // TODO, pixfmt call to make rgba type independet
318316 size_t NUMBYTES (width*height*4 );
@@ -333,9 +331,6 @@ newRendererAggObject(PyObject *args)
333331 self->NUMBYTES = NUMBYTES;
334332 self->x_attr = NULL ;
335333
336- // draw(self);
337- // print(self); //calling this makes agg.raw work ok. Is is path? Something
338- printf (" newRendererAggObject end\n " );
339334 return self;
340335}
341336
@@ -411,6 +406,121 @@ RendererAgg_draw_ellipse(RendererAggObject *renderer, PyObject* args) {
411406
412407}
413408
409+ char RendererAgg_draw_polygon__doc__[] =
410+ " draw_polygon(gcEdge, gdFace, points)\n "
411+ " \n "
412+ " Draw a polygon using the gd edge and face. point is a sequence of x,y tuples" ;
413+
414+ static PyObject *
415+ RendererAgg_draw_polygon (RendererAggObject *renderer, PyObject* args) {
416+
417+ PyObject *gcEdge, *gcFace, *points;
418+
419+ if (!PyArg_ParseTuple (args, " OOO" , &gcEdge, &gcFace, &points))
420+ return NULL ;
421+ if (! _gc_set_clip_rect (gcEdge, renderer)) return NULL ;
422+ double * plw = _gc_get_linewidth (gcEdge);
423+ if (plw==NULL ) return NULL ;
424+ double lw = _points_to_pixels (renderer, *plw);
425+ delete plw;
426+ // printf("draw_rectangle inited\n");
427+ agg::path_storage path;
428+
429+ PyObject *tup; // the x,y tup
430+ PyObject *xo, *yo; // xi, yi in tup
431+ PyObject *xf, *yf; // xi, yi in tup as Py_Float
432+ double x, y; // finally, the damned numbers
433+
434+ int Npoints = PySequence_Length (points);
435+
436+ if (Npoints==-1 ) {
437+ PyErr_SetString (PyExc_ValueError,
438+ " points must be a sequence type" );
439+ return NULL ;
440+ }
441+
442+ tup = PySequence_GetItem ( points, 0 );
443+ int N = PySequence_Length (tup);
444+
445+ if (N!=2 ) {
446+ PyErr_SetString (PyExc_ValueError,
447+ " seq must be a sequence of length 2 tuples" );
448+ Py_XDECREF (tup);
449+ return NULL ;
450+ }
451+
452+ xo = PySequence_GetItem ( tup, 0 );
453+ yo = PySequence_GetItem ( tup, 1 );
454+ Py_XDECREF (tup);
455+
456+ xf = PyNumber_Float ( xo );
457+ yf = PyNumber_Float ( yo );
458+ Py_XDECREF (xo); Py_XDECREF (yo);
459+
460+
461+ x = PyFloat_AsDouble (xf);
462+ y = PyFloat_AsDouble (yf);
463+ Py_XDECREF (xf); Py_XDECREF (yf);
464+
465+ y = renderer->rbase ->height () - y;
466+ path.move_to (x, y);
467+
468+ for (int i=1 ; i<Npoints; ++i) {
469+
470+ tup = PySequence_GetItem (points, i);
471+ int N = PySequence_Length (tup);
472+
473+ if (N!=2 ) {
474+ PyErr_SetString (PyExc_ValueError,
475+ " points must be a sequence of length 2 tuples" );
476+ Py_XDECREF (tup);
477+ return NULL ;
478+ }
479+
480+ xo = PySequence_GetItem ( tup, 0 );
481+ yo = PySequence_GetItem ( tup, 1 );
482+ Py_XDECREF (tup);
483+
484+ xf = PyNumber_Float ( xo );
485+ yf = PyNumber_Float ( yo );
486+ Py_XDECREF (xo); Py_XDECREF (yo);
487+
488+ x = PyFloat_AsDouble (xf);
489+ y = PyFloat_AsDouble (yf);
490+ Py_XDECREF (xf); Py_XDECREF (yf);
491+
492+ y = renderer->rbase ->height () - y;
493+ path.line_to (x, y);
494+
495+ }
496+ path.close_polygon ();
497+
498+
499+ if (gcFace != Py_None) {
500+ // fill the face
501+ agg::rgba* color = _gc_get_color (gcFace);
502+ if (color==NULL ) return NULL ;
503+ renderer->ren ->color (*color);
504+ renderer->ras ->add_path (path);
505+ renderer->ras ->render (*renderer->sline , *renderer->ren );
506+ delete color;
507+ }
508+
509+ // now fill the edge
510+ agg::conv_stroke<agg::path_storage> stroke (path);
511+ stroke.width (lw);
512+ // printf("setting edge wid %1.2f\n", lw);
513+ agg::rgba* color = _gc_get_color (gcEdge);
514+ if (color==NULL ) return NULL ;
515+ renderer->ren ->color (*color);
516+ // self->ras->gamma(agg::gamma_power(gamma));
517+ renderer->ras ->add_path (stroke);
518+ renderer->ras ->render (*renderer->sline , *renderer->ren );
519+ delete color;
520+ Py_INCREF (Py_None);
521+ return Py_None;
522+
523+ }
414524
415525static PyObject *
416526RendererAgg_draw_rectangle (RendererAggObject *renderer, PyObject* args) {
@@ -450,7 +560,7 @@ RendererAgg_draw_rectangle(RendererAggObject *renderer, PyObject* args) {
450560 // now fill the edge
451561 agg::conv_stroke<agg::path_storage> stroke (path);
452562 stroke.width (lw);
453- printf (" setting edge wid %1.2f\n " , lw);
563+ // printf("setting edge wid %1.2f\n", lw);
454564 agg::rgba* color = _gc_get_color (gcEdge);
455565 if (color==NULL ) return NULL ;
456566 renderer->ren ->color (*color);
@@ -760,6 +870,7 @@ static PyMethodDef RendererAgg_methods[] = {
760870
761871 { " draw_ellipse" , (PyCFunction)RendererAgg_draw_ellipse, METH_VARARGS},
762872 { " draw_rectangle" , (PyCFunction)RendererAgg_draw_rectangle, METH_VARARGS},
873+ { " draw_polygon" , (PyCFunction)RendererAgg_draw_polygon, METH_VARARGS},
763874 { " draw_lines" , (PyCFunction)RendererAgg_draw_lines, METH_VARARGS},
764875 { " draw_text" , (PyCFunction)RendererAgg_draw_text, METH_VARARGS, RendererAgg_draw_text__doc__},
765876 { " write_rgba" , (PyCFunction)RendererAgg_write_rgba, METH_VARARGS},
0 commit comments