33

Is it possible to create an own scalable font from a set of symbols (~700), all in SVG format. All of them are symbols (like Zapf Dingbats), so there would be no need for special settings like ligatures, italic corrections, etc. Basically I want that {\mysymbolfont\char123} displays the symbol which was originally provided as 123.svg. Should the ~700 symbols be to many I don't mind to split it into two or more fonts. All symbols have about the same height but vary in width.

I imagine that the SVG needs to be converted to MetaPost first. What would be the steps to do this and to create a basic font out of this? What LaTeX code is required to declare the font, i.e. how to create a LaTeX package for it?

I realize that font creation is not a trivial thing. Any hints are welcome.

PS: I realize that I can convert the SVGs to PDFs and include them as small images. That's what I'm doing at the moment, but it would be great to have it as font, because I guess its much more efficient.

4
  • 4
    You can import SVG into FontForge directly and then create a PostScript Type1 font from that. This is how I created the font for my ccicons package. Commented Jul 6, 2011 at 22:36
  • @Michael: This sounds very similar to what is intended here. Please feel free to post an answer with some short step-by-step instructions! Commented Jul 6, 2011 at 22:42
  • 2
    I now decided that the answer which doesn't get accepted gets a small bounty. I just have to wait 24 hours for that. Commented Jul 12, 2011 at 16:44
  • I give the reverse operation (from a font, or more precisely from a pdf with the font partially embedded) in this post regarding a single symbol.
    – Clément
    Commented Jul 9, 2014 at 17:50

3 Answers 3

39

Here are some rough step-by-step instructions to generate a font using FontForge and make it available to TeX.

  1. Start FontForge and create a new font.

  2. Import the SVG files into the different glyphs. The import is not perfect: For example, you might need to remove some spurious paths, and you should move and scale the glyphs so that they sit on the baseline and their height does not exceed 1000 units (probably around 800 units is fine). See also the instructions on the FontForge site.

  3. Use File->Generate Fonts to generate a (binary) PostScript Type1 font. Only 256 characters are accessible in one PS Type 1 font, so if you have 700 symbols, you actually want to make 3 different fonts (or you can make one font and then let pdftex/dvips re-encode them, but this a bit more complicated.) Alternatively, generate an OpenType font, which you can use directly with LuaTeX or XeTeX.

  4. You can let FontForge create TeX font metrics too, or you can use afm2tfm to generate these from the .afm files that FontForge generates.

  5. Generate a map file mysymbols.map that lists your fonts in the following format

    mysymbols1 MySymbols1 <mysymbols1.pfb
    mysymbols2 MySymbols2 <mysymbols2.pfb
    mysymbols3 MySymbols3 <mysymbols3.pfb
    

    The syntax of map files is described in Chapter 6 of the dvips manual.

  6. Copy all (.tfm, .pfb and .map) files into a texmf tree: .tfm files go into a subfolder of fonts/tfm/, .pfb files into a subfolder of fonts/type1 and the .map file goes into a subfolder of fonts/map/dvips.

  7. You might need to regenerate the file database by running mktexlsr.

  8. Activate the map file. In TeXLive, you can do this by running

    updmap-sys --enable Map mysymbols.map
    

