在 PostScript 中显示 Unicode 字符

2024-02-23

如何让我的 PostScript 程序显示 G 谱号字符Bravura https://github.com/steinbergmedia/bravura字体?根据这个SMuFL http://www.smufl.org/files/smufl-0.9.pdf根据记录,Bravura 中 G(高音)谱号的 Unicode 代码点是 U+E050(请参阅第 48 页谱号 (U+E050–U+E07F))。 PostScript 字形名称可能是 gClef(不确定)。

这是迄今为止我在页面上获取 unicode 字符的最佳尝试。我正在使用 GhostScript 9.25 生成 PDF。这是 GhostScript 的输出:

GPL Ghostscript 9.25 (2018-09-13)
Copyright (C) 2018 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Scanning C:/Windows/Fonts for fonts... 550 files, 358 scanned, 337 new fonts.
Can't find (or can't open) font file %rom%Resource/Font/Calibri.
Can't find (or can't open) font file Calibri.
Loading Calibri font from C:/Windows/Fonts/calibri.ttf... 8525920 7081126 4118548 2767358 1 done.
Can't find (or can't open) font file %rom%Resource/Font/BravuraText.
Can't find (or can't open) font file BravuraText.
Loading BravuraText font from C:/Windows/Fonts/BravuraText.otf... 9545496 7985907 8185868 6762307 1 done.
GPL Ghostscript 9.25: Can't embed the complete font BravuraText as it is too large, embedding a subset.
Main

这是最小的 PostScript 程序:

%!PS-Adobe-3.0
%%Title: unicode.ps
%%LanguageLevel: 3
%%EndComments


%%BeginProlog

userdict begin

%%EndProlog


%%BeginSetup

/mm { 25.4 div 72 mul } bind def
/A4Landscape [297 mm 210 mm] def
/PageSize //A4Landscape def
<< /PageSize PageSize >> setpagedevice


% ‘‘ReEncodeSmall’’ generates a new re-encoded font. It
% takes 3 arguments: the name of the font to be
% re-encoded, a new name, and an array of new character
% encoding and character name pairs (see the definition of
% the ‘‘scandvec’’ array below for the format of this
% array). This method has the advantage that it allows the
% user to make changes to an existing encoding vector
% without having to specify an entire new encoding
% vector. It also saves space when the character encoding
% and name pairs array is smaller than an entire encoding
% vector.

% Usage: /Times-Roman /Times-Roman-Scand scandvec new-font-encoding

/new-font-encoding { <<>> begin
    /newcodesandnames exch def
    /newfontname exch def
    /basefontname exch def

    /basefontdict basefontname findfont def     % Get the font dictionary on which to base the re-encoded version.
    /newfont basefontdict maxlength dict def    % Create a dictionary to hold the description for the re-encoded font.

    basefontdict 
        { exch dup /FID ne      % Copy all the entries in the base font dictionary to the new dictionary except for the FID field.
            { dup /Encoding eq
                { exch dup length array copy    % Make a copy of the Encoding field.
                    newfont 3 1 roll put }
                { exch newfont 3 1 roll put }
                ifelse
            }
            { pop pop }         % Ignore the FID pair.
            ifelse
        } forall

    newfont /FontName newfontname put   % Install the new name.
    newcodesandnames aload pop      % Modify the encoding vector. First load the new encoding and name pairs onto the operand stack.
    newcodesandnames length 2 idiv
        { newfont /Encoding get 3 1 roll put}
        repeat  % For each pair on the stack, put the new name into the designated position in the encoding vector. 
    newfontname newfont definefont pop      % Now make the re-encoded font description into a POSTSCRIPT font. Ignore the modified dictionary returned on the operand stack by the definefont operator.
end} def


