Graphviz  2.35.20130930.0449
fontmetrics.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 "render.h"
15 
16 static double timesFontWidth[] = {
17  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
18  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
19  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
20  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
21  0.2500, 0.3329, 0.4079, 0.5000, 0.5000, 0.8329, 0.7779, 0.3329, /* !"#$%&' */
22  0.3329, 0.3329, 0.5000, 0.5639, 0.2500, 0.3329, 0.2500, 0.2779, /* ()*+,-./ */
23  0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, /* 01234567 */
24  0.5000, 0.5000, 0.2779, 0.2779, 0.5639, 0.5639, 0.5639, 0.4439, /* 89:;<=>? */
25  0.9209, 0.7219, 0.6669, 0.6669, 0.7219, 0.6109, 0.5559, 0.7219, /* @ABCDEFG */
26  0.7219, 0.3329, 0.3889, 0.7219, 0.6109, 0.8889, 0.7219, 0.7219, /* HIJKLMNO */
27  0.5559, 0.7219, 0.6669, 0.5559, 0.6109, 0.7219, 0.7219, 0.9439, /* PQRSTUVW */
28  0.7219, 0.7219, 0.6109, 0.3329, 0.2779, 0.3329, 0.4689, 0.5000, /* XYZ[\]^_ */
29  0.3329, 0.4439, 0.5000, 0.4439, 0.5000, 0.4439, 0.3329, 0.5000, /* `abcdefg */
30  0.5000, 0.2779, 0.2779, 0.5000, 0.2779, 0.7779, 0.5000, 0.5000, /* hijklmno */
31  0.5000, 0.5000, 0.3329, 0.3889, 0.2779, 0.5000, 0.5000, 0.7219, /* pqrstuvw */
32  0.5000, 0.5000, 0.4439, 0.4799, 0.1999, 0.4799, 0.5409, 0.2500, /* xyz{|}~ */
33  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
34  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
35  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
36  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
37  0.2500, 0.3329, 0.5000, 0.5000, 0.1669, 0.5000, 0.5000, 0.5000, /* ¡¢£¤¥¦§ */
38  0.5000, 0.1799, 0.4439, 0.5000, 0.3329, 0.3329, 0.5559, 0.5559, /* ¨©ª«¬­®¯ */
39  0.2500, 0.5000, 0.5000, 0.5000, 0.2500, 0.2500, 0.4529, 0.3499, /* ±²³´ ¶· */
40  0.3329, 0.4439, 0.4439, 0.5000, 1.0000, 1.0000, 0.2500, 0.4439, /* ¸¹º»¼½ ¿ */
41  0.2500, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, /* ÁÂÃÄÅÆÇ */
42  0.3329, 0.2500, 0.3329, 0.3329, 0.2500, 0.3329, 0.3329, 0.3329, /* È ÊË ÍÎÏ */
43  1.0000, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* Ð */
44  0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, /* */
45  0.2500, 0.8889, 0.2500, 0.2759, 0.2500, 0.2500, 0.2500, 0.2500, /* á ã */
46  0.6109, 0.7219, 0.8889, 0.3099, 0.2500, 0.2500, 0.2500, 0.2500, /* èéêë */
47  0.2500, 0.6669, 0.2500, 0.2500, 0.2500, 0.2779, 0.2500, 0.2500, /* ñ õ */
48  0.2779, 0.5000, 0.7219, 0.5000, 0.2500, 0.2500, 0.2500, 0.2500, /* øùúû */
49 };
50 static double arialFontWidth[] = {
51  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
52  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
53  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
54  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
55  0.2779, 0.2779, 0.3549, 0.5559, 0.5559, 0.8889, 0.6669, 0.2209, /* !"#$%&' */
56  0.3329, 0.3329, 0.3889, 0.5839, 0.2779, 0.3329, 0.2779, 0.2779, /* ()*+,-./ */
57  0.5559, 0.5559, 0.5559, 0.5559, 0.5559, 0.5559, 0.5559, 0.5559, /* 01234567 */
58  0.5559, 0.5559, 0.2779, 0.2779, 0.5839, 0.5839, 0.5839, 0.5559, /* 89:;<=>? */
59  1.0149, 0.6669, 0.6669, 0.7219, 0.7219, 0.6669, 0.6109, 0.7779, /* @ABCDEFG */
60  0.7219, 0.2779, 0.5000, 0.6669, 0.5559, 0.8329, 0.7219, 0.7779, /* HIJKLMNO */
61  0.6669, 0.7779, 0.7219, 0.6669, 0.6109, 0.7219, 0.6669, 0.9439, /* PQRSTUVW */
62  0.6669, 0.6669, 0.6109, 0.2779, 0.2779, 0.2779, 0.4689, 0.5559, /* XYZ[\]^_ */
63  0.2219, 0.5559, 0.5559, 0.5000, 0.5559, 0.5559, 0.2779, 0.5559, /* `abcdefg */
64  0.5559, 0.2219, 0.2219, 0.5000, 0.2219, 0.8329, 0.5559, 0.5559, /* hijklmno */
65  0.5559, 0.5559, 0.3329, 0.5000, 0.2779, 0.5559, 0.5000, 0.7219, /* pqrstuvw */
66  0.5000, 0.5000, 0.5000, 0.3339, 0.2599, 0.3339, 0.5839, 0.2779, /* xyz{|}~ */
67  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
68  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
69  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
70  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
71  0.2779, 0.3329, 0.5559, 0.5559, 0.1669, 0.5559, 0.5559, 0.5559, /* ¡¢£¤¥¦§ */
72  0.5559, 0.1909, 0.3329, 0.5559, 0.3329, 0.3329, 0.5000, 0.5000, /* ¨©ª«¬­®¯ */
73  0.2779, 0.5559, 0.5559, 0.5559, 0.2779, 0.2779, 0.5369, 0.3499, /* ±²³´ ¶· */
74  0.2219, 0.3329, 0.3329, 0.5559, 1.0000, 1.0000, 0.2779, 0.6109, /* ¸¹º»¼½ ¿ */
75  0.2779, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, /* ÁÂÃÄÅÆÇ */
76  0.3329, 0.2779, 0.3329, 0.3329, 0.2779, 0.3329, 0.3329, 0.3329, /* È ÊË ÍÎÏ */
77  1.0000, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* Ð */
78  0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* */
79  0.2779, 1.0000, 0.2779, 0.3699, 0.2779, 0.2779, 0.2779, 0.2779, /* á ã */
80  0.5559, 0.7779, 1.0000, 0.3649, 0.2779, 0.2779, 0.2779, 0.2779, /* èéêë */
81  0.2779, 0.8889, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, /* ñ õ */
82  0.2219, 0.6109, 0.9439, 0.6109, 0.2779, 0.2779, 0.2779, 0.2779, /* øùúû */
83 };
84 static double courFontWidth[] = {
85  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
86  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
87  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
88  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
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, /* 01234567 */
92  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* 89:;<=>? */
93  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* @ABCDEFG */
94  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* HIJKLMNO */
95  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* PQRSTUVW */
96  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* XYZ[\]^_ */
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, /* */
102  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
103  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
104  0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, /* */
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 };
118 
119 /* estimate_textsize:
120  * Estimate width and height of text, for given face and size, in points.
121  * Value is stored para->width.
122  * NOTE: Tables are based on a font of size 1. Need to multiply by
123  * fontsize to get appropriate value.
124  */
125 static void
126 estimate_textlayout(graph_t *g, textpara_t * para, char **fontpath)
127 {
128  double *Fontwidth;
129  char c, *p, *fp;
130 
131  para->width = 0.0;
132  para->height = para->fontsize * LINESPACING;
133  para->yoffset_layout = 0.0;
134  para->yoffset_centerline = 0.1 * para->fontsize;
135  para->layout = para->fontname;
136  para->free_layout = NULL;
137 
138  if (!strncasecmp(para->fontname, "cour", 4)) {
139  fp = "[internal courier]";
140  Fontwidth = courFontWidth;
141  } else if (!strncasecmp(para->fontname, "arial", 5)
142  || !strncasecmp(para->fontname, "helvetica", 9)) {
143  fp = "[internal arial]";
144  Fontwidth = arialFontWidth;
145  } else {
146  fp = "[internal times]";
147  Fontwidth = timesFontWidth;
148  }
149  if (fontpath)
150  *fontpath = fp;
151  if ((p = para->str)) {
152  while ((c = *p++))
153  para->width += Fontwidth[(unsigned char) c];
154  para->width *= para->fontsize;
155  }
156 }
157 
158 /*
159  * This table maps standard Postscript font names to URW Type 1 fonts.
160  *
161  * The original source is in ps_font_equiv.txt. This is sorted
162  * during make into ps_font_equiv.h to ensure that it is in the right
163  * order for bsearch()
164  */
165 static PostscriptAlias postscript_alias[] = {
166 #include "ps_font_equiv.h"
167 };
168 
169 static int fontcmpf(const void *a, const void *b)
170 {
171  return (strcasecmp(((PostscriptAlias*)a)->name, ((PostscriptAlias*)b)->name));
172 }
173 
174 static PostscriptAlias* translate_postscript_fontname(char* fontname)
175 {
176  static PostscriptAlias key;
177  static PostscriptAlias *result;
178 
179  if (key.name == NULL || strcasecmp(key.name, fontname)) {
180  key.name = fontname;
181  result = (PostscriptAlias *) bsearch((void *) &key,
182  (void *) postscript_alias,
183  sizeof(postscript_alias) / sizeof(PostscriptAlias),
184  sizeof(PostscriptAlias),
185  fontcmpf);
186  }
187  return result;
188 }
189 
190 pointf textsize(graph_t *g, textpara_t * para, char *fontname, double fontsize)
191 {
192  char **fp = NULL, *fontpath = NULL;
193  pointf size;
194 
195  para->fontname = fontname;
196  para->fontsize = fontsize;
197 
198  para->postscript_alias = translate_postscript_fontname(fontname);
199 
200  if (Verbose && emit_once(para->fontname))
201  fp = &fontpath;
202 
203  if (! gvtextlayout(GD_gvc(g), para, fp))
204  estimate_textlayout(g, para, fp);
205 
206  if (fp) {
207  if (fontpath)
208  fprintf(stderr, "fontname: \"%s\" resolved to: %s\n",
209  para->fontname, fontpath);
210  else
211  fprintf(stderr, "fontname: unable to resolve \"%s\"\n", para->fontname);
212  }
213 
214  size.x = para->width;
215  size.y = para->height;
216  return size;
217 }