]> granicus.if.org Git - graphviz/commitdiff
Improve the font descriptions of the resolved font in "-v" output. Now includes full...
authorellson <devnull@localhost>
Fri, 20 Jul 2007 18:38:03 +0000 (18:38 +0000)
committerellson <devnull@localhost>
Fri, 20 Jul 2007 18:38:03 +0000 (18:38 +0000)
Plugin API was changed, so increment plugin version number to prevent loading incompatible plugins.

configure.ac
lib/common/fontmetrics.c
lib/gvc/gvplugin_textlayout.h
lib/gvc/gvtextlayout.c
plugin/gd/gvtextlayout_gd.c
plugin/pango/gvtextlayout_pango.c

index 285336c2f3aab0334d3655695da4a294a1bad255..c7af82a99fc13bef30c24e7f53537dae934f13a1 100644 (file)
@@ -11,7 +11,7 @@ AC_INIT(graphviz, 2.13)
 # libtool shared library version
 
 # Increment if the interface has additions, changes, removals.
-LT_CURRENT=3
+LT_CURRENT=4
 
 # Increment any time the source changes; set to
 # 0 if you increment CURRENT
index 7f86cd983d6c09dec1c0bc9bfbf6ba70adc02eab..c8852c598c043727ea5d2c62d061f924610c7b52 100644 (file)
@@ -134,7 +134,7 @@ static void
 estimate_textlayout(graph_t *g, textpara_t * para, char **fontpath)
 {
     double *Fontwidth;
-    char c, *p;
+    char c, *p, *fp;
 
     para->width = 0.0;
     para->height = para->fontsize * LINESPACING;
@@ -143,16 +143,18 @@ estimate_textlayout(graph_t *g, textpara_t * para, char **fontpath)
     para->free_layout = NULL;
 
     if (!strncasecmp(para->fontname, "cour", 4)) {
-       *fontpath = "[internal courier]";
+       fp = "[internal courier]";
        Fontwidth = courFontWidth;
     } else if (!strncasecmp(para->fontname, "arial", 5)
               || !strncasecmp(para->fontname, "helvetica", 9)) {
-       *fontpath = "[internal arial]";
+       fp = "[internal arial]";
        Fontwidth = arialFontWidth;
     } else {
-       *fontpath = "[internal times]";
+       fp = "[internal times]";
        Fontwidth = timesFontWidth;
     }
+    if (fontpath)
+       *fontpath = fp;
     if ((p = para->str)) {
        while ((c = *p++))
            para->width += Fontwidth[(unsigned char) c];
@@ -194,7 +196,7 @@ static PostscriptAlias* translate_postscript_fontname(char* fontname)
 
 pointf textsize(graph_t *g, textpara_t * para, char *fontname, double fontsize)
 {
-    char *fontpath = NULL;
+    char **fp = NULL, *fontpath = NULL;
     pointf size;
 
     para->fontname = fontname;
@@ -202,15 +204,16 @@ pointf textsize(graph_t *g, textpara_t * para, char *fontname, double fontsize)
 
     para->postscript_alias = translate_postscript_fontname(fontname);
 
-    if (! gvtextlayout(GD_gvc(g), para, &fontpath) || !fontpath)
-       estimate_textlayout(g, para, &fontpath);
+    if (Verbose && emit_once(para->fontname))
+       fp = &fontpath;
 
-    if (Verbose) {
-       if (emit_once(para->fontname)) {
-           fprintf(stderr, "%s: fontname \"%s\" resolved to \"%s\"\n",
+    if (! gvtextlayout(GD_gvc(g), para, fp))
+       estimate_textlayout(g, para, fp);
+
+    if (fp)
+       fprintf(stderr, "%s: fontname \"%s\" resolved to: %s\n",
                    GD_gvc(g)->common.cmdname, para->fontname, fontpath);
-       }
-    }
+
     size.x = para->width;
     size.y = para->height;
     return size;
index 25fcc8ba850c48fcc351cd3a4d5176a1f1e8fba5..c4819a6cb019ab9fd55d67f3b9c9a3682f6ca7be 100644 (file)
@@ -27,7 +27,7 @@ extern "C" {
 #endif
 
     struct gvtextlayout_engine_s {
-       void (*textlayout) (GVCOMMON_t *common, textpara_t *para, char** fontpath);
+       boolean (*textlayout) (GVCOMMON_t *common, textpara_t *para, char** fontpath);
     };
 
 #ifdef __cplusplus
index eb6b5e6fc7411a515023cd3efccc27ad314b2f4b..44357776e6242c285323667a346845f014b0687c 100644 (file)
@@ -45,9 +45,7 @@ boolean gvtextlayout(GVC_t *gvc, textpara_t *para, char **fontpath)
 {
     gvtextlayout_engine_t *gvte = gvc->textlayout.engine;
 
-    if (gvte && gvte->textlayout) {
-       gvte->textlayout(&(gvc->common), para, fontpath);
-       return TRUE;
-    }
+    if (gvte && gvte->textlayout)
+       return gvte->textlayout(&(gvc->common), para, fontpath);
     return FALSE;
 }
index 929fe6db26501e9fede5740a0f661981ebb34774..dc432f75856212885a4295baf905d7ea35bcdd5f 100644 (file)
@@ -97,9 +97,8 @@ char *gd_alternate_fontlist(char *font)
 }
 #endif                         /* HAVE_GD_FONTCONFIG */
 
-static void gd_textlayout(GVCOMMON_t *common, textpara_t * para, char **fontpath)
+static boolean gd_textlayout(GVCOMMON_t *common, textpara_t * para, char **fontpath)
 {
-    static char *fntpath;
     char *err;
     char *fontlist;
     int brect[8];
@@ -124,8 +123,7 @@ static void gd_textlayout(GVCOMMON_t *common, textpara_t * para, char **fontpath
 
     if (para->fontname) {
        if (para->fontsize <= FONTSIZE_MUCH_TOO_SMALL) {
-           /* OK, but ignore text entirely */
-           return;
+           return TRUE; /* OK, but ignore text entirely */
        } else if (para->fontsize <= FONTSIZE_TOO_SMALL) {
            /* draw line in place of text */
            /* fake a finite fontsize so that line length is calculated */
@@ -143,8 +141,7 @@ static void gd_textlayout(GVCOMMON_t *common, textpara_t * para, char **fontpath
 
        if (err) {
            fprintf(stderr,"%s\n", err);
-           *fontpath = NULL;   /* indicate error */
-           return;
+           return FALSE; /* indicate error */
        }
 
        if (strex.xshow) {
@@ -153,9 +150,8 @@ static void gd_textlayout(GVCOMMON_t *common, textpara_t * para, char **fontpath
            strex.xshow = NULL;
        }
 
-       if (fntpath)
-           free(fntpath);
-       *fontpath = fntpath = strex.fontpath;
+       if (fontpath)
+           *fontpath = strex.fontpath;
 
        if (para->str && para->str[0]) {
            /* can't use brect on some archtectures if strlen 0 */
@@ -166,6 +162,7 @@ static void gd_textlayout(GVCOMMON_t *common, textpara_t * para, char **fontpath
            para->height = (int)(para->fontsize * 1.2);
        }
     }
+    return TRUE;
 }
 
 static gvtextlayout_engine_t gd_textlayout_engine = {
index 8655ab7be75169d41d10c661ee80543eb358a830..443f9e1896a2002c6ba538e06f732799744729be 100644 (file)
@@ -1,17 +1,17 @@
 /* $Id$ $Revision$ */
 /* vim:set shiftwidth=4 ts=8: */
 
-/**********************************************************
-*      This software is part of the graphviz package      *
-*                http://www.graphviz.org/                 *
-*                                                         *
-*            Copyright (c) 1994-2004 AT&T Corp.           *
-*                and is licensed under the                *
-*            Common Public License, Version 1.0           *
-*                      by AT&T Corp.                      *
-*                                                         *
-*        Information and Software Systems Research        *
-*              AT&T Research, Florham Park NJ             *
+/*********************************************************
+*       This software is part of the graphviz package    *
+*              http://www.graphviz.org/                 *
+*                                                       *
+*          Copyright (c) 1994-2004 AT&T Corp.           *
+*              and is licensed under the                *
+*          Common Public License, Version 1.0           *
+*                    by AT&T Corp.                      *
+*                                                       *
+*      Information and Software Systems Research        *
+*            AT&T Research, Florham Park NJ             *
 **********************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -19,6 +19,7 @@
 #endif
 
 #include <string.h>
+#include <fontconfig/fontconfig.h>
 #include "gvplugin_textlayout.h"
 
 #ifdef HAVE_PANGOCAIRO
@@ -29,13 +30,14 @@ static void pango_free_layout (void *layout)
     g_object_unref((PangoLayout*)layout);
 }
 
-static void pango_textlayout(GVCOMMON_t *common, textpara_t * para, char **fontpath)
+static boolean pango_textlayout(GVCOMMON_t *common, textpara_t * para, char **fontpath)
 {
-    static char buf[512];  /* returned in fontpath, only good until next call */
+    static char buf[1024];  /* returned in fontpath, only good until next call */
     static PangoFontMap *fontmap;
     static PangoContext *context;
     static PangoFontDescription *desc;
     static char *fontname;
+    char *fnt;
     PangoLayout *layout;
     PangoRectangle ink_rect, logical_rect;
 #if ENABLE_PANGO_XSHOW
@@ -47,21 +49,16 @@ static void pango_textlayout(GVCOMMON_t *common, textpara_t * para, char **fontp
     GError *error = NULL;
 #endif
     char *text;
-    const char *family;
-    PangoStyle style;
-    PangoWeight weight;
-    PangoVariant variant;
-    PangoStretch stretch;
 
     if (!fontmap)
-        fontmap = pango_cairo_font_map_get_default();
+       fontmap = pango_cairo_font_map_get_default();
     pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(fontmap), (double)POINTS_PER_INCH);
     if (!context)
-        context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP(fontmap));
+       context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP(fontmap));
 
     if (!fontname || strcmp(fontname, para->fontname)) {
        fontname = para->fontname;
-        pango_font_description_free (desc);
+       pango_font_description_free (desc);
 
        if (para->postscript_alias) {
            int comma=0;
@@ -81,50 +78,53 @@ static void pango_textlayout(GVCOMMON_t *common, textpara_t * para, char **fontp
                comma = 1;
                strcat(buf, para->postscript_alias->style);
            }
-            desc = pango_font_description_from_string(buf);
+           fnt = buf;
        }
        else
-            desc = pango_font_description_from_string(fontname);
-    }
-    family = pango_font_description_get_family (desc);
-    style = pango_font_description_get_style (desc);
-    weight = pango_font_description_get_weight (desc);
-    variant = pango_font_description_get_variant (desc);
-    stretch = pango_font_description_get_stretch (desc);
-    strcpy(buf,family);
-    switch (style) {
-       case PANGO_STYLE_NORMAL:            /* strcat(buf, ", normal");*/ break;
-       case PANGO_STYLE_OBLIQUE:           strcat(buf, ", oblique"); break;
-       case PANGO_STYLE_ITALIC:            strcat(buf, ", italic"); break;
-    }
-    switch (weight) {
-       case PANGO_WEIGHT_ULTRALIGHT:       strcat(buf, ", ultralight"); break;
-       case PANGO_WEIGHT_LIGHT:            strcat(buf, ", light"); break;
-       case PANGO_WEIGHT_NORMAL:           /* strcat(buf, ", normal");*/ break;
-       case PANGO_WEIGHT_SEMIBOLD:         strcat(buf, ", semibold"); break;
-       case PANGO_WEIGHT_BOLD:             strcat(buf, ", bold"); break;
-       case PANGO_WEIGHT_ULTRABOLD:        strcat(buf, ", ultrabold"); break;
-       case PANGO_WEIGHT_HEAVY:            strcat(buf, ", heavy"); break;
-    }
-    switch (variant) {
-       case PANGO_VARIANT_NORMAL:          /* strcat(buf, ", normal");*/ break;
-       case PANGO_VARIANT_SMALL_CAPS:      strcat(buf, ", smallcaps"); break;
-    }
-    switch (stretch) {
-       case PANGO_STRETCH_ULTRA_CONDENSED: strcat(buf, ", ultracondensed"); break;
-       case PANGO_STRETCH_EXTRA_CONDENSED: strcat(buf, ", extracondensed"); break;
-       case PANGO_STRETCH_CONDENSED:       strcat(buf, ", condensed"); break;
-       case PANGO_STRETCH_SEMI_CONDENSED:  strcat(buf, ", semicondensed"); break;
-       case PANGO_STRETCH_NORMAL:          /* strcat(buf, ", normal");*/ break;
-       case PANGO_STRETCH_SEMI_EXPANDED:   strcat(buf, ", semiexpanded"); break;
-       case PANGO_STRETCH_EXPANDED:        strcat(buf, ", expanded"); break;
-       case PANGO_STRETCH_EXTRA_EXPANDED:  strcat(buf, ", extraexpanded"); break;
-       case PANGO_STRETCH_ULTRA_EXPANDED:  strcat(buf, ", ultraexpanded"); break;
+           fnt = fontname;
+
+       desc = pango_font_description_from_string(fnt);
+
+        if (fontpath) {  /* -v support */
+           FcPattern *pat, *match;
+           FcFontSet *fs;
+           FcResult result;
+    
+            if (! FcInit())
+               return FALSE;
+    
+           pat = FcNameParse((FcChar8 *) fnt);
+           FcConfigSubstitute (0, pat, FcMatchPattern);
+           FcDefaultSubstitute (pat);
+           fs = FcFontSetCreate();
+           match = FcFontMatch (0, pat, &result);
+           if (match)
+               FcFontSetAdd (fs, match);
+           FcPatternDestroy (pat);
+           strcpy(buf,"");
+           if (fs) {
+               FcChar8 *family, *style, *file;
+    
+               if (FcPatternGetString (fs->fonts[0], FC_FILE, 0, &file) != FcResultMatch)
+                   file = (FcChar8 *) "<unknown font filename>";
+               if (FcPatternGetString (fs->fonts[0], FC_FAMILY, 0, &family) != FcResultMatch)
+                   family = (FcChar8 *) "<unknown font family>";
+               if (FcPatternGetString (fs->fonts[0], FC_STYLE, 0, &style) != FcResultMatch)
+                   style = (FcChar8 *) "<unknown font style>";
+               strcat(buf, "\"");
+               strcat(buf, (char *)family);
+               strcat(buf, ", ");
+               strcat(buf, (char *)style);
+               strcat(buf, "\" ");
+               strcat(buf, (char *)file);
+           }
+            *fontpath = buf;
+           FcFontSetDestroy(fs);
+        }
     }
-    *fontpath = buf;
-
     pango_font_description_set_size (desc, (gint)(para->fontsize * PANGO_SCALE));
 
+
 #ifdef ENABLE_PANGO_MARKUP
     if (! pango_parse_markup (para->str, -1, 0, &attrs, &text, NULL, &error))
        die(error->message);
@@ -145,10 +145,8 @@ static void pango_textlayout(GVCOMMON_t *common, textpara_t * para, char **fontp
     pango_layout_get_extents (layout, &ink_rect, &logical_rect);
 
     /* if pango doesn't like the font then it sets width=0 but height = garbage */
-    if (logical_rect.width == 0) {
-       *fontpath = NULL;              /* indicate a problem */
+    if (logical_rect.width == 0)
        logical_rect.height = 0;
-    }
 
     para->width = (double)logical_rect.width / PANGO_SCALE;
     para->height = (double)logical_rect.height / PANGO_SCALE;
@@ -159,12 +157,15 @@ static void pango_textlayout(GVCOMMON_t *common, textpara_t * para, char **fontp
 /* FIXME - unfinished code */
     iter = pango_layout_get_iter (layout);
     do {
-        pango_layout_iter_get_char_extents (iter, &char_rect);
+       pango_layout_iter_get_char_extents (iter, &char_rect);
        char_rect.x /= PANGO_SCALE;
        char_rect.y /= PANGO_SCALE;
     } while (pango_layout_iter_next_char (iter));
     pango_layout_iter_free (iter);
 #endif
+    if (logical_rect.width == 0)
+       return FALSE;
+    return TRUE;
 }
 
 static gvtextlayout_engine_t pango_textlayout_engine = {