Graphviz  2.41.20171026.1811
gvloadimage_pango.c
Go to the documentation of this file.
1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 #include "config.h"
15 
16 #include <stdlib.h>
17 
18 #include "gvplugin_loadimage.h"
19 #include "gvio.h"
20 
21 #include <cairo.h>
22 
23 typedef enum {
25 } format_type;
26 
27 static cairo_status_t
28 reader (void *closure, unsigned char *data, unsigned int length)
29 {
30  assert(closure);
31  if (length == fread(data, 1, length, (FILE *)closure)
32  || feof((FILE *)closure))
33  return CAIRO_STATUS_SUCCESS;
34  return CAIRO_STATUS_READ_ERROR;
35 }
36 
37 static void cairo_freeimage(usershape_t *us)
38 {
39  cairo_surface_destroy((cairo_surface_t*)(us->data));
40 }
41 
42 static cairo_surface_t* cairo_loadimage(GVJ_t * job, usershape_t *us)
43 {
44  cairo_surface_t *surface = NULL; /* source surface */
45 
46  assert(job);
47  assert(us);
48  assert(us->name);
49  assert(us->name[0]);
50 
51  if (us->data) {
52  if (us->datafree == cairo_freeimage)
53  surface = (cairo_surface_t*)(us->data); /* use cached data */
54  else {
55  us->datafree(us); /* free incompatible cache data */
56  us->datafree = NULL;
57  us->data = NULL;
58  }
59  }
60  if (!surface) { /* read file into cache */
61  if (!gvusershape_file_access(us))
62  return NULL;
63  assert(us->f);
64  switch (us->type) {
65 #ifdef CAIRO_HAS_PNG_FUNCTIONS
66  case FT_PNG:
67  surface = cairo_image_surface_create_from_png_stream(reader, us->f);
68  cairo_surface_reference(surface);
69  break;
70 #endif
71  default:
72  surface = NULL;
73  }
74  if (surface) {
75  us->data = (void*)surface;
76  us->datafree = cairo_freeimage;
77  }
79  }
80  return surface;
81 }
82 
83 static void pango_loadimage_cairo(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
84 {
85  cairo_t *cr = (cairo_t *) job->context; /* target context */
86  cairo_surface_t *surface; /* source surface */
87 
88  assert(job);
89  assert(us);
90  assert(us->name);
91  assert(us->name[0]);
92 
93  surface = cairo_loadimage(job, us);
94  if (surface) {
95  cairo_save(cr);
96  cairo_translate(cr, b.LL.x, -b.UR.y);
97  cairo_scale(cr, (b.UR.x - b.LL.x)/(us->w), (b.UR.y - b.LL.y)/(us->h));
98  cairo_set_source_surface (cr, surface, 0, 0);
99  cairo_paint (cr);
100  cairo_restore(cr);
101  }
102 }
103 
104 static void pango_loadimage_ps(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
105 {
106  cairo_surface_t *surface; /* source surface */
107  cairo_format_t format;
108  int X, Y, x, y, stride;
109  unsigned char *data, *ix, alpha, red, green, blue;
110 
111  surface = cairo_loadimage(job, us);
112  if (surface) {
113  format = cairo_image_surface_get_format(surface);
114  if ((format != CAIRO_FORMAT_ARGB32) && (format != CAIRO_FORMAT_RGB24))
115  return;
116 
117  X = cairo_image_surface_get_width(surface);
118  Y = cairo_image_surface_get_height(surface);
119  stride = cairo_image_surface_get_stride(surface);
120  data = cairo_image_surface_get_data(surface);
121 
122  gvputs(job, "save\n");
123 
124  /* define image data as string array (one per raster line) */
125  /* see parallel code in gd_loadimage_ps(). FIXME: refactor... */
126  gvputs(job, "/myctr 0 def\n");
127  gvputs(job, "/myarray [\n");
128  for (y = 0; y < Y; y++) {
129  gvputs(job, "<");
130  ix = data + y * stride;
131  for (x = 0; x < X; x++) {
132  /* FIXME - this code may have endian problems */
133  blue = *ix++;
134  green = *ix++;
135  red = *ix++;
136  alpha = *ix++;
137  if (alpha < 0x7f)
138  gvputs(job, "ffffff");
139  else
140  gvprintf(job, "%02x%02x%02x", red, green, blue);
141  }
142  gvputs(job, ">\n");
143  }
144  gvputs(job, "] def\n");
145  gvputs(job,"/myproc { myarray myctr get /myctr myctr 1 add def } def\n");
146 
147  /* this sets the position of the image */
148  gvprintf(job, "%g %g translate\n",
149  (b.LL.x + (b.UR.x - b.LL.x) * (1. - (job->dpi.x) / 96.) / 2.),
150  (b.LL.y + (b.UR.y - b.LL.y) * (1. - (job->dpi.y) / 96.) / 2.));
151 
152  /* this sets the rendered size to fit the box */
153  gvprintf(job,"%g %g scale\n",
154  ((b.UR.x - b.LL.x) * 72. / 96.),
155  ((b.UR.y - b.LL.y) * 72. / 96.));
156 
157  /* xsize ysize bits-per-sample [matrix] */
158  gvprintf(job, "%d %d 8 [%d 0 0 %d 0 %d]\n", X, Y, X, -Y, Y);
159 
160  gvputs(job, "{myproc} false 3 colorimage\n");
161 
162  gvputs(job, "restore\n");
163  }
164 }
165 
166 static gvloadimage_engine_t engine_cairo = {
167  pango_loadimage_cairo
168 };
169 
170 static gvloadimage_engine_t engine_ps = {
171  pango_loadimage_ps
172 };
173 
175  {FORMAT_PNG_CAIRO, "png:cairo", 1, &engine_cairo, NULL},
176  {FORMAT_PNG_PS, "png:lasi", 2, &engine_ps, NULL},
177  {FORMAT_PNG_PS, "png:ps", 2, &engine_ps, NULL},
178  {0, NULL, 0, NULL, NULL}
179 };
void(* datafree)(usershape_t *us)
Definition: usershape.h:63
void * context
Definition: gvcjob.h:304
#define assert(x)
Definition: cghdr.h:47
void * data
Definition: usershape.h:61
Definition: gvcjob.h:271
gvplugin_installed_t gvloadimage_pango_types[]
int gvputs(GVJ_t *job, const char *s)
Definition: gvdevice.c:270
pointf dpi
Definition: gvcjob.h:334
boolean gvusershape_file_access(usershape_t *us)
Definition: gvusershape.c:584
FILE * f
Definition: usershape.h:57
double y
Definition: geom.h:28
imagetype_t type
Definition: usershape.h:58
void gvusershape_file_release(usershape_t *us)
Definition: gvusershape.c:618
format_type
#define NULL
Definition: logic.h:39
double x
Definition: geom.h:28
pointf LL
Definition: geom.h:35
#define alpha
Definition: shapes.c:3902
const char * name
Definition: usershape.h:53
pointf UR
Definition: geom.h:35
Definition: geom.h:35
Definition: legal.c:60
void gvprintf(GVJ_t *job, const char *format,...)
Definition: gvdevice.c:389