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

Skip to content

Commit 96b28e5

Browse files
committed
Use floating-point rendering buffer
1 parent cf80280 commit 96b28e5

File tree

3 files changed

+129
-113
lines changed

3 files changed

+129
-113
lines changed

src/_backend_agg.cpp

Lines changed: 2 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,11 @@
66
#include "mplutils.h"
77
#include "MPL_isnan.h"
88

9-
void BufferRegion::to_string_argb(uint8_t *buf)
10-
{
11-
unsigned char *pix;
12-
unsigned char tmp;
13-
size_t i, j;
14-
15-
memcpy(buf, data, height * stride);
16-
17-
for (i = 0; i < (size_t)height; ++i) {
18-
pix = buf + i * stride;
19-
for (j = 0; j < (size_t)width; ++j) {
20-
// Convert rgba to argb
21-
tmp = pix[2];
22-
pix[2] = pix[0];
23-
pix[0] = tmp;
24-
pix += 4;
25-
}
26-
}
27-
}
28-
299
RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi)
3010
: width(width),
3111
height(height),
3212
dpi(dpi),
33-
NUMBYTES(width * height * 4),
13+
NUMBYTES(width * height * sizeof(pixfmt::color_type)),
3414
pixBuffer(NULL),
3515
renderingBuffer(),
3616
alphaBuffer(NULL),
@@ -50,7 +30,7 @@ RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi)
5030
lastclippath(NULL),
5131
_fill_color(agg::rgba(1, 1, 1, 0))
5232
{
53-
unsigned stride(width * 4);
33+
unsigned stride(width * sizeof(pixfmt::color_type));
5434

5535
pixBuffer = new agg::int8u[NUMBYTES];
5636
renderingBuffer.attach(pixBuffer, width, height, stride);
@@ -78,54 +58,6 @@ void RendererAgg::create_alpha_buffers()
7858
}
7959
}
8060

