Menu

[r3938]: / branches / transforms / src / _gtkagg.cpp  Maximize  Restore  History

Download this file

161 lines (117 with data), 3.9 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <cstring>
#include <cerrno>
#include <cstdio>
#include <iostream>
#include <cmath>
#include <utility>
#include <fstream>
#include <pygobject.h>
#include <pygtk/pygtk.h>
#include "agg_basics.h"
#include "_backend_agg.h"
// the extension module
class _gtkagg_module : public Py::ExtensionModule<_gtkagg_module>
{
public:
_gtkagg_module()
: Py::ExtensionModule<_gtkagg_module>( "_gtkagg" )
{
add_varargs_method("agg_to_gtk_drawable",
&_gtkagg_module::agg_to_gtk_drawable,
"Draw to a gtk drawable from a agg buffer.");
initialize( "The _gtkagg module" );
}
virtual ~_gtkagg_module() {}
private:
Py::Object agg_to_gtk_drawable(const Py::Tuple &args) {
// args are gc, renderer, bbox where bbox is a transforms BBox
// (possibly None). If bbox is None, blit the entire agg buffer
// to gtk. If bbox is not None, blit only the region defined by
// the bbox
args.verify_length(3);
PyGObject *py_drawable = (PyGObject *)(args[0].ptr());
RendererAgg* aggRenderer = static_cast<RendererAgg*>(args[1].ptr());
GdkDrawable *drawable = GDK_DRAWABLE(py_drawable->obj);
GdkGC* gc = gdk_gc_new(drawable);
int srcstride = aggRenderer->get_width()*4;
int srcwidth = (int)aggRenderer->get_width();
int srcheight = (int)aggRenderer->get_height();
// these three will be overridden below
int destx = 0;
int desty = 0;
int destwidth = 1;
int destheight = 1;
int deststride = 1;
bool needfree = false;
agg::int8u *destbuffer = NULL;
if (args[2].ptr() == Py_None) {
//bbox is None; copy the entire image
destbuffer = aggRenderer->pixBuffer;
destwidth = srcwidth;
destheight = srcheight;
deststride = srcstride;
}
else {
//bbox is not None; copy the image in the bbox
// MGDTODO: Use PyArray rather than buffer interface here
PyObject* clipbox = args[2].ptr();
const void* clipbox_buffer;
Py_ssize_t clipbox_buffer_len;
if (!PyObject_CheckReadBuffer(clipbox))
throw Py::TypeError
("Argument 3 to agg_to_gtk_drawable must be a Bbox object.");
if (PyObject_AsReadBuffer(clipbox, &clipbox_buffer, &clipbox_buffer_len))
throw Py::Exception();
if (clipbox_buffer_len != sizeof(double) * 4)
throw Py::TypeError
("Argument 3 to agg_to_gtk_drawable must be a Bbox object.");
double* clipbox_values = (double*)clipbox_buffer;
double l = clipbox_values[0];
double b = clipbox_values[1];
double r = clipbox_values[2];
double t = clipbox_values[3];
//std::cout << b << " "
// << t << " ";
destx = (int)l;
desty = srcheight-(int)t;
destwidth = (int)(r-l);
destheight = (int)(t-b);
deststride = destwidth*4;
needfree = true;
destbuffer = new agg::int8u[deststride*destheight];
if (destbuffer ==NULL) {
throw Py::MemoryError("_gtkagg could not allocate memory for destbuffer");
}
agg::rendering_buffer destrbuf;
destrbuf.attach(destbuffer, destwidth, destheight, deststride);
pixfmt destpf(destrbuf);
renderer_base destrb(destpf);
//destrb.clear(agg::rgba(1, 0, 0));
agg::rect_base<int> region(destx, desty, (int)r, srcheight-(int)b);
destrb.copy_from(*aggRenderer->renderingBuffer, &region,
-destx, -desty);
}
/*std::cout << desty << " "
<< destheight << " "
<< srcheight << std::endl;*/
//gdk_rgb_init();
gdk_draw_rgb_32_image(drawable, gc, destx, desty,
destwidth,
destheight,
GDK_RGB_DITHER_NORMAL,
destbuffer,
deststride);
if (needfree) delete [] destbuffer;
return Py::Object();
}
};
extern "C"
DL_EXPORT(void)
init_gtkagg(void)
{
init_pygobject();
init_pygtk();
//suppress unused warning by creating in two lines
static _gtkagg_module* _gtkagg = NULL;
_gtkagg = new _gtkagg_module;
};
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.