@@ -462,6 +462,8 @@ bool RendererAgg::render_clippath(const Py::Object& clippath, const agg::trans_a
462462 return has_clippath;
463463}
464464
465+ #define MARKER_CACHE_SIZE 512
466+
465467Py::Object
466468RendererAgg::draw_markers (const Py::Tuple& args) {
467469 typedef agg::conv_transform<PathIterator> transformed_path_t ;
@@ -505,6 +507,8 @@ RendererAgg::draw_markers(const Py::Tuple& args) {
505507 agg::scanline_storage_aa8 scanlines;
506508 theRasterizer->reset ();
507509
510+ agg::int8u staticFillCache[MARKER_CACHE_SIZE];
511+ agg::int8u staticStrokeCache[MARKER_CACHE_SIZE];
508512 agg::int8u* fillCache = NULL ;
509513 agg::int8u* strokeCache = NULL ;
510514
@@ -514,7 +518,10 @@ RendererAgg::draw_markers(const Py::Tuple& args) {
514518 theRasterizer->add_path (marker_path_curve);
515519 agg::render_scanlines (*theRasterizer, *slineP8, scanlines);
516520 fillSize = scanlines.byte_size ();
517- fillCache = new agg::int8u[fillSize]; // or any container
521+ if (fillSize < MARKER_CACHE_SIZE)
522+ fillCache = staticFillCache;
523+ else
524+ fillCache = new agg::int8u[fillSize];
518525 scanlines.serialize (fillCache);
519526 }
520527
@@ -526,7 +533,10 @@ RendererAgg::draw_markers(const Py::Tuple& args) {
526533 theRasterizer->add_path (stroke);
527534 agg::render_scanlines (*theRasterizer, *slineP8, scanlines);
528535 unsigned strokeSize = scanlines.byte_size ();
529- strokeCache = new agg::int8u[strokeSize]; // or any container
536+ if (strokeSize < MARKER_CACHE_SIZE)
537+ strokeCache = staticStrokeCache;
538+ else
539+ strokeCache = new agg::int8u[strokeSize];
530540 scanlines.serialize (strokeCache);
531541
532542 theRasterizer->reset_clipping ();
@@ -539,52 +549,44 @@ RendererAgg::draw_markers(const Py::Tuple& args) {
539549 agg::serialized_scanlines_adaptor_aa8 sa;
540550 agg::serialized_scanlines_adaptor_aa8::embedded_scanline sl;
541551
542- if (face.first ) {
543- // render the fill
552+ while (path_quantized.vertex (&x, &y) != agg::path_cmd_stop) {
544553 if (has_clippath) {
545554 pixfmt_amask_type pfa (*pixFmt, *alphaMask);
546555 amask_ren_type r (pfa);
547556 amask_aa_renderer_type ren (r);
548- ren.color (face.second );
549- while (path_quantized.vertex (&x, &y) != agg::path_cmd_stop) {
557+
558+ if (face.first ) {
559+ ren.color (face.second );
550560 sa.init (fillCache, fillSize, x, y);
551561 agg::render_scanlines (sa, sl, ren);
552562 }
563+ ren.color (gc.color );
564+ sa.init (strokeCache, strokeSize, x, y);
565+ agg::render_scanlines (sa, sl, ren);
553566 } else {
554- rendererAA-> color (face.second );
555- while (path_quantized. vertex (&x, &y) != agg::path_cmd_stop) {
567+ if (face.first ) {
568+ rendererAA-> color (face. second );
556569 sa.init (fillCache, fillSize, x, y);
557570 agg::render_scanlines (sa, sl, *rendererAA);
558571 }
559- }
560- path_quantized.rewind (0 );
561- }
562572
563- // render the stroke
564- if (has_clippath) {
565- pixfmt_amask_type pfa (*pixFmt, *alphaMask);
566- amask_ren_type r (pfa);
567- amask_aa_renderer_type ren (r);
568- ren.color (gc.color );
569- while (path_quantized.vertex (&x, &y) != agg::path_cmd_stop) {
570- sa.init (strokeCache, strokeSize, x, y);
571- agg::render_scanlines (sa, sl, ren);
572- }
573- } else {
574- rendererAA->color (gc.color );
575- while (path_quantized.vertex (&x, &y) != agg::path_cmd_stop) {
573+ rendererAA->color (gc.color );
576574 sa.init (strokeCache, strokeSize, x, y);
577575 agg::render_scanlines (sa, sl, *rendererAA);
578576 }
579577 }
580578 } catch (...) {
581- delete[] fillCache;
582- delete[] strokeCache;
579+ if (fillCache != staticFillCache)
580+ delete[] fillCache;
581+ if (strokeCache != staticStrokeCache)
582+ delete[] strokeCache;
583583 throw ;
584584 }
585585
586- delete [] fillCache;
587- delete [] strokeCache;
586+ if (fillCache != staticFillCache)
587+ delete[] fillCache;
588+ if (strokeCache != staticStrokeCache)
589+ delete[] strokeCache;
588590
589591 return Py::Object ();
590592
@@ -945,16 +947,14 @@ RendererAgg::_draw_path_collection_generic
945947 size_t i = 0 ;
946948
947949 // Convert all of the transforms up front
948- master_transform *= agg::trans_affine_scaling (1.0 , -1.0 );
949- master_transform *= agg::trans_affine_translation (0.0 , (double )height);
950-
951950 typedef std::vector<agg::trans_affine> transforms_t ;
952951 transforms_t transforms;
953952 transforms.reserve (Ntransforms);
954953 for (i = 0 ; i < Ntransforms; ++i) {
955954 agg::trans_affine trans = py_to_agg_transformation_matrix
956955 (transforms_obj[i], false );
957956 trans *= master_transform;
957+
958958 transforms.push_back (trans);
959959 }
960960
@@ -996,6 +996,10 @@ RendererAgg::_draw_path_collection_generic
996996 trans *= agg::trans_affine_translation (xo, yo);
997997 }
998998
999+ // These transformations must be done post-offsets
1000+ trans *= agg::trans_affine_scaling (1.0 , -1.0 );
1001+ trans *= agg::trans_affine_translation (0.0 , (double )height);
1002+
9991003 if (Nfacecolors) {
10001004 size_t fi = i % Nfacecolors;
10011005 face.second = agg::rgba (*(double *)PyArray_GETPTR2 (facecolors, fi, 0 ),
0 commit comments