Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
gvloadimage_pango.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 <stdint.h>
15#include <stdlib.h>
16#include <string.h>
17
19#include <gvc/gvio.h>
20
21#include <cairo.h>
22
26
27static cairo_status_t
28reader (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
38{
39 cairo_surface_destroy(us->data);
40}
41
42static 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 = 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 */
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 = surface;
77 }
79 }
80 return surface;
81}
82
83static void pango_loadimage_cairo(GVJ_t * job, usershape_t *us, boxf b, bool filled)
84{
85 cairo_t *cr = 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 // suppress unused parameter warning
94 (void)filled;
95
96 surface = cairo_loadimage(job, us);
97 if (surface) {
98 cairo_save(cr);
99 cairo_translate(cr, b.LL.x, -b.UR.y);
100 cairo_scale(cr, (b.UR.x - b.LL.x)/(us->w), (b.UR.y - b.LL.y)/(us->h));
101 cairo_set_source_surface (cr, surface, 0, 0);
102 cairo_paint (cr);
103 cairo_restore(cr);
104 }
105}
106
107static void pango_loadimage_ps(GVJ_t * job, usershape_t *us, boxf b, bool filled)
108{
109 cairo_surface_t *surface; /* source surface */
110 cairo_format_t format;
111 int X, Y, x, y, stride;
112
113 // suppress unused parameter warning
114 (void)filled;
115
116 surface = cairo_loadimage(job, us);
117 if (surface) {
118 format = cairo_image_surface_get_format(surface);
119 if ((format != CAIRO_FORMAT_ARGB32) && (format != CAIRO_FORMAT_RGB24))
120 return;
121
122 X = cairo_image_surface_get_width(surface);
123 Y = cairo_image_surface_get_height(surface);
124 stride = cairo_image_surface_get_stride(surface);
125 const unsigned char *data = cairo_image_surface_get_data(surface);
126
127 gvputs(job, "save\n");
128
129 /* define image data as string array (one per raster line) */
130 /* see parallel code in gd_loadimage_ps(). FIXME: refactor... */
131 gvputs(job, "/myctr 0 def\n");
132 gvputs(job, "/myarray [\n");
133 for (y = 0; y < Y; y++) {
134 gvputs(job, "<");
135 const unsigned char *ix = data + y * stride;
136 for (x = 0; x < X; x++) {
137 uint32_t rgba;
138 memcpy(&rgba, ix, sizeof(rgba));
139 ix += sizeof(rgba);
140 const unsigned blue = rgba & 0xff;
141 const unsigned green = (rgba >> 8) & 0xff;
142 const unsigned red = (rgba >> 16) & 0xff;
143 const unsigned alpha = (rgba >> 24) & 0xff;
144 if (alpha < 0x7f)
145 gvputs(job, "ffffff");
146 else
147 gvprintf(job, "%02x%02x%02x", red, green, blue);
148 }
149 gvputs(job, ">\n");
150 }
151 gvputs(job, "] def\n");
152 gvputs(job,"/myproc { myarray myctr get /myctr myctr 1 add def } def\n");
153
154 /* this sets the position of the image */
155 gvprintf(job, "%g %g translate\n",
156 (b.LL.x + (b.UR.x - b.LL.x) * (1. - (job->dpi.x) / 96.) / 2.),
157 (b.LL.y + (b.UR.y - b.LL.y) * (1. - (job->dpi.y) / 96.) / 2.));
158
159 /* this sets the rendered size to fit the box */
160 gvprintf(job,"%g %g scale\n",
161 ((b.UR.x - b.LL.x) * 72. / 96.),
162 ((b.UR.y - b.LL.y) * 72. / 96.));
163
164 /* xsize ysize bits-per-sample [matrix] */
165 gvprintf(job, "%d %d 8 [%d 0 0 %d 0 %d]\n", X, Y, X, -Y, Y);
166
167 gvputs(job, "{myproc} false 3 colorimage\n");
168
169 gvputs(job, "restore\n");
170 }
171}
172
176
180
182 {FORMAT_PNG_CAIRO, "png:cairo", 1, &engine_cairo, NULL},
183 {FORMAT_PNG_PS, "png:lasi", 2, &engine_ps, NULL},
184 {FORMAT_PNG_PS, "png:ps", 2, &engine_ps, NULL},
185 {0, NULL, 0, NULL, NULL}
186};
#define Y(i)
Definition gdefs.h:3
#define X(prefix, name, str, type, subtype,...)
Definition gdefs.h:14
node NULL
Definition grammar.y:163
void gvusershape_file_release(usershape_t *us)
bool gvusershape_file_access(usershape_t *us)
int gvputs(GVJ_t *job, const char *s)
Definition gvdevice.c:264
void gvprintf(GVJ_t *job, const char *format,...)
Definition gvdevice.c:395
GVIO_API const char * format
Definition gvio.h:51
static gvloadimage_engine_t engine_ps
static gvloadimage_engine_t engine_cairo
gvplugin_installed_t gvloadimage_pango_types[]
static void pango_loadimage_cairo(GVJ_t *job, usershape_t *us, boxf b, bool filled)
static void cairo_freeimage(usershape_t *us)
static void pango_loadimage_ps(GVJ_t *job, usershape_t *us, boxf b, bool filled)
format_type
@ FORMAT_PNG_PS
@ FORMAT_PNG_CAIRO
static cairo_surface_t * cairo_loadimage(GVJ_t *job, usershape_t *us)
static cairo_status_t reader(void *closure, unsigned char *data, unsigned int length)
#define alpha
Definition shapes.c:4058
pointf dpi
Definition gvcjob.h:325
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
FILE * f
Definition usershape.h:58
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_PNG
Definition usershape.h:25