3

Is there a programmatic way of converting a set of LaTeX symbols into a set of svg files using the font files directly? In particular, I would like to create svg files for some of the symbols that are listed in the comprehensive LaTeX symbol list, i.e., http://anorien.csc.warwick.ac.uk/mirrors/CTAN/info/symbols/comprehensive/symbols-a4.pdf And if I were to chose one of these packages of symbols and get all the directories and files (atm/, tfm/, etc) from e.g. http://tug.ctan.org/fonts/linearA/, could I use these dirs and files directly and covert all the symbols defined therein to svg.

I suppose I am looking for something like:

 magic_convert_fonts_to_svg --input_dir font_package_dir/ --output all_symbols_in_package.svg  

I understand that there may be more manual ways of doing this involving e.g. dvisvgm (http://dvisvgm.bplaced.net/), but I would like to know if there is a straightforward automatic way of convert from font files directly.

2

You can loop over all glyphs in the font, print each of them on separate page, generate a dvi file and convert it to svg using dvisvgm. We can automate it using Lua script which takes a font name and some other options as argument. fonttosvg.lua:

kpse.set_program_name "luatex"
local lapp = require "lapp-mk4"

local args = lapp [[
Convert TeX font to SVG
-s,--scale (default 1) Glyph scaling
<fontname> (string)
]]

local fontname = args.fontname

if fontname == nil then
  print "Missing font name"
  os.exit()
end

local latex = io.popen("dviluatex -jobname=".. fontname, "w")

latex:write(string.format([[
\font\sample=%s at 48pt
\nopagenumbers
\count55=0
\newif\ifvalidchar
\loop\ifnum\count55<256
  \validchartrue
  \setbox0=\hbox{\sample\char\count55}
  \ifdim\wd0=0pt\relax
    \ifdim\ht0=0pt\relax
     \ifdim\dp0=0pt\relax
       \global\validcharfalse
     \fi
    \fi
  \fi
  \ifvalidchar
    \box0
    \vfill\eject
  \fi
  \advance\count55 by1\relax
\repeat
\bye
]], fontname))
latex:close()

os.execute(string.format("dvisvgm -b none -t 0,2 -n -p 1- -c %s  %s.dvi", args.scale, fontname))

this script writes plain TeX document which loops over all possible characters in the tfm file and writes each existing character to standalone page. dvisvgm then traces glyph curves (-n option) and save each character in file fontname-pagenumber.svg.

For example if we want to create svgs for linearA font, we can call the script as following:

texlua fonttosvg.lua -s 3 LinearA

LinearA if name of the tfm file provided by the package, -s option is used to scale the svg files. Some resulting glyph:

enter image description here

  • Amazing! Thank you! It is exactly what I need. – mjandrews Mar 9 '16 at 12:04
2

Alternatively to Michal's nice solution, you can also use the little command-line program font2svg. It's a quick hack written in C++. It takes the path to a font file as an argument and creates separate SVG files for each glyph. For example,

font2svg /path/to/LinearA.pfb

creates the files LinearA-0001.svg,...,LinearA-0178.svg.

The program works with all vector fonts supported by FreeType and doesn't require any TeX files.

  • Another excellent tool. I just ran it on Linux (making a few changes to Makefile) and it did the job perfectly. – mjandrews Mar 9 '16 at 17:10
1

FontForge can export the glyph outlines as SVG files.

Interactive way: Open a font, then select and open a glyph. The outline is exported to SVG via the menu item File->Export.

FontForge can also be scripted with Python if the bindings for Python are installed. The following script exports the glyphs of a font to SVG files with names consisting of the font name, Unicode/encoding number and glyph name.

#!/usr/bin/env python
import argparse
import fontforge

def parse_command_line_options():
    parser = argparse.ArgumentParser(
        description='Export font glyphs as SVG files via fontforge.')
    parser.add_argument(
        'font_file_name',
        metavar='FONT',
        help='font file name')
    return parser.parse_args()

def generate_file_name(glyph):
    sep = '-'
    # Font name
    file_name = glyph.font.fontname
    file_name += sep
    # Unicode or encoding number
    if glyph.unicode >= 0:
        file_name += 'U+' + format(glyph.unicode, '04X')
        file_name += sep
    elif glyph.encoding >= 0:
        file_name += '0x' + format(glyph.encoding, '02X')
        file_name += sep
    # Glyph name
    file_name += glyph.glyphname
    # Extension
    file_name += '.svg'
    return file_name

def export_glyphs(font_file_name):
    font = fontforge.open(font_file_name)
    glyphs = font.selection.byGlyphs.all()
    for glyph in glyphs:
        svg_file_name = generate_file_name(glyph)
        if glyph.isWorthOutputting:
            glyph.export(svg_file_name)
            print(svg_file_name)

def main():
    args = parse_command_line_options()
    export_glyphs(args.font_file_name)

if __name__ == "__main__":
    main()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.