在下面的代码中(基于以前由Chris Haas提供的代码),我正在阅读现有文档中的字体。使用此方法,我可以在现有文档的其他位置重用这些字体对象。但是,现在我想使用这种方法来阅读文档" A"中的字体,并在我创建全新文档" B"时嵌入它们。可以这样做吗?
这里的BaseFont.CreateFont方法将PRindirectReference作为参数,这使我无法指定" BaseFont.EMBEDDED"作为参数,可以在方法的重载版本中看到,其中已知字体的特定路径。
internal static HybridDictionary findAllFonts(PdfReader reader)
{
HybridDictionary fd = new HybridDictionary();
//Get the document's acroform dictionary
PdfDictionary acroForm = (PdfDictionary)PdfReader.GetPdfObject(reader.Catalog.Get(PdfName.ACROFORM));
//Bail if there isn't one
if (acroForm == null)
{
return null;
}
//Get the resource dictionary
var DR = acroForm.GetAsDict(PdfName.DR);
//Get the font dictionary (required per spec)
var fontDict = DR.GetAsDict(PdfName.FONT);
foreach (var internalFontName in fontDict.Keys)
{
var internalFontDict = (PdfDictionary)PdfReader.GetPdfObject(fontDict.Get(internalFontName));
var baseFontName = (PdfName)PdfReader.GetPdfObject(internalFontDict.Get(PdfName.BASEFONT));
//Console.WriteLine(baseFontName.ToString().Substring(1, baseFontName.ToString().Length - 1));
var iRef = (PRIndirectReference)fontDict.GetAsIndirectObject(internalFontName);
if (iRef != null)
{
fd.Add(baseFontName.ToString().Substring(1, baseFontName.ToString().Length - 1).ToLower(),
BaseFont.CreateFont(iRef));
}
}
return fd;
}
答案 0 :(得分:0)
这并不总是可行的,因为通常字体不是完全嵌入。相反,你将拥有该字体的子集。一个子集中存在的字形可能不存在于另一个子集中。
此外,您将面临编码问题:假设您有一个文档,其中Arial用作希腊字形的简单字体。在这种情况下,如果要在另一个文档中使用Arial来呈现俄语文本或使用Latin-1中的文本,则最多可以重复使用256个字符。
即使您使用Unicode,您仍然会遇到问题,因为没有一种字体包含所有Unicode字符。 Unicode中有1,114,112个代码点,而复合字体中的字符标识符只能是0到65,535之间的数字......
您应该放弃重用现有文档中存在的字体来创建新文档的想法。一方面,它闻起来像你试图做一些非法的事情(你没有使用实际字体的许可)。在另一方面,你的问题听起来像:我有胡萝卜汤,请告诉我如何从汤中提取原始胡萝卜,以便我可以将它们重新用于其他目的。如果你仍然能在汤中找到大块的胡萝卜,你可能会得到一些结果,但在大多数情况下,你会失败。
例如:如果你有一个完全嵌入的基本Type 1字体,你应该能够复制字体描述符的所有基本元素,但是只要你面对存储字体子集的现代方式在PDF中,你会发现你正在尝试做一些根本不可能的事情。