Graphviz 13.0.0~dev.20250424.1043
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#include <TargetConditionals.h>
18
20
21#include "gvplugin_quartz.h"
22
23static size_t file_data_provider_get_bytes(void *info, void *buffer, size_t count)
24{
25 return fread(buffer, 1, count, (FILE*)info);
26}
27
29{
30 rewind(info);
31}
32
33static off_t file_data_provider_skip_forward(void *info, off_t count)
34{
35 fseek((FILE*)info, count, SEEK_CUR);
36 return count;
37}
38
39/* bridge FILE* to a sequential CGDataProvider */
47
49{
50 CGImageRelease(us->data);
51}
52
53static CGImageRef quartz_loadimage(GVJ_t * job, usershape_t *us)
54{
55 assert(job);
56 assert(us);
57 assert(us->name);
58
59 if (us->data && us->datafree != quartz_freeimage) {
60 us->datafree(us); /* free incompatible cache data */
61 us->data = NULL;
62 us->datafree = NULL;
63 }
64
65 if (!us->data) { /* read file into cache */
67 return NULL;
68
69 CGDataProviderRef data_provider = CGDataProviderCreateSequential(us->f, &file_data_provider_callbacks);
70
71#if !TARGET_OS_IPHONE
72 /* match usershape format to a UTI for type hinting, if possible */
73 format_type hint_format_type;
74 switch (us->type) {
75 case FT_BMP:
76 hint_format_type = FORMAT_BMP;
77 break;
78 case FT_GIF:
79 hint_format_type = FORMAT_GIF;
80 break;
81 case FT_PNG:
82 hint_format_type = FORMAT_PNG;
83 break;
84 case FT_JPEG:
85 hint_format_type = FORMAT_JPEG;
86 break;
87 case FT_PDF:
88 hint_format_type = FORMAT_PDF;
89 break;
90 default:
91 hint_format_type = FORMAT_NONE;
92 break;
93 }
94 CFStringRef uti_hint = format_to_uti(hint_format_type);
95 CFDictionaryRef options = hint_format_type == FORMAT_NONE ? NULL : CFDictionaryCreate(
96 kCFAllocatorDefault,
97 (const void **)&kCGImageSourceTypeIdentifierHint,
98 (const void **)&uti_hint,
99 1,
100 &kCFTypeDictionaryKeyCallBacks,
101 &kCFTypeDictionaryValueCallBacks);
102
103 /* get first image from usershape file */
104 CGImageSourceRef image_source = CGImageSourceCreateWithDataProvider(data_provider, options);
105 us->data = CGImageSourceCreateImageAtIndex(image_source, 0, NULL);
106 if (image_source)
107 CFRelease(image_source);
108 if (options)
109 CFRelease(options);
110#else
111 switch (us->type) {
112 case FT_PNG:
113 us->data = CGImageCreateWithPNGDataProvider(data_provider, NULL, false, kCGRenderingIntentDefault);
114 break;
115 case FT_JPEG:
116 us->data = CGImageCreateWithJPEGDataProvider(data_provider, NULL, false, kCGRenderingIntentDefault);
117 break;
118 default:
119 us->data = NULL;
120 break;
121 }
122
123#endif
124 /* clean up */
125 if (us->data)
127 CGDataProviderRelease(data_provider);
128
130 }
131 return us->data;
132}
133
134static void quartz_loadimage_quartz(GVJ_t * job, usershape_t *us, boxf b, bool filled)
135{
136 (void)filled;
137
138 /* get the image from usershape details, then blit it to the context */
139 CGImageRef image = quartz_loadimage(job, us);
140 if (image)
141 CGContextDrawImage((CGContextRef)job->context, CGRectMake(b.LL.x, b.LL.y, b.UR.x - b.LL.x, b.UR.y - b.LL.y), image);
142}
143
147
149#if !TARGET_OS_IPHONE
150 {FORMAT_BMP, "bmp:quartz", 8, &engine, NULL},
151 {FORMAT_GIF, "gif:quartz", 8, &engine, NULL},
152 {FORMAT_PDF, "pdf:quartz", 8, &engine, NULL},
153#endif
154 {FORMAT_JPEG, "jpe:quartz", 8, &engine, NULL},
155 {FORMAT_JPEG, "jpeg:quartz", 8, &engine, NULL},
156 {FORMAT_JPEG, "jpg:quartz", 8, &engine, NULL},
157 {FORMAT_PNG, "png:quartz", 8, &engine, NULL},
158 {0, NULL, 0, NULL, NULL}
159};
node NULL
Definition grammar.y:163
void gvusershape_file_release(usershape_t *us)
bool gvusershape_file_access(usershape_t *us)
static CGDataProviderSequentialCallbacks file_data_provider_callbacks
static void file_data_provider_rewind(void *info)
static gvloadimage_engine_t engine
static void quartz_freeimage(usershape_t *us)
gvplugin_installed_t gvloadimage_quartz_types[]
static off_t file_data_provider_skip_forward(void *info, off_t count)
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
CFStringRef format_to_uti(format_type format)
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:340
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:60
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