Graphviz 12.0.1~dev.20240716.0800
Loading...
Searching...
No Matches
gvloadimage_gdk.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#include <cgraph/agxbuf.h>
13#include <stdbool.h>
14#include <stdlib.h>
15
17#include <gvc/gvio.h>
18
19#ifdef HAVE_PANGOCAIRO
20#include <cairo.h>
21#include <gdk-pixbuf/gdk-pixbuf.h>
22#include <gdk/gdkcairo.h>
23
24#ifdef _MSC_VER //*dependencies
25 #pragma comment( lib, "gvc.lib" )
26 #pragma comment( lib, "glib-2.0.lib" )
27 #pragma comment( lib, "cairo.lib" )
28 #pragma comment( lib, "gobject-2.0.lib" )
29 #pragma comment( lib, "graph.lib" )
30 #pragma comment( lib, "gdk-pixbuf.lib" )
31#endif
32
33typedef enum {
34 FORMAT_BMP_CAIRO,
35 FORMAT_JPEG_CAIRO,
37 FORMAT_ICO_CAIRO,
39
40static void gdk_set_mimedata_from_file (cairo_surface_t *image, const char *mime_type, const char *file)
41{
42 FILE *fp;
43 unsigned char *data = NULL;
44 long len;
45 const char *id_prefix = "gvloadimage_gdk-";
46
47 fp = fopen (file, "rb");
48 if (fp == NULL)
49 return;
50 fseek (fp, 0, SEEK_END);
51 len = ftell(fp);
52 fseek (fp, 0, SEEK_SET);
53 if (len > 0)
54 data = malloc ((size_t)len);
55 if (data) {
56 if (fread(data, (size_t)len, 1, fp) != 1) {
57 free (data);
58 data = NULL;
59 }
60 }
61 fclose(fp);
62
63 if (data) {
64 cairo_surface_set_mime_data (image, mime_type, data, (unsigned long)len, free, data);
65 agxbuf id = {0};
66 agxbprint(&id, "%s%s", id_prefix, file);
67 char *unique_id = agxbdisown(&id);
68 cairo_surface_set_mime_data(image, CAIRO_MIME_TYPE_UNIQUE_ID,
69 (unsigned char*)unique_id,
70 strlen(unique_id), free, unique_id);
71 }
72}
73
74static void gdk_set_mimedata(cairo_surface_t *image, usershape_t *us)
75{
76 switch (us->type) {
77 case FT_PNG:
78 gdk_set_mimedata_from_file (image, CAIRO_MIME_TYPE_PNG, us->name);
79 break;
80 case FT_JPEG:
81 gdk_set_mimedata_from_file (image, CAIRO_MIME_TYPE_JPEG, us->name);
82 break;
83 default:
84 break;
85 }
86}
87
88static void gdk_freeimage(usershape_t *us)
89{
90 cairo_surface_destroy(us->data);
91}
92
93static cairo_surface_t* gdk_loadimage(GVJ_t * job, usershape_t *us)
94{
95 cairo_t *cr = job->context; /* target context */
96 GdkPixbuf *image = NULL;
97 cairo_surface_t *cairo_image = NULL;
98 cairo_pattern_t *pattern;
99
100 assert(job);
101 assert(us);
102 assert(us->name);
103
104 if (us->data) {
105 if (us->datafree == gdk_freeimage) {
106 cairo_image = cairo_surface_reference(us->data); /* use cached data */
107 } else {
108 us->datafree(us); /* free incompatible cache data */
109 us->datafree = NULL;
110 us->data = NULL;
111 }
112 }
113 if (!cairo_image) { /* read file into cache */
115 return NULL;
116 switch (us->type) {
117 case FT_PNG:
118 case FT_JPEG:
119 case FT_BMP:
120 case FT_ICO:
121 case FT_TIFF:
122 // FIXME - should be using a stream reader
123 image = gdk_pixbuf_new_from_file(us->name, NULL);
124 break;
125 default:
126 image = NULL;
127 }
128 if (image) {
129 cairo_save (cr);
130 gdk_cairo_set_source_pixbuf (cr, image, 0, 0);
131 pattern = cairo_get_source (cr);
132 assert(cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SURFACE);
133 cairo_pattern_get_surface (pattern, &cairo_image);
134 cairo_image = cairo_surface_reference (cairo_image);
135 cairo_restore (cr);
136 gdk_set_mimedata (cairo_image, us);
137 us->data = cairo_surface_reference(cairo_image);
138 us->datafree = gdk_freeimage;
139 }
141 }
142 return cairo_image;
143}
144
145static void gdk_loadimage_cairo(GVJ_t * job, usershape_t *us, boxf b, bool filled)
146{
147 (void)filled;
148
149 cairo_t *cr = job->context; /* target context */
150 cairo_surface_t *image;
151
152 image = gdk_loadimage(job, us);
153 if (image) {
154 cairo_save(cr);
155 cairo_translate(cr, b.LL.x, -b.UR.y);
156 cairo_scale(cr, (b.UR.x - b.LL.x)/(us->w), (b.UR.y - b.LL.y)/(us->h));
157 cairo_set_source_surface (cr, image, 0, 0);
158 cairo_paint (cr);
159 cairo_restore(cr);
160 cairo_surface_destroy (image);
161 }
162}
163
164static gvloadimage_engine_t engine_gdk = {
165 gdk_loadimage_cairo
166};
167
168#endif
169
171#ifdef HAVE_PANGOCAIRO
172 {FORMAT_BMP_CAIRO, "bmp:cairo", 1, &engine_gdk, NULL},
173 {FORMAT_JPEG_CAIRO, "jpe:cairo", 2, &engine_gdk, NULL},
174 {FORMAT_JPEG_CAIRO, "jpg:cairo", 2, &engine_gdk, NULL},
175 {FORMAT_JPEG_CAIRO, "jpeg:cairo", 2, &engine_gdk, NULL},
176 {FORMAT_PNG_CAIRO, "png:cairo", -1, &engine_gdk, NULL},
177 {FORMAT_ICO_CAIRO, "ico:cairo", 1, &engine_gdk, NULL},
178#endif
179 {0, NULL, 0, NULL, NULL}
180};
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
Definition agxbuf.h:213
static char * agxbdisown(agxbuf *xb)
Definition agxbuf.h:299
static double len(glCompPoint p)
Definition glutils.c:150
void * malloc(YYSIZE_T)
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
@ FORMAT_PNG_CAIRO
gvplugin_installed_t gvloadimage_gdk_types[]
T_cell image
Definition htmlparse.y:538
void * context
Definition gvcjob.h:295
Definition geom.h:41
pointf UR
Definition geom.h:41
pointf LL
Definition geom.h:41
Definition legal.c:50
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_BMP
Definition usershape.h:25
@ FT_ICO
Definition usershape.h:27
@ FT_TIFF
Definition usershape.h:27
@ FT_JPEG
Definition usershape.h:25
@ FT_PNG
Definition usershape.h:25