是否有一种编程方式可以直接使用字体文件将一组 LaTeX 符号转换为一组 svg 文件?具体来说,我想为综合 LaTeX 符号列表中列出的一些符号创建 svg 文件,即http://anorien.csc.warwick.ac.uk/mirrors/CTAN/info/symbols/comprehensive/symbols-a4.pdf 如果我选择其中一个符号包并从例如获取所有目录和文件(atm /,tfm /等)http://tug.ctan.org/fonts/linearA/,我可以直接使用这些目录和文件并将其中定义的所有符号转换为 svg 吗?
我想我正在寻找类似的东西:
magic_convert_fonts_to_svg --input_dir font_package_dir/ --output all_symbols_in_package.svg
我理解可能还有更多手动方式来实现这一点,例如韋斯維爾(http://dvisvgm.bplaced.net/),但我想知道是否有一种直接自动从字体文件转换的方法。
答案1
您可以循环遍历字体中的所有字形,将每个字形打印在单独的页面上,生成 dvi 文件并将其转换为svg
使用dvisvgm
。我们可以使用以Lua
字体名称和一些其他选项作为参数的脚本来自动化它。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))
该脚本编写纯 TeX 文档,循环遍历 tfm 文件中的所有可能字符,并将每个现有字符写入独立页面。dvisvgm
然后跟踪字形曲线(-n
选项)并将每个字符保存在文件中fontname-pagenumber.svg
。
例如,如果我们想为linearA
字体创建 svg,我们可以调用以下脚本:
texlua fonttosvg.lua -s 3 LinearA
LinearA
tfm
如果包提供了文件名,-s
则使用选项来缩放 svg 文件。一些生成的字形:
答案2
除了 Michal 的解决方案之外,您还可以使用小命令行程序字体转SVG。这是一个用 C++ 编写的快速 hack。它将字体文件的路径作为参数,并为每个字形创建单独的 SVG 文件。例如,
font2svg /path/to/LinearA.pfb
创建文件LinearA-0001.svg
,...,LinearA-0178.svg
。
该程序适用于 FreeType 支持的所有矢量字体,并且不需要任何 TeX 文件。
答案3
FontForge可以将字形轮廓导出为 SVG 文件。
交互方式:打开字体,然后选择并打开字形。通过菜单项文件->导出将轮廓导出到 SVG。
如果安装了 Python 绑定,FontForge 也可以用 Python 编写脚本。以下脚本将字体的字形导出到 SVG 文件,其名称由字体名称、Unicode/编码编号和字形名称组成。
#!/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()