如何在Matlab R2013a中使字体可用于LaTeX解释器?

13

通过将text属性的 'Interpreter' 值设置为 'latex',可以将LaTeX格式的文本和方程式嵌入到Matlab图中。

text(0.1, 0.5, 'Einstein: $E = m c^2$', ...
    'Interpreter', 'latex', 'FontSize', 32)

这些方程式会显示在屏幕上,并导出为eps文件的插图。

通过适当的LaTeX命令,还可以将字体从默认的Computer Modern Serif更改为例如Computer Modern Typewriter。

text(0.1, 0.5, '\fontfamily{cmtt}\selectfont Einstein: $E = m c^2$', ...
    'Interpreter', 'latex', 'FontSize', 32)

我的问题是:是否可以将其他字体插入Matlab安装程序中,使这些字体可用于“解释器”“latex”,在屏幕上呈现和生成eps文件?如果可以,怎么做?

背景

(所有路径均相对于我Linux系统上的Matlab安装程序/opt/MATLAB/R2013a。)

Matlab包括定制版本的(La)TeX解释器。它通过位于toolbox/matlab/graphics下的前端m文件tex.m被调用,该文件以LaTeX代码为参数并返回其输出参数中的dvi数据。 定制的LaTeX安装位于sys/tex中,并包括sys/tex/tfm下的TeX字体度量文件。

我没有关于渲染此dvi的Matlab部分的任何信息。但是,用于呈现的字体数据在sys/fonts/ttfsys/fonts/type1下。

因此,使附加字体可用包括两个部分:使其对LaTeX解释器可用,以及使其对渲染函数可用。第一部分可以通过操纵tex.m来处理,从而使其通过独立的常规LaTeX安装程序生成dvi,并以通常的方式安装字体(例如字体包)到此LaTeX中。请参见undocumentedmatlab

因此,问题的第二部分是至关重要的:如何将其他字体插入sys/fonts/ttfsys/fonts/type1,使它们可被Matlab的dvi渲染器组件使用。

具体案例

我尝试为特殊情况具体解决第二个问题:通过tex/tfm/cmss10.tfm,计算机现代无衬线字体包含在Matlab-LaTeX安装程序中,但对应的ttf和pfb文件丢失于sys/fonts中,因此未能呈现。

Matlab的ttf文件集似乎没有任何清单。因此,我将cmss10.ttf文件从matplotlib的安装程序复制到sys/fonts/ttf/cm/mwa_cmss10.ttf,遵循其他文件的命名约定。根据报道,这个过程在Max OS X上的Matlab 2011b上在Alec's Web Log上运行正常,但在我的系统上没有效果,无论是屏幕显示还是eps导出。

Matlab的type1字体集具有复杂的清单,分布在文件fonts.dirfonts.scaleencodings.dir和一个包含enc文件的文件夹encodings中。再次找到了cmss10.pfb,这次来自TeXlive安装,并将其重命名并复制,然后根据其他列出的字体的示例,在库存文件中进行了条目。同样,这个过程根本没有效果。

是否有人知道更多关于Matlab如何使用ttf和pfb文件,并可以给我一些提示,以使cmss10文件可用于Matlab渲染?或者是否有人建议如何调试此问题,并了解Matlab的LaTeX支持的


关于 OS X 博客,Matlab Solution 1-1432GA 可能是相关的。 - StrongBad
3个回答

5
我投入了数小时的研究来解决我的问题,得出了一些有趣的新见解,但没有真正的解决方案。不过,我在这里发布我的结果,以便其他可能进行研究的人可以从此开始。我将其作为一个“答案”发布,而不是使我的问题变得更长。

Matlab旧版(R2010a)和当前版(R2013a)texfonts基础设施的比较

对于标准字体Computer Modern Roman,旧的基础设施包含:

sys/tex/tfm/cmr10.tfm
sys/fonts/ttf/cm/cmr10.ttf
sys/fonts/type1/cm/cmr10.pfb
sys/fonts/type1/cm/cmr10.pfm

和当前

sys/tex/tfm/cmr10.tfm
sys/fonts/ttf/cm/mwa_cmr10.ttf
sys/fonts/ttf/cm/mwb_cmr10.ttf
sys/fonts/type1/cm/mwa_cmr10.pfb
sys/fonts/type1/cm/mwb_cmr10.pfb

