28 #include <pango/pangocairo.h>
38 #define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0]))
40 static double dashed[] = {6.};
43 static double dotted[] = {2., 6.};
46 #ifdef CAIRO_HAS_PS_SURFACE
50 #ifdef CAIRO_HAS_PDF_SURFACE
51 #include <cairo-pdf.h>
54 #ifdef CAIRO_HAS_SVG_SURFACE
55 #include <cairo-svg.h>
58 static void cairogen_polyline(
GVJ_t * job,
pointf * A,
int n);
60 static void cairogen_set_color(cairo_t * cr,
gvcolor_t * color)
62 cairo_set_source_rgba(cr, color->
u.
RGBA[0], color->
u.
RGBA[1],
66 static void cairogen_add_color_stop_rgba(cairo_pattern_t *pat,
double stop ,
gvcolor_t * color)
68 cairo_pattern_add_color_stop_rgba (pat, stop,color->
u.
RGBA[0], color->
u.
RGBA[1],
74 writer (
void *closure,
const unsigned char *
data,
unsigned int length)
76 if (length ==
gvwrite((
GVJ_t *)closure, (
const char*)data, length))
77 return CAIRO_STATUS_SUCCESS;
78 return CAIRO_STATUS_WRITE_ERROR;
81 static void cairogen_begin_job(
GVJ_t * job)
84 cairo_save((cairo_t *) job->
context);
87 static void cairogen_end_job(
GVJ_t * job)
89 cairo_t *cr = (cairo_t *) job->
context;
99 #define CAIRO_XMAX 32767
100 #define CAIRO_YMAX 32767
102 static void cairogen_begin_page(
GVJ_t * job)
104 cairo_t *cr = (cairo_t *) job->
context;
105 cairo_surface_t *surface;
106 cairo_status_t status;
111 #ifdef CAIRO_HAS_PS_SURFACE
112 surface = cairo_ps_surface_create_for_stream (writer,
117 #ifdef CAIRO_HAS_PDF_SURFACE
118 surface = cairo_pdf_surface_create_for_stream (writer,
123 #ifdef CAIRO_HAS_SVG_SURFACE
124 surface = cairo_svg_surface_create_for_stream (writer,
139 "%s: graph is too large for cairo-renderer bitmaps. Scaling by %g to fit\n",
142 surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
146 "%s: allocating a %dK cairo image surface (%d x %d pixels)\n",
152 status = cairo_surface_status(surface);
153 if (status != CAIRO_STATUS_SUCCESS) {
154 fprintf(stderr,
"%s: failure to create cairo surface: %s\n",
156 cairo_status_to_string(status));
157 cairo_surface_destroy (surface);
160 cr = cairo_create(surface);
161 cairo_surface_destroy (surface);
175 static void cairogen_end_page(
GVJ_t * job)
177 cairo_t *cr = (cairo_t *) job->
context;
178 cairo_surface_t *surface;
179 cairo_status_t status;
183 #ifdef CAIRO_HAS_PNG_FUNCTIONS
185 surface = cairo_get_target(cr);
186 cairo_surface_write_to_png_stream(surface, writer, job);
194 surface = cairo_surface_reference(cairo_get_target(cr));
195 cairo_surface_finish(surface);
196 status = cairo_surface_status(surface);
197 cairo_surface_destroy(surface);
198 if (status != CAIRO_STATUS_SUCCESS)
199 fprintf(stderr,
"cairo: %s\n", cairo_status_to_string(status));
204 surface = cairo_get_target(cr);
205 if (cairo_image_surface_get_width(surface) == 0 || cairo_image_surface_get_height(surface) == 0) {
211 job->
imagedata = (
char *)(cairo_image_surface_get_data(surface));
220 cairo_t *cr = (cairo_t *) job->
context;
223 cairo_set_dash (cr, dashed, 0, 0.0);
224 cairogen_set_color(cr, &(obj->
pencolor));
226 switch (span->
just) {
235 p.
x -= span->
size.
x / 2.0;
240 cairo_move_to (cr, p.
x, -p.
y);
243 pango_cairo_show_layout(cr, (PangoLayout*)(span->
layout));
248 A[1].x = p.
x + span->
size.
x;
249 A[1].y = A[0].y = p.
y;
250 cairogen_polyline(job, A, 2);
254 static void cairogen_set_penstyle(
GVJ_t *job, cairo_t *cr)
259 cairo_set_dash (cr, dashed, dashed_len, 0.0);
261 cairo_set_dash (cr, dotted, dotted_len, 0.0);
263 cairo_set_dash (cr, dashed, 0, 0.0);
265 cairo_set_line_width (cr, obj->
penwidth);
269 static void cairo_gradient_fill (cairo_t* cr,
obj_state_t* obj,
int filled,
pointf* A,
int n)
271 cairo_pattern_t* pat;
278 pat = cairo_pattern_create_linear (G[0].x,G[0].y,G[1].x,G[1].y);
290 c1.
x = G[0].
x + r1 * cos(angle);
291 c1.
y = G[0].
y - r1 * sin(angle);
293 pat = cairo_pattern_create_radial(c1.
x,c1.
y,r1,G[0].
x,G[0].
y,r2);
300 cairogen_add_color_stop_rgba(pat,0,&(obj->
fillcolor));
301 cairogen_add_color_stop_rgba(pat,1,&(obj->
stopcolor));
303 cairo_set_source (cr, pat);
304 cairo_fill_preserve (cr);
305 cairo_pattern_destroy (pat);
308 static void cairogen_ellipse(
GVJ_t * job,
pointf * A,
int filled)
311 cairo_t *cr = (cairo_t *) job->
context;
312 cairo_matrix_t matrix;
315 cairogen_set_penstyle(job, cr);
317 cairo_get_matrix(cr, &matrix);
319 rx = A[1].
x - A[0].
x;
320 ry = A[1].
y - A[0].
y;
326 cairo_translate(cr, A[0].x, -A[0].y);
327 cairo_scale(cr, rx, ry);
328 cairo_move_to(cr, 1., 0.);
329 cairo_arc(cr, 0., 0., 1., 0., 2 *
M_PI);
331 cairo_set_matrix(cr, &matrix);
334 cairo_gradient_fill (cr, obj, filled, A, 2);
337 cairogen_set_color(cr, &(obj->
fillcolor));
338 cairo_fill_preserve(cr);
340 cairogen_set_color(cr, &(obj->
pencolor));
345 cairogen_polygon(
GVJ_t * job,
pointf * A,
int n,
int filled)
348 cairo_t *cr = (cairo_t *) job->
context;
351 cairogen_set_penstyle(job, cr);
353 cairo_move_to(cr, A[0].x, -A[0].y);
354 for (i = 1; i < n; i++)
355 cairo_line_to(cr, A[i].x, -A[i].y);
356 cairo_close_path(cr);
358 cairo_gradient_fill (cr, obj, filled, A, n);
361 cairogen_set_color(cr, &(obj->
fillcolor));
362 cairo_fill_preserve(cr);
364 cairogen_set_color(cr, &(obj->
pencolor));
369 cairogen_bezier(
GVJ_t * job,
pointf * A,
int n,
int arrow_at_start,
370 int arrow_at_end,
int filled)
373 cairo_t *cr = (cairo_t *) job->
context;
376 cairogen_set_penstyle(job, cr);
378 cairo_move_to(cr, A[0].x, -A[0].y);
379 for (i = 1; i < n; i += 3)
380 cairo_curve_to(cr, A[i].x, -A[i].y, A[i + 1].x, -A[i + 1].y,
381 A[i + 2].x, -A[i + 2].y);
383 cairo_gradient_fill (cr, obj, filled, A, n);
386 cairogen_set_color(cr, &(obj->
fillcolor));
387 cairo_fill_preserve(cr);
389 cairogen_set_color(cr, &(obj->
pencolor));
397 cairo_t *cr = (cairo_t *) job->
context;
400 cairogen_set_penstyle(job, cr);
402 cairo_move_to(cr, A[0].x, -A[0].y);
403 for (i = 1; i < n; i++)
404 cairo_line_to(cr, A[i].x, -A[i].y);
405 cairogen_set_color(cr, &(obj->
pencolor));
482 {
FORMAT_CAIRO,
"cairo", 10, &cairogen_engine, &render_features_cairo},
487 #ifdef CAIRO_HAS_PNG_FUNCTIONS
490 #ifdef CAIRO_HAS_PS_SURFACE
493 #ifdef CAIRO_HAS_PDF_SURFACE
496 #ifdef CAIRO_HAS_SVG_SURFACE
#define GVDEVICE_BINARY_FORMAT
gvplugin_installed_t gvrender_pango_types[]
#define GVRENDER_DOES_TRANSFORM
#define GVRENDER_Y_GOES_DOWN
gvplugin_active_render_t render
double yoffset_centerline
if(aagss+aagstacksize-1<=aagssp)
gvplugin_installed_t gvdevice_pango_types[]
gvdevice_features_t device_features_svg
size_t gvwrite(GVJ_t *job, const char *s, size_t len)
#define GVDEVICE_DOES_TRUECOLOR
void get_gradient_points(pointf *A, pointf *G, int n, float angle, int flags)