github.com/pdfcpu/pdfcpu@v0.11.1/internal/corefont/metrics/gen.go (about) 1 // Copyright 2019 The pdfcpu Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:build ignore 16 // +build ignore 17 18 package main 19 20 import ( 21 "bufio" 22 "bytes" 23 "flag" 24 "fmt" 25 "go/format" 26 "log" 27 "os" 28 "path/filepath" 29 "sort" 30 "strconv" 31 "strings" 32 ) 33 34 var debug = flag.Bool("debug", false, "") 35 36 func main() { 37 flag.Parse() 38 39 // Generate standard.go. 40 { 41 w := &bytes.Buffer{} 42 w.WriteString(header) 43 writeWinAnsiGlyphMap(w) 44 writeSymbolGlyphMap(w) 45 writeZapfDingbatsGlyphMap(w) 46 writeCoreFontMetrics(w) 47 finish(w, "standard.go") 48 } 49 50 } 51 52 func writeWinAnsiGlyphMap(w *bytes.Buffer) { 53 s := `// WinAnsiGlyphMap is a glyph lookup table for CP1252 character codes. 54 // See Annex D.2 Latin Character Set and Encodings. 55 var WinAnsiGlyphMap = map[int]string { 56 ` 57 writeGlyphMap(w, s, winAnsiGlyphMap) 58 } 59 60 func writeSymbolGlyphMap(w *bytes.Buffer) { 61 s := `// SymbolGlyphMap is a glyph lookup table for Symbol character codes. 62 // See Annex D.5 Symbol Set and Encoding. 63 var SymbolGlyphMap = map[int]string { 64 ` 65 writeGlyphMap(w, s, symbolGlyphMap) 66 67 } 68 69 func writeZapfDingbatsGlyphMap(w *bytes.Buffer) { 70 s := `// ZapfDingbatsGlyphMap is a glyph lookup table for ZapfDingbats character codes. 71 // See Annex D.6 ZapfDingbats Set and Encoding 72 var ZapfDingbatsGlyphMap = map[int]string { 73 ` 74 writeGlyphMap(w, s, zapfDingbatsGlyphMap) 75 } 76 77 func writeGlyphMap(w *bytes.Buffer, varDec string, m map[int]string) { 78 w.WriteString(varDec) 79 keys := make([]int, 0, len(m)) 80 for k := range m { 81 keys = append(keys, k) 82 } 83 sort.Ints(keys) 84 for _, k := range keys { 85 fmt.Fprintf(w, "%d: \"%s\", // %#U\n", k, m[k], rune(k)) 86 } 87 w.WriteString("}\n\n") 88 } 89 90 func writeCoreFontMetrics(w *bytes.Buffer) { 91 s := `type fontMetrics struct { 92 FBox *types.Rectangle // font box 93 W map[string]int // glyph widths 94 } 95 96 // CoreFontMetrics represents font metrics for the Adobe standard type 1 core fonts. 97 var CoreFontMetrics = map[string]fontMetrics{ 98 ` 99 w.WriteString(s) 100 dir := "../Core14_AFMs" 101 files, err := os.ReadDir(dir) 102 if err != nil { 103 log.Fatal(err) 104 } 105 for _, f := range files { 106 if !strings.HasSuffix(f.Name(), ".afm") { 107 continue 108 } 109 writeFontMetrics(w, dir, f.Name()) 110 } 111 w.WriteString("}") 112 } 113 114 func writeFontBBox(w *bytes.Buffer, ss []string) { 115 if len(ss) != 5 { 116 panic("corrupt .afm file!") 117 } 118 f1, err := strconv.ParseFloat(ss[1], 64) 119 if err != nil { 120 log.Fatal(err) 121 } 122 f2, err := strconv.ParseFloat(ss[2], 64) 123 if err != nil { 124 log.Fatal(err) 125 } 126 f3, err := strconv.ParseFloat(ss[3], 64) 127 if err != nil { 128 log.Fatal(err) 129 } 130 f4, err := strconv.ParseFloat(ss[4], 64) 131 if err != nil { 132 log.Fatal(err) 133 } 134 fmt.Fprintf(w, "types.NewRectangle(%.1f, %.1f, %.1f, %.1f),\n", f1, f2, f3, f4) 135 } 136 137 func writeFontMetrics(w *bytes.Buffer, dir, fileName string) { 138 fmt.Fprintf(w, "\"%s\": {\n", fileName[:len(fileName)-4]) 139 f, err := os.Open(filepath.Join(dir, fileName)) 140 if err != nil { 141 log.Fatal(err) 142 } 143 defer f.Close() 144 s := bufio.NewScanner(f) 145 isHeader := true 146 var headerDigested bool 147 for s.Scan() { 148 ss := strings.Fields(s.Text()) 149 if isHeader { 150 switch ss[0] { 151 case "FontBBox": 152 writeFontBBox(w, ss) 153 headerDigested = true 154 case "StartCharMetrics": 155 if !headerDigested { 156 panic("corrupt .afm file!") 157 } 158 isHeader = false 159 w.WriteString("map[string]int{") 160 } 161 continue 162 } 163 switch ss[0] { 164 case "C": 165 if len(ss) < 8 { 166 panic("corrupt .afm file!") 167 } 168 i, err := strconv.Atoi(ss[4]) 169 if err != nil { 170 log.Fatal(err) 171 } 172 fmt.Fprintf(w, "\"%s\": %d, ", ss[7], i) 173 case "EndCharMetrics": 174 w.WriteString("},\n") 175 break 176 } 177 } 178 if err := s.Err(); err != nil { 179 log.Fatal(err) 180 } 181 w.WriteString("\n},\n") 182 } 183 184 const header = `// generated by "go run gen.go". DO NOT EDIT. 185 186 package metrics 187 188 import ( 189 "github.com/pdfcpu/pdfcpu/pkg/pdfcpu/types" 190 ) 191 ` 192 193 func finish(w *bytes.Buffer, filename string) { 194 if *debug { 195 os.Stdout.Write(w.Bytes()) 196 return 197 } 198 out, err := format.Source(w.Bytes()) 199 if err != nil { 200 log.Fatalf("format.Source: %v", err) 201 } 202 if err := os.WriteFile(filename, out, 0660); err != nil { 203 log.Fatalf("os.WriteFile: %v", err) 204 } 205 } 206 207 // See Annex D.2 Latin Character Set and Encodings 208 var winAnsiGlyphMap = map[int]string{ 209 0101: "A", 210 0306: "AE", 211 0301: "Aacute", 212 0302: "Acircumflex", 213 0304: "Adieresis", 214 0300: "Agrave", 215 0305: "Aring", 216 0303: "Atilde", 217 0102: "B", 218 0103: "C", 219 0307: "Ccedilla", 220 0104: "D", 221 0105: "E", 222 0311: "Eacute", 223 0312: "Ecircumflex", 224 0313: "Edieresis", 225 0310: "Egrave", 226 0320: "Eth", 227 0200: "Euro", 228 0106: "F", 229 0107: "G", 230 0110: "H", 231 0111: "I", 232 0315: "Iacute", 233 0316: "Icircumflex", 234 0317: "Idieresis", 235 0314: "Igrave", 236 0112: "J", 237 0113: "K", 238 0114: "L", 239 0115: "M", 240 0116: "N", 241 0321: "Ntilde", 242 0117: "O", 243 0214: "OE", 244 0323: "Oacute", 245 0324: "Ocircumflex", 246 0326: "Odieresis", 247 0322: "Ograve", 248 0330: "Oslash", 249 0325: "Otilde", 250 0120: "P", 251 0121: "Q", 252 0122: "R", 253 0123: "S", 254 0212: "Scaron", 255 0124: "T", 256 0336: "Thorn", 257 0125: "U", 258 0332: "Uacute", 259 0333: "Ucircumflex", 260 0334: "Udieresis", 261 0331: "Ugrave", 262 0126: "V", 263 0127: "W", 264 0130: "X", 265 0131: "Y", 266 0335: "Yacute", 267 0237: "Ydieresis", 268 0132: "Z", 269 0216: "Zcaron", 270 0141: "a", 271 0341: "aacute", 272 0342: "acircumflex", 273 0264: "acute", 274 0344: "adieresis", 275 0346: "ae", 276 0340: "agrave", 277 0046: "ampersand", 278 0345: "aring", 279 0136: "asciicircum", 280 0176: "asciitilde", 281 0052: "asterisk", 282 0100: "at", 283 0343: "atilde", 284 0142: "b", 285 0134: "backslash", 286 0174: "bar", 287 0173: "braceleft", 288 0175: "braceright", 289 0133: "bracketleft", 290 0135: "bracketright", 291 0246: "brokenbar", 292 0225: "bullet", 293 0143: "c", 294 0347: "ccedilla", 295 0270: "cedilla", 296 0242: "cent", 297 0210: "circumflex", 298 0072: "colon", 299 0054: "comma", 300 0251: "copyright", 301 0244: "currency", 302 0144: "d", 303 0206: "dagger", 304 0207: "daggerdbl", 305 0260: "degree", 306 0250: "dieresis", 307 0367: "divide", 308 0044: "dollar", 309 0145: "e", 310 0351: "eacute", 311 0352: "ecircumflex", 312 0353: "edieresis", 313 0350: "egrave", 314 0070: "eight", 315 0205: "ellipsis", 316 0227: "emdash", 317 0226: "endash", 318 0075: "equal", 319 0360: "eth", 320 0041: "exclam", 321 0241: "exclamdown", 322 0146: "f", 323 0065: "five", 324 0203: "florin", 325 0064: "four", 326 0147: "g", 327 0337: "germandbls", 328 0140: "grave", 329 0076: "greater", 330 0253: "guillemotleft", 331 0273: "guillemotright", 332 0213: "guilsinglleft", 333 0233: "guilsinglright", 334 0150: "h", 335 0055: "hyphen", 336 0151: "i", 337 0355: "iacute", 338 0356: "icircumflex", 339 0357: "idieresis", 340 0354: "igrave", 341 0152: "j", 342 0153: "k", 343 0154: "l", 344 0074: "less", 345 0254: "logicalnot", 346 0155: "m", 347 0257: "macron", 348 0265: "mu", 349 0327: "multiply", 350 0156: "n", 351 0071: "nine", 352 0361: "ntilde", 353 0043: "numbersign", 354 0157: "o", 355 0363: "oacute", 356 0364: "ocircumflex", 357 0366: "odieresis", 358 0234: "oe", 359 0362: "ograve", 360 0061: "one", 361 0275: "onehalf", 362 0274: "onequarter", 363 0271: "onesuperior", 364 0252: "ordfeminine", 365 0272: "ordmasculine", 366 0370: "oslash", 367 0365: "otilde", 368 0160: "p", 369 0266: "paragraph", 370 0050: "parenleft", 371 0051: "parenright", 372 0045: "percent", 373 0056: "period", 374 0267: "periodcentered", 375 0211: "perthousand", 376 0053: "plus", 377 0261: "plusminus", 378 0161: "q", 379 0077: "question", 380 0277: "questiondown", 381 0042: "quotedbl", 382 0204: "quotedblbase", 383 0223: "quotedblleft", 384 0224: "quotedblright", 385 0221: "quoteleft", 386 0222: "quoteright", 387 0202: "quotesinglbase", 388 0047: "quotesingle", 389 0162: "r", 390 0256: "registered", 391 0163: "s", 392 0232: "scaron", 393 0247: "section", 394 0073: "semicolon", 395 0067: "seven", 396 0066: "six", 397 0057: "slash", 398 0040: "space", 399 0243: "sterling", 400 0164: "t", 401 0376: "thorn", 402 0063: "three", 403 0276: "threequarters", 404 0263: "threesuperior", 405 0230: "tilde", 406 0231: "trademark", 407 0062: "two", 408 0262: "twosuperior", 409 0165: "u", 410 0372: "uacute", 411 0373: "ucircumflex", 412 0374: "udieresis", 413 0371: "ugrave", 414 0137: "underscore", 415 0166: "v", 416 0167: "w", 417 0170: "x", 418 0171: "y", 419 0375: "yacute", 420 0377: "ydieresis", 421 0245: "yen", 422 0172: "z", 423 0236: "zcaron", 424 0060: "zero", 425 } 426 427 // See Annex D.5 Symbol Set and Encoding 428 var symbolGlyphMap = map[int]string{ 429 0101: "Alpha", 430 0102: "Beta", 431 0103: "Chi", 432 0104: "Delta", 433 0105: "Epsilon", 434 0110: "Eta", 435 0240: "Euro", 436 0107: "Gamma", 437 0301: "Ifraktur", 438 0111: "Iota", 439 0113: "Kappa", 440 0114: "Lambda", 441 0115: "Mu", 442 0116: "Nu", 443 0127: "Omega", 444 0117: "Omicron", 445 0106: "Phi", 446 0120: "Pi", 447 0131: "Psi", 448 0302: "Rfraktur", 449 0122: "Rho", 450 0123: "Sigma", 451 0124: "Tau", 452 0121: "Theta", 453 0125: "Upsilon", 454 0241: "Upsilon1", 455 0130: "Xi", 456 0132: "Zeta", 457 0300: "aleph", 458 0141: "alpha", 459 0046: "ampersand", 460 0320: "angle", 461 0341: "angleleft", 462 0361: "angleright", 463 0273: "approxequal", 464 0253: "arrowboth", 465 0333: "arrowdblboth", 466 0337: "arrowdbldown", 467 0334: "arrowdblleft", 468 0336: "arrowdblright", 469 0335: "arrowdblup", 470 0257: "arrowdown", 471 0276: "arrowhorizex", 472 0254: "arrowleft", 473 0256: "arrowright", 474 0255: "arrowup", 475 0275: "arrowvertex", 476 0052: "asteriskmath", 477 0174: "bar", 478 0142: "beta", 479 0173: "braceleft", 480 0175: "braceright", 481 0354: "bracelefttp", 482 0355: "braceleftmid", 483 0356: "braceleftbt", 484 0374: "bracerighttp", 485 0375: "bracerightmid", 486 0376: "bracerightbt", 487 0357: "braceex", 488 0133: "bracketleft", 489 0135: "bracketright", 490 0351: "bracketlefttp", 491 0352: "bracketleftex", 492 0353: "bracketleftbt", 493 0371: "bracketrighttp", 494 0372: "bracketrightex", 495 0373: "bracketrightbt", 496 0267: "bullet", 497 0277: "carriagereturn", 498 0143: "chi", 499 0304: "circlemultiply", 500 0305: "circleplus", 501 0247: "club", 502 0072: "colon", 503 0054: "comma", 504 0100: "congruent", 505 0343: "copyrightsans", 506 0323: "copyrightserif", 507 0260: "degree", 508 0144: "delta", 509 0250: "diamond", 510 0270: "divide", 511 0327: "dotmath", 512 0070: "eight", 513 0316: "element", 514 0274: "ellipsis", 515 0306: "emptyset", 516 0145: "epsilon", 517 0075: "equal", 518 0272: "equivalence", 519 0150: "eta", 520 0041: "exclam", 521 0044: "existential", 522 0065: "five", 523 0246: "florin", 524 0064: "four", 525 0244: "fraction", 526 0147: "gamma", 527 0321: "gradient", 528 0076: "greater", 529 0263: "greaterequal", 530 0251: "heart", 531 0245: "infinity", 532 0362: "integral", 533 0363: "integraltp", 534 0364: "integralex", 535 0365: "integralbt", 536 0307: "intersection", 537 0151: "iota", 538 0153: "kappa", 539 0154: "lambda", 540 0074: "less", 541 0243: "lessequal", 542 0331: "logicaland", 543 0330: "logicalnot", 544 0332: "logicalor", 545 0340: "lozenge", 546 0055: "minus", 547 0242: "minute", 548 0155: "mu", 549 0264: "multiply", 550 0071: "nine", 551 0317: "notelement", 552 0271: "notequal", 553 0313: "notsubset", 554 0156: "nu", 555 0043: "numbersign", 556 0167: "omega", 557 0166: "omega1", 558 0157: "omicron", 559 0061: "one", 560 0050: "parenleft", 561 0051: "parenright", 562 0346: "parenlefttp", 563 0347: "parenleftex", 564 0350: "parenleftbt", 565 0366: "parenrighttp", 566 0367: "parenrightex", 567 0370: "parenrightbt", 568 0266: "partialdiff", 569 0045: "percent", 570 0056: "period", 571 0136: "perpendicular", 572 0146: "phi", 573 0152: "phi1", 574 0160: "pi", 575 0053: "plus", 576 0261: "plusminus", 577 0325: "product", 578 0314: "propersubset", 579 0311: "propersuperset", 580 0265: "proportional", 581 0171: "psi", 582 0077: "question", 583 0326: "radical", 584 0140: "radicalex", 585 0315: "reflexsubset", 586 0312: "reflexsuperset", 587 0342: "registersans", 588 0322: "registerserif", 589 0162: "rho", 590 0262: "second", 591 0073: "semicolon", 592 0067: "seven", 593 0163: "sigma", 594 0126: "sigma1", 595 0176: "similar", 596 0066: "six", 597 0057: "slash", 598 0040: "space", 599 0252: "spade", 600 0047: "suchthat", 601 0345: "summation", 602 0164: "tau", 603 0134: "therefore", 604 0161: "theta", 605 0112: "theta1", 606 0063: "three", 607 0344: "trademarksans", 608 0324: "trademarkserif", 609 0062: "two", 610 0137: "underscore", 611 0310: "union", 612 0042: "universal", 613 0165: "upsilon", 614 0303: "weierstrass", 615 0170: "xi", 616 0060: "zero", 617 0172: "zeta", 618 } 619 620 // See Annex D.6 ZapfDingbats Set and Encoding 621 var zapfDingbatsGlyphMap = map[int]string{ 622 0040: "space", 623 0041: "a1", 624 0042: "a2", 625 0043: "a202", 626 0044: "a3", 627 0045: "a4", 628 0046: "a5", 629 0047: "a119", 630 0050: "a118", 631 0051: "a117", 632 0052: "a11", 633 0053: "a12", 634 0054: "a13", 635 0055: "a14", 636 0056: "a15", 637 0057: "a16", 638 0060: "a105", 639 0061: "a17", 640 0062: "a18", 641 0063: "a19", 642 0064: "a20", 643 0065: "a21", 644 0066: "a22", 645 0067: "a23", 646 0070: "a24", 647 0071: "a25", 648 0072: "a26", 649 0073: "a27", 650 0074: "a28", 651 0075: "a6", 652 0076: "a7", 653 0077: "a8", 654 0100: "a9", 655 0101: "a10", 656 0102: "a29", 657 0103: "a30", 658 0104: "a31", 659 0105: "a32", 660 0106: "a33", 661 0107: "a34", 662 0110: "a35", 663 0111: "a36", 664 0112: "a37", 665 0113: "a38", 666 0114: "a39", 667 0115: "a40", 668 0116: "a41", 669 0117: "a42", 670 0120: "a43", 671 0121: "a44", 672 0122: "a45", 673 0123: "a46", 674 0124: "a47", 675 0125: "a48", 676 0126: "a49", 677 0127: "a50", 678 0130: "a51", 679 0131: "a52", 680 0132: "a53", 681 0133: "a54", 682 0134: "a55", 683 0135: "a56", 684 0136: "a57", 685 0137: "a58", 686 0140: "a59", 687 0141: "a60", 688 0142: "a61", 689 0143: "a62", 690 0144: "a63", 691 0145: "a64", 692 0146: "a65", 693 0147: "a66", 694 0150: "a67", 695 0151: "a68", 696 0152: "a69", 697 0153: "a70", 698 0154: "a71", 699 0155: "a72", 700 0156: "a73", 701 0157: "a74", 702 0160: "a203", 703 0161: "a75", 704 0162: "a204", 705 0163: "a76", 706 0164: "a77", 707 0165: "a78", 708 0166: "a79", 709 0167: "a81", 710 0170: "a82", 711 0171: "a83", 712 0172: "a84", 713 0173: "a97", 714 0174: "a98", 715 0175: "a99", 716 0176: "a100", 717 0241: "a101", 718 0242: "a102", 719 0243: "a103", 720 0244: "a104", 721 0245: "a106", 722 0246: "a107", 723 0247: "a108", 724 0250: "a112", 725 0251: "a111", 726 0252: "a110", 727 0253: "a109", 728 0254: "a120", 729 0255: "a121", 730 0256: "a122", 731 0257: "a123", 732 0260: "a124", 733 0261: "a125", 734 0262: "a126", 735 0263: "a127", 736 0264: "a128", 737 0265: "a129", 738 0266: "a130", 739 0267: "a131", 740 0270: "a132", 741 0271: "a133", 742 0272: "a134", 743 0273: "a135", 744 0274: "a136", 745 0275: "a137", 746 0276: "a138", 747 0277: "a139", 748 0300: "a140", 749 0301: "a141", 750 0302: "a142", 751 0303: "a143", 752 0304: "a144", 753 0305: "a145", 754 0306: "a146", 755 0307: "a147", 756 0310: "a148", 757 0311: "a149", 758 0312: "a150", 759 0313: "a151", 760 0314: "a152", 761 0315: "a153", 762 0316: "a154", 763 0317: "a155", 764 0320: "a156", 765 0321: "a157", 766 0322: "a158", 767 0323: "a159", 768 0324: "a160", 769 0325: "a161", 770 0326: "a163", 771 0327: "a164", 772 0330: "a196", 773 0331: "a165", 774 0332: "a192", 775 0333: "a166", 776 0334: "a167", 777 0335: "a168", 778 0336: "a169", 779 0337: "a170", 780 0340: "a171", 781 0341: "a172", 782 0342: "a173", 783 0343: "a162", 784 0344: "a174", 785 0345: "a175", 786 0346: "a176", 787 0347: "a177", 788 0350: "a178", 789 0351: "a179", 790 0352: "a193", 791 0353: "a180", 792 0354: "a199", 793 0355: "a181", 794 0356: "a200", 795 0357: "a182", 796 0361: "a201", 797 0362: "a183", 798 0363: "a184", 799 0364: "a197", 800 0365: "a185", 801 0366: "a194", 802 0367: "a198", 803 0370: "a186", 804 0371: "a195", 805 0372: "a187", 806 0373: "a188", 807 0374: "a189", 808 0375: "a190", 809 0376: "a191", 810 }