TeX字体度量文件是相同的。TrueType和Type1文件似乎包含相同的字形数据,但已分成包含拉丁字符(mwa)和希腊字符(mwb)的文件。pfm文件已经消失了。旧的Type1文件具有AMS 1997版权声明,新的文件则由MW 2011版权声明。
这表明为了使旧Matlab中的Computer Modern Sans在当前Matlab中工作,只需复制cmss10.ttf和cmss10.pfb到mwa_cmss10.ttf和mwa_cmss10.pfb,因为tfm文件仍然存在(参见问题)。
R2013a使用哪些文件?
sys / fonts / type1中的附加dir和enc文件似乎未被使用,因为删除它们后屏幕呈现和eps生成功能完全正常。
我怀疑ttf文件用于屏幕渲染,而pfb文件用于生成eps文件。前者似乎并非如此,因为删除所有ttf文件后,屏幕渲染和eps生成仍然正常运行。然而,如果文件夹sys/fonts/ttf/cm不存在,Matlab会发出警告!这表明a)不必费心修改dir和enc文件,b)不必复制ttf文件。
插入新的pfb文件就足够了吗?将旧版本Matlab中的cmss10.pfb复制到sys/fonts/type1/cm/mwa_cmss10.pfb后,在方程中使用Computer Modern Sans仍然会导致Matlab警告"cmss10不受支持",屏幕渲染也不正确。此外,生成的eps文件无法正确呈现。
然而,生成的eps文件包含了文件的内容,它不能正常工作的原因是包含的pfb文件定义了一个名为“CMSS10”的字体,而eps引用了一个名为“mwa_cmss10”的字体。可以编辑< mwa_cmss10.pfb >文件并将其<\ FontName>更改为"mwa_cmss10",而不是@Daniel E. Shub的解决方案来更改eps中的引用。可以使用应用于pfb的简单文本编辑器完成此操作。然而,更好的方法是使用t1disasm将pfb文件分解为PostScript,更改PostScript,然后使用t1asm重新组合。这些工具包含在CTAN上的t1utils软件包中。
但是生成的eps仍然无法正常工作:字符位置不正确,特别是对于较大的字体大小。
这表明仅有pfb文件的存在并不能为Matlab提供正确的字体度量,而由Matlab的LaTeX生成的dvi文件并没有明确地定位字符,而是依赖于渲染器具有这些度量。

请参见tex.se,其中提供了有关第二点解决方法的问题。

“黑客”现有字体是否可行?

Daniel E. Shub在他的答案中建议不要添加字体,而是覆盖Matlab安装中已有的字体。这样做存在两个问题:

- Matlab仍然无法使用正确的字体度量。因此,如果原始字体和新字体的度量相似,则覆盖字体只能近似地工作。

例如:
enter image description here

- 屏幕渲染仅在某些情况下有效。对于我来说,使用修补的cmss10覆盖mwa_cmr10并使用\rm确实导致计算机现代无衬线字体在屏幕上和eps文件中呈现,尽管位置略有偏差。但是,覆盖mwa_cmtt10并使用\tt并没有导致计算机现代无衬线字体在屏幕上呈现;相反,计算机现代打字机字体被呈现。

这意味着a) Matlab的渲染器还有另一个独立的字体度量源。据我所知,它们并不来自sys/texsys/fonts文件中的任何一个文件。b) 字体轮廓只在某些情况下从sys/fonts/type1/cm中的pfb文件中读取。

结论

因此,最近Matlab的dvi渲染器的内部工作仍然是神秘的。缺失信息可能隐藏在toolbox/matlab/graphics/hardcopy.p和/或java/jar/hg.jar中的com/mathworks/hg/uij/TextRasterizer.class中。

我暂时停止调查(并去看一下psfrag ;)。


我非常确定dvi文件的度量标准不正确,因为您没有更改tfm文件。您尝试过将cmms10.tfm重命名为cmr10.tfm吗?我猜测这个问题与从cmr10.tfm更改名称为mwa_cmr10.pfb有关。 - StrongBad
你说得对,“黑客”解决方案正常工作需要修改cmr10.tfm文件。但我已经做到了(包括在tfm文件中修补字体名称),但是度量仍然出错。我仍然相信Matlab渲染器使用的还有另一个独立的字体度量来源。 - A. Donda

3
我在Undocumented Matlab 的评论区中提到了您所参考的问题。很明显,我严重低估了使用字体让Matlab DVI浏览器正常工作的难度。我提供了一个不能工作的解决方案,希望有人能了解它所生成的警告。我还有一个能够工作但不太优秀的解决方案。我使用的是Linux上的Matlab R2013a和TexLive 2013,我不确定在Mac或Windows上会发生什么。

不能工作的解决方案

