Graphviz  2.31.20130524.0447
lib/common/fontmetrics.c
Go to the documentation of this file.
00001 /* $Id$ $Revision$ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /*************************************************************************
00005  * Copyright (c) 2011 AT&T Intellectual Property 
00006  * All rights reserved. This program and the accompanying materials
00007  * are made available under the terms of the Eclipse Public License v1.0
00008  * which accompanies this distribution, and is available at
00009  * http://www.eclipse.org/legal/epl-v10.html
00010  *
00011  * Contributors: See CVS logs. Details at http://www.graphviz.org/
00012  *************************************************************************/
00013 
00014 #include "render.h"
00015 
00016 static double timesFontWidth[] = {
00017     0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500,     /*          */
00018     0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500,     /*          */
00019     0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500,     /*          */
00020     0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500,     /*          */
00021     0.2500, 0.3329, 0.4079, 0.5000, 0.5000, 0.8329, 0.7779, 0.3329,     /*  !"#$%&' */
00022     0.3329, 0.3329, 0.5000, 0.5639, 0.2500, 0.3329, 0.2500, 0.2779,     /* ()*+,-./ */
00023     0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000, 0.5000,     /* 01234567 */
00024     0.5000, 0.5000, 0.2779, 0.2779, 0.5639, 0.5639, 0.5639, 0.4439,     /* 89:;<=>? */
00025     0.9209, 0.7219, 0.6669, 0.6669, 0.7219, 0.6109, 0.5559, 0.7219,     /* @ABCDEFG */
00026     0.7219, 0.3329, 0.3889, 0.7219, 0.6109, 0.8889, 0.7219, 0.7219,     /* HIJKLMNO */
00027     0.5559, 0.7219, 0.6669, 0.5559, 0.6109, 0.7219, 0.7219, 0.9439,     /* PQRSTUVW */
00028     0.7219, 0.7219, 0.6109, 0.3329, 0.2779, 0.3329, 0.4689, 0.5000,     /* XYZ[\]^_ */
00029     0.3329, 0.4439, 0.5000, 0.4439, 0.5000, 0.4439, 0.3329, 0.5000,     /* `abcdefg */
00030     0.5000, 0.2779, 0.2779, 0.5000, 0.2779, 0.7779, 0.5000, 0.5000,     /* hijklmno */
00031     0.5000, 0.5000, 0.3329, 0.3889, 0.2779, 0.5000, 0.5000, 0.7219,     /* pqrstuvw */
00032     0.5000, 0.5000, 0.4439, 0.4799, 0.1999, 0.4799, 0.5409, 0.2500,     /* xyz{|}~  */
00033     0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500,     /*          */
00034     0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500,     /*          */
00035     0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500,     /*          */
00036     0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500,     /*          */
00037     0.2500, 0.3329, 0.5000, 0.5000, 0.1669, 0.5000, 0.5000, 0.5000,     /*  ¡¢£¤¥¦§ */
00038     0.5000, 0.1799, 0.4439, 0.5000, 0.3329, 0.3329, 0.5559, 0.5559,     /* ¨©ª«¬­®¯ */
00039     0.2500, 0.5000, 0.5000, 0.5000, 0.2500, 0.2500, 0.4529, 0.3499,     /*  ±²³´ ¶· */
00040     0.3329, 0.4439, 0.4439, 0.5000, 1.0000, 1.0000, 0.2500, 0.4439,     /* ¸¹º»¼½ ¿ */
00041     0.2500, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329,     /*  ÁÂÃÄÅÆÇ */
00042     0.3329, 0.2500, 0.3329, 0.3329, 0.2500, 0.3329, 0.3329, 0.3329,     /* È ÊË ÍÎÏ */
00043     1.0000, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500,     /* Ð        */
00044     0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500, 0.2500,     /*          */
00045     0.2500, 0.8889, 0.2500, 0.2759, 0.2500, 0.2500, 0.2500, 0.2500,     /*  á ã     */
00046     0.6109, 0.7219, 0.8889, 0.3099, 0.2500, 0.2500, 0.2500, 0.2500,     /* èéêë     */
00047     0.2500, 0.6669, 0.2500, 0.2500, 0.2500, 0.2779, 0.2500, 0.2500,     /*  ñ   õ   */
00048     0.2779, 0.5000, 0.7219, 0.5000, 0.2500, 0.2500, 0.2500, 0.2500,     /* øùúû     */
00049 };
00050 static double arialFontWidth[] = {
00051     0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779,     /*          */
00052     0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779,     /*          */
00053     0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779,     /*          */
00054     0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779,     /*          */
00055     0.2779, 0.2779, 0.3549, 0.5559, 0.5559, 0.8889, 0.6669, 0.2209,     /*  !"#$%&' */
00056     0.3329, 0.3329, 0.3889, 0.5839, 0.2779, 0.3329, 0.2779, 0.2779,     /* ()*+,-./ */
00057     0.5559, 0.5559, 0.5559, 0.5559, 0.5559, 0.5559, 0.5559, 0.5559,     /* 01234567 */
00058     0.5559, 0.5559, 0.2779, 0.2779, 0.5839, 0.5839, 0.5839, 0.5559,     /* 89:;<=>? */
00059     1.0149, 0.6669, 0.6669, 0.7219, 0.7219, 0.6669, 0.6109, 0.7779,     /* @ABCDEFG */
00060     0.7219, 0.2779, 0.5000, 0.6669, 0.5559, 0.8329, 0.7219, 0.7779,     /* HIJKLMNO */
00061     0.6669, 0.7779, 0.7219, 0.6669, 0.6109, 0.7219, 0.6669, 0.9439,     /* PQRSTUVW */
00062     0.6669, 0.6669, 0.6109, 0.2779, 0.2779, 0.2779, 0.4689, 0.5559,     /* XYZ[\]^_ */
00063     0.2219, 0.5559, 0.5559, 0.5000, 0.5559, 0.5559, 0.2779, 0.5559,     /* `abcdefg */
00064     0.5559, 0.2219, 0.2219, 0.5000, 0.2219, 0.8329, 0.5559, 0.5559,     /* hijklmno */
00065     0.5559, 0.5559, 0.3329, 0.5000, 0.2779, 0.5559, 0.5000, 0.7219,     /* pqrstuvw */
00066     0.5000, 0.5000, 0.5000, 0.3339, 0.2599, 0.3339, 0.5839, 0.2779,     /* xyz{|}~  */
00067     0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779,     /*          */
00068     0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779,     /*          */
00069     0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779,     /*          */
00070     0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779,     /*          */
00071     0.2779, 0.3329, 0.5559, 0.5559, 0.1669, 0.5559, 0.5559, 0.5559,     /*  ¡¢£¤¥¦§ */
00072     0.5559, 0.1909, 0.3329, 0.5559, 0.3329, 0.3329, 0.5000, 0.5000,     /* ¨©ª«¬­®¯ */
00073     0.2779, 0.5559, 0.5559, 0.5559, 0.2779, 0.2779, 0.5369, 0.3499,     /*  ±²³´ ¶· */
00074     0.2219, 0.3329, 0.3329, 0.5559, 1.0000, 1.0000, 0.2779, 0.6109,     /* ¸¹º»¼½ ¿ */
00075     0.2779, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329, 0.3329,     /*  ÁÂÃÄÅÆÇ */
00076     0.3329, 0.2779, 0.3329, 0.3329, 0.2779, 0.3329, 0.3329, 0.3329,     /* È ÊË ÍÎÏ */
00077     1.0000, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779,     /* Ð        */
00078     0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779,     /*          */
00079     0.2779, 1.0000, 0.2779, 0.3699, 0.2779, 0.2779, 0.2779, 0.2779,     /*  á ã     */
00080     0.5559, 0.7779, 1.0000, 0.3649, 0.2779, 0.2779, 0.2779, 0.2779,     /* èéêë     */
00081     0.2779, 0.8889, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779, 0.2779,     /*  ñ   õ   */
00082     0.2219, 0.6109, 0.9439, 0.6109, 0.2779, 0.2779, 0.2779, 0.2779,     /* øùúû     */
00083 };
00084 static double courFontWidth[] = {
00085     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*          */
00086     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*          */
00087     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*          */
00088     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*          */
00089     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*  !"#$%&' */
00090     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* ()*+,-./ */
00091     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* 01234567 */
00092     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* 89:;<=>? */
00093     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* @ABCDEFG */
00094     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* HIJKLMNO */
00095     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* PQRSTUVW */
00096     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* XYZ[\]^_ */
00097     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* `abcdefg */
00098     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* hijklmno */
00099     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* pqrstuvw */
00100     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* xyz{|}~  */
00101     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*          */
00102     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*          */
00103     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*          */
00104     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*          */
00105     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*  ¡¢£¤¥¦§ */
00106     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* ¨©ª«¬­®¯ */
00107     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*  ±²³´ ¶· */
00108     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* ¸¹º»¼½ ¿ */
00109     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*  ÁÂÃÄÅÆÇ */
00110     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* È ÊË ÍÎÏ */
00111     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* Ð        */
00112     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*          */
00113     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*  á ã     */
00114     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* èéêë     */
00115     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /*  ñ   õ   */
00116     0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999, 0.5999,     /* øùúû     */
00117 };
00118 
00119 /* estimate_textsize:
00120  * Estimate width and height of text, for given face and size, in points.
00121  * Value is stored para->width.
00122  * NOTE: Tables are based on a font of size 1. Need to multiply by
00123  * fontsize to get appropriate value.
00124  */
00125 static void
00126 estimate_textlayout(graph_t *g, textpara_t * para, char **fontpath)
00127 {
00128     double *Fontwidth;
00129     char c, *p, *fp;
00130 
00131     para->width = 0.0;
00132     para->height = para->fontsize * LINESPACING;
00133     para->yoffset_layout = 0.0;
00134     para->yoffset_centerline = 0.1 * para->fontsize;
00135     para->layout = para->fontname;
00136     para->free_layout = NULL;
00137 
00138     if (!strncasecmp(para->fontname, "cour", 4)) {
00139         fp = "[internal courier]";
00140         Fontwidth = courFontWidth;
00141     } else if (!strncasecmp(para->fontname, "arial", 5)
00142                || !strncasecmp(para->fontname, "helvetica", 9)) {
00143         fp = "[internal arial]";
00144         Fontwidth = arialFontWidth;
00145     } else {
00146         fp = "[internal times]";
00147         Fontwidth = timesFontWidth;
00148     }
00149     if (fontpath)
00150         *fontpath = fp;
00151     if ((p = para->str)) {
00152         while ((c = *p++))
00153             para->width += Fontwidth[(unsigned char) c];
00154         para->width *= para->fontsize;
00155     }
00156 }
00157 
00158 /*
00159  * This table maps standard Postscript font names to URW Type 1 fonts.
00160  *
00161  *   The original source is in ps_font_equiv.txt.  This is sorted 
00162  *   during make into ps_font_equiv.h to ensure that it is in the right
00163  *   order for bsearch()
00164  */
00165 static PostscriptAlias postscript_alias[] = {
00166 #include "ps_font_equiv.h"
00167 };
00168 
00169 static int fontcmpf(const void *a, const void *b)
00170 {
00171     return (strcasecmp(((PostscriptAlias*)a)->name, ((PostscriptAlias*)b)->name));
00172 }
00173 
00174 static PostscriptAlias* translate_postscript_fontname(char* fontname)
00175 {
00176     static PostscriptAlias key;
00177     static PostscriptAlias *result;
00178 
00179     if (key.name == NULL || strcasecmp(key.name, fontname)) {
00180         key.name = fontname;
00181         result = (PostscriptAlias *) bsearch((void *) &key,
00182                         (void *) postscript_alias,
00183                         sizeof(postscript_alias) / sizeof(PostscriptAlias),
00184                         sizeof(PostscriptAlias),
00185                         fontcmpf);
00186     }
00187     return result;
00188 }
00189 
00190 pointf textsize(graph_t *g, textpara_t * para, char *fontname, double fontsize)
00191 {
00192     char **fp = NULL, *fontpath = NULL;
00193     pointf size;
00194 
00195     para->fontname = fontname;
00196     para->fontsize = fontsize;
00197 
00198     para->postscript_alias = translate_postscript_fontname(fontname);
00199 
00200     if (Verbose && emit_once(para->fontname))
00201         fp = &fontpath;
00202 
00203     if (! gvtextlayout(GD_gvc(g), para, fp))
00204         estimate_textlayout(g, para, fp);
00205 
00206     if (fp) {
00207         if (fontpath)
00208             fprintf(stderr, "fontname: \"%s\" resolved to: %s\n",
00209                     para->fontname, fontpath);
00210         else
00211             fprintf(stderr, "fontname: unable to resolve \"%s\"\n", para->fontname);
00212     }
00213 
00214     size.x = para->width;
00215     size.y = para->height;
00216     return size;
00217 }