1 Star 0 Fork 0

coodder / unipdf

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
truetype.go 4.12 KB
一键复制 编辑 原始数据 按行查看 历史
jhonm 提交于 2023-08-07 15:31 . init
package textencoding
import (
"fmt"
"sort"
"strings"
"gitee.com/coodder/unipdf/common"
"gitee.com/coodder/unipdf/core"
)
// GID is a glyph index.
type GID uint16
// TODO(dennwc): should not mix Identity-H CMap and Encoding in the same object
// TrueTypeFontEncoder handles text encoding for composite TrueType fonts.
// It performs mapping between character ids and glyph ids.
// It has a preloaded rune (unicode code point) to glyph index map that has been loaded from a font.
// Corresponds to Identity-H CMap and Identity encoding.
type TrueTypeFontEncoder struct {
runeToGIDMap map[rune]GID
}
// NewTrueTypeFontEncoder creates a new text encoder for TTF fonts with a runeToGlyphIndexMap that
// has been preloaded from the font file.
// The new instance is preloaded with a CMapIdentityH (Identity-H) CMap which maps 2-byte charcodes
// to CIDs (glyph index).
func NewTrueTypeFontEncoder(runeToGIDMap map[rune]GID) TrueTypeFontEncoder {
return TrueTypeFontEncoder{
runeToGIDMap: runeToGIDMap,
}
}
// ttEncoderMaxNumEntries is the maximum number of encoding entries shown in simpleEncoder.String().
const ttEncoderMaxNumEntries = 10
// String returns a string that describes `enc`.
func (enc TrueTypeFontEncoder) String() string {
parts := []string{
fmt.Sprintf("%d entries", len(enc.runeToGIDMap)),
}
runes := make([]rune, 0, len(enc.runeToGIDMap))
for r := range enc.runeToGIDMap {
runes = append(runes, r)
}
sort.Slice(runes, func(i, j int) bool {
return runes[i] < runes[j]
})
n := len(runes)
if n > ttEncoderMaxNumEntries {
n = ttEncoderMaxNumEntries
}
for i := 0; i < n; i++ {
r := runes[i]
parts = append(parts, fmt.Sprintf("%d=0x%02x: %q",
r, r, enc.runeToGIDMap[r]))
}
return fmt.Sprintf("TRUETYPE_ENCODER{%s}", strings.Join(parts, ", "))
}
// Encode converts the Go unicode string to a PDF encoded string.
func (enc TrueTypeFontEncoder) Encode(str string) []byte {
return encodeString16bit(enc, str)
}
// Decode converts PDF encoded string to a Go unicode string.
func (enc TrueTypeFontEncoder) Decode(raw []byte) string {
return decodeString16bit(enc, raw)
}
// GlyphToCharcode returns character code matching the glyph name `glyph`.
// The bool return flag is true if there was a match, and false otherwise.
func (enc TrueTypeFontEncoder) GlyphToCharcode(glyph GlyphName) (CharCode, bool) {
// String with "uniXXXX" format where XXXX is the hexcode.
if len(glyph) == 7 && glyph[0:3] == "uni" {
var unicode uint16
n, err := fmt.Sscanf(string(glyph), "uni%X", &unicode)
if n == 1 && err == nil {
return enc.RuneToCharcode(rune(unicode))
}
}
// Look in glyphlist.
if rune, found := glyphlistGlyphToRuneMap[glyph]; found {
return enc.RuneToCharcode(rune)
}
common.Log.Debug("Symbol encoding error: unable to find glyph->charcode entry (%s)", glyph)
return 0, false
}
// RuneToCharcode converts rune `r` to a PDF character code.
// The bool return flag is true if there was a match, and false otherwise.
func (enc TrueTypeFontEncoder) RuneToCharcode(r rune) (CharCode, bool) {
glyphIndex, ok := enc.runeToGIDMap[r]
if !ok {
common.Log.Debug("Missing rune %d (%+q) from encoding", r, r)
return 0, false
}
// Identity : charcode <-> glyphIndex
// TODO(dennwc): Here charcode is probably the same as CID.
// TODO(dennwc): Find out what are the alternative mappings (enc.cmap?).
charcode := CharCode(glyphIndex)
return charcode, true
}
// CharcodeToRune converts PDF character code `code` to a rune.
// The bool return flag is true if there was a match, and false otherwise.
func (enc TrueTypeFontEncoder) CharcodeToRune(code CharCode) (rune, bool) {
// TODO: Make a reverse map stored.
for r, gid := range enc.runeToGIDMap {
// Identity : glyphIndex <-> charcode
charcode := CharCode(gid)
if charcode == code {
return r, true
}
}
common.Log.Debug("CharcodeToRune: No match. code=0x%04x enc=%s", code, enc)
return 0, false
}
// ToPdfObject returns a nil as it is not truly a PDF object and should not be attempted to store in file.
func (enc TrueTypeFontEncoder) ToPdfObject() core.PdfObject {
// TODO(dennwc): reasonable question: why it have to implement this interface then?
return core.MakeNull()
}
Go
1
https://gitee.com/coodder/unipdf.git
git@gitee.com:coodder/unipdf.git
coodder
unipdf
unipdf
v1.2.0

搜索帮助