Graphviz  2.41.20171026.1811
gvloadimage_poppler.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 #include <sys/stat.h>
18 
19 #include "gvplugin_loadimage.h"
20 
21 #ifdef HAVE_PANGOCAIRO
22 #ifdef HAVE_POPPLER
23 #include <poppler.h>
24 #include <cairo.h>
25 
26 #ifdef _WIN32
27 #define NUL_FILE "nul"
28 #else
29 #define NUL_FILE "/dev/null"
30 #endif
31 
32 typedef enum {
33  FORMAT_PDF_CAIRO,
34 } format_type;
35 
36 
37 static void gvloadimage_poppler_free(usershape_t *us)
38 {
39  g_object_unref((PopplerDocument*)us->data);
40 }
41 
42 static PopplerDocument* gvloadimage_poppler_load(GVJ_t * job, usershape_t *us)
43 {
44  PopplerDocument *document = NULL;
45  GError *error;
46  gchar *absolute, *uri;
47  int num_pages;
48 
49  assert(job);
50  assert(us);
51  assert(us->name);
52 
53  if (us->data) {
54  if (us->datafree == gvloadimage_poppler_free)
55  document = (PopplerDocument*)(us->data); /* use cached data */
56  else {
57  us->datafree(us); /* free incompatible cache data */
58  us->data = NULL;
59  us->datafree = NULL;
60  }
61 
62  }
63 
64  if (!document) { /* read file into cache */
65  if (!gvusershape_file_access(us))
66  return NULL;
67  switch (us->type) {
68  case FT_PDF:
69 
70  if (g_path_is_absolute(us->name)) {
71  absolute = g_strdup (us->name);
72  } else {
73  gchar *dir = g_get_current_dir ();
74  absolute = g_build_filename (dir, us->name, (gchar *) 0);
75  free (dir);
76  }
77 
78  uri = g_filename_to_uri (absolute, NULL, &error);
79 
80  free (absolute);
81  if (uri == NULL) {
82  printf("%s\n", error->message);
83  return NULL;
84  }
85 
86  document = poppler_document_new_from_file (uri, NULL, &error);
87  if (document == NULL) {
88  printf("%s\n", error->message);
89  return NULL;
90  }
91 
92  // check page 1 exists
93 
94  num_pages = poppler_document_get_n_pages (document);
95  if (num_pages < 1) {
96  printf("poppler fail: num_pages %d, must be at least 1", num_pages);
97  return NULL;
98  }
99  break;
100 
101  default:
102  break;
103  }
104 
105  if (document) {
106  us->data = (void*)document;
107  us->datafree = gvloadimage_poppler_free;
108  }
109 
111  }
112 
113  return document;
114 }
115 
116 static void gvloadimage_poppler_cairo(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
117 {
118  PopplerDocument* document = gvloadimage_poppler_load(job, us);
119  PopplerPage* page;
120 
121  cairo_t *cr = (cairo_t *) job->context; /* target context */
122  cairo_surface_t *surface; /* source surface */
123 
124  if (document) {
125 
126  // already done this once, so no err checking
127  page = poppler_document_get_page (document, 0);
128 
129  cairo_save(cr);
130 
131  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, us->w, us->h);
132  cairo_surface_reference(surface);
133 
134  cairo_set_source_surface(cr, surface, 0, 0);
135  cairo_translate(cr, b.LL.x, -b.UR.y);
136  cairo_scale(cr, (b.UR.x - b.LL.x)/(us->w), (b.UR.y - b.LL.y)/(us->h));
137  poppler_page_render (page, cr);
138  cairo_paint (cr);
139 
140  cairo_restore(cr);
141  }
142 }
143 
144 static gvloadimage_engine_t engine_cairo = {
145  gvloadimage_poppler_cairo
146 };
147 #endif
148 #endif
149 
151 #ifdef HAVE_PANGOCAIRO
152 #ifdef HAVE_POPPLER
153  {FORMAT_PDF_CAIRO, "pdf:cairo", 1, &engine_cairo, NULL},
154 #endif
155 #endif
156  {0, NULL, 0, NULL, NULL}
157 };
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
boolean gvusershape_file_access(usershape_t *us)
Definition: gvusershape.c:584
double y
Definition: geom.h:28
imagetype_t type
Definition: usershape.h:58
void gvusershape_file_release(usershape_t *us)
Definition: gvusershape.c:618
if(aagss+aagstacksize-1<=aagssp)
Definition: grammar.c:1332
format_type
#define NULL
Definition: logic.h:39
double x
Definition: geom.h:28
pointf LL
Definition: geom.h:35
gvplugin_installed_t gvloadimage_poppler_types[]
const char * name
Definition: usershape.h:53
pointf UR
Definition: geom.h:35
Definition: geom.h:35