为了在PDF中嵌入字体,需要确定一组字形宽度(包含在元数据中)。为了在文本流动时对文本消耗的页面区域进行计算,需要知道相同的信息。
我正在考虑在Web服务器上使用C#来生成PDF文档。字体不是(也不是)安装的;它们可以从TTF文件/流加载。我需要知道"页面中有多少"将被用于正确处理文本溢出,并且如果要嵌入字体,还需要提供字形宽度。
System.Drawing.Text.PrivateFontCollection
可以获得"单元格的上升/下降和行间距,这对垂直计算很有用,但我还需要进行水平计算。
有没有办法从C#访问私有(即未安装)字体的字形宽度而不诉诸于此: How to get glyph widths by parsing a TTF font file?
答案 0 :(得分:2)
System.Windows.Media(PresentationCore.dll)中的GlyphTypeface类提供了对em的分数的提前宽度的访问。 PDF字体描述符要求宽度为整数千分之一的整数。
using System;
using System.Windows.Media; // requires PresentationCore.dll
namespace ConsoleAppFontMetrics
{
internal class Metrics
{
internal static void PrintWidths(string path)
{
var ffs = Fonts.GetFontFamilies(path);
foreach (var ff in ffs)
{
foreach (var t in ff.GetTypefaces())
{
Console.WriteLine(t.Style);
if (t.TryGetGlyphTypeface(out GlyphTypeface gt))
{
foreach (var ctg in gt.CharacterToGlyphMap)
{
var width = (int)Math.Round(gt.AdvanceWidths[ctg.Value] * 1000);
Console.WriteLine($"{(char)ctg.Key} ({ctg.Key}) Width = {width}");
}
}
}
}
}
}
}
为我的TrueType字体运行上面的代码给了我:
Normal
a (97) Width = 1160
b (98) Width = 1663
c (99) Width = 2065
输出与先前导出的PDF(来自其他程序)内嵌的字体中的元数据匹配。
8 0 obj
<<
/Type/Font
/Subtype/TrueType
/Name/F2
/BaseFont/XXXXXX
/FontDescriptor 7 0 R
/FirstChar 97
/LastChar 99
/Widths[1160 1663 2065]
>>
endobj