mirror of
https://github.com/unidoc/unipdf.git
synced 2025-04-30 13:48:51 +08:00
122 lines
3.7 KiB
Go
122 lines
3.7 KiB
Go
/*
|
|
* This file is subject to the terms and conditions defined in
|
|
* file 'LICENSE.md', which is part of this source code package.
|
|
*/
|
|
|
|
package textencoding
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
|
|
"github.com/unidoc/unidoc/common"
|
|
"github.com/unidoc/unidoc/pdf/core"
|
|
)
|
|
|
|
// IdentityEncoder represents an 2-byte identity encoding
|
|
type IdentityEncoder struct {
|
|
baseName string
|
|
}
|
|
|
|
// NewIdentityTextEncoder returns a new IdentityEncoder based on predefined
|
|
// encoding `baseName` and difference map `differences`.
|
|
func NewIdentityTextEncoder(baseName string) IdentityEncoder {
|
|
return IdentityEncoder{baseName}
|
|
}
|
|
|
|
// String returns a string that describes `enc`.
|
|
func (enc IdentityEncoder) String() string {
|
|
return enc.baseName
|
|
}
|
|
|
|
// Encode converts the Go unicode string `raw` to a PDF encoded string.
|
|
func (enc IdentityEncoder) Encode(raw string) string {
|
|
// runes -> character codes -> bytes
|
|
var encoded bytes.Buffer
|
|
for _, r := range raw {
|
|
code, ok := enc.RuneToCharcode(r)
|
|
if !ok {
|
|
common.Log.Debug("Failed to map rune to charcode. rune=%+q", r)
|
|
continue
|
|
}
|
|
|
|
// Each entry represented by 2 bytes.
|
|
encoded.WriteByte(byte((code & 0xff00) >> 8))
|
|
encoded.WriteByte(byte(code & 0xff))
|
|
}
|
|
return encoded.String()
|
|
}
|
|
|
|
// CharcodeToGlyph returns the glyph name matching character code `code`.
|
|
// The bool return flag is true if there was a match, and false otherwise.
|
|
func (enc IdentityEncoder) CharcodeToGlyph(code uint16) (string, bool) {
|
|
r, found := enc.CharcodeToRune(code)
|
|
if found && r == 0x20 {
|
|
return "space", true
|
|
}
|
|
|
|
// Returns "uniXXXX" format where XXXX is the code in hex format.
|
|
glyph := fmt.Sprintf("uni%.4X", code)
|
|
return glyph, true
|
|
}
|
|
|
|
// GlyphToCharcode returns the character code matching glyph `glyph`.
|
|
// The bool return flag is true if there was a match, and false otherwise.
|
|
func (enc IdentityEncoder) GlyphToCharcode(glyph string) (uint16, 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(glyph, "uni%X", &unicode)
|
|
if n == 1 && err == nil {
|
|
return enc.RuneToCharcode(rune(unicode))
|
|
}
|
|
}
|
|
|
|
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 IdentityEncoder) RuneToCharcode(r rune) (uint16, bool) {
|
|
return uint16(r), 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 IdentityEncoder) CharcodeToRune(code uint16) (rune, bool) {
|
|
return rune(code), true
|
|
}
|
|
|
|
// RuneToGlyph returns the glyph name for rune `r`.
|
|
// The bool return flag is true if there was a match, and false otherwise.
|
|
func (enc IdentityEncoder) RuneToGlyph(r rune) (string, bool) {
|
|
if r == 0x20 {
|
|
return "space", true
|
|
}
|
|
glyph := fmt.Sprintf("uni%.4X", r)
|
|
return glyph, true
|
|
}
|
|
|
|
// GlyphToRune returns the rune corresponding to glyph name `glyph`.
|
|
// The bool return flag is true if there was a match, and false otherwise.
|
|
func (enc IdentityEncoder) GlyphToRune(glyph string) (rune, bool) {
|
|
// String with "uniXXXX" format where XXXX is the hexcode.
|
|
if len(glyph) == 7 && glyph[0:3] == "uni" {
|
|
unicode := uint16(0)
|
|
n, err := fmt.Sscanf(glyph, "uni%X", &unicode)
|
|
if n == 1 && err == nil {
|
|
return rune(unicode), true
|
|
}
|
|
}
|
|
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 IdentityEncoder) ToPdfObject() core.PdfObject {
|
|
if enc.baseName != "" {
|
|
return core.MakeName(enc.baseName)
|
|
}
|
|
return core.MakeNull()
|
|
}
|