我的第一个尝试是重载Matlab tex.m函数,这样我就可以轻松地在LaTeX中处理并且只需要担心dvi文件。

function [dviout,errout,auxout] = tex(varargin)
    fid = fopen('matlab.dvi');
    dviout = fread(fid, 'uint8');
    dviout = uint8(dviout);
    fclose(fid);
    errout = [];
    auxout = [];
end

我接着通过处理创建了matlab.dvi

\documentclass{article}
\setlength\topmargin{-0.5in}
\setlength\oddsidemargin{0in}
\DeclareFontFamily{T1}{myfont}{}
\DeclareFontShape{T1}{myfont}{m}{n}{<-> [1.2] AuriocusKalligraphicus}{}
\begin{document}%
\setbox0=\hbox{\usefont{T1}{myfont}{m}{n}Some text with a distinct font $\alpha$}%
\copy0\special{bounds: \the\wd0 \the\ht0 \the\dp0}%
\end{document}%

我将TexLive字体复制到Matlab中。
# cp $TEXLIVEROOT/texmf-dist/fonts/type1/public/aurical/AuriocusKalligraphicus.pfb $MATLABROOT/sys/fonts/AuriocusKalligraphicus.pfb

我从中得到了“预期”的警告

>> text(0.0, 0.5, 'DOES NOT MATTER', 'Interpreter', 'LaTeX', 'FontSize', 20)
Warning: Font AuriocusKalligraphicus10 is not supported. 
Warning: Font AuriocusKalligraphicus10 is not supported. 

如果我尝试通过alt+falt+r将图像(缺少字体)导出为pdf文件,则会出现一堆警告,包括可能有用的警告:

警告:缺失 /usr/local/matlab/R2013a/sys/fonts/type1/cm/mwa_auriocuskalligraphicus10.pfb

有效的解决方法

由于不知道如何调用pfb文件,我决定覆盖一个已经可用的(cmr10)。

在CLI中:

# cp $MATLABROOT/sys/fonts/mwa_cmr10.pfb $MATLABROOT/sys/fonts/mwa_cmr10.pfb.bak
# cp $TEXLIVEROOT/texmf-dist/fonts/type1/public/aurical/AuriocusKalligraphicus.pfb $MATLABROOT/sys/fonts/mwa_cmr10.pfb

并在Matlab提示符处

>> text(0.0, 0.5, 'Some text with a distinct font $\alpha$', 'Interpreter', 'LaTeX', 'FontSize', 20)

给我

Matlab图形.

为了将该图导出为带有字体的eps文件,您需要在eps文件中将所有/mwa_cmr10的实例替换为/AuriocusKalligraphicus。这可能是因为此解决方案是一种hack方法。理想情况下,不仅应该替换pfb文件,还应该替换fdtfm文件。可能有足够的pfb字体可用于创建大多数图形。


嗨,Daniel,有意思的材料。我从来没有遇到过关于缺少pfb文件的警告。你有试过把字体放在文件夹cm中的mwa_auriocuskalligraphicus10.pfb文件中吗? - A. Donda
@A.Donda 是的,这样可以消除警告,但这还不够。我认为你不能只是重命名字体文件。 - StrongBad
丹尼尔,我找到了一些更多的东西,但是它没有导致解决方案。请看我的“答案”。 - A. Donda

0

这是一个非常简单的解决方案,但您可以使用文本编辑器编辑生成的 .eps 文件并获取所需的字体。例如,您可以将以下内容替换为:

%%IncludeResource: font mwa_cmr10 /mwa_cmr10 /WindowsLatin1Encoding 120 FMSR

替换为以下内容:

%%IncludeResource: font Helvetica /Helvetica /WindowsLatin1Encoding 120 FMSR

您甚至可以编写一个简单的脚本,打开生成的 .eps 文件并将任何字体替换为您想要的字体。希望这能帮到您!


谢谢,但这假设字体度量匹配于Matlab使用的字体和替换它的字体之间,是吗?否则结果可能会像我回答中的图像一样。 - A. Donda
1
如果您需要像字母上的点这样的特殊字符,那么将字体更改为像Helvetica这样的其他字体将无法得到您想要的结果。但是,在您的E = mc ^ 2示例中,您可以将所有字符更改为Helvetica。在我的情况下,我正在尝试撰写一篇将提交给Elsevier期刊的论文。在他们的网站上,他们说字体类型应该限制在他们的五种字体列表(包括Helvetica)尽可能使用。对于特殊字符,简单地不可能实现,我会保留它们。对于其余部分,我应用了我提到的技巧。 - mugurg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接