forked from signintech/gopdf
/
unicode_map.go
90 lines (76 loc) · 2.15 KB
/
unicode_map.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package gopdf
import (
"bytes"
"fmt"
)
type UnicodeMap struct {
buffer bytes.Buffer
PtrToSubsetFontObj *SubsetFontObj
}
func (u *UnicodeMap) init(funcGetRoot func() *GoPdf) {}
func (u *UnicodeMap) SetPtrToSubsetFontObj(ptr *SubsetFontObj) {
u.PtrToSubsetFontObj = ptr
}
func (u *UnicodeMap) build() error {
u.buffer.Write(u.pdfToUnicodeMap().Bytes())
return nil
}
func (u *UnicodeMap) getType() string {
return "Unicode"
}
func (u *UnicodeMap) getObjBuff() *bytes.Buffer {
return &u.buffer
}
func (u *UnicodeMap) pdfToUnicodeMap() *bytes.Buffer {
//stream
characterToGlyphIndex := u.PtrToSubsetFontObj.CharacterToGlyphIndex
prefix :=
"/CIDInit /ProcSet findresource begin\n" +
"12 dict begin\n" +
"begincmap\n" +
"/CIDSystemInfo << /Registry (Adobe)/Ordering (UCS)/Supplement 0>> def\n" +
"/CMapName /Adobe-Identity-UCS def /CMapType 2 def\n"
suffix := "endcmap CMapName currentdict /CMap defineresource pop end end"
glyphIndexToCharacter := make(map[int]rune)
lowIndex := 65536
hiIndex := -1
for k, v := range characterToGlyphIndex {
index := int(v)
if index < lowIndex {
lowIndex = index
}
if index > hiIndex {
hiIndex = index
}
glyphIndexToCharacter[index] = k
}
var buff bytes.Buffer
buff.WriteString(prefix)
buff.WriteString("1 begincodespacerange\n")
buff.WriteString(fmt.Sprintf("<%04X><%04X>\n", lowIndex, hiIndex))
buff.WriteString("endcodespacerange\n")
buff.WriteString(fmt.Sprintf("%d beginbfrange\n", len(glyphIndexToCharacter)))
for k, v := range glyphIndexToCharacter {
buff.WriteString(fmt.Sprintf("<%04X><%04X><%04X>\n", k, k, v))
}
buff.WriteString("endbfrange\n")
buff.WriteString(suffix)
buff.WriteString("\n")
length := buff.Len()
var streambuff bytes.Buffer
streambuff.WriteString("<<\n")
streambuff.WriteString(fmt.Sprintf("/Length %d\n", length))
streambuff.WriteString(">>\n")
streambuff.WriteString("stream\n")
streambuff.Write(buff.Bytes())
streambuff.WriteString("endstream\n")
return &streambuff
}
//GetObjBuff get buffer
func (u *UnicodeMap) GetObjBuff() *bytes.Buffer {
return u.getObjBuff()
}
//Build build buffer
func (u *UnicodeMap) Build() error {
return u.build()
}