Graphviz 14.0.3~dev.20251028.0232
Loading...
Searching...
No Matches
gvloadimage_quartz.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 <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17
19
20#include "gvplugin_quartz.h"
21
22static size_t file_data_provider_get_bytes(void *info, void *buffer, size_t count)
23{
24 return fread(buffer, 1, count, (FILE*)info);
25}
26
28{
29 rewind(info);
30}
31
32#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 20000
33
34static off_t file_data_provider_skip_forward(void *info, off_t count)
35{
36 fseek((FILE*)info, count, SEEK_CUR);
37 return count;
38}
39
40/* bridge FILE* to a sequential CGDataProvider */
41static CGDataProviderSequentialCallbacks file_data_provider_callbacks = {
42 0,
44 file_data_provider_skip_forward,
46 NULL
47};
48
49#else
50
51static void file_data_provider_skip_bytes(void *info, size_t count)
52{
53 fseek((FILE*)info, count, SEEK_CUR);
54}
55
56/* bridge FILE* to a sequential CGDataProvider */
63
64#endif
65
66
67
69{
70 CGImageRelease(us->data);
71}
72
73static CGImageRef quartz_loadimage(GVJ_t * job, usershape_t *us)
74{
75 assert(job);
76 assert(us);
77 assert(us->name);
78
79 if (us->data && us->datafree != quartz_freeimage) {
80 us->datafree(us); /* free incompatible cache data */
81 us->data = NULL;
82 us->datafree = NULL;
83 }
84
85 if (!us->data) { /* read file into cache */
87 return NULL;
88
89#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 20000
90 CGDataProviderRef data_provider = CGDataProviderCreateSequential(us->f, &file_data_provider_callbacks);
91#else
92 CGDataProviderRef data_provider = CGDataProviderCreate(us->f, &file_data_provider_callbacks);
93#endif
94
95#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1040
96 /* match usershape format to a UTI for type hinting, if possible */
97 format_type hint_format_type;
98 switch (us->type) {
99 case FT_BMP:
100 hint_format_type = FORMAT_BMP;
101 break;
102 case FT_GIF:
103 hint_format_type = FORMAT_GIF;
104 break;
105 case FT_PNG:
106 hint_format_type = FORMAT_PNG;
107 break;
108 case FT_JPEG:
109 hint_format_type = FORMAT_JPEG;
110 break;
111 case FT_PDF:
112 hint_format_type = FORMAT_PDF;
113 break;
114 default:
115 hint_format_type = FORMAT_NONE;
116 break;
117 }
118 CFStringRef uti_hint = format_to_uti(hint_format_type);
119 const void *keys[] = {kCGImageSourceTypeIdentifierHint};
120 const void *values[] = {uti_hint};
121 CFDictionaryRef options = hint_format_type == FORMAT_NONE ? NULL : CFDictionaryCreate(
122 NULL,
123 keys,
124 values,
125 sizeof(keys) / sizeof(keys[0]),
126 &kCFTypeDictionaryKeyCallBacks,
127 &kCFTypeDictionaryValueCallBacks);
128
129 /* get first image from usershape file */
130 CGImageSourceRef image_source = CGImageSourceCreateWithDataProvider(data_provider, options);
131 us->data = CGImageSourceCreateImageAtIndex(image_source, 0, NULL);
132 if (image_source)
133 CFRelease(image_source);
134 if (options)
135 CFRelease(options);
136#else
137 switch (us->type) {
138 case FT_PNG:
139 us->data = CGImageCreateWithPNGDataProvider(data_provider, NULL, false, kCGRenderingIntentDefault);
140 break;
141 case FT_JPEG:
142 us->data = CGImageCreateWithJPEGDataProvider(data_provider, NULL, false, kCGRenderingIntentDefault);
143 break;
144 default:
145 us->data = NULL;
146 break;
147 }
148
149#endif
150 /* clean up */
151 if (us->data)
153 CGDataProviderRelease(data_provider);
154
156 }
157 return us->data;
158}
159
160static void quartz_loadimage_quartz(GVJ_t * job, usershape_t *us, boxf b, bool filled)
161{
162 (void)filled;
163
164 /* get the image from usershape details, then blit it to the context */
165 CGImageRef image = quartz_loadimage(job, us);
166 if (image)
167 CGContextDrawImage((CGContextRef)job->context, CGRectMake(b.LL.x, b.LL.y, b.UR.x - b.LL.x, b.UR.y - b.LL.y), image);
168}
169
173
175#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1040
176 {FORMAT_BMP, "bmp:quartz", 8, &engine, NULL},
177 {FORMAT_GIF, "gif:quartz", 8, &engine, NULL},
178 {FORMAT_PDF, "pdf:quartz", 8, &engine, NULL},
179#endif
180 {FORMAT_JPEG, "jpe:quartz", 8, &engine, NULL},
181 {FORMAT_JPEG, "jpeg:quartz", 8, &engine, NULL},
182 {FORMAT_JPEG, "jpg:quartz", 8, &engine, NULL},
183 {FORMAT_PNG, "png:quartz", 8, &engine, NULL},
184 {0, NULL, 0, NULL, NULL}
185};
node NULL
Definition grammar.y:181
void gvusershape_file_release(usershape_t *us)
bool gvusershape_file_access(usershape_t *us)
static void file_data_provider_rewind(void *info)
static void file_data_provider_skip_bytes(void *info, size_t count)
static gvloadimage_engine_t engine
static void quartz_freeimage(usershape_t *us)
gvplugin_installed_t gvloadimage_quartz_types[]
static CGDataProviderCallbacks file_data_provider_callbacks
static size_t file_data_provider_get_bytes(void *info, void *buffer, size_t count)
static void quartz_loadimage_quartz(GVJ_t *job, usershape_t *us, boxf b, bool filled)
static CGImageRef quartz_loadimage(GVJ_t *job, usershape_t *us)
@ FORMAT_NONE
@ FORMAT_BMP
format_type
@ FORMAT_JPEG
Definition gvrender_gd.c:37
@ FORMAT_GIF
Definition gvrender_gd.c:36
@ FORMAT_PNG
Definition gvrender_gd.c:38
@ FORMAT_PDF
T_cell image
Definition htmlparse.y:334
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
Definition gvpr.c:66
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
@ FT_BMP
Definition usershape.h:25
@ FT_GIF
Definition usershape.h:25
@ FT_JPEG
Definition usershape.h:25
@ FT_PNG
Definition usershape.h:25
@ FT_PDF
Definition usershape.h:26