1

我设法创建了一段从 PDF 文件中提取嵌入字体的 C# 代码。我正在使用嵌入了 TrueType 字体的文档对其进行测试。

问题是当我将字体字节写入文件时,我无法用任何字体查看器打开它,因为它似乎已损坏

有趣的是,代码似乎相当不错,因为执行MuPDF mutool.exe extract我得到了完全相同的文件和相同的结果(损坏的 .ttf 文件)。

这是代码(对不起,它很大,但到目前为止我没有找到更短的方法来实现这一点):

public void ExtractFonts(PdfReader reader, PdfParserDocument document)
{
    foreach (var fontData in BaseFont.GetDocumentFonts(reader))
    {
        // Get font name and indirect reference
        var name = (string)fontData[0];
        var reference = (PRIndirectReference)fontData[1];

        // Get font bytes from PDF
        var XrefIndex = Convert.ToInt32(reference.Number.ToString(System.Globalization.CultureInfo.InvariantCulture));
        var fontDictionary = (PdfDictionary)reader.GetPdfObject(XrefIndex);
        var fontDescriptor = fontDictionary.GetAsDict(PdfName.FONTDESCRIPTOR);

        PRIndirectReference fontBytesReference = null;

        if (fontDescriptor != null)
        {
            if (fontDescriptor.Get(PdfName.FONTFILE) != null)
            {
                fontBytesReference = (PRIndirectReference)fontDescriptor.Get(PdfName.FONTFILE);
            }
            else if (fontDescriptor.Get(PdfName.FONTFILE2) != null)
            {
                fontBytesReference = (PRIndirectReference)fontDescriptor.Get(PdfName.FONTFILE2);
            }
            else if (fontDescriptor.Get(PdfName.FONTFILE3) != null)
            {
                fontBytesReference = (PRIndirectReference)fontDescriptor.Get(PdfName.FONTFILE3);
            }
        }

        // Only add embedded fonts
        if (fontBytesReference != null)
        {
            var fontBytesReferenceIndex = Convert.ToInt32(fontBytesReference.Number.ToString(System.Globalization.CultureInfo.InvariantCulture));
            var pdfObject = reader.GetPdfObject(fontBytesReferenceIndex);
            var pdfStream = (PdfStream)pdfObject;
            var bytes = PdfReader.FlateDecode(PdfReader.GetStreamBytesRaw((PRStream)pdfStream));

            // Write to file
            using (var file = File.OpenWrite(name + ".ttf"))
            {
                file.Write(bytes, 0, bytes.Length);
            }
        }
    }
}
4

0 回答 0