81-
BufferRegion *RendererAgg::copy_from_bbox(agg::rect_d in_rect)
82-
{
83-
agg::rect_i rect(
84-
(int)in_rect.x1, height - (int)in_rect.y2, (int)in_rect.x2, height - (int)in_rect.y1);
85-
86-
BufferRegion *reg = NULL;
87-
reg = new BufferRegion(rect);
88-
89-
agg::rendering_buffer rbuf;
90-
rbuf.attach(reg->get_data(), reg->get_width(), reg->get_height(), reg->get_stride());
91-
92-
pixfmt pf(rbuf);
93-
renderer_base rb(pf);
94-
rb.copy_from(renderingBuffer, &rect, -rect.x1, -rect.y1);
95-
96-
return reg;
97-
}
98-
99-
void RendererAgg::restore_region(BufferRegion &region)
100-
{
101-
if (region.get_data() == NULL) {
102-
throw "Cannot restore_region from NULL data";
103-
}
104-
105-
agg::rendering_buffer rbuf;
106-
rbuf.attach(region.get_data(), region.get_width(), region.get_height(), region.get_stride());
107-
108-
rendererBase.copy_from(rbuf, 0, region.get_rect().x1, region.get_rect().y1);
109-
}
110-
111-
// Restore the part of the saved region with offsets
112-
void
113-
RendererAgg::restore_region(BufferRegion &region, int x, int y, int xx1, int yy1, int xx2, int yy2)
114-
{
115-
if (region.get_data() == NULL) {
116-
throw "Cannot restore_region from NULL data";
117-
}
118-
119-
agg::rect_i &rrect = region.get_rect();
120-
121-
agg::rect_i rect(xx1 - rrect.x1, (yy1 - rrect.y1), xx2 - rrect.x1, (yy2 - rrect.y1));
122-
123-
agg::rendering_buffer rbuf;
124-
rbuf.attach(region.get_data(), region.get_width(), region.get_height(), region.get_stride());
125-
126-
rendererBase.copy_from(rbuf, &rect, x, y);
127-
}
128-
12961
bool RendererAgg::render_clippath(py::PathIterator &clippath,
13062
const agg::trans_affine &clippath_trans)
13163
{

src/_backend_agg.h

Lines changed: 79 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,15 @@
4343

4444
// a helper class to pass agg::buffer objects around. agg::buffer is
4545
// a class in the swig wrapper
46+
template <class PixFmt>
4647
class BufferRegion
4748
{
4849
public:
4950
BufferRegion(const agg::rect_i &r) : rect(r)
5051
{
5152
width = r.x2 - r.x1;
5253
height = r.y2 - r.y1;
53-
stride = width * 4;
54+
stride = width * sizeof(typename PixFmt::color_type);
5455
data = new agg::int8u[stride * height];
5556
}
5657

@@ -84,7 +85,13 @@ class BufferRegion
8485
return stride;
8586
}
8687

87-
void to_string_argb(uint8_t *buf);
88+
void to_string_argb(uint8_t *buf)
89+
{
90+
agg::rendering_buffer src(data, width, height, width * sizeof(typename PixFmt::color_type));
91+
agg::rendering_buffer dst(buf, width, height, width * sizeof(agg::rgba8));
92+
93+
agg::convert<agg::pixfmt_argb32, PixFmt>(&dst, &src);
94+
}
8895

8996
private:
9097
agg::int8u *data;
@@ -105,9 +112,8 @@ class BufferRegion
105112
class RendererAgg
106113
{
107114
public:
108-
109-
typedef fixed_blender_rgba_plain<agg::rgba8, agg::order_rgba> fixed_blender_rgba32_plain;
110-
typedef agg::pixfmt_alpha_blend_rgba<fixed_blender_rgba32_plain, agg::rendering_buffer> pixfmt;
115+
typedef agg::pixfmt_rgba128_plain pixfmt;
116+
typedef typename pixfmt::color_type color_type;
111117
typedef agg::renderer_base<pixfmt> renderer_base;
112118
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_aa;
113119
typedef agg::renderer_scanline_bin_solid<renderer_base> renderer_bin;
@@ -211,9 +217,54 @@ class RendererAgg
211217
agg::rect_i get_content_extents();
212218
void clear();
213219

214-
BufferRegion *copy_from_bbox(agg::rect_d in_rect);
215-
void restore_region(BufferRegion &reg);
216-
void restore_region(BufferRegion &region, int x, int y, int xx1, int yy1, int xx2, int yy2);
220+
BufferRegion<pixfmt> *copy_from_bbox(agg::rect_d in_rect)
221+
{
222+
agg::rect_i rect(
223+
(int)in_rect.x1, height - (int)in_rect.y2, (int)in_rect.x2, height - (int)in_rect.y1);
224+
225+
BufferRegion<pixfmt> *reg = NULL;
226+
reg = new BufferRegion<pixfmt>(rect);
227+
228+
agg::rendering_buffer rbuf;
229+
rbuf.attach(reg->get_data(), reg->get_width(), reg->get_height(), reg->get_stride());
230+
231+
pixfmt pf(rbuf);
232+
renderer_base rb(pf);
233+
rb.copy_from(renderingBuffer, &rect, -rect.x1, -rect.y1);
234+
235+
return reg;
236+
}
237+
238+
void restore_region(BufferRegion<pixfmt> &region)
239+
{
240+
if (region.get_data() == NULL) {
241+
throw "Cannot restore_region from NULL data";
242+
}
243+
244+
agg::rendering_buffer rbuf;
245+
rbuf.attach(
246+
region.get_data(), region.get_width(), region.get_height(), region.get_stride());
247+
248+
rendererBase.copy_from(rbuf, 0, region.get_rect().x1, region.get_rect().y1);
249+
}
250+
251+
void
252+
restore_region(BufferRegion<pixfmt> &region, int x, int y, int xx1, int yy1, int xx2, int yy2)
253+
{
254+
if (region.get_data() == NULL) {
255+
throw "Cannot restore_region from NULL data";
256+
}
257+
258+
agg::rect_i &rrect = region.get_rect();
259+
260+
agg::rect_i rect(xx1 - rrect.x1, (yy1 - rrect.y1), xx2 - rrect.x1, (yy2 - rrect.y1));
261+
262+
agg::rendering_buffer rbuf;
263+
rbuf.attach(
264+
region.get_data(), region.get_width(), region.get_height(), region.get_stride());
265+
266+
rendererBase.copy_from(rbuf, &rect, x, y);
267+
}
217268

218269
unsigned int width, height;
219270
double dpi;
@@ -392,7 +443,7 @@ RendererAgg::_draw_path(path_t &path, bool has_clippath, const facepair_t &face,
392443
agg::wrap_mode_repeat_auto_pow2,
393444
agg::wrap_mode_repeat_auto_pow2> img_source_type;
394445
typedef agg::span_pattern_rgba<img_source_type> span_gen_type;
395-
agg::span_allocator<agg::rgba8> sa;
446+
agg::span_allocator<pixfmt::color_type> sa;
396447
img_source_type img_src(hatch_img_pixf);
397448
span_gen_type sg(img_src, 0, 0);
398449
theRasterizer.add_path(path);
@@ -551,10 +602,8 @@ inline void RendererAgg::draw_markers(GCAgg &gc,
551602
fillCache = new agg::int8u[fillSize];
552603
}
553604
scanlines.serialize(fillCache);
554-
marker_size = agg::rect_i(scanlines.min_x(),
555-
scanlines.min_y(),
556-
scanlines.max_x(),
557-
scanlines.max_y());
605+
marker_size = agg::rect_i(
606+
scanlines.min_x(), scanlines.min_y(), scanlines.max_x(), scanlines.max_y());
558607
}
559608

560609
stroke_t stroke(marker_path_curve);
@@ -676,34 +725,34 @@ inline void RendererAgg::draw_markers(GCAgg &gc,
676725
* This is a custom span generator that converts spans in the
677726
* 8-bit inverted greyscale font buffer to rgba that agg can use.
678727
*/
679-
template <class ChildGenerator>
728+
template <class ChildGenerator, class ColorType>
680729
class font_to_rgba
681730
{
682731
public:
683732
typedef ChildGenerator child_type;
684-
typedef agg::rgba8 color_type;
685733
typedef typename child_type::color_type child_color_type;
686734
typedef agg::span_allocator<child_color_type> span_alloc_type;
687735

688736
private:
689737
child_type *_gen;
690-
color_type _color;
738+
ColorType _color;
691739
span_alloc_type _allocator;
692740

693741
public:
694-
font_to_rgba(child_type *gen, color_type color) : _gen(gen), _color(color)
742+
font_to_rgba(child_type *gen, ColorType color) : _gen(gen), _color(color)
695743
{
696744
}
697745

698-
inline void generate(color_type *output_span, int x, int y, unsigned len)
746+
inline void generate(ColorType *output_span, int x, int y, unsigned len)
699747
{
700748
_allocator.allocate(len);
701749
child_color_type *input_span = _allocator.span();
702750
_gen->generate(input_span, x, y, len);
703751

704752
do {
705753
*output_span = _color;
706-
output_span->a = ((unsigned int)_color.a * (unsigned int)input_span->v) >> 8;
754+
output_span->opacity(_color.opacity() *
755+
input_span->to_double(input_span->v));
707756
++output_span;
708757
++input_span;
709758
} while (--len);
@@ -718,11 +767,11 @@ class font_to_rgba
718767
template <class ImageArray>
719768
inline void RendererAgg::draw_text_image(GCAgg &gc, ImageArray &image, int x, int y, double angle)
720769
{
721-
typedef agg::span_allocator<agg::rgba8> color_span_alloc_type;
770+
typedef agg::span_allocator<pixfmt::color_type> color_span_alloc_type;
722771
typedef agg::span_interpolator_linear<> interpolator_type;
723772
typedef agg::image_accessor_clip<agg::pixfmt_gray8> image_accessor_type;
724773
typedef agg::span_image_filter_gray<image_accessor_type, interpolator_type> image_span_gen_type;
725-
typedef font_to_rgba<image_span_gen_type> span_gen_type;
774+
typedef font_to_rgba<image_span_gen_type, color_type> span_gen_type;
726775
typedef agg::renderer_scanline_aa<renderer_base, color_span_alloc_type, span_gen_type>
727776
renderer_type;
728777

@@ -763,11 +812,10 @@ inline void RendererAgg::draw_text_image(GCAgg &gc, ImageArray &image, int x, in
763812
agg::render_scanlines(theRasterizer, slineP8, ri);
764813
}
765814

815+
template <class color_type>
766816
class span_conv_alpha
767817
{
768818
public:
769-
typedef agg::rgba8 color_type;
770-
771819
double m_alpha;
772820

773821
span_conv_alpha(double alpha) : m_alpha(alpha)
@@ -835,18 +883,19 @@ inline void RendererAgg::draw_image(GCAgg &gc,
835883
agg::trans_affine inv_mtx(mtx);
836884
inv_mtx.invert();
837885

838-
typedef agg::span_allocator<agg::rgba8> color_span_alloc_type;
886+
typedef agg::span_allocator<pixfmt::color_type> color_span_alloc_type;
839887
typedef agg::image_accessor_clip<pixfmt> image_accessor_type;
840888
typedef agg::span_interpolator_linear<> interpolator_type;
841889
typedef agg::span_image_filter_rgba_nn<image_accessor_type, interpolator_type>
842890
image_span_gen_type;
843-
typedef agg::span_converter<image_span_gen_type, span_conv_alpha> span_conv;
891+
typedef agg::span_converter<image_span_gen_type, span_conv_alpha<pixfmt::color_type> >
892+
span_conv;
844893

845894
color_span_alloc_type sa;
846-
image_accessor_type ia(pixf, agg::rgba8(0, 0, 0, 0));
895+
image_accessor_type ia(pixf, pixfmt::color_type(0, 0, 0, 0));
847896
interpolator_type interpolator(inv_mtx);
848897
image_span_gen_type image_span_generator(ia, interpolator);
849-
span_conv_alpha conv_alpha(alpha);
898+
span_conv_alpha<pixfmt::color_type> conv_alpha(alpha);
850899
span_conv spans(image_span_generator, conv_alpha);
851900

852901
if (has_clippath) {
@@ -1200,7 +1249,7 @@ inline void RendererAgg::_draw_gouraud_triangle(PointArray &points,
12001249
agg::trans_affine trans,
12011250
bool has_clippath)
12021251
{
1203-
typedef agg::rgba8 color_t;
1252+
typedef pixfmt::color_type color_t;
12041253
typedef agg::span_gouraud_rgba<color_t> span_gen_t;
12051254
typedef agg::span_allocator<color_t> span_alloc_t;
12061255

@@ -1266,7 +1315,7 @@ inline void RendererAgg::draw_gouraud_triangle(GCAgg &gc,
12661315
throw "colors must be a 3x4 array";
12671316
}
12681317

1269-
_draw_gouraud_triangle(points, colors, trans, has_clippath);
1318+
// _draw_gouraud_triangle(points, colors, trans, has_clippath);
12701319
}
12711320

12721321
template <class PointArray, class ColorArray>
@@ -1296,7 +1345,7 @@ inline void RendererAgg::draw_gouraud_triangles(GCAgg &gc,
12961345
typename PointArray::sub_t point = points[i];
12971346
typename ColorArray::sub_t color = colors[i];
12981347

1299-
_draw_gouraud_triangle(point, color, trans, has_clippath);
1348+
// _draw_gouraud_triangle(point, color, trans, has_clippath);
13001349
}
13011350
}
13021351

0 commit comments

Comments
 (0)