From ca74ee87a1e81f3baf8519c6361c74212d06499d Mon Sep 17 00:00:00 2001 From: Gunnsteinn Hall Date: Sun, 9 Jul 2017 22:37:05 +0000 Subject: [PATCH] Add Symbol font encoder and test example case for symbol font use --- pdf/creator/creator_test.go | 35 +- pdf/model/fonts/afms/export_metrics.go | 158 ++++- pdf/model/fonts/symbol.go | 6 +- pdf/model/textencoding/symbol.go | 876 +++++++++++++++++++++++++ 4 files changed, 1067 insertions(+), 8 deletions(-) create mode 100644 pdf/model/textencoding/symbol.go diff --git a/pdf/creator/creator_test.go b/pdf/creator/creator_test.go index 38244859..e39cd5fd 100644 --- a/pdf/creator/creator_test.go +++ b/pdf/creator/creator_test.go @@ -19,10 +19,16 @@ import ( "github.com/boombuler/barcode" "github.com/boombuler/barcode/qr" + "github.com/unidoc/unidoc/common" "github.com/unidoc/unidoc/pdf/model" "github.com/unidoc/unidoc/pdf/model/fonts" + "github.com/unidoc/unidoc/pdf/model/textencoding" ) +func init() { + common.SetLogger(common.NewConsoleLogger(common.LogLevelDebug)) +} + const testPdfFile1 = "../../testfiles/minimal.pdf" const testPdfLoremIpsumFile = "../../testfiles/lorem.pdf" const testPdfTemplatesFile1 = "../../testfiles/templates1.pdf" @@ -314,10 +320,10 @@ func TestParagraphStandardFonts(t *testing.T) { "Helvetica-Bold", "Helvetica-BoldOblique", "Helvetica-Oblique", + "Times-Roman", "Times-Bold", "Times-BoldItalic", "Times-Italic", - "Times-Roman", "Symbol", "ZapfDingbats", } @@ -330,21 +336,44 @@ func TestParagraphStandardFonts(t *testing.T) { fonts.NewFontHelveticaBold(), fonts.NewFontHelveticaBoldOblique(), fonts.NewFontHelveticaOblique(), + fonts.NewFontTimesRoman(), fonts.NewFontTimesBold(), fonts.NewFontTimesBoldItalic(), fonts.NewFontTimesItalic(), - fonts.NewFontTimesRoman(), fonts.NewFontSymbol(), fonts.NewFontZapfDingbats(), } + texts := []string{ + "Courier: Lorem ipsum dolor sit amet, consectetur adipiscing elit...", + "Courier-Bold: Lorem ipsum dolor sit amet, consectetur adipiscing elit...", + "Courier-BoldOblique: Lorem ipsum dolor sit amet, consectetur adipiscing elit...", + "Courier-Oblique: Lorem ipsum dolor sit amet, consectetur adipiscing elit...", + + "Helvetica: Lorem ipsum dolor sit amet, consectetur adipiscing elit...", + "Helvetica-Bold: Lorem ipsum dolor sit amet, consectetur adipiscing elit...", + "Helvetica-BoldOblique: Lorem ipsum dolor sit amet, consectetur adipiscing elit...", + "Helvetica-Oblique: Lorem ipsum dolor sit amet, consectetur adipiscing elit...", + + "Times-Roman: Lorem ipsum dolor sit amet, consectetur adipiscing elit...", + "Times-Bold: Lorem ipsum dolor sit amet, consectetur adipiscing elit...", + "Times-BoldItalic: Lorem ipsum dolor sit amet, consectetur adipiscing elit...", + "Times-Italic: Lorem ipsum dolor sit amet, consectetur adipiscing elit...", + "\u2206\u0393\u0020\u2192\u0020\u0030", // Delta Gamma space arrowright space zero (demonstrate Symbol font) + "", + } for idx, font := range fonts { - p := NewParagraph(names[idx] + ": Lorem ipsum dolor sit amet, consectetur adipiscing elit...") + p := NewParagraph(texts[idx]) p.SetFont(font) p.SetFontSize(12) p.SetLineHeight(1.2) p.SetMargins(0, 0, 5, 0) + if names[idx] == "Symbol" { + // For symbol font, need to use Symbol Encoder. + p.SetEncoder(textencoding.NewSymbolEncoder()) + } + err := creator.Draw(p) if err != nil { t.Errorf("Fail: %v\n", err) diff --git a/pdf/model/fonts/afms/export_metrics.go b/pdf/model/fonts/afms/export_metrics.go index 35653ad6..d5be98e9 100644 --- a/pdf/model/fonts/afms/export_metrics.go +++ b/pdf/model/fonts/afms/export_metrics.go @@ -11,22 +11,50 @@ import ( "strconv" "strings" + "flag" + pdfcommon "github.com/unidoc/unidoc/common" "github.com/unidoc/unidoc/pdf/model/fonts" ) func main() { - if len(os.Args) < 2 { - fmt.Printf("Syntax: %s \n", os.Args[0]) + filepath := flag.String("file", "", "AFM input file") + method := flag.String("method", "charmetrics", "charmetrics/charcodes/glyph-to-charcode") + + flag.Parse() + + if len(*filepath) == 0 { + fmt.Println("Please specify an input file. Run with -h to get options.") return } - metrics, err := GetCharmetricsFromAfmFile(os.Args[1]) + var err error + switch *method { + case "charmetrics": + err = runCharmetricsOnFile(*filepath) + case "charcodes": + err = runCharcodeToGlyphRetrievalOnFile(*filepath) + case "glyph-to-charcode": + err = runGlyphToCharcodeRetrievalOnFile(*filepath) + } + if err != nil { fmt.Printf("Error: %v\n", err) os.Exit(1) } + // --charmetrics to get char metric data. + // --charcodes to get charcode to glyph data + +} + +// Generate a glyph to charmetrics (width and height) map. +func runCharmetricsOnFile(path string) error { + metrics, err := GetCharmetricsFromAfmFile(path) + if err != nil { + return err + } + keys := []string{} for key, _ := range metrics { keys = append(keys, key) @@ -39,6 +67,49 @@ func main() { fmt.Printf("\t\"%s\":\t{GlyphName:\"%s\", Wx:%f, Wy:%f},\n", key, metric.GlyphName, metric.Wx, metric.Wy) } fmt.Printf("}\n") + return nil +} + +func runCharcodeToGlyphRetrievalOnFile(afmpath string) error { + charcodeToGlyphMap, err := GetCharcodeToGlyphEncodingFromAfmFile(afmpath) + if err != nil { + return err + } + + keys := []int{} + for key, _ := range charcodeToGlyphMap { + keys = append(keys, int(key)) + } + sort.Ints(keys) + + fmt.Printf("var xxfontCharcodeToGlyphMap map[byte]string = map[byte]string{\n") + for _, key := range keys { + fmt.Printf("\t%d: \"%s\",\n", key, charcodeToGlyphMap[byte(key)]) + } + fmt.Printf("}\n") + + return nil +} + +func runGlyphToCharcodeRetrievalOnFile(afmpath string) error { + charcodeToGlyphMap, err := GetCharcodeToGlyphEncodingFromAfmFile(afmpath) + if err != nil { + return err + } + + keys := []int{} + for key, _ := range charcodeToGlyphMap { + keys = append(keys, int(key)) + } + sort.Ints(keys) + + fmt.Printf("var xxfontGlyphToCharcodeMap map[string]byte = map[string]byte ={\n") + for _, key := range keys { + fmt.Printf("\t\"%s\":\t%d,\n", charcodeToGlyphMap[byte(key)], key) + } + fmt.Printf("}\n") + + return nil } func GetCharmetricsFromAfmFile(filename string) (map[string]fonts.CharMetrics, error) { @@ -139,3 +210,84 @@ func GetCharmetricsFromAfmFile(filename string) (map[string]fonts.CharMetrics, e return glyphMetricsMap, nil } + +func GetCharcodeToGlyphEncodingFromAfmFile(filename string) (map[byte]string, error) { + charcodeToGlypMap := map[byte]string{} + + f, err := os.Open(filename) + if err != nil { + return nil, err + } + defer f.Close() + + readingCharMetrics := false + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + line := scanner.Text() + + parts := strings.Split(line, " ") + if len(parts) < 1 { + continue + } + if !readingCharMetrics && parts[0] == "StartCharMetrics" { + readingCharMetrics = true + continue + } + if readingCharMetrics && parts[0] == "EndCharMetrics" { + break + } + if !readingCharMetrics { + continue + } + if parts[0] != "C" { + continue + } + + parts = strings.Split(line, ";") + var charcode int64 + var glyph string + + for _, part := range parts { + cmd := strings.TrimSpace(part) + if len(cmd) == 0 { + continue + } + args := strings.Split(cmd, " ") + if len(args) < 1 { + continue + } + + switch args[0] { + case "C": + if len(args) != 2 { + pdfcommon.Log.Debug("Failed C line: %s", line) + return nil, errors.New("Invalid C line") + } + charcode, err = strconv.ParseInt(strings.TrimSpace(args[1]), 10, 64) + if err != nil { + return nil, err + } + case "N": + if len(args) != 2 { + pdfcommon.Log.Debug("Failed C line: %s", line) + return nil, errors.New("Invalid C line") + } + + glyph = strings.TrimSpace(args[1]) + if charcode >= 0 && charcode <= 255 { + charcodeToGlypMap[byte(charcode)] = glyph + } else { + fmt.Printf("NOT included: %d -> %s\n", charcode, glyph) + } + } + } + + } + + if err := scanner.Err(); err != nil { + return nil, err + } + + return charcodeToGlypMap, nil +} diff --git a/pdf/model/fonts/symbol.go b/pdf/model/fonts/symbol.go index b0c89b36..bfe85317 100644 --- a/pdf/model/fonts/symbol.go +++ b/pdf/model/fonts/symbol.go @@ -17,12 +17,12 @@ import ( // Font Symbol. Implements Font interface. // This is a built-in font and it is assumed that every reader has access to it. type fontSymbol struct { + // By default encoder is not set, which means that we use the font's built in encoding. encoder textencoding.TextEncoder } func NewFontSymbol() fontSymbol { font := fontSymbol{} - font.encoder = textencoding.NewWinAnsiTextEncoder() // Default return font } @@ -46,7 +46,9 @@ func (font fontSymbol) ToPdfObject() core.PdfObject { fontDict.Set("Type", core.MakeName("Font")) fontDict.Set("Subtype", core.MakeName("Type1")) fontDict.Set("BaseFont", core.MakeName("Symbol")) - fontDict.Set("Encoding", font.encoder.ToPdfObject()) + if font.encoder != nil { + fontDict.Set("Encoding", font.encoder.ToPdfObject()) + } obj.PdfObject = fontDict return obj diff --git a/pdf/model/textencoding/symbol.go b/pdf/model/textencoding/symbol.go new file mode 100644 index 00000000..83c36d48 --- /dev/null +++ b/pdf/model/textencoding/symbol.go @@ -0,0 +1,876 @@ +package textencoding + +import ( + "github.com/unidoc/unidoc/common" + "github.com/unidoc/unidoc/pdf/core" +) + +// Encoding for Symbol font. +type SymbolEncoder struct { +} + +func NewSymbolEncoder() SymbolEncoder { + encoder := SymbolEncoder{} + return encoder +} + +// Raw utf-8 rune string -> encoded string for use in PDF. +func (enc SymbolEncoder) Encode(raw string) string { + encoded := []byte{} + for _, rune := range raw { + // rune -> glyph -> code ?: + + code, found := enc.RuneToCharcode(rune) + if !found { + continue + } + + encoded = append(encoded, code) + } + + return string(encoded) +} + +// Symbol char code -> glyph name. Returns the glyph and a bool to indicate whether or not it was found. +func (enc SymbolEncoder) CharcodeToGlyphName(code byte) (string, bool) { + glyph, has := symbolEncodingCharcodeToGlyphMap[code] + if !has { + common.Log.Debug("Symbol encoding error: unable to find charcode->glyph entry (%v)", code) + return "", false + } + return glyph, true +} + +// Convert utf-8 input rune to a charcode. +func (enc SymbolEncoder) RuneToCharcode(val rune) (byte, bool) { + glyph, found := symbolEncodingRuneToGlyphMap[val] + if !found { + common.Log.Debug("Symbol encoding error: unable to find rune->glyph entry (%v)", val) + return 0, false + } + + code, found := symbolEncodingGlyphToCharcodeMap[glyph] + if !found { + common.Log.Debug("Symbol encoding error: unable to find glyph->charcode entry (%s)", glyph) + return 0, false + } + + return code, true +} + +// Convert utf-8 input rune to glyph name. +func (enc SymbolEncoder) RuneToGlyphName(val rune) (string, bool) { + glyph, found := symbolEncodingRuneToGlyphMap[val] + if !found { + common.Log.Debug("Symbol encoding error: unable to find rune->glyph entry (%v)", val) + return "", false + } + + return glyph, true +} + +// Convert glyph name to char code in this encoding. +func (enc SymbolEncoder) GlyphNameToCharcode(glyph string) (byte, bool) { + code, found := symbolEncodingGlyphToCharcodeMap[glyph] + if !found { + common.Log.Debug("Symbol encoding error: unable to find glyph->charcode entry (%s)", glyph) + return 0, false + } + + return code, found +} + +// Convert charcode to utf-8 rune. +func (enc SymbolEncoder) CharcodeToRune(charcode byte) (rune, bool) { + glyph, found := symbolEncodingCharcodeToGlyphMap[charcode] + if !found { + common.Log.Debug("Symbol encoding error: unable to find charcode->glyph entry (%d)", charcode) + return 0, false + } + + val, found := symbolEncodingGlyphToRuneMap[glyph] + if !found { + common.Log.Debug("Symbol encoding error: unable to find glyph->rune entry (%v)", glyph) + return 0, false + } + + return val, true +} + +// Convert to PDF Object. +func (enc SymbolEncoder) ToPdfObject() core.PdfObject { + dict := core.MakeDict() + dict.Set("Type", core.MakeName("Encoding")) + + // Returning an empty Encoding object with no differences. Indicates that we are using the font's built-in + // encoding. + return core.MakeIndirectObject(dict) +} + +var symbolEncodingCharcodeToGlyphMap map[byte]string = map[byte]string{ + 32: "space", + 33: "exclam", + 34: "universal", + 35: "numbersign", + 36: "existential", + 37: "percent", + 38: "ampersand", + 39: "suchthat", + 40: "parenleft", + 41: "parenright", + 42: "asteriskmath", + 43: "plus", + 44: "comma", + 45: "minus", + 46: "period", + 47: "slash", + 48: "zero", + 49: "one", + 50: "two", + 51: "three", + 52: "four", + 53: "five", + 54: "six", + 55: "seven", + 56: "eight", + 57: "nine", + 58: "colon", + 59: "semicolon", + 60: "less", + 61: "equal", + 62: "greater", + 63: "question", + 64: "congruent", + 65: "Alpha", + 66: "Beta", + 67: "Chi", + 68: "Delta", + 69: "Epsilon", + 70: "Phi", + 71: "Gamma", + 72: "Eta", + 73: "Iota", + 74: "theta1", + 75: "Kappa", + 76: "Lambda", + 77: "Mu", + 78: "Nu", + 79: "Omicron", + 80: "Pi", + 81: "Theta", + 82: "Rho", + 83: "Sigma", + 84: "Tau", + 85: "Upsilon", + 86: "sigma1", + 87: "Omega", + 88: "Xi", + 89: "Psi", + 90: "Zeta", + 91: "bracketleft", + 92: "therefore", + 93: "bracketright", + 94: "perpendicular", + 95: "underscore", + 96: "radicalex", + 97: "alpha", + 98: "beta", + 99: "chi", + 100: "delta", + 101: "epsilon", + 102: "phi", + 103: "gamma", + 104: "eta", + 105: "iota", + 106: "phi1", + 107: "kappa", + 108: "lambda", + 109: "mu", + 110: "nu", + 111: "omicron", + 112: "pi", + 113: "theta", + 114: "rho", + 115: "sigma", + 116: "tau", + 117: "upsilon", + 118: "omega1", + 119: "omega", + 120: "xi", + 121: "psi", + 122: "zeta", + 123: "braceleft", + 124: "bar", + 125: "braceright", + 126: "similar", + 160: "Euro", + 161: "Upsilon1", + 162: "minute", + 163: "lessequal", + 164: "fraction", + 165: "infinity", + 166: "florin", + 167: "club", + 168: "diamond", + 169: "heart", + 170: "spade", + 171: "arrowboth", + 172: "arrowleft", + 173: "arrowup", + 174: "arrowright", + 175: "arrowdown", + 176: "degree", + 177: "plusminus", + 178: "second", + 179: "greaterequal", + 180: "multiply", + 181: "proportional", + 182: "partialdiff", + 183: "bullet", + 184: "divide", + 185: "notequal", + 186: "equivalence", + 187: "approxequal", + 188: "ellipsis", + 189: "arrowvertex", + 190: "arrowhorizex", + 191: "carriagereturn", + 192: "aleph", + 193: "Ifraktur", + 194: "Rfraktur", + 195: "weierstrass", + 196: "circlemultiply", + 197: "circleplus", + 198: "emptyset", + 199: "intersection", + 200: "union", + 201: "propersuperset", + 202: "reflexsuperset", + 203: "notsubset", + 204: "propersubset", + 205: "reflexsubset", + 206: "element", + 207: "notelement", + 208: "angle", + 209: "gradient", + 210: "registerserif", + 211: "copyrightserif", + 212: "trademarkserif", + 213: "product", + 214: "radical", + 215: "dotmath", + 216: "logicalnot", + 217: "logicaland", + 218: "logicalor", + 219: "arrowdblboth", + 220: "arrowdblleft", + 221: "arrowdblup", + 222: "arrowdblright", + 223: "arrowdbldown", + 224: "lozenge", + 225: "angleleft", + 226: "registersans", + 227: "copyrightsans", + 228: "trademarksans", + 229: "summation", + 230: "parenlefttp", + 231: "parenleftex", + 232: "parenleftbt", + 233: "bracketlefttp", + 234: "bracketleftex", + 235: "bracketleftbt", + 236: "bracelefttp", + 237: "braceleftmid", + 238: "braceleftbt", + 239: "braceex", + 241: "angleright", + 242: "integral", + 243: "integraltp", + 244: "integralex", + 245: "integralbt", + 246: "parenrighttp", + 247: "parenrightex", + 248: "parenrightbt", + 249: "bracketrighttp", + 250: "bracketrightex", + 251: "bracketrightbt", + 252: "bracerighttp", + 253: "bracerightmid", + 254: "bracerightbt", +} + +var symbolEncodingGlyphToRuneMap map[string]rune = map[string]rune{ + "space": '\u0020', + "exclam": '\u0021', + "universal": '\u2200', + "numbersign": '\u0023', + "existential": '\u2203', + "percent": '\u0025', + "ampersand": '\u0026', + "suchthat": '\u220b', + "parenleft": '\u0028', + "parenright": '\u0029', + "asteriskmath": '\u2217', + "plus": '\u002b', + "comma": '\u002c', + "minus": '\u2212', + "period": '\u002e', + "slash": '\u002f', + "zero": '\u0030', + "one": '\u0031', + "two": '\u0032', + "three": '\u0033', + "four": '\u0034', + "five": '\u0035', + "six": '\u0036', + "seven": '\u0037', + "eight": '\u0038', + "nine": '\u0039', + "colon": '\u003a', + "semicolon": '\u003b', + "less": '\u003c', + "equal": '\u003d', + "greater": '\u003e', + "question": '\u003f', + "congruent": '\u2245', + "Alpha": '\u0391', + "Beta": '\u0392', + "Chi": '\u03a7', + "Delta": '\u2206', + "Epsilon": '\u0395', + "Phi": '\u03a6', + "Gamma": '\u0393', + "Eta": '\u0397', + "Iota": '\u0399', + "theta1": '\u03d1', + "Kappa": '\u039a', + "Lambda": '\u039b', + "Mu": '\u039c', + "Nu": '\u039d', + "Omicron": '\u039f', + "Pi": '\u03a0', + "Theta": '\u0398', + "Rho": '\u03a1', + "Sigma": '\u03a3', + "Tau": '\u03a4', + "Upsilon": '\u03a5', + "sigma1": '\u03c2', + "Omega": '\u2126', + "Xi": '\u039e', + "Psi": '\u03a8', + "Zeta": '\u0396', + "bracketleft": '\u005b', + "therefore": '\u2234', + "bracketright": '\u005d', + "perpendicular": '\u22a5', + "underscore": '\u005f', + "radicalex": '\uf8e5', + "alpha": '\u03b1', + "beta": '\u03b2', + "chi": '\u03c7', + "delta": '\u03b4', + "epsilon": '\u03b5', + "phi": '\u03c6', + "gamma": '\u03b3', + "eta": '\u03b7', + "iota": '\u03b9', + "phi1": '\u03d5', + "kappa": '\u03ba', + "lambda": '\u03bb', + "mu": '\u00b5', + "nu": '\u03bd', + "omicron": '\u03bf', + "pi": '\u03c0', + "theta": '\u03b8', + "rho": '\u03c1', + "sigma": '\u03c3', + "tau": '\u03c4', + "upsilon": '\u03c5', + "omega1": '\u03d6', + "omega": '\u03c9', + "xi": '\u03be', + "psi": '\u03c8', + "zeta": '\u03b6', + "braceleft": '\u007b', + "bar": '\u007c', + "braceright": '\u007d', + "similar": '\u223c', + "Euro": '\u20ac', + "Upsilon1": '\u03d2', + "minute": '\u2032', + "lessequal": '\u2264', + "fraction": '\u2044', + "infinity": '\u221e', + "florin": '\u0192', + "club": '\u2663', + "diamond": '\u2666', + "heart": '\u2665', + "spade": '\u2660', + "arrowboth": '\u2194', + "arrowleft": '\u2190', + "arrowup": '\u2191', + "arrowright": '\u2192', + "arrowdown": '\u2193', + "degree": '\u00b0', + "plusminus": '\u00b1', + "second": '\u2033', + "greaterequal": '\u2265', + "multiply": '\u00d7', + "proportional": '\u221d', + "partialdiff": '\u2202', + "bullet": '\u2022', + "divide": '\u00f7', + "notequal": '\u2260', + "equivalence": '\u2261', + "approxequal": '\u2248', + "ellipsis": '\u2026', + "arrowvertex": '\uf8e6', + "arrowhorizex": '\uf8e7', + "carriagereturn": '\u21b5', + "aleph": '\u2135', + "Ifraktur": '\u2111', + "Rfraktur": '\u211c', + "weierstrass": '\u2118', + "circlemultiply": '\u2297', + "circleplus": '\u2295', + "emptyset": '\u2205', + "intersection": '\u2229', + "union": '\u222a', + "propersuperset": '\u2283', + "reflexsuperset": '\u2287', + "notsubset": '\u2284', + "propersubset": '\u2282', + "reflexsubset": '\u2286', + "element": '\u2208', + "notelement": '\u2209', + "angle": '\u2220', + "gradient": '\u2207', + "registerserif": '\uf6da', + "copyrightserif": '\uf6d9', + "trademarkserif": '\uf6db', + "product": '\u220f', + "radical": '\u221a', + "dotmath": '\u22c5', + "logicalnot": '\u00ac', + "logicaland": '\u2227', + "logicalor": '\u2228', + "arrowdblboth": '\u21d4', + "arrowdblleft": '\u21d0', + "arrowdblup": '\u21d1', + "arrowdblright": '\u21d2', + "arrowdbldown": '\u21d3', + "lozenge": '\u25ca', + "angleleft": '\u2329', + "registersans": '\uf8e8', + "copyrightsans": '\uf8e9', + "trademarksans": '\uf8ea', + "summation": '\u2211', + "parenlefttp": '\uf8eb', + "parenleftex": '\uf8ec', + "parenleftbt": '\uf8ed', + "bracketlefttp": '\uf8ee', + "bracketleftex": '\uf8ef', + "bracketleftbt": '\uf8f0', + "bracelefttp": '\uf8f1', + "braceleftmid": '\uf8f2', + "braceleftbt": '\uf8f3', + "braceex": '\uf8f4', + "angleright": '\u232a', + "integral": '\u222b', + "integraltp": '\u2320', + "integralex": '\uf8f5', + "integralbt": '\u2321', + "parenrighttp": '\uf8f6', + "parenrightex": '\uf8f7', + "parenrightbt": '\uf8f8', + "bracketrighttp": '\uf8f9', + "bracketrightex": '\uf8fa', + "bracketrightbt": '\uf8fb', + "bracerighttp": '\uf8fc', + "bracerightmid": '\uf8fd', + "bracerightbt": '\uf8fe', +} + +var symbolEncodingRuneToGlyphMap map[rune]string = map[rune]string{ + '\u0020': "space", + '\u0021': "exclam", + '\u2200': "universal", + '\u0023': "numbersign", + '\u2203': "existential", + '\u0025': "percent", + '\u0026': "ampersand", + '\u220b': "suchthat", + '\u0028': "parenleft", + '\u0029': "parenright", + '\u2217': "asteriskmath", + '\u002b': "plus", + '\u002c': "comma", + '\u2212': "minus", + '\u002e': "period", + '\u002f': "slash", + '\u0030': "zero", + '\u0031': "one", + '\u0032': "two", + '\u0033': "three", + '\u0034': "four", + '\u0035': "five", + '\u0036': "six", + '\u0037': "seven", + '\u0038': "eight", + '\u0039': "nine", + '\u003a': "colon", + '\u003b': "semicolon", + '\u003c': "less", + '\u003d': "equal", + '\u003e': "greater", + '\u003f': "question", + '\u2245': "congruent", + '\u0391': "Alpha", + '\u0392': "Beta", + '\u03a7': "Chi", + '\u2206': "Delta", + '\u0395': "Epsilon", + '\u03a6': "Phi", + '\u0393': "Gamma", + '\u0397': "Eta", + '\u0399': "Iota", + '\u03d1': "theta1", + '\u039a': "Kappa", + '\u039b': "Lambda", + '\u039c': "Mu", + '\u039d': "Nu", + '\u039f': "Omicron", + '\u03a0': "Pi", + '\u0398': "Theta", + '\u03a1': "Rho", + '\u03a3': "Sigma", + '\u03a4': "Tau", + '\u03a5': "Upsilon", + '\u03c2': "sigma1", + '\u2126': "Omega", + '\u039e': "Xi", + '\u03a8': "Psi", + '\u0396': "Zeta", + '\u005b': "bracketleft", + '\u2234': "therefore", + '\u005d': "bracketright", + '\u22a5': "perpendicular", + '\u005f': "underscore", + '\uf8e5': "radicalex", + '\u03b1': "alpha", + '\u03b2': "beta", + '\u03c7': "chi", + '\u03b4': "delta", + '\u03b5': "epsilon", + '\u03c6': "phi", + '\u03b3': "gamma", + '\u03b7': "eta", + '\u03b9': "iota", + '\u03d5': "phi1", + '\u03ba': "kappa", + '\u03bb': "lambda", + '\u00b5': "mu", + '\u03bd': "nu", + '\u03bf': "omicron", + '\u03c0': "pi", + '\u03b8': "theta", + '\u03c1': "rho", + '\u03c3': "sigma", + '\u03c4': "tau", + '\u03c5': "upsilon", + '\u03d6': "omega1", + '\u03c9': "omega", + '\u03be': "xi", + '\u03c8': "psi", + '\u03b6': "zeta", + '\u007b': "braceleft", + '\u007c': "bar", + '\u007d': "braceright", + '\u223c': "similar", + '\u20ac': "Euro", + '\u03d2': "Upsilon1", + '\u2032': "minute", + '\u2264': "lessequal", + '\u2044': "fraction", + '\u221e': "infinity", + '\u0192': "florin", + '\u2663': "club", + '\u2666': "diamond", + '\u2665': "heart", + '\u2660': "spade", + '\u2194': "arrowboth", + '\u2190': "arrowleft", + '\u2191': "arrowup", + '\u2192': "arrowright", + '\u2193': "arrowdown", + '\u00b0': "degree", + '\u00b1': "plusminus", + '\u2033': "second", + '\u2265': "greaterequal", + '\u00d7': "multiply", + '\u221d': "proportional", + '\u2202': "partialdiff", + '\u2022': "bullet", + '\u00f7': "divide", + '\u2260': "notequal", + '\u2261': "equivalence", + '\u2248': "approxequal", + '\u2026': "ellipsis", + '\uf8e6': "arrowvertex", + '\uf8e7': "arrowhorizex", + '\u21b5': "carriagereturn", + '\u2135': "aleph", + '\u2111': "Ifraktur", + '\u211c': "Rfraktur", + '\u2118': "weierstrass", + '\u2297': "circlemultiply", + '\u2295': "circleplus", + '\u2205': "emptyset", + '\u2229': "intersection", + '\u222a': "union", + '\u2283': "propersuperset", + '\u2287': "reflexsuperset", + '\u2284': "notsubset", + '\u2282': "propersubset", + '\u2286': "reflexsubset", + '\u2208': "element", + '\u2209': "notelement", + '\u2220': "angle", + '\u2207': "gradient", + '\uf6da': "registerserif", + '\uf6d9': "copyrightserif", + '\uf6db': "trademarkserif", + '\u220f': "product", + '\u221a': "radical", + '\u22c5': "dotmath", + '\u00ac': "logicalnot", + '\u2227': "logicaland", + '\u2228': "logicalor", + '\u21d4': "arrowdblboth", + '\u21d0': "arrowdblleft", + '\u21d1': "arrowdblup", + '\u21d2': "arrowdblright", + '\u21d3': "arrowdbldown", + '\u25ca': "lozenge", + '\u2329': "angleleft", + '\uf8e8': "registersans", + '\uf8e9': "copyrightsans", + '\uf8ea': "trademarksans", + '\u2211': "summation", + '\uf8eb': "parenlefttp", + '\uf8ec': "parenleftex", + '\uf8ed': "parenleftbt", + '\uf8ee': "bracketlefttp", + '\uf8ef': "bracketleftex", + '\uf8f0': "bracketleftbt", + '\uf8f1': "bracelefttp", + '\uf8f2': "braceleftmid", + '\uf8f3': "braceleftbt", + '\uf8f4': "braceex", + '\u232a': "angleright", + '\u222b': "integral", + '\u2320': "integraltp", + '\uf8f5': "integralex", + '\u2321': "integralbt", + '\uf8f6': "parenrighttp", + '\uf8f7': "parenrightex", + '\uf8f8': "parenrightbt", + '\uf8f9': "bracketrighttp", + '\uf8fa': "bracketrightex", + '\uf8fb': "bracketrightbt", + '\uf8fc': "bracerighttp", + '\uf8fd': "bracerightmid", + '\uf8fe': "bracerightbt", +} + +var symbolEncodingGlyphToCharcodeMap map[string]byte = map[string]byte{ + "space": 32, + "exclam": 33, + "universal": 34, + "numbersign": 35, + "existential": 36, + "percent": 37, + "ampersand": 38, + "suchthat": 39, + "parenleft": 40, + "parenright": 41, + "asteriskmath": 42, + "plus": 43, + "comma": 44, + "minus": 45, + "period": 46, + "slash": 47, + "zero": 48, + "one": 49, + "two": 50, + "three": 51, + "four": 52, + "five": 53, + "six": 54, + "seven": 55, + "eight": 56, + "nine": 57, + "colon": 58, + "semicolon": 59, + "less": 60, + "equal": 61, + "greater": 62, + "question": 63, + "congruent": 64, + "Alpha": 65, + "Beta": 66, + "Chi": 67, + "Delta": 68, + "Epsilon": 69, + "Phi": 70, + "Gamma": 71, + "Eta": 72, + "Iota": 73, + "theta1": 74, + "Kappa": 75, + "Lambda": 76, + "Mu": 77, + "Nu": 78, + "Omicron": 79, + "Pi": 80, + "Theta": 81, + "Rho": 82, + "Sigma": 83, + "Tau": 84, + "Upsilon": 85, + "sigma1": 86, + "Omega": 87, + "Xi": 88, + "Psi": 89, + "Zeta": 90, + "bracketleft": 91, + "therefore": 92, + "bracketright": 93, + "perpendicular": 94, + "underscore": 95, + "radicalex": 96, + "alpha": 97, + "beta": 98, + "chi": 99, + "delta": 100, + "epsilon": 101, + "phi": 102, + "gamma": 103, + "eta": 104, + "iota": 105, + "phi1": 106, + "kappa": 107, + "lambda": 108, + "mu": 109, + "nu": 110, + "omicron": 111, + "pi": 112, + "theta": 113, + "rho": 114, + "sigma": 115, + "tau": 116, + "upsilon": 117, + "omega1": 118, + "omega": 119, + "xi": 120, + "psi": 121, + "zeta": 122, + "braceleft": 123, + "bar": 124, + "braceright": 125, + "similar": 126, + "Euro": 160, + "Upsilon1": 161, + "minute": 162, + "lessequal": 163, + "fraction": 164, + "infinity": 165, + "florin": 166, + "club": 167, + "diamond": 168, + "heart": 169, + "spade": 170, + "arrowboth": 171, + "arrowleft": 172, + "arrowup": 173, + "arrowright": 174, + "arrowdown": 175, + "degree": 176, + "plusminus": 177, + "second": 178, + "greaterequal": 179, + "multiply": 180, + "proportional": 181, + "partialdiff": 182, + "bullet": 183, + "divide": 184, + "notequal": 185, + "equivalence": 186, + "approxequal": 187, + "ellipsis": 188, + "arrowvertex": 189, + "arrowhorizex": 190, + "carriagereturn": 191, + "aleph": 192, + "Ifraktur": 193, + "Rfraktur": 194, + "weierstrass": 195, + "circlemultiply": 196, + "circleplus": 197, + "emptyset": 198, + "intersection": 199, + "union": 200, + "propersuperset": 201, + "reflexsuperset": 202, + "notsubset": 203, + "propersubset": 204, + "reflexsubset": 205, + "element": 206, + "notelement": 207, + "angle": 208, + "gradient": 209, + "registerserif": 210, + "copyrightserif": 211, + "trademarkserif": 212, + "product": 213, + "radical": 214, + "dotmath": 215, + "logicalnot": 216, + "logicaland": 217, + "logicalor": 218, + "arrowdblboth": 219, + "arrowdblleft": 220, + "arrowdblup": 221, + "arrowdblright": 222, + "arrowdbldown": 223, + "lozenge": 224, + "angleleft": 225, + "registersans": 226, + "copyrightsans": 227, + "trademarksans": 228, + "summation": 229, + "parenlefttp": 230, + "parenleftex": 231, + "parenleftbt": 232, + "bracketlefttp": 233, + "bracketleftex": 234, + "bracketleftbt": 235, + "bracelefttp": 236, + "braceleftmid": 237, + "braceleftbt": 238, + "braceex": 239, + "angleright": 241, + "integral": 242, + "integraltp": 243, + "integralex": 244, + "integralbt": 245, + "parenrighttp": 246, + "parenrightex": 247, + "parenrightbt": 248, + "bracketrighttp": 249, + "bracketrightex": 250, + "bracketrightbt": 251, + "bracerighttp": 252, + "bracerightmid": 253, + "bracerightbt": 254, +}