尝试将简单的 UTF16 字符嵌入手动创建的 PDF 但失败

Trying to embed simple UTF16 character into manually created PDF but failing

我正在尝试手动创建 PDF 文档(使用 github 上的 PDFGen C 代码)。这是在存储空间有限的小型设备上。

一切正常,直到我想嵌入(比如说)Unicode 欧姆字符 (U+2126)。

下面是我正在使用的测试文件,应该 在 'H'.

之后显示带有欧姆符号的“Hello”

但是,实际上显示“H!&ello”。

%PDF-1.4
<hex chars removed>
1 0 obj
<< /Pages 2 0 R /Type /Catalog >>
endobj
2 0 obj
<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
endobj
3 0 obj
<< /Contents 4 0 R /MediaBox [ 0 0 500 800 ] /Parent 2 0 R /Resources 5 0 R /Type /Page >>
endobj
4 0 obj
<< /Length 57 >>
stream
BT /F1 24 Tf 175 720 Td <FEFF004821260065006C006C006F> Tj ET
endstream
endobj
5 0 obj
<< /Font << /F1 6 0 R >> >>
endobj
6 0 obj
<< /BaseFont /Courier /Subtype /Type1 /Type /Font >>
endobj
xref
0 7
0000000000 65535 f 
0000000015 00000 n 
0000000064 00000 n 
0000000123 00000 n 
0000000229 00000 n 
0000000335 00000 n 
0000000378 00000 n 
trailer << /Root 1 0 R /Size 7 /ID [<89311a609a751f1666063e6962e79bd5><89311a609a751f1666063e6962e79bd5>] >>
startxref
448
%%EOF

我只能假设我的 Unicode 十六进制字符串 <FEFF004821260065006C006C006F> 格式错误。

或者字体定义不正确?

或者我对如何嵌入 Unicode 的理解有误?

我最终不想 嵌入任何字体,因为我没有存储空间space 或处理能力。我只想添加 Unicode 字符并依靠 PDF 渲染器来计算如何使用默认的 Courier 字体显示它们。

这可能吗?

提前感谢任何help/advice/comments。

更新

经过以下一些有用的建议,我现在已经设法实现了我所需要的。

我修改了我的代码以在 Courier 和 Symbol 之间基于每个字符切换字体,现在支持(几乎)所有标准字符。

我还添加了一些字符缩放以保持 Symbol 字符与 Courier 字体对齐,但最终结果适合我:)

这是我的测试 PDF 的图像...

你做不到。

注意:您想插入一个 Unicode 字符(不是 UTF-16,它只是许多 representation/encoding Unicode 字符之一)。

没有字体包含所有字形,据我所知,只有少数 Latin-1 字体对于 PDF 是安全的(并且是必需的)。注意:此类字体需要 Latin-1 编码(与所有其他字体相反,对于“前 Unicode 时代”,这只是一个可移植性问题)。一个额外的问题。 Type1 使用字形索引,这可能与 Unicode 代码点不同(事实上,我认为它们总是不同的)。 IIRC Adob​​e 有一些关于此的文档。而type1也快要过时了,或许2021年的节目还是不要用它比较好。

您可能假设人们会使用 Microsoft Windows,因此您可以使用 Symbol 字体(并使用 Omega,而不是 Ohm,后者可能用相同的字形表示)。但在这种情况下,您正在创建“不可移植”的可移植文档格式 (PDF)。

奇怪的是,原始 PC IBM 437 代码集包含 Ω wiki note i [03A9] (234) 但没有送到 Courier ?? 您可以尝试将您需要的那几个字符编码为嵌入式子集符号字体,并且很可能使用 ascii(7bit) 或 ansi(8bit) 来实现,但是对于您的几个字符来说,开销将是巨大的。

更简单的尝试将字体(根据目标字符的要求)切换为 Symbol 字体,它可能看起来像这样

P.S。代码不需要是“单词”双打,只有 256 个字符。

    << /BaseFont /Symbol /Subtype /Type1 /Type /Font >>
    BT /F2 24 Tf 175 720 Td <4857657C7C6F20766FC27C64> Tj ET

通过交替使用快递和符号,您将获得您想要的

在您的代码中它可能类似于(包含转换)

BT
/F0 24 Tf 1 0 0 1 0 .0675 Tm (H) Tj
ET
BT
/F1 24 Tf 1 0 0 1 14.4 .0675 Tm <003a> Tj
ET
BT
/F0 24 Tf 1 0 0 1 32.832 .0675 Tm (ello) Tj
ET

请注意,我的编辑器使用 F0 表示 Courier,使用 F1 表示 Symbol(基数 0 更正常) 它还使用稍微不同的代码方法将 Omega 定义为 <003a>

我正在调整 Windows 记事本中的文本,以观察编译 (Ctrl+S) 如何移动 Omega 字符间距,同时在预览器中实时观察它横向滑动。还要注意 大写 Omega 在原始符号字体中是 W !!

所以我对您的代码的替换修复 看起来像这样(您可以通过删除白色 space 和换行轻松地使它看起来更接近您的,并且更精简)

%PDF-1.4
%µ¶

1 0 obj
<<
  /Pages 2 0 R
  /Type /Catalog
>>
endobj

2 0 obj
<<
  /Count 1
  /Kids [ 3 0 R ]
  /Type /Pages
>>
endobj

3 0 obj
<<
  /Contents 4 0 R
  /MediaBox [ 0 0 500 800 ]
  /Parent 2 0 R
  /Resources <<
    /Font <<
      /F1 5 0 R
      /F2 6 0 R
    >>
  >>
  /Type /Page
>>
endobj

4 0 obj
<<
  /Length 133
>>
stream
q
BT
/F1 24 Tf
1 0 0 1 175 720 Tm
(H) Tj
ET
BT
/F2 24 Tf
1 0 0 1 189 720 Tm
(W) Tj
ET
BT
/F1 24 Tf
1 0 0 1 206 720 Tm
(ello) Tj
ET
Q

endstream
endobj

5 0 obj
<<
  /BaseFont /Courier
  /Subtype /Type1
  /Type /Font
>>
endobj

6 0 obj
<<
  /BaseFont /Symbol
  /Subtype /Type1
  /Type /Font
>>
endobj

xref
0 7
0000000000 65536 f 
0000000016 00000 n 
0000000070 00000 n 
0000000136 00000 n 
0000000307 00000 n 
0000000494 00000 n 
0000000569 00000 n 

trailer
<<
  /Size 7
  /Root 1 0 R
  /ID [ <89311A609A751F1666063E6962E79BD5> <EE408A115072E92E3A34C8BB8BDC6AE6> ]
>>
startxref
643
%%EOF