]> granicus.if.org Git - graphviz/commitdiff
working on font faq
authornorth <devnull@localhost>
Thu, 20 Dec 2007 02:55:09 +0000 (02:55 +0000)
committernorth <devnull@localhost>
Thu, 20 Dec 2007 02:55:09 +0000 (02:55 +0000)
doc/fontfaq.txt

index cec8f31f76e8f19b7a39a2a3ebc9b3a66eab8790..f1591ebd1ddc4e67fb6571c326694541d5cac16c 100644 (file)
 Graphviz and fonts.
 ===================
 
-The graphviz layout engines (dot, neato, etc) create layouts with nodes sized
-to enclose the text labels.  This requires knowing the size of the text blocks,
-which in turn requires knowing the metrics of the font glyphs and their
-composition into words, taking into account wordspacing, kerning, hinting, etc.
-
-The font is normally selected by family name, and any other required properties,
-(see: FAQ item: "Font selection") then fontconfig is used to match the font request
-to a specific font available on the system.  (see FAQ item: "No fontconfig.")
-
-[Note.  In older versions of dot, fontname was a font filename, which was
-exact, and which either existed or it didn't.   With fontconfig, fontnames are
-now family names, which fontconfig will match to the closest font it can find.
-This should always succeed, but unfortunately sometimes produces surprising
-results if its idea of "close" doesn't match yours.]
-
-Text layout is normally performed by pango, which accepts text and
-produces a layout with metrics which we can use to size the node shapes.
-(See FAQ item: "No pango.")
-
-Line drawing is provided by cairo for many output formats, and likely more in
-the future, however font rendering is passed though cairo to freetype.  The same
-is true if gd is used for drawing.  (See FAQ items: "No cairo," "No gd.")
-
-Font rendering is provided by freetype, which provides antialiasing, hinting,
-kerning, and other low-level font features.
-(See FAQ item: "No freetype.")
-
-The font metrics are obtained using fonts available on the system running dot.
-This works fine, except for outputs like -Tps and -Tsvg where the final rendering
-may be done on a different platform altogether, where the same fonts might not
-be available.  For these cases (in PostScript only at this time) we pass down the
-expected metrics of the text block to the renderer and ask it to make a final
-stretch (or squeeze) to make the text fit the metrics that were used at layout time.
-
-Default fonts and PostScript fonts.
-===================================
+Before we launch into the gory details, we would like to explain
+why this is a hard problem.  The naming and rendering of text fonts
+in Graphviz (and other programs) is complicated.  There are several reasons:
+
+- Graphviz runs on a wide range of systems: Linux and other Unix
+variants, Microsoft Windows, and Mac.
+- Graphviz has a wide range of output formats: raster-oriented formats
+like PNG and GIF; path-based ones like Postscript, PDF and SVG; some
+idiosyncractic legacy formats, like troff PIC and HPGL.
+- Often, output will be downloaded and displayed on a computer or other 
+device, different than the one where the layout was created.
+- Graphviz layouts should be identical in size and appearance,
+regardless of the output format.
+- Graphviz can run on external libraries that help with naming and
+rendering text fonts, but they are not required, and stripped-down
+Graphviz tools can be built without them. In fact, Graphviz may have
+to run on systems with no font files installed.
+- There are several major font file formats to be supported.
+- Non-Western, international character sets should be supported.
+- Graphviz should provide a good set of standard fonts.
+- It should be easy to specify standard fonts.
+- Users should be able to load their own custom fonts.
+- Output should be small to download quickly.
+- Output should allow the best rendering possible in a given format.
+- Output files should be easy to postprocess, for example, retaining
+the objects of the original graph if possible.
+- It is very helpful to work around known bugs or missing features
+in support libraries and popular external tools.
+
+This is a tall order. Some of the goals conflict.  Generally our
+approach has been to define defaults that favor convenience and good
+looking output, and give the user options to override the defaults.
+
+===Overview===
+
+In the following, we will assume a ''standard'' version of Graphviz 
+with the full set of support libraries (fontconfig, gd, Cairo and Pango),
+running on a desktop system or server with a standard installation of
+font files.
+
+The graphviz layout engines (dot, neato, etc) create layouts with nodes
+sized to enclose the text labels.  This requires knowing the size of
+the text blocks, which in turn requires knowing the metrics of the font
+glyphs and their composition into words, taking into account wordspacing,
+kerning, hinting, etc.  So the overall process is: font specification,
+then text layout, followed by Graphviz output (and final rendering on
+the target display or device, which may or may not be by a Graphviz tool.)
+
+
+A font is usually selected by family name ("fontname") and other properties
+(see below: "Font selection"). Then fontconfig matches the request
+to a system font.  [Note: in older versions of Graphviz, fontname was
+simply a file name.  This required exact file name matching (with a little
+bit of helpful name mangling under the hood, e.g. translating Times-Roman
+to Times, or Helvetica to Arial on Windows systems (and yes we know
+there is a difference).  Under fontconfig, fontnames are family names,
+which fontconfig matches to the closest font it finds. This always
+"succeeds", but unfortunately produces surprising results if fontconfig's
+idea of "close" doesn't match yours. This can happen when you specify
+a custom (or just nonexistent) font, like Steve-North-Handwriting,
+and fontconfig silently falls back to something safe like a typewriter
+font.]
+
+Text layout is performed by pango, which accepts text and computes a
+layout with metrics that determine node sizes.
+
+Though line drawing is provided by cairo for many output formats (and
+likely more in the future), for raster output formats, font rendering
+is passed though cairo to freetype. Freetype is also called if gd is
+used for drawing.  (gd can also be requested explicitly, e.g. dot -Tpng:gd,
+or by default when Graphviz is built without cairo).  Freetype provides
+antialiasing, hinting, kerning, and other low-level font features.  
+
+Font metrics are obtained from the fonts installed on the system running
+Graphviz.  Results are guaranteed when Graphviz outputs raster formats,
+because freetype immediately renders the fonts into pixels.  On the
+other hand, with path-based formats like Postscript (-Tps) and SVG (-Tsvg),
+final rendering may be done on a different platform altogether, with
+different font files installed.  Clearly, Your Milage May Vary.  In the
+case of Postscript, the driver in Graphviz passes the expected metrics
+of the text block down to the renderer, and asks it to make a final stretch
+(or squeeze) to force the text to fit the metrics that were in effect at
+layout time.  In Graphviz SVG, there is only a hope and a prayer that
+the SVG rendering program's fonts match the ones fontconfig and freetype
+used when Graphviz was run.  (More about this later.)
+
+Default fonts and PostScript fonts.  ===================================
 
 The default font in graphviz is, and always has been, Times-Roman.
-Unfortunately, fontconfig doesn't recognize this PostScript-style font
-specification directly, so we have custom mappings from a basic set of
-PostScipt fontnames into fontconfig family names for use in all cairo and gd
-based renderers. In -Tps output, these fonts are used without name
-translation.
-
-The supported PostScript fontnames are:
-       AvantGarde-Book
-       AvantGarde-BookOblique
-       AvantGarde-Demi
-       AvantGarde-DemiOblique
-       Bookman-Demi
-       Bookman-DemiItalic
-       Bookman-Light
-       Bookman-LightItalic
-       Courier
-       Courier-Bold
-       Courier-BoldOblique
-       Courier-Oblique
-       Helvetica
-       Helvetica-Bold
-       Helvetica-BoldOblique
-       Helvetica-Narrow
-       Helvetica-Narrow-Bold
-       Helvetica-Narrow-BoldOblique
-       Helvetica-Narrow-Oblique
-       Helvetica-Oblique
-       NewCenturySchlbk-Bold
-       NewCenturySchlbk-BoldItalic
-       NewCenturySchlbk-Italic
-       NewCenturySchlbk-Roman
-       Palatino-Bold
-       Palatino-BoldItalic
-       Palatino-Italic
-       Palatino-Roman
-       Symbol
-       Times-Bold
-       Times-BoldItalic
-       Times-Italic
-       Times-Roman
-       ZapfChancery-MediumItalic
-       ZapfDingbats
-
-Font selection.
-===============
-
-The fontname attribute in .dot graphs is a fontconfig style
-specification.  From: http://www.fontconfig.org/fontconfig-user.html
-
-       Fontconfig provides a textual representation for patterns that the library can
-       both accept and generate. The representation is in three parts, first a list
-       of family names, second a list of point sizes and finally a list of additional
-       properties:
+
+Graphviz has historically supported some ``standard'' Postscript
+fonts, initially, Times-Roman, Helvetica, Courier and Symbol.
+This list was later enlarged by Adobe to include 35 fonts, which are:
+       AvantGarde-Book AvantGarde-BookOblique AvantGarde-Demi
+       AvantGarde-DemiOblique Bookman-Demi Bookman-DemiItalic
+       Bookman-Light Bookman-LightItalic Courier Courier-Bold
+       Courier-BoldOblique Courier-Oblique Helvetica
+       Helvetica-Bold Helvetica-BoldOblique Helvetica-Narrow
+       Helvetica-Narrow-Bold Helvetica-Narrow-BoldOblique
+       Helvetica-Narrow-Oblique Helvetica-Oblique NewCenturySchlbk-Bold
+       NewCenturySchlbk-BoldItalic NewCenturySchlbk-Italic
+       NewCenturySchlbk-Roman Palatino-Bold Palatino-BoldItalic
+       Palatino-Italic Palatino-Roman Symbol Times-Bold Times-BoldItalic
+       Times-Italic Times-Roman ZapfChancery-MediumItalic ZapfDingbats
+
+Unfortunately, fontconfig doesn't recognize PostScript-style font
+names directly, so Graphviz makes custom mappings from its list of
+PostScipt names into fontconfig family names for use in all cairo
+and gd based renderers. In -Tps output, these fonts are used without
+name translation.
+
+Font selection.  ===============
+
+The fontname attribute in .dot graphs is a fontconfig style specification.
+From: http://www.fontconfig.org/fontconfig-user.html
+
+       Fontconfig provides a textual representation for patterns that
+       the library can both accept and generate. The representation is
+       in three parts, first a family name list, second list of point sizes,
+       and finally a list of additional properties:
 
        <families>-<point sizes>:<name1>=<values1>:<name2>=<values2>...
-    
 
-       Values in a list are separated with commas. The name needn't include either
-       families or point sizes; they can be elided. In addition, there are symbolic
-       constants that simultaneously indicate both a name and a value. Here are some
-       examples:
+       Values in a list are separated with commas. The name needn't
+       include either a family or point size; they can be elided. In
+       addition, there are symbolic constants that simultaneously
+       indicate both a name and a value. Here are some examples:
 
-       Name                            Meaning
-       ----------------------------------------------------------
-       Times-12                        12 point Times Roman
-       Times-12:bold                   12 point Times Bold
-       Courier:italic                  Courier Italic in the default size
-       Monospace:matrix=1 .1 0 1       The users preferred monospace font
-                                       with artificial obliquing
+       Name                            Meaning
+       ----------------------------------------------------------
+       Times-12                        12 point Times Roman
+       Times-12:bold                   12 point Times Bold
+       Courier:italic                  Courier Italic in the default size
+       Monospace:matrix=1 .1 0         The users preferred monospace font
+                                       with artificial obliquing
 
-In graphviz we currently have a seperate attribute for specififying fontsize.
+Graphviz currently has a seperate attribute for specififying fontsize.
 
 [ FIXME
-  We should allow the fontconfig style specification.  "Times-20" does not
-  currently result in a 20pt font.
+  We should allow the fontconfig style specification.  "Times-20" does
+  not currently result in a 20pt font.
 
-  This is probably because of special treatment of '-' for postscript font
-  names.
+  This is probably because of special treatment of '-' for postscript
+  font names.
 ]
 
 [ FIXME
-  We seem to have a bug with use of ':' in fontnames, probably because of
-  special treatment for filenames in Windows.
+  We seem to have a bug with use of ':' in fontnames, probably because
+  of special treatment for filenames in Windows.
 
   In fontnames, use <space> instead of ':' to separate values.
 
-  -Nfontname="Courier:italic" doesn't produce an italic font in graphviz-2.16.1, but:
-  -Nfontname="Courier italic" works, but 
+  -Nfontname="Courier:italic" doesn't produce an italic font in
+  graphviz-2.16.1, but: -Nfontname="Courier italic" works, but
   -Nfontname="Monospace matrix=1 .1 0 1" doesn't.
 ]
 
 
-Font management with fontconfig.
-================================
+Font management with fontconfig.  ================================
 
 How can I tell what fonts are available?
        $ fc-list
@@ -140,7 +167,11 @@ How can I tell what fonts are available?
 How can I tell what fonts dot is using;
        $ dot foo.dot -Tpng -o foo.png -v 2>&1 | grep font
 
-How can I add a new font?
+How can I add a custom font?
+(Note, in current versions of Graphviz with fontconfig, Cairo and
+Pango this cannot be done by simply putting a file in the
+current directory or setting the DOTFONTPATH path variable.
+Your custom font must be explicitly installed by fontconfig tools.)
        $ mkdir -p ~/.fonts
        $ cp foo.ttf ~/.fonts/
        $ fc-cache
@@ -149,69 +180,125 @@ How can I ... font?
        See: http://www.fontconfig.org/fontconfig-user.html
 
 Can I specifiy a font by filename instead of by familyname?
-       Not if fontconfig is enabled.
+       Sorry, the answer is no.  {The reason is that for this to
+       work, Graphviz has to intercept the font lookup before
+       fontconfig is called, and this can't be done when fonts
+       are being looked up by Pango.)
+
 [ FIXME
-  I thought we still recognized any fontname containing a path separator ( '/'
-  or '\') as a font filename.   This doesn't seem to work anymore.
+  I thought we still recognized any fontname containing a path separator (
+  '/' or '\') as a font filename.   This doesn't seem to work anymore.
 ]
 
 How can I be sure that a specific font is selected?
-       Provide enough specification in the fontname, and test it with
-       fc-match to ensure that your desired font is selected.
-       (Note, this will not ensure that the same font is used in -Tps or
-       -Tsvg renderings where we rely on the fonts available on the final
-       printer or computer.)
-
-
-No freetype.
-============
-
-If graphviz is built on systems without freetype, then only the gd renderer
-will be available for bitmap outputs, and all fonts will revert to a set of
-builtin bitmap fonts.  The poor quality of these fonts will be evident, 
-also, "dot ... -v 2>&1 | grep font"  will indicate that the font is "<internal>"
-
-
-No fontconfig.
-==============
-
-If graphviz is built on systems without fontconfig (e.g. Redhat-7) then the
-fontname attribute will accept a filename for a fontfile and use gd and
-freetype to obtain metrics and render the font.  The PATH searched for fonts
-can be specified with the GDFONTPATH environment variable.
-
-No pango/cairo renderers will be available without fontconfig support.
-
-
-Disabling fontconfig.
-=====================
+       Provide enough specification in the fontname, and test it
+       with fc-match to ensure that your desired font is selected.
+       (Note, this will not ensure that the same font is used in -Tps
+       or -Tsvg renderings where we rely on the fonts available on the
+       final printer or computer.)
+
+       Note the downside, as mentioned previously, is that Graphviz cannot
+       do much to warn you when fontconfig didn't find a very
+       good match, because fontconfig just cheerfully falls back
+       to some standard font.  It would be really nice if the
+       fontconfig developers could provide a metric reflecting the
+       quality of the font match in their API.
+
+What about SVG fonts?
+       Graphviz has a native SVG driver that we wrote (which is the
+       default), and cairo's SVG driver (which you get with -Tsvg:cairo).
+
+       Graphviz' native SVG driver generates Windows compliant names
+       like "Times New Roman" or Arial by default. The names work in a
+       lot of situations (like Firefox running on Windows), but are
+       not guaranteed to be portable.  If you set -Gfontnames=ps,
+       you get Postscript names like Times-Roman.  If you set -Gfontnames=svg
+       you are guaranteed to get rock solid standards compliant SVG.
+       The SVG standard says that the legal generic font names
+       are Serif, Sans-Serif, and Monospace (plus Cursive and
+       Fantasy which we don't use in Graphviz). We generate those names.
+       The bad news is that various downstream renderers and editors
+       may resolve the generic font names differently, so it's not
+       quite clear how your SVG will look.  Many W3C examples show
+       how to use CSS (Cascading Style Sheets) to get around this
+       problem by giving a list of font family names in order of
+       lookup precedence, but some downstream processors (like the
+       inkscape editor in Linux) don't implement CSS, so we're up a tree here.
+
+       The cairo SVG driver solves this in an effective though brute
+       force way: it simply encodes embeds the needed fonts as lines and
+       curves in the target SVG.  For small examples, -Tsvg:cairo is
+       about 10 times bigger than -Tsvg, but maybe it's worth it for
+       correctness.  The other problem is that such SVG is much much
+       slower to render, no doubt because it bypasses any system
+       font rendering services, and does it the old fashioned way.
+
+What about Postscript fonts?
+
+       say something here.  What about non-ASCII like Latin1.
+       what about loading your own fonts via -L like in the old
+       days with the weird outline font example.
+
+==="What if" issues for nonstandard Graphviz builds===
+The following only apply if you build your own version of Graphviz
+by configuring and compiling the source code to build your own
+custom executable.  If you don't know what this means, it
+definitely does not mean you.
+
+No freetype.  ============
+
+When graphviz is built on systems without freetype, then only the gd
+renderer will be available for bitmap outputs, and the only available
+fonts are a small set of builtin bitmap fonts.  The poor quality of
+these fonts will be evident, also, "dot ... -v 2>&1 | grep font"  will
+say that the font is "<internal>". This may actually be desirable
+for installing minimal graphviz programs on a server where fonts
+may not even be installed.
+
+
+No fontconfig. ==============
+
+If graphviz is built on systems without fontconfig (e.g. Redhat-7) then
+the fontname attribute will be interpreted as a font file name. The
+system directories will be searched for this, or the directories can
+be specified with the GDFONTPATH environment variable (or DOTFONTPATH
+for historical reasons). Graphviz will use gd and freetype to obtain
+metrics and render text.  No pango/cairo renderers will be available
+without fontconfig support.
+
+
+Disabling fontconfig.  =====================
 
 Pango/cairo depends on fontconfig, so to disable fontconfig you also have
 to disable pango/cairo.    The easiest way to do this temporarily is to
 edit /usr/lib/graphviz/config and remove the entire "libpango" block.
-[ Note that any changes to this file will be lost the next time graphviz
+[Note that any changes to this file will be lost the next time graphviz
 is updated, or "dot -c" is run with installer priviledges.]
 
-With pango disabled, graphviz will use gd which, even if it was built
-with fontconfig support, will still allow fontnames to be given as filenames.
+With pango disabled, graphviz will use gd which, even if it was built with
+fontconfig support, will still allow fontnames to be given as filenames.
 
+You can also disable cairopango at build time with configure script options.
 
-No pango/cairo.
-===============
 
-Without pango/cairo many of the renderers will available only via gd
-which produces lower quality output.
+No gd. =====
 
-Looking forward, we expect to depend more on pango for things like: line
-wrapping, multiple fonts per label, bidi. text and other internationalization
-features.
+Cairopango works without gd.  We are moving graphviz to the pango/cairo
+libraries, but gd still offers some features that are hard to replace,
+such as JPEGs, GIFs and paletted color bitmap outputs. However, font support
+is fully functional without gd so long as pango, cairo, fontconfig,
+freetype are available.
 
+No pango/cairo.  ===============
 
-No gd
-=====
+Without pango/cairo, some of the key renderers are only available
+with gd, which produces lower quality (but smaller) output.
 
-We have been trying to move graphviz to the newer pango/cairo libraries, but
-gd still offers some features that are hard to replace, such as JPGs, GIFs and
-paletted color bitmap outputs.   However, font support is fully functional without gd
-so long as pango, cairo, fontconfig, freetype are available.
+Looking forward, we expect to depend more on pango for things like:
+line wrapping, multiple fonts per label, bidirectional text and
+other internationalization features.
 
+No gd and no cairopango =====
+This is basically the original Graphviz without any external fonts.
+It cannot render any raster formats, so it's mainly good for Postscript.
+It relies on a few internal font tables