1 49 81 82 101 102 113 114 124 125 132 133 141 package com.lowagie.text.pdf; 142 143 import java.io.FileOutputStream ; 144 import java.io.IOException ; 145 import java.io.OutputStream ; 146 import java.io.OutputStreamWriter ; 147 import java.io.PrintWriter ; 148 149 152 public class Pfm2afm { 153 private RandomAccessFileOrArray in; 154 private PrintWriter out; 155 156 157 private Pfm2afm(RandomAccessFileOrArray in, OutputStream out) throws IOException { 158 this.in = in; 159 this.out = new PrintWriter (new OutputStreamWriter (out, "ISO-8859-1")); 160 } 161 162 168 public static void convert(RandomAccessFileOrArray in, OutputStream out) throws IOException { 169 Pfm2afm p = new Pfm2afm(in, out); 170 p.openpfm(); 171 p.putheader(); 172 p.putchartab(); 173 p.putkerntab(); 174 p.puttrailer(); 175 p.out.flush(); 176 } 177 178 public static void main(String [] args) { 179 try { 180 RandomAccessFileOrArray in = new RandomAccessFileOrArray(args[0]); 181 OutputStream out = new FileOutputStream (args[1]); 182 convert(in, out); 183 in.close(); 184 out.close(); 185 } 186 catch (Exception e) { 187 e.printStackTrace(); 188 } 189 } 190 191 private String readString(int n) throws IOException { 192 byte b[] = new byte[n]; 193 in.readFully(b); 194 int k; 195 for (k = 0; k < b.length; ++k) { 196 if (b[k] == 0) 197 break; 198 } 199 return new String (b, 0, k, "ISO-8859-1"); 200 } 201 202 private String readString() throws IOException { 203 StringBuffer buf = new StringBuffer (); 204 while (true) { 205 int c = in.read(); 206 if (c <= 0) 207 break; 208 buf.append((char)c); 209 } 210 return buf.toString(); 211 } 212 213 private void outval(int n) { 214 out.print(' '); 215 out.print(n); 216 } 217 218 221 private void outchar(int code, int width, String name) { 222 out.print("C "); 223 outval(code); 224 out.print(" ; WX "); 225 outval(width); 226 if (name != null) { 227 out.print(" ; N "); 228 out.print(name); 229 } 230 out.print(" ;\n"); 231 } 232 233 private void openpfm() throws IOException { 234 in.seek(0); 235 vers = in.readShortLE(); 236 h_len = in.readIntLE(); 237 copyright = readString(60); 238 type = in.readShortLE(); 239 points = in.readShortLE(); 240 verres = in.readShortLE(); 241 horres = in.readShortLE(); 242 ascent = in.readShortLE(); 243 intleading = in.readShortLE(); 244 extleading = in.readShortLE(); 245 italic = (byte)in.read(); 246 uline = (byte)in.read(); 247 overs = (byte)in.read(); 248 weight = in.readShortLE(); 249 charset = (byte)in.read(); 250 pixwidth = in.readShortLE(); 251 pixheight = in.readShortLE(); 252 kind = (byte)in.read(); 253 avgwidth = in.readShortLE(); 254 maxwidth = in.readShortLE(); 255 firstchar = in.read(); 256 lastchar = in.read(); 257 defchar = (byte)in.read(); 258 brkchar = (byte)in.read(); 259 widthby = in.readShortLE(); 260 device = in.readIntLE(); 261 face = in.readIntLE(); 262 bits = in.readIntLE(); 263 bitoff = in.readIntLE(); 264 extlen = in.readShortLE(); 265 psext = in.readIntLE(); 266 chartab = in.readIntLE(); 267 res1 = in.readIntLE(); 268 kernpairs = in.readIntLE(); 269 res2 = in.readIntLE(); 270 fontname = in.readIntLE(); 271 if (h_len != in.length() || extlen != 30 || fontname < 75 || fontname > 512) 272 throw new IOException ("Not a valid PFM file."); 273 in.seek(psext + 14); 274 capheight = in.readShortLE(); 275 xheight = in.readShortLE(); 276 ascender = in.readShortLE(); 277 descender = in.readShortLE(); 278 } 279 280 private void putheader() throws IOException { 281 out.print("StartFontMetrics 2.0\n"); 282 if (copyright.length() > 0) 283 out.print("Comment " + copyright + '\n'); 284 out.print("FontName "); 285 in.seek(fontname); 286 String fname = readString(); 287 out.print(fname); 288 out.print("\nEncodingScheme "); 289 if (charset != 0) 290 out.print("FontSpecific\n"); 291 else 292 out.print("AdobeStandardEncoding\n"); 293 298 out.print("FullName " + fname.replace('-', ' ')); 299 if (face != 0) { 300 in.seek(face); 301 out.print("\nFamilyName " + readString()); 302 } 303 304 out.print("\nWeight "); 305 if (weight > 475 || fname.toLowerCase().indexOf("bold") >= 0) 306 out.print("Bold"); 307 else if ((weight < 325 && weight != 0) || fname.toLowerCase().indexOf("light") >= 0) 308 out.print("Light"); 309 else if (fname.toLowerCase().indexOf("black") >= 0) 310 out.print("Black"); 311 else 312 out.print("Medium"); 313 314 out.print("\nItalicAngle "); 315 if (italic != 0 || fname.toLowerCase().indexOf("italic") >= 0) 316 out.print("-12.00"); 317 319 else 320 out.print("0"); 321 322 326 out.print("\nIsFixedPitch "); 327 if ((kind & 1) == 0 || 328 avgwidth == maxwidth ) { 329 out.print("true"); 330 isMono = true; 331 } 332 else { 333 out.print("false"); 334 isMono = false; 335 } 336 337 342 out.print("\nFontBBox"); 343 if (isMono) 344 outval(-20); 345 else 346 outval(-100); 347 outval(-(descender+5)); 348 outval(maxwidth+10); 349 outval(ascent+5); 350 351 354 out.print("\nCapHeight"); 355 outval(capheight); 356 out.print("\nXHeight"); 357 outval(xheight); 358 out.print("\nDescender"); 359 outval(descender); 360 out.print("\nAscender"); 361 outval(ascender); 362 out.print('\n'); 363 } 364 365 private void putchartab() throws IOException { 366 int count = lastchar - firstchar + 1; 367 int ctabs[] = new int[count]; 368 in.seek(chartab); 369 for (int k = 0; k < count; ++k) 370 ctabs[k] = in.readUnsignedShortLE(); 371 int back[] = new int[256]; 372 if (charset == 0) { 373 for (int i = firstchar; i <= lastchar; ++i) { 374 if (Win2PSStd[i] != 0) 375 back[Win2PSStd[i]] = i; 376 } 377 } 378 379 out.print("StartCharMetrics"); 380 outval(count); 381 out.print('\n'); 382 383 384 if (charset != 0) { 385 389 for (int i = firstchar; i <= lastchar; i++) { 390 if (ctabs[i - firstchar] != 0) { 391 outchar(i, ctabs[i - firstchar], null); 392 } 393 } 394 } 395 else { 396 for (int i = 0; i < 256; i++) { 397 int j = back[i]; 398 if (j != 0) { 399 outchar(i, ctabs[j - firstchar], WinChars[j]); 400 ctabs[j - firstchar] = 0; 401 } 402 } 403 404 for (int i = firstchar; i <= lastchar; i++) { 405 if (ctabs[i - firstchar] != 0) { 406 outchar(-1, ctabs[i - firstchar], WinChars[i]); 407 } 408 } 409 } 410 411 out.print("EndCharMetrics\n"); 412 413 } 414 415 private void putkerntab() throws IOException { 416 if (kernpairs == 0) 417 return; 418 in.seek(kernpairs); 419 int count = in.readUnsignedShortLE(); 420 int nzero = 0; 421 int kerns[] = new int[count * 3]; 422 for (int k = 0; k < kerns.length;) { 423 kerns[k++] = in.read(); 424 kerns[k++] = in.read(); 425 if ((kerns[k++] = in.readShortLE()) != 0) 426 ++nzero; 427 } 428 if (nzero == 0) 429 return; 430 out.print("StartKernData\nStartKernPairs"); 431 outval(nzero); 432 out.print('\n'); 433 for (int k = 0; k < kerns.length; k += 3) { 434 if (kerns[k + 2] != 0) { 435 out.print("KPX "); 436 out.print(WinChars[kerns[k]]); 437 out.print(' '); 438 out.print(WinChars[kerns[k + 1]]); 439 outval(kerns[k + 2]); 440 out.print('\n'); 441 } 442 } 443 444 out.print("EndKernPairs\nEndKernData\n"); 445 } 446 447 448 private void puttrailer() { 449 out.print("EndFontMetrics\n"); 450 } 451 452 private short vers; 453 private int h_len; 454 private String copyright; 455 private short type; 456 private short points; 457 private short verres; 458 private short horres; 459 private short ascent; 460 private short intleading; 461 private short extleading; 462 private byte italic; 463 private byte uline; 464 private byte overs; 465 private short weight; 466 private byte charset; 467 private short pixwidth; 468 private short pixheight; 469 private byte kind; 470 private short avgwidth; 471 private short maxwidth; 472 private int firstchar; 473 private int lastchar; 474 private byte defchar; 475 private byte brkchar; 476 private short widthby; 477 private int device; 478 private int face; 479 private int bits; 480 private int bitoff; 481 private short extlen; 482 private int psext; 483 private int chartab; 484 private int res1; 485 private int kernpairs; 486 private int res2; 487 private int fontname; 488 489 492 private short capheight; 493 private short xheight; 494 private short ascender; 495 private short descender; 496 497 498 private boolean isMono; 499 503 private int Win2PSStd[] = { 504 0, 0, 0, 0, 197, 198, 199, 0, 202, 0, 205, 206, 207, 0, 0, 0, 505 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 506 32, 33, 34, 35, 36, 37, 38, 169, 40, 41, 42, 43, 44, 45, 46, 47, 507 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 508 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 509 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 510 193, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 511 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 512 0, 0, 184, 0, 185, 188, 178, 179, 94, 189, 0, 172, 234, 0, 0, 0, 513 0, 96, 0, 170, 186, 0, 177, 208, 126, 0, 0, 173, 250, 0, 0, 0, 514 0, 161, 162, 163, 168, 165, 0, 167, 200, 0, 227, 171, 0, 0, 0, 0, 515 0, 0, 0, 0, 194, 0, 182, 180, 203, 0, 235, 187, 0, 0, 0, 191, 516 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 517 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 251, 518 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 519 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0 520 }; 521 522 526 private int WinClass[] = { 527 0, 0, 0, 0, 2, 2, 2, 0, 2, 0, 2, 2, 2, 0, 0, 0, 528 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 529 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 530 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 531 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 532 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 533 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 534 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 535 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 536 0, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 537 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 538 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 539 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 540 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 541 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 542 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 543 }; 544 545 549 private String WinChars[] = { 550 "W00", 551 "W01", 552 "W02", 553 "W03", 554 "macron", 555 "breve", 556 "dotaccent", 557 "W07", 558 "ring", 559 "W09", 560 "W0a", 561 "W0b", 562 "W0c", 563 "W0d", 564 "W0e", 565 "W0f", 566 "hungarumlaut", 567 "ogonek", 568 "caron", 569 "W13", 570 "W14", 571 "W15", 572 "W16", 573 "W17", 574 "W18", 575 "W19", 576 "W1a", 577 "W1b", 578 "W1c", 579 "W1d", 580 "W1e", 581 "W1f", 582 "space", 583 "exclam", 584 "quotedbl", 585 "numbersign", 586 "dollar", 587 "percent", 588 "ampersand", 589 "quotesingle", 590 "parenleft", 591 "parenright", 592 "asterisk", 593 "plus", 594 "comma", 595 "hyphen", 596 "period", 597 "slash", 598 "zero", 599 "one", 600 "two", 601 "three", 602 "four", 603 "five", 604 "six", 605 "seven", 606 "eight", 607 "nine", 608 "colon", 609 "semicolon", 610 "less", 611 "equal", 612 "greater", 613 "question", 614 "at", 615 "A", 616 "B", 617 "C", 618 "D", 619 "E", 620 "F", 621 "G", 622 "H", 623 "I", 624 "J", 625 "K", 626 "L", 627 "M", 628 "N", 629 "O", 630 "P", 631 "Q", 632 "R", 633 "S", 634 "T", 635 "U", 636 "V", 637 "W", 638 "X", 639 "Y", 640 "Z", 641 "bracketleft", 642 "backslash", 643 "bracketright", 644 "asciicircum", 645 "underscore", 646 "grave", 647 "a", 648 "b", 649 "c", 650 "d", 651 "e", 652 "f", 653 "g", 654 "h", 655 "i", 656 "j", 657 "k", 658 "l", 659 "m", 660 "n", 661 "o", 662 "p", 663 "q", 664 "r", 665 "s", 666 "t", 667 "u", 668 "v", 669 "w", 670 "x", 671 "y", 672 "z", 673 "braceleft", 674 "bar", 675 "braceright", 676 "asciitilde", 677 "W7f", 678 "W80", 679 "W81", 680 "quotesinglbase", 681 "W83", 682 "quotedblbase", 683 "ellipsis", 684 "dagger", 685 "daggerdbl", 686 "asciicircum", 687 "perthousand", 688 "Scaron", 689 "guilsinglleft", 690 "OE", 691 "W8d", 692 "W8e", 693 "W8f", 694 "W90", 695 "quoteleft", 696 "quoteright", 697 "quotedblleft", 698 "quotedblright", 699 "bullet1", 700 "endash", 701 "emdash", 702 "asciitilde", 703 "trademark", 704 "scaron", 705 "guilsinglright", 706 "oe", 707 "W9d", 708 "W9e", 709 "Ydieresis", 710 "reqspace", 711 "exclamdown", 712 "cent", 713 "sterling", 714 "currency", 715 "yen", 716 "brokenbar", 717 "section", 718 "dieresis", 719 "copyright", 720 "ordfeminine", 721 "guillemotleft", 722 "logicalnot", 723 "syllable", 724 "registered", 725 "overbar", 726 "degree", 727 "plusminus", 728 "twosuperior", 729 "threesuperior", 730 "acute", 731 "mu", 732 "paragraph", 733 "periodcentered", 734 "cedilla", 735 "onesuperior", 736 "ordmasculine", 737 "guillemotright", 738 "onequarter", 739 "onehalf", 740 "threequarters", 741 "questiondown", 742 "Agrave", 743 "Aacute", 744 "Acircumflex", 745 "Atilde", 746 "Adieresis", 747 "Aring", 748 "AE", 749 "Ccedilla", 750 "Egrave", 751 "Eacute", 752 "Ecircumflex", 753 "Edieresis", 754 "Igrave", 755 "Iacute", 756 "Icircumflex", 757 "Idieresis", 758 "Eth", 759 "Ntilde", 760 "Ograve", 761 "Oacute", 762 "Ocircumflex", 763 "Otilde", 764 "Odieresis", 765 "multiply", 766 "Oslash", 767 "Ugrave", 768 "Uacute", 769 "Ucircumflex", 770 "Udieresis", 771 "Yacute", 772 "Thorn", 773 "germandbls", 774 "agrave", 775 "aacute", 776 "acircumflex", 777 "atilde", 778 "adieresis", 779 "aring", 780 "ae", 781 "ccedilla", 782 "egrave", 783 "eacute", 784 "ecircumflex", 785 "edieresis", 786 "igrave", 787 "iacute", 788 "icircumflex", 789 "idieresis", 790 "eth", 791 "ntilde", 792 "ograve", 793 "oacute", 794 "ocircumflex", 795 "otilde", 796 "odieresis", 797 "divide", 798 "oslash", 799 "ugrave", 800 "uacute", 801 "ucircumflex", 802 "udieresis", 803 "yacute", 804 "thorn", 805 "ydieresis" 806 }; 807 } | Popular Tags |