如何使我的PostScript程序显示Bravura字体中的G谱号字符?根据此SMuFL文档,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
答案 0 :(得分:2)
第一个问题是如何定义Bravura和Calibri。这些字体不是标准Ghostscript安装的一部分,因此必须以某种方式添加它们,可能通过fontconfig(在Linux上)进行添加,但是我看到您正在使用Windows(从路径名开始)。您如何添加字体?
现在(再次从上个频道消息中)您正在加载TrueType字体,并将它们用作丢失的PostScript字体的替代品。这是一项非标准功能,因此Ghostscript必须进行大量猜测才能尝试从TrueType字体创建Type 42字体(带有TrueType轮廓的PostScript字体)。尽管现在情况还不错,但不能保证它会做对。
顺便说一下,这与Unicode无关:-)
在PostScript中,您要为每个要显示的字符使用一个字符代码。在您的情况下,您已连续使用0x40(@)至0x4C(L)。渲染字形时,解释器获取字符代码,并在该位置查找“编码”。请注意,您的编码数组仅包含从0x41到0x47的条目,因此代码0x48到0x4C将是未定义的。
让我们考虑一下您的“文字字体”,即Calibri。在“编码”中的位置0x41,您具有字形名称“ Scaron”。因此,解释器然后查询字体的CharStrings字典。 CharStrings词典包含键/值对,键(在本例中为名称),值是定义如何呈现字形的可执行程序。
因此,解释器在CharStrings词典中查找名为/ Scaron的键,然后执行与其关联的程序。如果找不到键/ Scaron,则会查找键/.notdef(需要所有字体都必须具有.notdef),然后执行该键。
您实际上并没有说出要做什么。我假设存在问题,因为您已经发布了一个问题(该问题似乎没有包含任何实际问题...。),但您没有说它是什么。如果您得到的是空心矩形而不是期望的字形,那是因为解释程序正在执行/.notdef,对于TrueType字体,它通常是一个矩形(PostScript字体通常具有完全空白的.notdef,但是两种字体类型都可以包含它们想要)
在这种情况下,问题是您使用了CharStrings词典中不存在的字形名称(例如/ muscialnote)。除非TrueType字体具有POST表(大多数情况下没有),否则这并不奇怪,因为/ musicalnote是字形的非常不标准的名称。
如果我将Calibri添加到fontmap.GS,然后执行以下操作:
%!
/Calibri findfont /CharStrings get {== ==} forall
然后我看到很多表单:
0 / _6756 0 / _6689
这些将名称(例如/ _6576)映射到TrueType GID。使用TrueType字体时,Ghostscript需要GID,以便它可以从GLYF表中找到该字体中的字形程序。当定义TrueType字体用作类型42时,这是Ghostscript必须尝试自己创建的(此字典定义了真正的Type 42字体作为字体的一部分)。它是如何实现的是启发式的,即猜测很多。
在这种情况下,GID为0,这是.notdef字形的TrueType保留GID,因此这些名称都将映射到.notdef。
我还看到了许多条目,例如:
4 / A
这些(显然)是您可以使用的字形,在这种情况下,名称/ A映射到GID4。检查输出,没有名称'quarternote,'musicalnote'等。有一个Scaron,所以我期望您的'@'字符将呈现为带有重音符号的大写字母S。其余字形将呈现为空正方形,或完全不显示。这里的测试(有趣地)显示了一个带有问号的矩形。
现在,Calibri字体可能包含所需的字形,如果确实如此,那么恐怕访问它们的唯一方法(从PostScript)是识别Ghostscript与该字形关联的名称。 Bravura字体也是如此。
进行一些PostScript编程(似乎您胜任编写该文件)可以使您从字体中检索CharStrings字典,对其进行迭代,并构建一个包含所有非零名称的数组。值。然后,您可以打印一个页面(可能有很多页面),在该页面中您可以从字体中打印命名的字形,并在其下方打印与该字形关联的名称。有您的地图,现在您可以构建一个Encoding,将字形名称映射到要在PostScript程序中使用以绘制该字形的字符代码。
当我尝试使用Bravura(这是OpenType字体,而不是TrueType字体)时,FWIW在加载字体时出现语法错误。对于BravuraText也是如此。