/Calibri /TextFont [
    16#41   /Scaron     % A (/Scaron Š U+0160)
    16#42   /quarternote                % B U+2669
    16#43   /musicalnote                % C
    16#44   /eighthnotebeamed           % D
    16#45   /musicalnotedbl             % E
    16#46   /beamedsixteenthnotes       % F
    16#47   /musicflatsign              % G
    16#47   /musicsharpsign             % H U+266F
] new-font-encoding

% https://github.com/steinbergmedia/bravura
% The Unicode code point for a G (treble) clef in Bravura Text is U+E050
% http://www.smufl.org/files/smufl-0.9.pdf
% p48 Clefs (U+E050–U+E07F)
% U+E050 (and U+1D11E) gClef G clef 
% http://www.jdawiseman.com/papers/trivia/character-entities.html
/Bravura /MusicFont [
    16#41   /gClef                      % A
    16#42   /quarternote                % B U+2669
    16#43   /musicalnote                % C
    16#44   /eighthnotebeamed           % D
    16#45   /musicalnotedbl             % E
    16#46   /beamedsixteenthnotes       % F
    16#47   /musicflatsign              % G
    16#47   /musicsharpsign             % H U+266F
] new-font-encoding

/MusicFont findfont 48 scalefont setfont

%%EndSetup


%%BeginScript

%% Main
(Main\n) print
<<>>begin
    /TextFont findfont 48 scalefont setfont
    0 setgray
    72 72 moveto
    (@ABCDEFGHIJKL) show

    0 72 translate

    /MusicFont findfont 48 scalefont setfont
    0 setgray
    72 72 moveto
    (@ABCDEFGHIJKL) show
end
showpage

%%EndScript

%%Trailer
%%EOF

第一个问题是您如何定义 Bravura 和 Calibri。这些字体不是标准 Ghostscript 安装的一部分,因此必须以某种方式添加它们,可能通过 fontconfig(在 Linux 上),但我看到您使用的是 Windows(从路径名)。你是如何添加字体的?

现在您(再次从反向通道消息)加载 TrueType 字体并使用它们作为缺少的 PostScript 字体的替代品。这是一个非标准功能,因此 Ghostscript 必须进行大量猜测才能尝试从 TrueType 字体创建 Type 42 字体(具有 TrueType 轮廓的 PostScript 字体)。尽管现在已经相当不错了,但不能保证它会成功。

顺便说一句,这与 Unicode 无关:-)

在 PostScript 中,您对要显示的每个字符使用字符代码。在您的情况下,您连续使用了 0x40 (@) 到 0x4C (L)。渲染字形时,解释器获取字符代码,并查找该位置的编码。请注意,您的编码数组仅包含从 0x41 到 0x47 的条目,因此代码 0x48 到 0x4C 将是未定义的。

让我们考虑一下您的“TextFont”,即 Calibri。在编码中的位置 0x41 处,您有一个字形名称“Scaron”。因此解释器随后会查阅该字体的 CharStrings 字典。 CharStrings 字典包含键/值对,键(在本例中)是名称,值是定义如何呈现字形的可执行程序。

因此解释器在 CharStrings 字典中查找名为 /Scaron 的键,然后执行与其关联的程序。如果它找不到键 /Scaron,那么它会查找键 /.notdef(所有字体都是required有一个 .notdef) 并执行它。

你实际上还没有说出你要说什么。我假设存在问题,因为您已经发布了一个问题(似乎不包含任何实际问题......),但您还没有说出它是什么。如果您得到的是空心矩形而不是预期的字形,那么这是因为解释器正在执行 /.notdef,对于 TrueType 字体来说,它通常是一个矩形(PostScript 字体通常有一个完全空白的 .notdef,但是两种字体类型都可以有它们想要的任何内容)。想)

在这种情况下,问题是您使用的字形名称(例如 /muscialnote)在 CharStrings 字典中不存在。除非 TrueType 字体有 POST 表(大多数没有),否则这并不奇怪,因为 /musicalnote 是一个非常不标准的字形名称。

如果我将 Calibri 添加到 fontmap.GS 然后执行以下操作:

%!
/Calibri findfont /CharStrings get {== ==} forall

然后我看到many表格的条目:

0 /_6756 0 /_6689

这些将名称(例如 /_6576)映射到 TrueType GID。当使用 TrueType 字体时,Ghostscript 需要 GID,以便它可以从 GLYF 表中找到该字体中的字形程序。当定义用作 type 42 的 TrueType 字体时,这是 Ghostscript 必须尝试为自己创建的东西(真正的 Type 42 字体是使用此字典作为字体的一部分来定义的)。它如何实现这一点是启发式的,即它猜测很多。

在本例中,GID 为 0,这是 TrueType 为 .notdef 字形保留的 GID,因此这些名称将全部映射到 .notdef。

我还看到许多条目,例如:

4 /A

这些(显然)是您可以使用的字形,在本例中名称 /A 映射到 GID 4。检查输出,没有名称“quarternote”、“musicalnote”等。有一个 Scaron,所以我希望您的“@”字符将呈现为带抑扬音符号的大写 S。剩余的字形将呈现为空方块,或者根本不呈现。这里的测试显示(有趣的是)一个带有问号的矩形。

现在,Calibri 字体可能包含您想要的字形,如果确实如此,那么恐怕访问它们的唯一方法(从 PostScript)就是识别 Ghostscript 与字形关联的名称。 Bravura 字体也是如此。

一些 PostScript 编程(看起来您完全有能力编写这个)将允许您从字体中检索 CharStrings 字典,迭代它,并构建一个包含所有具有非零值的名称的数组。然后,您可以打印一页(可能是很多页),在其中打印字体的命名字形,并在其下方打印与该字形关联的名称。这就是您的映射,现在您可以构建一个编码,将字形名称映射到您想要在 PostScript 程序中用于绘制该字形的字符代码。

FWIW,当我尝试使用 Bravura(这是一种 OpenType 字体,而不是 TrueType 字体)时,我在加载字体时遇到语法错误。 BravuraText 也是如此。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 PostScript 中显示 Unicode 字符 的相关文章