as a super user (Use updmap if you don't have admin rights.) 9. Now you should be able to use the fonts in TeX. For instance

    \font\mysym=mysymbols1 at 10pt\mysym\char0

should print the first glyph in mysymbols1.
  1. To use the font with the LaTeX font selection macros, you need to declare it using \DeclareFontFamily and \DeclareFontShape in a package or font definition file. For instance, to declare the first family, you could use the following code:

    \DeclareFontFamily{U}{mysymbols1}{} \DeclareFontShape{U}{mysymbols1}{m}{n}{ <-> mysymbols1 }{}

After that, you can access the font in LaTeX like this:

    \usefont{U}{mysymbols1}{m}{n}\char0

See the [LaTeX 2e font selection guide][5] for more information.
6
  • 1
    Thanks for the detailed description. I could create the font files with the small script Khaled Hosny posted, but I will most likely also go over the symbols as shown in 2. for a manual optimized version. Points 5. and 8. were very helpful, otherwise I wouldn't have been able to use it. Thanks a lot! I will wait a little as usual before accepting an answer. Commented Jul 7, 2011 at 7:41
  • 1
    @Martin: Thanks. I updated my answer to give more information on how to declare the font in LaTeX. Commented Jul 7, 2011 at 9:51
  • @MichaelUmmels Vey useful instruction, but I had problem in finding the fonts folder. Do you mean usr/local/texlive/2011/texmf/fonts? In that folder there was no folder of tfm and type1 (should they be created?) and in dvips, map files reside in updmap. Could you please refer to full address of corresponding folders in texlive!
    – Googlebot
    Commented Aug 18, 2012 at 9:45
  • @Ali TeXLive provides a local texmf tree for these purposes. If you installed TeXLive into /usr/local/texlive, the relevant directories are /usr/local/texlive/texmf-local/fonts/tfm, /usr/local/texlive/texmf-local/fonts/type1 and /usr/local/texlive/texmf-local/fonts/map/dvips. Commented Aug 19, 2012 at 21:35
  • 1
    @Ali There is nothing wrong with your installation. I can confirm that you need to create this directory yourself in a fresh TeXLive installation. Commented Aug 20, 2012 at 14:47
45
+50

Assuming you have FontForge with Python scripting, all the svg files in the current directory numbered from 1-700, the following should create both a Type1, OTF and TTF fonts out of it.

import fontforge

# create empty font
font = fontforge.font()

# set font names
font.fontname = "FooBar"
font.fullname = "Foo Bar"
font.familyname = "Foo Bar"

# import svgs
for i in range(1, 701):
    # create a new glyph with the code point i
    glyph = font.createChar(i)

    # import svg file into it
    glyph.importOutlines("%s.svg" %i)

    # make the glyph rest on the baseline
    ymin = glyph.boundingBox()[1]
    glyph.transform([1, 0, 0, 1, 0, -ymin])

    # set glyph side bearings, can be any value or even 0
    glyph.left_side_bearing = glyph.right_side_bearing = 10

font.generate("foobar.pfb", flags=["tfm", "afm"]) # type1 with tfm/afm
font.generate("foobar.otf") # opentype
font.generate("foobar.ttf") # truetype

Note that Type1/TFM can have maximum of 255 glyphs, so you have to either spread your SVGs over multiple fonts or use OTF/TTF with a suitable engine. Check FontForge's Python scripting documentation for more details.

Update: The script now bottom aligns all the glyphs on the base line, and also allows setting glyph side bearings.

4
  • This worked very good and I could use the font with TeX, after creating and installing a .map file as described in Michaels answer. Thanks a lot! Commented Jul 7, 2011 at 7:36
  • The symbols seem to be all top-aligned, i.e. the smaller symbols have some white space below them and do not sit on the baseline. Any idea how to change that, i.e. bottom-align them to the baseline? Commented Jul 7, 2011 at 7:47
  • 1
    @Martin: I updated the answer to do this as well. Commented Jul 7, 2011 at 9:29
  • 2
    Thanks for the nice script which will be VERY useful. I accepted Michael's answer because it is gives further details on how to use the font with LaTeX etc. Please accept the 50rep bounty for your help instead. Commented Jul 13, 2011 at 17:14
0

I would like to point out the following site:

https://web.archive.org/web/20171211114543/http://math.stanford.edu:80/~jyzhao/latexfonts.php

Also, you can make your own true-type font in font forge. Using svg files with font forge and the above link, you should be able to easily create and use your own font. Make sure to follow the instructions on the above site precisely: actually make a copy of your true-type font file called custom.ttf and use that.

This will give you an easy way to use a custom font in a single LaTeX document!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .