Graphviz 14.0.3~dev.20251028.0232
Loading...
Searching...
No Matches
gvtextlayout_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 <stdlib.h>
15#include <string.h>
16
18#include "gvplugin_quartz.h"
19
20#ifdef __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__
21#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 30200
22#include <CoreText/CoreText.h>
23#endif
24#endif
25
26#if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
27 __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050) || \
28 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
29 __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 30200)
30
31#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
32#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1060
33/* symbol defined in 10.5.x dylib but not in headers */
34extern const CFStringRef kCTForegroundColorFromContextAttributeName;
35#endif
36#endif
37
38void *quartz_new_layout(char* fontname, double fontsize, char* text)
39{
40 CFStringRef fontnameref = CFStringCreateWithCString(NULL, fontname, kCFStringEncodingUTF8);
41 CFStringRef textref = CFStringCreateWithCString(NULL, text, kCFStringEncodingUTF8);
42 CTLineRef line = NULL;
43
44 if (fontnameref && textref) {
45 /* set up the Core Text line */
46 CTFontRef font = CTFontCreateWithName(fontnameref, fontsize, NULL);
47 const void *attributeNames[] = {
48 kCTFontAttributeName, kCTForegroundColorFromContextAttributeName};
49 const void *attributeValues[] = {font, kCFBooleanTrue};
50 CFDictionaryRef attributes = CFDictionaryCreate(
51 NULL,
52 attributeNames,
53 attributeValues,
54 sizeof(attributeNames) / sizeof(attributeNames[0]),
55 &kCFTypeDictionaryKeyCallBacks,
56 &kCFTypeDictionaryValueCallBacks);
57 CFAttributedStringRef attributed = CFAttributedStringCreate(NULL, textref, attributes);
58 line = CTLineCreateWithAttributedString(attributed);
59
60 CFRelease(attributed);
61 CFRelease(attributes);
62 CFRelease(font);
63 }
64
65 if (textref)
66 CFRelease(textref);
67 if (fontnameref)
68 CFRelease(fontnameref);
69// Suppress Clang/GCC -Wcast-qual warning. Casting away const here is acceptable
70// as we do not intend to modify the target through the resulting non-const
71// pointer. We need a non-const pointer simply to satisfy the type of
72// `textspan_t.layout`.
73#ifdef __GNUC__
74#pragma GCC diagnostic push
75#pragma GCC diagnostic ignored "-Wcast-qual"
76#endif
77 return (void *)line;
78#ifdef __GNUC__
79#pragma GCC diagnostic pop
80#endif
81}
82
83void quartz_size_layout(void *layout, double* width, double* height, double* yoffset_layout)
84{
85 /* get the typographic bounds */
86 CGFloat ascent = 0.0;
87 CGFloat descent = 0.0;
88 CGFloat leading = 0.0;
89
90 *width = CTLineGetTypographicBounds(layout, &ascent, &descent, &leading);
91 *height = ascent + descent + leading;
92 *yoffset_layout = ascent;
93}
94
95void quartz_draw_layout(void *layout, CGContextRef context, CGPoint position)
96{
97 CGContextSetTextPosition(context, position.x, position.y);
98 CTLineDraw(layout, context);
99}
100
101void quartz_free_layout(void *layout)
102{
103 if (layout)
104 CFRelease(layout);
105}
106
107#endif
108
109static bool quartz_textlayout(textspan_t *para, char **fontpath)
110{
111 (void)fontpath;
112
113 void *line = quartz_new_layout(para->font->name, para->font->size, para->str);
114 if (line)
115 {
116 /* report the layout */
117 para->layout = line;
119 quartz_size_layout(line, &para->size.x, &para->size.y, &para->yoffset_layout);
120 para->yoffset_centerline = 0.2 * para->font->size;
121 return true;
122 }
123 else
124 return false;
125};
126
130
132 {0, "textlayout", 8, &quartz_textlayout_engine, NULL},
133 {0, NULL, 0, NULL, NULL}
134};
node NULL
Definition grammar.y:181
void quartz_draw_layout(void *layout, CGContextRef context, CGPoint position)
void * quartz_new_layout(char *fontname, double fontsize, char *text)
void quartz_size_layout(void *layout, double *width, double *height, double *yoffset_layout)
void quartz_free_layout(void *layout)
static gvtextlayout_engine_t quartz_textlayout_engine
gvplugin_installed_t gvtextlayout_quartz_types[]
static bool quartz_textlayout(textspan_t *para, char **fontpath)
$2 font
Definition htmlparse.y:294
static int layout(graph_t *g, layout_info *infop)
Definition layout.c:814
ingroup plugin_api
Definition gvplugin.h:35
double x
Definition geom.h:29
double y
Definition geom.h:29
double x
Definition simple.h:21
double y
Definition simple.h:21
char * name
Definition textspan.h:54
double size
Definition textspan.h:57
double yoffset_layout
Definition textspan.h:69
char * str
Definition textspan.h:65
void * layout
Definition textspan.h:67
pointf size
Definition textspan.h:70
textfont_t * font
Definition textspan.h:66
double yoffset_centerline
Definition textspan.h:69
void(* free_layout)(void *layout)
Definition textspan.h:68