Graphviz  2.41.20171026.1811
textspan.c
Go to the documentation of this file.
1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include "cdt.h"
18 #include "render.h"
19 
20 static double timesFontWidth[] = {
21  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
22  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
23  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
24  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
25  0.2500, 0.3329, 0.4079, 0.5000, 0.5000, 0.8329, 0.7779, 0.3329, /* !"#$%&' */
26  0.3329, 0.3329, 0.5000, 0.5639, 0.2500, 0.3329, 0.2500, 0.2779, /* ()*+,-./ */
27  0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, /* 01234567 */
28  0.5000, 0.5000, 0.2779, 0.2779, 0.5639, 0.5639, 0.5639, 0.4439, /* 89:;<=>? */
29  0.9209, 0.7219, 0.6669, 0.6669, 0.7219, 0.6109, 0.5559, 0.7219, /* @ABCDEFG */
30  0.7219, 0.3329, 0.3889, 0.7219, 0.6109, 0.8889, 0.7219, 0.7219, /* HIJKLMNO */
31  0.5559, 0.7219, 0.6669, 0.5559, 0.6109, 0.7219, 0.7219, 0.9439, /* PQRSTUVW */
32  0.7219, 0.7219, 0.6109, 0.3329, 0.2779, 0.3329, 0.4689, 0.5000, /* XYZ[\]^_ */
33  0.3329, 0.4439, 0.5000, 0.4439, 0.5000, 0.4439, 0.3329, 0.5000, /* `abcdefg */
34  0.5000, 0.2779, 0.2779, 0.5000, 0.2779, 0.7779, 0.5000, 0.5000, /* hijklmno */
35  0.5000, 0.5000, 0.3329, 0.3889, 0.2779, 0.5000, 0.5000, 0.7219, /* pqrstuvw */
36  0.5000, 0.5000, 0.4439, 0.4799, 0.1999, 0.4799, 0.5409, 0.2500, /* xyz{|}~ */
37  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
38  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
39  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
40  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
41  0.2500, 0.3329, 0.5000, 0.5000, 0.1669, 0.5000, 0.5000, 0.5000, /* ¡¢£¤¥¦§ */
42  0.5000, 0.1799, 0.4439, 0.5000, 0.3329, 0.3329, 0.5559, 0.5559, /* ¨©ª«¬­®¯ */
43  0.2500, 0.5000, 0.5000, 0.5000, 0.2500, 0.2500, 0.4529, 0.3499, /* ±²³´ ¶· */
44  0.3329, 0.4439, 0.4439, 0.5000, 1.0000, 1.0000, 0.2500, 0.4439, /* ¸¹º»¼½ ¿ */
45  0.2500, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, /* ÁÂÃÄÅÆÇ */
46  0.3329, 0.2500, 0.3329, 0.3329, 0.2500, 0.3329, 0.3329, 0.3329, /* È ÊË ÍÎÏ */
47  1.0000, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* Ð */
48  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
49  0.2500, 0.8889, 0.2500, 0.2759, 0.2500, 0.2500, 0.2500, 0.2500, /* á ã */
50  0.6109, 0.7219, 0.8889, 0.3099, 0.2500, 0.2500, 0.2500, 0.2500, /* èéêë */
51  0.2500, 0.6669, 0.2500, 0.2500, 0.2500, 0.2779, 0.2500, 0.2500, /* ñ õ */
52  0.2779, 0.5000, 0.7219, 0.5000, 0.2500, 0.2500, 0.2500, 0.2500, /* øùúû */
53 };
54 static double arialFontWidth[] = {
55  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
56  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
57  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
58  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
59  0.2779, 0.2779, 0.3549, 0.5559, 0.5559, 0.8889, 0.6669, 0.2209, /* !"#$%&' */
60  0.3329, 0.3329, 0.3889, 0.5839, 0.2779, 0.3329, 0.2779, 0.2779, /* ()*+,-./ */
61  0.5559, 0.5559, 0.5559, 0.5559, 0.5559, 0.5559, 0.5559, 0.5559, /* 01234567 */
62  0.5559, 0.5559, 0.2779, 0.2779, 0.5839, 0.5839, 0.5839, 0.5559, /* 89:;<=>? */
63  1.0149, 0.6669, 0.6669, 0.7219, 0.7219, 0.6669, 0.6109, 0.7779, /* @ABCDEFG */
64  0.7219, 0.2779, 0.5000, 0.6669, 0.5559, 0.8329, 0.7219, 0.7779, /* HIJKLMNO */
65  0.6669, 0.7779, 0.7219, 0.6669, 0.6109, 0.7219, 0.6669, 0.9439, /* PQRSTUVW */
66  0.6669, 0.6669, 0.6109, 0.2779, 0.2779, 0.2779, 0.4689, 0.5559, /* XYZ[\]^_ */
67  0.2219, 0.5559, 0.5559, 0.5000, 0.5559, 0.5559, 0.2779, 0.5559, /* `abcdefg */
68  0.5559, 0.2219, 0.2219, 0.5000, 0.2219, 0.8329, 0.5559, 0.5559, /* hijklmno */
69  0.5559, 0.5559, 0.3329, 0.5000, 0.2779, 0.5559, 0.5000, 0.7219, /* pqrstuvw */
70  0.5000, 0.5000, 0.5000, 0.3339, 0.2599, 0.3339, 0.5839, 0.2779, /* xyz{|}~ */
71  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
72  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
73  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
74  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
75  0.2779, 0.3329, 0.5559, 0.5559, 0.1669, 0.5559, 0.5559, 0.5559, /* ¡¢£¤¥¦§ */
76  0.5559, 0.1909, 0.3329, 0.5559, 0.3329, 0.3329, 0.5000, 0.5000, /* ¨©ª«¬­®¯ */
77  0.2779, 0.5559, 0.5559, 0.5559, 0.2779, 0.2779, 0.5369, 0.3499, /* ±²³´ ¶· */
78  0.2219, 0.3329, 0.3329, 0.5559, 1.0000, 1.0000, 0.2779, 0.6109, /* ¸¹º»¼½ ¿ */
79  0.2779, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, /* ÁÂÃÄÅÆÇ */
80  0.3329, 0.2779, 0.3329, 0.3329, 0.2779, 0.3329, 0.3329, 0.3329, /* È ÊË ÍÎÏ */
81  1.0000, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* Ð */
82  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
83  0.2779, 1.0000, 0.2779, 0.3699, 0.2779, 0.2779, 0.2779, 0.2779, /* á ã */
84  0.5559, 0.7779, 1.0000, 0.3649, 0.2779, 0.2779, 0.2779, 0.2779, /* èéêë */
85  0.2779, 0.8889, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* ñ õ */
86  0.2219, 0.6109, 0.9439, 0.6109, 0.2779, 0.2779, 0.2779, 0.2779, /* øùúû */
87 };
88 static double courFontWidth[] = {
89  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
90  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
91  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
92  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
93  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* !"#$%&' */
94  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* ()*+,-./ */
95  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* 01234567 */
96  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* 89:;<=>? */
97  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* @ABCDEFG */
98  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* HIJKLMNO */
99  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* PQRSTUVW */
100  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* XYZ[\]^_ */
101  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* `abcdefg */
102  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* hijklmno */
103  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* pqrstuvw */
104  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* xyz{|}~ */
105  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
106  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
107  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
108  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
109  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* ¡¢£¤¥¦§ */
110  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* ¨©ª«¬­®¯ */
111  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* ±²³´ ¶· */
112  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* ¸¹º»¼½ ¿ */
113  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* ÁÂÃÄÅÆÇ */
114  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* È ÊË ÍÎÏ */
115  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* Ð */
116  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
117  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* á ã */
118  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* èéêë */
119  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* ñ õ */
120  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* øùúû */
121 };
122 
123 /* estimate_textspan_size:
124  * Estimate size of textspan, for given face and size, in points.
125  */
126 static void
127 estimate_textspan_size(textspan_t * span, char **fontpath)
128 {
129  double *Fontwidth, fontsize;
130  char c, *p, *fpp, *fontname;
131 
132  fontname = span->font->name;
133  fontsize = span->font->size;
134 
135  span->size.x = 0.0;
136  span->size.y = fontsize * LINESPACING;
137  span->yoffset_layout = 0.0;
138  span->yoffset_centerline = 0.1 * fontsize;
139  span->layout = NULL;
140  span->free_layout = NULL;
141 
142  if (!strncasecmp(fontname, "cour", 4)) {
143  fpp = "[internal courier]";
144  Fontwidth = courFontWidth;
145  } else if (!strncasecmp(fontname, "arial", 5)
146  || !strncasecmp(fontname, "helvetica", 9)) {
147  fpp = "[internal arial]";
148  Fontwidth = arialFontWidth;
149  } else {
150  fpp = "[internal times]";
151  Fontwidth = timesFontWidth;
152  }
153  if (fontpath)
154  *fontpath = fpp;
155  if ((p = span->str)) {
156  while ((c = *p++))
157  span->size.x += Fontwidth[(unsigned char) c];
158  /* NOTE: Tables are based on a font of size 1. Need to multiply by
159  * fontsize to get appropriate value.
160  */
161  span->size.x *= fontsize;
162  }
163 }
164 
165 /*
166  * This table maps standard Postscript font names to URW Type 1 fonts.
167  *
168  * The original source is in ps_font_equiv.txt. This is sorted
169  * during make into ps_font_equiv.h to ensure that it is in the right
170  * order for bsearch()
171  */
172 static PostscriptAlias postscript_alias[] = {
173 #include "ps_font_equiv.h"
174 };
175 
176 static int fontcmpf(const void *a, const void *b)
177 {
178  return (strcasecmp(((PostscriptAlias*)a)->name, ((PostscriptAlias*)b)->name));
179 }
180 
181 static PostscriptAlias* translate_postscript_fontname(char* fontname)
182 {
183  static PostscriptAlias key;
184  static PostscriptAlias *result;
185 
186  if (key.name == NULL || strcasecmp(key.name, fontname)) {
187  free(key.name);
188  key.name = strdup(fontname);
189  result = (PostscriptAlias *) bsearch((void *) &key,
190  (void *) postscript_alias,
191  sizeof(postscript_alias) / sizeof(PostscriptAlias),
192  sizeof(PostscriptAlias),
193  fontcmpf);
194  }
195  return result;
196 }
197 
199 {
200  char **fpp = NULL, *fontpath = NULL;
201  textfont_t *font;
202 
203  assert(span->font);
204  font = span->font;
205 
206  assert(font->name);
207 
208  /* only need to find alias once per font, since they are unique in dict */
209  if (! font->postscript_alias)
210  font->postscript_alias = translate_postscript_fontname(font->name);
211 
212  if (Verbose && emit_once(font->name))
213  fpp = &fontpath;
214 
215  if (! gvtextlayout(gvc, span, fpp))
216  estimate_textspan_size(span, fpp);
217 
218  if (fpp) {
219  if (fontpath)
220  fprintf(stderr, "fontname: \"%s\" resolved to: %s\n",
221  font->name, fontpath);
222  else
223  fprintf(stderr, "fontname: unable to resolve \"%s\"\n", font->name);
224  }
225 
226  return span->size;
227 }
228 
229 static void* textfont_makef(Dt_t* dt, void* obj, Dtdisc_t* disc)
230 {
231  textfont_t *f1 = (textfont_t*)obj;
232  textfont_t *f2 = calloc(1,sizeof(textfont_t));
233 
234  /* key */
235  if (f1->name) f2->name = strdup(f1->name);
236  if (f1->color) f2->color = strdup(f1->color);
237  f2->flags = f1->flags;
238  f2->size = f1->size;
239 
240  /* non key */
242 
243  return f2;
244 }
245 
246 static void textfont_freef(Dt_t* dt, void* obj, Dtdisc_t* disc)
247 {
248  textfont_t *f = (textfont_t*)obj;
249 
250  if (f->name) free(f->name);
251  if (f->color) free(f->color);
252  free(f);
253 }
254 
255 static int textfont_comparf (Dt_t* dt, void* key1, void* key2, Dtdisc_t* disc)
256 {
257  int rc;
258  textfont_t *f1 = (textfont_t*)key1, *f2 = (textfont_t*)key2;
259 
260  if (f1->name || f2->name) {
261  if (! f1->name) return -1;
262  if (! f2->name) return 1;
263  rc = strcmp(f1->name, f2->name);
264  if (rc) return rc;
265  }
266  if (f1->color || f2->color) {
267  if (! f1->color) return -1;
268  if (! f2->color) return 1;
269  rc = strcmp(f1->color, f2->color);
270  if (rc) return rc;
271  }
272  rc = (f1->flags - f2->flags);
273  if (rc) return rc;
274  if (f1->size < f2->size) return -1;
275  if (f1->size > f2->size) return 1;
276  return 0;
277 }
278 
280 {
281  DTDISC(&(gvc->textfont_disc),0,sizeof(textfont_t),-1,textfont_makef,textfont_freef,textfont_comparf,NULL,NULL,NULL);
282  gvc->textfont_dt = dtopen(&(gvc->textfont_disc), Dtoset);
283  return gvc->textfont_dt;
284 }
285 
287 {
288  dtclose(gvc->textfont_dt);
289 }
pointf size
Definition: textspan.h:64
CDT_API int dtclose(Dt_t *)
boolean gvtextlayout(GVC_t *gvc, textspan_t *span, char **fontpath)
Definition: gvtextlayout.c:39
Dt_t * textfont_dict_open(GVC_t *gvc)
Definition: textspan.c:279
Dt_t * textfont_dt
Definition: gvcint.h:96
CDT_API Dtmethod_t * Dtoset
Definition: cdt.h:166
double size
Definition: textspan.h:52
#define assert(x)
Definition: cghdr.h:47
Definition: geom.h:28
Definition: cdt.h:80
char * name
Definition: textspan.h:49
Dtdisc_t textfont_disc
Definition: gvcint.h:95
#define LINESPACING
Definition: const.h:73
CDT_API Dt_t * dtopen(Dtdisc_t *, Dtmethod_t *)
Definition: dtopen.c:9
struct _PostscriptAlias PostscriptAlias
char * str
Definition: textspan.h:59
#define DTDISC(dc, ky, sz, lk, mkf, frf, cmpf, hshf, memf, evf)
Definition: cdt.h:92
unsigned int flags
Definition: textspan.h:53
void textfont_dict_close(GVC_t *gvc)
Definition: textspan.c:286
int emit_once(char *str)
Definition: emit.c:3621
double y
Definition: geom.h:28
Definition: gvcint.h:70
int strncasecmp(const char *s1, const char *s2, unsigned int n)
Definition: strncasecmp.c:20
double yoffset_centerline
Definition: textspan.h:63
PostscriptAlias * postscript_alias
Definition: textspan.h:51
char * color
Definition: textspan.h:50
#define NULL
Definition: logic.h:39
double yoffset_layout
Definition: textspan.h:63
double x
Definition: geom.h:28
EXTERN unsigned char Verbose
Definition: globals.h:64
GVC_t * gvc
Definition: htmlparse.c:87
int strcasecmp(const char *s1, const char *s2)
Definition: strcasecmp.c:21
void(* free_layout)(void *layout)
Definition: textspan.h:62
pointf textspan_size(GVC_t *gvc, textspan_t *span)
Definition: textspan.c:198
Definition: cdt.h:99
textfont_t * font
Definition: textspan.h:60
void * layout
Definition: textspan.h:61