@@ -462,6 +462,8 @@ bool RendererAgg::render_clippath(const Py::Object& clippath, const agg::trans_a
462
462
return has_clippath;
463
463
}
464
464
465
+ #define MARKER_CACHE_SIZE 512
466
+
465
467
Py::Object
466
468
RendererAgg::draw_markers (const Py::Tuple& args) {
467
469
typedef agg::conv_transform<PathIterator> transformed_path_t ;
@@ -505,6 +507,8 @@ RendererAgg::draw_markers(const Py::Tuple& args) {
505
507
agg::scanline_storage_aa8 scanlines;
506
508
theRasterizer->reset ();
507
509
510
+ agg::int8u staticFillCache[MARKER_CACHE_SIZE];
511
+ agg::int8u staticStrokeCache[MARKER_CACHE_SIZE];
508
512
agg::int8u* fillCache = NULL ;
509
513
agg::int8u* strokeCache = NULL ;
510
514
@@ -514,7 +518,10 @@ RendererAgg::draw_markers(const Py::Tuple& args) {
514
518
theRasterizer->add_path (marker_path_curve);
515
519
agg::render_scanlines (*theRasterizer, *slineP8, scanlines);
516
520
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];
518
525
scanlines.serialize (fillCache);
519
526
}
520
527
@@ -526,7 +533,10 @@ RendererAgg::draw_markers(const Py::Tuple& args) {
526
533
theRasterizer->add_path (stroke);
527
534
agg::render_scanlines (*theRasterizer, *slineP8, scanlines);
528
535
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];
530
540
scanlines.serialize (strokeCache);
531
541
532
542
theRasterizer->reset_clipping ();
@@ -539,52 +549,44 @@ RendererAgg::draw_markers(const Py::Tuple& args) {
539
549
agg::serialized_scanlines_adaptor_aa8 sa;
540
550
agg::serialized_scanlines_adaptor_aa8::embedded_scanline sl;
541
551
542
- if (face.first ) {
543
- // render the fill
552
+ while (path_quantized.vertex (&x, &y) != agg::path_cmd_stop) {
544
553
if (has_clippath) {
545
554
pixfmt_amask_type pfa (*pixFmt, *alphaMask);
546
555
amask_ren_type r (pfa);
547
556
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 );
550
560
sa.init (fillCache, fillSize, x, y);
551
561
agg::render_scanlines (sa, sl, ren);
552
562
}
563
+ ren.color (gc.color );
564
+ sa.init (strokeCache, strokeSize, x, y);
565
+ agg::render_scanlines (sa, sl, ren);
553
566
} 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 );
556
569
sa.init (fillCache, fillSize, x, y);
557
570
agg::render_scanlines (sa, sl, *rendererAA);
558
571
}
559
- }
560
- path_quantized.rewind (0 );
561
- }
562
572
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 );
576
574
sa.init (strokeCache, strokeSize, x, y);
577
575
agg::render_scanlines (sa, sl, *rendererAA);
578
576
}
579
577
}
580
578
} catch (...) {
581
- delete[] fillCache;
582
- delete[] strokeCache;
579
+ if (fillCache != staticFillCache)
580
+ delete[] fillCache;
581
+ if (strokeCache != staticStrokeCache)
582
+ delete[] strokeCache;
583
583
throw ;
584
584
}
585
585
586
- delete [] fillCache;
587
- delete [] strokeCache;
586
+ if (fillCache != staticFillCache)
587
+ delete[] fillCache;
588
+ if (strokeCache != staticStrokeCache)
589
+ delete[] strokeCache;
588
590
589
591
return Py::Object ();
590
592
@@ -945,16 +947,14 @@ RendererAgg::_draw_path_collection_generic
945
947
size_t i = 0 ;
946
948
947
949
// 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
-
951
950
typedef std::vector<agg::trans_affine> transforms_t ;
952
951
transforms_t transforms;
953
952
transforms.reserve (Ntransforms);
954
953
for (i = 0 ; i < Ntransforms; ++i) {
955
954
agg::trans_affine trans = py_to_agg_transformation_matrix
956
955
(transforms_obj[i], false );
957
956
trans *= master_transform;
957
+
958
958
transforms.push_back (trans);
959
959
}
960
960
@@ -996,6 +996,10 @@ RendererAgg::_draw_path_collection_generic
996
996
trans *= agg::trans_affine_translation (xo, yo);
997
997
}
998
998
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
+
999
1003
if (Nfacecolors) {
1000
1004
size_t fi = i % Nfacecolors;
1001
1005
face.second = agg::rgba (*(double *)PyArray_GETPTR2 (facecolors, fi, 0 ),
0 commit comments