Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit faeba6f

Browse files
committed
Fix marker drawing bug, and improve speed (by using buffers on the
stack if possible). svn path=/branches/transforms/; revision=4480
1 parent 1b3f939 commit faeba6f

File tree

1 file changed

+35
-31
lines changed

1 file changed

+35
-31
lines changed

src/_backend_agg.cpp

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
465467
Py::Object
466468
RendererAgg::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

Comments
 (0)