随机推荐

  • 改造多个 POST 参数

    我正在尝试向需要 2 组信息的服务器提交调用 这是我的界面 POST venues get by location void getByLocation Body Coordinates coordinates Body MaxDistan
  • React-native:如何控制键盘向上推

    该应用程序的结构相当简单 底部有一个搜索栏 一个列表视图和react native tabs 问题 如果我点击 Android 上的搜索栏 它会将整个应用程序向上推 因此我可以直接在键盘上看到选项卡 但在 iOS 上 键盘覆盖了整个应用程序
  • 调用从 EDN 文件读取的函数

    我有一个 EDN 配置文件 其中的条目引用现有功能 例如 attribute modules content class lohan extractors content process schema class lohan extract
  • 查询超慢...我做错了什么?

    你们太棒了 在过去的几天里 我已经在这里发帖两次 作为一个新用户 我对这些帮助感到震惊 因此 我想我应该采用软件中最慢的查询 看看是否有人可以帮助我加快速度 我使用此查询作为视图 因此速度快很重要 但事实并非如此 首先 我有一个联系人表 用
  • 我们应该在数据库表命名约定中使用前缀吗?

    我们正在工作中的开发团队决定表 列 过程等的命名约定 单复数表命名已经决定了 我们使用单数 我们正在讨论是否为每个表名使用前缀 我想阅读有关是否使用前缀以及原因的建议 它是否提供任何安全性 至少为可能的入侵者多了一个障碍 我认为用前缀命名它
  • 通过 Python 在 Selenium 中使用 WebDriverWait for link_text “TypeError: 'str' object is not callable”

    这是我在 Stack Overflow 上的第一篇文章 我一直在浏览和搜索这个问题的每一个可能的答案 我想在这一点上我应该问一个问题 因为我已经在这堵墙上呆了好几天了 我目前正在使用 Python 中的 Selenium 开发一个网络抓取项
  • 强制编码风格[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 几年前 当我开始一个小型开发项目时 我和其他开发人员坐下来就折衷的大括号和缩进样式达成了一致 它不是任何人的最爱 但却是没有人真正讨厌的东西 我
  • 如何在 PHP 中查找单词组合

    我有一个数组 new array array c a m t p 现在我想找到单词表中存在的单词组合 我曾尝试实现但没有成功 这是我的 php 代码 words array set powerSet new array 2 mysql ne
  • Webstorm 关闭匿名函数声明中的新空格

    例如我有这个 exports getsertHexId function table hex Webstorm 8 的自动缩进在关键字之间创建空格function和开括号 其设置空间选项包括 函数声明括号 函数调用括号 如果 括号 很困惑
  • 如何定期唤醒我的应用程序

    我想在Android中做一个功能 比如提醒 我想在我的应用程序 活动未运行或者其 UI 不可见时启动它 它类似于提醒 在所需的时间唤醒应用程序 我没有使用过任何类型的后台任务或服务 所以我不知道该怎么办 或者我应该学习什么类型的课程或演示
  • 在 SQLite 中的 GROUP_CONCAT 函数中使用 ORDER BY 子句

    我不认为我可以使用ORDER BY里面的子句GROUP CONCAT功能 有谁知道一种棘手的方法来完成这种行为SQLite 我看到了这个question https stackoverflow com questions 1897352 s
  • 如何将由东北坐标和西南坐标组成的特定边界拟合到可见地图视图中?

    我需要在地图内适应特定的边界 我通过调用谷歌地理编码器并读取视口属性来获取边界 如下所示 northeast lat 30 4212235 lng 97 486942 southwest lat 30 1128403 lng 97 9991
  • 在加载的 ELF(.so 共享库)中挂钩并替换导出函数

    我正在编写一些 C 代码来将 so ELF 共享库 的某些函数加载到内存中 我的 C 代码应该能够重定向另一个加载到应用程序 程序内存中的 so 库的导出函数 这里有一些详细说明 Android 应用程序将加载多个 so 文件 我的 C 代
  • Google 登录:使用 google-auth Python 包时“未找到密钥 ID xxxx 的证书”

    我正在维护一个网站及其移动应用程序 iOS 和 Android 对于移动应用程序中的 Google 登录 我正在使用google auth Python 包 https github com googleapis google auth l
  • 知道任何体素图形 C++ 库吗? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 所以 我正在寻找带有 C 库 面向游戏 的体素图形引擎 只是为了好玩 这将是我第一次使用图形库 因此它不必非常复杂或强大 只需易于理解即可
  • 尽管allowtgtsessionkey注册表项无法检索TGT

    我正在尝试连接我们的 Windows 客户端应用程序以使用单点登录机制 我正在遵循可以找到的解释here http www javaactivedirectory com page id 196 我已经很难完成第一步 即获取登录用户的票证授
  • 尝试在构造函数中访问 @Inject bean 时出现 NullPointerException

    我有一个会话范围的 bean Named SessionScoped public class SessionBean implements Serializable private String someProperty public S
  • JTable更改列字体

    我正在制作一个表格 我想在其中制作具有更高字体大小的第一列 例如 在第 0 列中 我希望字体大小为 30 在第 1 3 列中 我希望字体大小为 13 这是我的代码 import java awt import java awt event
  • 当cmd以管理员身份运行时如何将输入发送到命令?

    我创建了一个将键盘输入发送到的应用程序cmd exe 这在运行时有效cmd作为普通用户但失败时cmd以管理员身份运行 这是我的代码 Var Wnd hwnd begin wnd FindWindow ConsoleWindowClass 0
  • 在 PostScript 中显示 Unicode 字符

    如何让我的 PostScript 程序显示 G 谱号字符Bravura https github com steinbergmedia bravura字体 根据这个SMuFL http www smufl org files smufl 0