2

I am working on generation of PDF on the fly tool, with custom chosen local font. Embeeding the font is not a problem, and been proven that font been found w/o problem. However, the font is Chinese, and so the text string to appear is Chinese.

My content stream of a page looks like this:

2.835 0 0 2.835 0 0 cm
BT
/F1 12.000 Tf
15.000 TL
50 350 Td
(?氊) Tj
ET

The "Tj" line has actually a BOM (fe ff) and a single Chinese character: "高" (just for test) encoded as UTF-16BE (9a d8).

The Font object I am using:

7 0 obj
<<
/Type /Font
/Subtype /TrueType
/BaseFont /MicrosoftYaHei
>>
endobj

"/F1" also point to that Font Object in Page Resources. I've tried many things like "encoding", or mapping, I prefer to no go complicated and load "Cmap" from the font, also I understand I don't need to load it if the program could find the font. After trying many things, I got to conclusion that I have encoding problem in my content stream, as the PDF consumer app treating the string byte by byte and no multi-byte recognition.

The question here: How do I force the PDF to treat my string (the only string, and not the whole content stream) to be read as UTF-16BE? What is the settings I need to use in my Font object (or Font Decriptor) to achieve this?

Sample PDF file available here

2 Answers 2

1

You should not mix 8 bit and 16 bit characters in the same group. I have seen it work with some vey few character cases but it very unreliable expecting readers to cope.

We can combine various fonts in various ways for some readers but Acrobat Reader will often complain and attempt to edit the file making matters worse.

enter image description here

When you need to use a single UTF-16 character it is best to use all as 16 bit or use 2 different font groups Note (8 bit syntax) <16 bi t UT F sy nt ax> NO BOM which is only normally only used for AcroForm Fields (FDF).

The structure needs to be changed much for combining character types, also note the need to start using Unicode substitution so that font requires a later CMAP

4 0 obj<</Length 110>>
stream
q 1 0 0 1 50 200 cm BT
/F0 24 Tf 1 0 0 1 0 0 Tm
[(Hello world )] TJ
/F1 24 Tf 1 0 0 1 125 0 Tm
<45f5> Tj
ET
Q

CMAP

endcodespacerange
1 beginbfchar
<45F5> <6C0A>
endbfchar

SO the 45F5 is simply an ID it does not reflect the character seen if I change the map to <45F5> <9AD8> we get your desired " UTF-16BE (9a d8)". enter image description here

Answer

For this one character we need a file about 25 KB larger to carry that single imbedded character font. Temporary copy here https://filetransfer.io/data-package/TEY8uEhI#link
enter image description here

...........prior content as before
5 0 obj
<</Length 73>>
stream
2.835 0 0 2.835 0 0 cm
BT
/F1 12.000 Tf
15.000 TL
50 350 Td
<0be4> Tj
ET

endstream
endobj

6 0 obj
<</Type/Page/Parent 3 0 R/Resources 4 0 R/Contents 5 0 R>>
endobj

7 0 obj
<</BaseFont/ABCDEF+MicrosoftYaHei/DescendantFonts[<</BaseFont/ABCDEF+MicrosoftYaHei/CIDSystemInfo<</Ordering(Identity)/Registry(0)/Supplement 0>>/FontDescriptor 8 0 R/Subtype/CIDFontType2/Type/Font>>]/Encoding/Identity-H/Subtype/Type0/ToUnicode 9 0 R/Type/Font>>
endobj

8 0 obj
<</Ascent 1058/CapHeight 756/Descent -262/Flags 32/FontBBox[-158 -255 1270 1036]/FontFamily(MicrosoftYaHei)/FontFile2 10 0 R/FontName/ABCDEF+MicrosoftYaHei/FontWeight 400/ItalicAngle 0/StemV 0/Type/FontDescriptor>>
endobj

9 0 obj
<</Length 344>>
stream
/CIDInit /ProcSet findresource begin
12 dict begin
begincmap
/CIDSystemInfo
<<
/Registry (0)
/Ordering (Identity0)
/Supplement 0
>>
def
/CMapName /ABCDEF+MicrosoftYaHei def
/CMapType 2 def
1 begincodespacerange
<0000> <FFFF>
endcodespacerange
1 beginbfchar
<0BE4> <9AD8>
endbfchar
endcmap
CMapName currentdict /CMap defineresource pop
end
end


endstream
endobj

10 0 obj
<</Length1 23560/Length 23560>>
stream

..............................binary data

endstream
endobj

xref
0 11
...................etc.
2
  • Strange: But when I import the PDF to Illustrator, there is no character appears at all..... (Possibly due to mistakenly looking for the glyph unicode "0BE4", I have no clue about it yet) Also: The ID you gave (0BE4) is not accidental ("Just ID" as been said earlier), I believe it has something to do with the Font CMap, something I will have to research. It is known that the format of Illustrator is similar to PDF, and my tool actually can save it as *.ai file, then I see the BIG difference in output....
    – Xerix
    May 17 at 5:25
  • Illustrator issue - Solved. I had a small mistake.
    – Xerix
    May 17 at 6:00
0

Per the standard, 9.4.3 "Text Showing Operators":

"A string operand of a text-showing operator shall be interpreted as a sequence of character codes identifying the glyphs to be painted."

"With a simple font, each byte of the string shall be treated as a separate character code. The character code shall then be looked up in the font’s encoding to select the glyph, as described in 9.6.5, "Character encoding""

"With a composite font (PDF 1.2), multiple-byte codes may be used to select glyphs. In this instance, one or more consecutive bytes of the string shall be treated as a single character code. The code lengths and the mappings from codes to glyphs are defined in a data structure called a CMap, described in 9.7, "Composite fonts""

So, this is more complicated that you think - the string given to Tj is not a Unicode string at all. You will need provide a proper encoding for the font. Also, embed the font file in the PDF - don't rely on the PDF viewer to try to find it on your system - what you're trying to do will be hard enough without that hurdle.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .