Graphviz 12.0.1~dev.20240716.0800
Loading...
Searching...
No Matches
gvloadimage_poppler.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include "config.h"
12
13#include <stdbool.h>
14#include <stdlib.h>
15#include <sys/stat.h>
16
18
19#ifdef HAVE_PANGOCAIRO
20#ifdef HAVE_POPPLER
21#include <poppler.h>
22#include <cairo.h>
23
24typedef enum {
25 FORMAT_PDF_CAIRO,
27
28
29static void gvloadimage_poppler_free(usershape_t *us)
30{
31 g_object_unref(us->data);
32}
33
34static PopplerDocument* gvloadimage_poppler_load(GVJ_t * job, usershape_t *us)
35{
36 PopplerDocument *document = NULL;
37 GError *error;
38 gchar *absolute, *uri;
39 int num_pages;
40
41 assert(job);
42 assert(us);
43 assert(us->name);
44
45 if (us->data) {
46 if (us->datafree == gvloadimage_poppler_free)
47 document = us->data; /* use cached data */
48 else {
49 us->datafree(us); /* free incompatible cache data */
50 us->data = NULL;
51 us->datafree = NULL;
52 }
53
54 }
55
56 if (!document) { /* read file into cache */
58 return NULL;
59 switch (us->type) {
60 case FT_PDF:
61
62 if (g_path_is_absolute(us->name)) {
63 absolute = g_strdup (us->name);
64 } else {
65 gchar *dir = g_get_current_dir ();
66 absolute = g_build_filename(dir, us->name, NULL);
67 free (dir);
68 }
69
70 uri = g_filename_to_uri (absolute, NULL, &error);
71
72 g_free(absolute);
73 if (uri == NULL) {
74 printf("%s\n", error->message);
75 return NULL;
76 }
77
78 document = poppler_document_new_from_file (uri, NULL, &error);
79 if (document == NULL) {
80 printf("%s\n", error->message);
81 return NULL;
82 }
83
84 // check page 1 exists
85
86 num_pages = poppler_document_get_n_pages (document);
87 if (num_pages < 1) {
88 printf("poppler fail: num_pages %d, must be at least 1", num_pages);
89 return NULL;
90 }
91 break;
92
93 default:
94 break;
95 }
96
97 if (document) {
98 us->data = document;
99 us->datafree = gvloadimage_poppler_free;
100 }
101
103 }
104
105 return document;
106}
107
108static void gvloadimage_poppler_cairo(GVJ_t * job, usershape_t *us, boxf b, bool filled)
109{
110 (void)filled;
111
112 PopplerDocument* document = gvloadimage_poppler_load(job, us);
113 PopplerPage* page;
114
115 cairo_t *cr = job->context; /* target context */
116 cairo_surface_t *surface; /* source surface */
117
118 if (document) {
119
120 // already done this once, so no err checking
121 page = poppler_document_get_page (document, 0);
122
123 cairo_save(cr);
124
125 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, (int)us->w, (int)us->h);
126 cairo_surface_reference(surface);
127
128 cairo_set_source_surface(cr, surface, 0, 0);
129 cairo_translate(cr, b.LL.x, -b.UR.y);
130 cairo_scale(cr, (b.UR.x - b.LL.x)/(us->w), (b.UR.y - b.LL.y)/(us->h));
131 poppler_page_render (page, cr);
132 cairo_paint (cr);
133
134 cairo_restore(cr);
135 }
136}
137
139 gvloadimage_poppler_cairo
140};
141#endif
142#endif
143
145#ifdef HAVE_PANGOCAIRO
146#ifdef HAVE_POPPLER
147 {FORMAT_PDF_CAIRO, "pdf:cairo", 1, &engine_cairo, NULL},
148#endif
149#endif
150 {0, NULL, 0, NULL, NULL}
151};
void error(int level, const char *s,...)
Definition error.c:83
void free(void *)
node NULL
Definition grammar.y:149
void gvusershape_file_release(usershape_t *us)
bool gvusershape_file_access(usershape_t *us)
format_type
static gvloadimage_engine_t engine_cairo
gvplugin_installed_t gvloadimage_poppler_types[]
void * context
Definition gvcjob.h:295
Definition geom.h:41
pointf UR
Definition geom.h:41
pointf LL
Definition geom.h:41
ingroup plugin_api
Definition gvplugin.h:35
double x
Definition geom.h:29
double y
Definition geom.h:29
const char * name
Definition usershape.h:54
void(* datafree)(usershape_t *us)
Definition usershape.h:65
void * data
Definition usershape.h:63
imagetype_t type
Definition usershape.h:59
double h
Definition usershape.h:61
double w
Definition usershape.h:61
@ FT_PDF
Definition usershape.h:26