SVGFonts: Fonts from the SVG-Font format

[ bsd3, graphics, library ] [ Propose Tags ] [ Report a vulnerability ]

Native font support for the diagrams framework (https://diagrams.github.io/). Note that this package can be used with any diagrams backend, not just the SVG backend. The SVG-font format is easy to parse and was therefore chosen for a font library completely written in Haskell.

You can convert your own font to SVG with http://fontforge.github.io/, or use the included LinLibertine and Bitstream fonts.

Features:

  • Complete implementation of the features that Fontforge produces (though not the complete SVG format)

  • Kerning (i.e. the two characters in "VA" are closer than the characters in "VV")

  • Unicode

  • Ligatures

XML speed issues can be solved by trimming the svg file to only those characters that are used (or maybe binary xml one day).

Version 1.0 of this library supports texturing, though this only makes sense in a diagrams backend that does rasterization in Haskell, such as diagrams-rasterific.

Note: for help porting pre-1.8 code to SVGFonts-1.8, see the README.


[Skip to Readme]

Downloads

Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.1, 0.2, 0.3, 0.4, 1.0, 1.1, 1.1.1, 1.1.2, 1.2, 1.2.1, 1.3, 1.3.0.1, 1.3.0.2, 1.4, 1.4.0.1, 1.4.0.2, 1.4.0.3, 1.5.0.0, 1.5.0.1, 1.6.0.0, 1.6.0.1, 1.6.0.2, 1.6.0.3, 1.7, 1.7.0.1, 1.8, 1.8.0.1
Change log CHANGES.md
Dependencies attoparsec, base (>=4 && <5), blaze-markup (>=0.5), blaze-svg (>=0.3.3), bytestring (>=0.10 && <1.0), cereal, cereal-vector, containers (>=0.4 && <0.8), data-default-class (>=0.1 && <0.3), diagrams-core (>=1.3 && <1.6), diagrams-lib (>=1.3 && <1.5), directory (>=1.1), parsec, split, text, vector, xml [details]
Tested with ghc ==8.2.2 || ==8.4.4 || ==8.6.5 || ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.8 || ==9.6.5 || ==9.8.2 || ==9.10.1
License BSD-3-Clause
Author Tillmann Vogt
Maintainer diagrams-discuss@googlegroups.com
Revised Revision 2 made by BrentYorgey at 2024-11-05T20:33:19Z
Category Graphics
Source repo head: git clone https://github.com/diagrams/SVGFonts.git
Uploaded by BrentYorgey at 2021-11-01T14:34:27Z
Distributions LTSHaskell:1.8.0.1, NixOS:1.8.0.1, Stackage:1.8.0.1
Reverse Dependencies 11 direct, 12 indirect [details]
Downloads 36561 total (195 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2021-11-01 [all 1 reports]

Readme for SVGFonts-1.8.0.1

[back to package description]

SVGFonts

Native font support for the Diagrams library. The SVG-Font format is easy to parse and was therefore chosen for a font library completely written in Haskell.

You can convert your own font to SVG with FontForge or use one of the SVG fonts included with the library.

Features

Complete implementation of the features that fontforge produces (but not the complete SVG format):

  • Kerning (e.g. the two characters in "VA" have a shorter distance than in "VV")
  • Unicode
  • Ligatures
  • Text boxes with syntax highlighting

XML speed issues can be solved by trimming the svg file to only those characters that are used (or maybe binary xml one day)

Version 1.0 of this library supports texturing which would only make sense in a Diagrams Backend that does rasterization in Haskell.

Example

import Diagrams.Prelude
import Diagrams.Backend.SVG.CmdLine
import qualified Graphics.SVGFonts as F

main = do
  font <- F.loadFont "/path/to/font.svg"
  let
    diagram :: Diagram B
    diagram =
      (F.drop_rect$ F.fit_height 22$ F.svgText def{F.textFont = font} "Hello World!")
      # stroke # fc blue # lc blue # bg lightgrey # fillRule EvenOdd # showOrigin
  mainWith diagram

Usage

Convert your favourite font (i.e. .ttf) into a .svg file with fontforge (the menu item under "Save All"). If a font converted on your own doesn't work, try the repair options, and if this still doesn't work edit the file by hand or report an issue. Remember that a lot of fonts are not allowed to be distributed freely.

Porting to version 1.8

Version 1.8 of the library greatly improved the API but introduced a number of breaking changes.

Previously, functions provided by the library took a large TextOpts options record and directly produced a diagrams Path. For example, it was common to see code like this:

text' font h s = (strokeP $ textSVG' (TextOpts font INSIDE_H KERN False h h) s)
               # lw none # fc black

Compared to this, version 1.8:

  • Introduces a new intermediate type PathInRect
  • Splits out width and height options into dedicated combinators such as fit_width and fit_height
  • There are also several new functions that allow specifying width and height in different ways, such as svgText_fitRect and svgText_fitRect_stretchySpace.

The only things remaining in TextOpts are options for the font, spacing mode, and underline.

Here is an idiomatic way to translate the above example code into the new API:

text' font h s
  = s
  # svgText def { textFont = font }
  # fit_height h
  # set_envelope
  # lw none # fc black
  • We use the svgText function with a default options record def, overriding the textFont field to set the font explicitly.
  • We then use the fit_height function to scale the resulting text so it has height h. This corresponds to our previous use of INSIDE_H. This is probably the most common mode, but fit_width and svgText_fitRect also available.
  • Finally, we call set_envelope which converts a PathInRect to a Diagram, by stroking the text path and appropriately setting the envelope.
  • If you actually want an explicit Path instead of a Diagram, you can call drop_rect instead of set_envelope.
  • Note that the old textSVG' function resulted in a centered local origin, whereas all the new API functions result in a local origin and the left end of the text baseline. If you need the text centered, you can of course call centerXY.