1 37 38 68 69 package com.lowagie.text.pdf; 70 71 import java.util.Iterator ; 72 import java.util.LinkedList ; 73 74 import com.lowagie.text.ExceptionConverter; 75 76 public class CFFFont { 77 78 static final String operatorNames[] = { 79 "version", "Notice", "FullName", "FamilyName", 80 "Weight", "FontBBox", "BlueValues", "OtherBlues", 81 "FamilyBlues", "FamilyOtherBlues", "StdHW", "StdVW", 82 "UNKNOWN_12", "UniqueID", "XUID", "charset", 83 "Encoding", "CharStrings", "Private", "Subrs", 84 "defaultWidthX", "nominalWidthX", "UNKNOWN_22", "UNKNOWN_23", 85 "UNKNOWN_24", "UNKNOWN_25", "UNKNOWN_26", "UNKNOWN_27", 86 "UNKNOWN_28", "UNKNOWN_29", "UNKNOWN_30", "UNKNOWN_31", 87 "Copyright", "isFixedPitch", "ItalicAngle", "UnderlinePosition", 88 "UnderlineThickness", "PaintType", "CharstringType", "FontMatrix", 89 "StrokeWidth", "BlueScale", "BlueShift", "BlueFuzz", 90 "StemSnapH", "StemSnapV", "ForceBold", "UNKNOWN_12_15", 91 "UNKNOWN_12_16", "LanguageGroup", "ExpansionFactor", "initialRandomSeed", 92 "SyntheticBase", "PostScript", "BaseFontName", "BaseFontBlend", 93 "UNKNOWN_12_24", "UNKNOWN_12_25", "UNKNOWN_12_26", "UNKNOWN_12_27", 94 "UNKNOWN_12_28", "UNKNOWN_12_29", "ROS", "CIDFontVersion", 95 "CIDFontRevision", "CIDFontType", "CIDCount", "UIDBase", 96 "FDArray", "FDSelect", "FontName" 97 }; 98 99 static final String standardStrings[] = { 100 ".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", 103 "percent", "ampersand", "quoteright", "parenleft", "parenright", 104 "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", 105 "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", 106 "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", 107 "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", 108 "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", 109 "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", 110 "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", 111 "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", 112 "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", 113 "florin", "section", "currency", "quotesingle", "quotedblleft", 114 "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash", 115 "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", 116 "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", 117 "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex", 118 "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", 119 "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", 120 "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", 121 "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth", 122 "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar", 123 "degree", "thorn", "threequarters", "twosuperior", "registered", "minus", 124 "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", 125 "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute", 126 "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", 127 "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve", 128 "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave", 129 "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis", 130 "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", 131 "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave", 132 "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde", 133 "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", 134 "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall", 135 "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", 136 "parenleftsuperior", "parenrightsuperior", "twodotenleader", 137 "onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle", 138 "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", 139 "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior", 140 "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", 141 "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", 142 "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", 143 "ssuperior", "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", 144 "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", 145 "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", 146 "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", 147 "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", 148 "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", 149 "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", 150 "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", 151 "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", 152 "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", 153 "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", 154 "seveneighths", "onethird", "twothirds", "zerosuperior", "foursuperior", 155 "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", 156 "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", 157 "threeinferior", "fourinferior", "fiveinferior", "sixinferior", 158 "seveninferior", "eightinferior", "nineinferior", "centinferior", 159 "dollarinferior", "periodinferior", "commainferior", "Agravesmall", 160 "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", 161 "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", 162 "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", 163 "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", 164 "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", 165 "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", 166 "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", 167 "Ydieresissmall", "001.000", "001.001", "001.002", "001.003", "Black", 168 "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold" 169 }; 170 171 public String getString(char sid) { 173 if (sid < standardStrings.length) return standardStrings[sid]; 174 if (sid >= standardStrings.length+(stringOffsets.length-1)) return null; 175 int j = sid - standardStrings.length; 176 int p = getPosition(); 178 seek(stringOffsets[j]); 179 StringBuffer s = new StringBuffer (); 180 for (int k=stringOffsets[j]; k<stringOffsets[j+1]; k++) { 181 s.append(getCard8()); 182 } 183 seek(p); 184 return s.toString(); 185 } 186 187 char getCard8() { 188 try { 189 byte i = buf.readByte(); 190 return (char)(i & 0xff); 191 } 192 catch (Exception e) { 193 throw new ExceptionConverter(e); 194 } 195 } 196 197 char getCard16() { 198 try { 199 return buf.readChar(); 200 } 201 catch (Exception e) { 202 throw new ExceptionConverter(e); 203 } 204 } 205 206 int getOffset(int offSize) { 207 int offset = 0; 208 for (int i=0; i<offSize; i++) { 209 offset *= 256; 210 offset += getCard8(); 211 } 212 return offset; 213 } 214 215 void seek(int offset) { 216 try { 217 buf.seek(offset); 218 } 219 catch (Exception e) { 220 throw new ExceptionConverter(e); 221 } 222 } 223 224 short getShort() { 225 try { 226 return buf.readShort(); 227 } 228 catch (Exception e) { 229 throw new ExceptionConverter(e); 230 } 231 } 232 233 int getInt() { 234 try { 235 return buf.readInt(); 236 } 237 catch (Exception e) { 238 throw new ExceptionConverter(e); 239 } 240 } 241 242 int getPosition() { 243 try { 244 return buf.getFilePointer(); 245 } 246 catch (Exception e) { 247 throw new ExceptionConverter(e); 248 } 249 } 250 int nextIndexOffset; 251 int[] getIndex(int nextIndexOffset) { 256 int count, indexOffSize; 257 258 seek(nextIndexOffset); 259 count = getCard16(); 260 int[] offsets = new int[count+1]; 261 262 if (count==0) { 263 offsets[0] = -1; 264 nextIndexOffset += 2; 265 return offsets; 266 } 267 268 indexOffSize = getCard8(); 269 270 for (int j=0; j<=count; j++) { 271 offsets[j] = nextIndexOffset 273 + 2+1 275 + (count+1)*indexOffSize 277 - 1 279 + getOffset(indexOffSize); 281 } 282 return offsets; 284 } 285 286 protected String key; 287 protected Object [] args = new Object [48]; 288 protected int arg_count = 0; 289 290 protected void getDictItem() { 291 for (int i=0; i<arg_count; i++) args[i]=null; 292 arg_count = 0; 293 key = null; 294 boolean gotKey = false; 295 296 while (!gotKey) { 297 char b0 = getCard8(); 298 if (b0 == 29) { 299 int item = getInt(); 300 args[arg_count] = new Integer (item); 301 arg_count++; 302 continue; 304 } 305 if (b0 == 28) { 306 short item = getShort(); 307 args[arg_count] = new Integer (item); 308 arg_count++; 309 continue; 311 } 312 if (b0 >= 32 && b0 <= 246) { 313 byte item = (byte) (b0-139); 314 args[arg_count] = new Integer (item); 315 arg_count++; 316 continue; 318 } 319 if (b0 >= 247 && b0 <= 250) { 320 char b1 = getCard8(); 321 short item = (short) ((b0-247)*256+b1+108); 322 args[arg_count] = new Integer (item); 323 arg_count++; 324 continue; 326 } 327 if (b0 >= 251 && b0 <= 254) { 328 char b1 = getCard8(); 329 short item = (short) (-(b0-251)*256-b1-108); 330 args[arg_count] = new Integer (item); 331 arg_count++; 332 continue; 334 } 335 if (b0 == 30) { 336 String item = ""; 337 boolean done = false; 338 char buffer = 0; 339 byte avail = 0; 340 int nibble = 0; 341 while (!done) { 342 if (avail==0) { buffer = getCard8(); avail=2; } 344 if (avail==1) { nibble = (buffer / 16); avail--; } 345 if (avail==2) { nibble = (buffer % 16); avail--; } 346 switch (nibble) { 347 case 0xa: item += "." ; break; 348 case 0xb: item += "E" ; break; 349 case 0xc: item += "E-"; break; 350 case 0xe: item += "-" ; break; 351 case 0xf: done=true ; break; 352 default: 353 if (nibble >= 0 && nibble <= 9) 354 item += String.valueOf(nibble); 355 else { 356 item += "<NIBBLE ERROR: " + nibble + '>'; 357 done = true; 358 } 359 break; 360 } 361 } 362 args[arg_count] = item; 363 arg_count++; 364 continue; 366 } 367 if (b0 <= 21) { 368 gotKey=true; 369 if (b0 != 12) key = operatorNames[b0]; 370 else key = operatorNames[32 + getCard8()]; 371 continue; 375 } 376 } 377 } 378 379 381 382 protected static abstract class Item { 383 protected int myOffset = -1; 384 385 public void increment(int[] currentOffset) { 386 myOffset = currentOffset[0]; 387 } 388 389 public void emit(byte[] buffer) {} 390 391 public void xref() {} 392 } 393 394 protected static abstract class OffsetItem extends Item { 395 public int value; 396 399 public void set(int offset) { this.value = offset; } 400 } 401 402 403 405 406 protected static final class RangeItem extends Item { 407 public int offset, length; 408 private RandomAccessFileOrArray buf; 409 public RangeItem(RandomAccessFileOrArray buf, int offset, int length) { 410 this.offset = offset; 411 this.length = length; 412 this.buf = buf; 413 } 414 public void increment(int[] currentOffset) { 415 super.increment(currentOffset); 416 currentOffset[0] += length; 417 } 418 public void emit(byte[] buffer) { 419 try { 421 buf.seek(offset); 422 for (int i=myOffset; i<myOffset+length; i++) 423 buffer[i] = buf.readByte(); 424 } 425 catch (Exception e) { 426 throw new ExceptionConverter(e); 427 } 428 } 430 } 431 432 438 static protected final class IndexOffsetItem extends OffsetItem { 439 public final int size; 440 public IndexOffsetItem(int size, int value) {this.size=size; this.value=value;} 441 public IndexOffsetItem(int size) {this.size=size; } 442 443 public void increment(int[] currentOffset) { 444 super.increment(currentOffset); 445 currentOffset[0] += size; 446 } 447 public void emit(byte[] buffer) { 448 int i=0; 449 switch (size) { 450 case 4: 451 buffer[myOffset+i] = (byte) ((value >>> 24) & 0xff); 452 i++; 453 case 3: 454 buffer[myOffset+i] = (byte) ((value >>> 16) & 0xff); 455 i++; 456 case 2: 457 buffer[myOffset+i] = (byte) ((value >>> 8) & 0xff); 458 i++; 459 case 1: 460 buffer[myOffset+i] = (byte) ((value >>> 0) & 0xff); 461 i++; 462 } 463 470 } 471 } 472 473 static protected final class IndexBaseItem extends Item { 474 public IndexBaseItem() {} 475 } 476 477 static protected final class IndexMarkerItem extends Item { 478 private OffsetItem offItem; 479 private IndexBaseItem indexBase; 480 public IndexMarkerItem(OffsetItem offItem, IndexBaseItem indexBase) { 481 this.offItem = offItem; 482 this.indexBase = indexBase; 483 } 484 public void xref() { 485 offItem.set(this.myOffset-indexBase.myOffset+1); 487 } 488 } 489 493 static protected final class SubrMarkerItem extends Item { 494 private OffsetItem offItem; 495 private IndexBaseItem indexBase; 496 public SubrMarkerItem(OffsetItem offItem, IndexBaseItem indexBase) { 497 this.offItem = offItem; 498 this.indexBase = indexBase; 499 } 500 public void xref() { 501 offItem.set(this.myOffset-indexBase.myOffset); 503 } 504 } 505 506 507 510 static protected final class DictOffsetItem extends OffsetItem { 511 public final int size; 512 public DictOffsetItem() {this.size=5; } 513 514 public void increment(int[] currentOffset) { 515 super.increment(currentOffset); 516 currentOffset[0] += size; 517 } 518 public void emit(byte[] buffer) { 520 if (size==5) { 521 buffer[myOffset] = 29; 522 buffer[myOffset+1] = (byte) ((value >>> 24) & 0xff); 523 buffer[myOffset+2] = (byte) ((value >>> 16) & 0xff); 524 buffer[myOffset+3] = (byte) ((value >>> 8) & 0xff); 525 buffer[myOffset+4] = (byte) ((value >>> 0) & 0xff); 526 } 527 } 528 } 529 530 532 533 static protected final class UInt24Item extends Item { 534 public int value; 535 public UInt24Item(int value) {this.value=value;} 536 537 public void increment(int[] currentOffset) { 538 super.increment(currentOffset); 539 currentOffset[0] += 3; 540 } 541 public void emit(byte[] buffer) { 543 buffer[myOffset+0] = (byte) ((value >>> 16) & 0xff); 544 buffer[myOffset+1] = (byte) ((value >>> 8) & 0xff); 545 buffer[myOffset+2] = (byte) ((value >>> 0) & 0xff); 546 } 547 } 548 549 551 552 static protected final class UInt32Item extends Item { 553 public int value; 554 public UInt32Item(int value) {this.value=value;} 555 556 public void increment(int[] currentOffset) { 557 super.increment(currentOffset); 558 currentOffset[0] += 4; 559 } 560 public void emit(byte[] buffer) { 562 buffer[myOffset+0] = (byte) ((value >>> 24) & 0xff); 563 buffer[myOffset+1] = (byte) ((value >>> 16) & 0xff); 564 buffer[myOffset+2] = (byte) ((value >>> 8) & 0xff); 565 buffer[myOffset+3] = (byte) ((value >>> 0) & 0xff); 566 } 567 } 568 569 571 572 static protected final class UInt16Item extends Item { 573 public char value; 574 public UInt16Item(char value) {this.value=value;} 575 576 public void increment(int[] currentOffset) { 577 super.increment(currentOffset); 578 currentOffset[0] += 2; 579 } 580 public void emit(byte[] buffer) { 582 buffer[myOffset+0] = (byte) ((value >>> 8) & 0xff); 583 buffer[myOffset+1] = (byte) ((value >>> 0) & 0xff); 584 } 585 } 586 587 589 590 static protected final class UInt8Item extends Item { 591 public char value; 592 public UInt8Item(char value) {this.value=value;} 593 594 public void increment(int[] currentOffset) { 595 super.increment(currentOffset); 596 currentOffset[0] += 1; 597 } 598 public void emit(byte[] buffer) { 600 buffer[myOffset+0] = (byte) ((value >>> 0) & 0xff); 601 } 602 } 603 604 static protected final class StringItem extends Item { 605 public String s; 606 public StringItem(String s) {this.s=s;} 607 608 public void increment(int[] currentOffset) { 609 super.increment(currentOffset); 610 currentOffset[0] += s.length(); 611 } 612 public void emit(byte[] buffer) { 613 for (int i=0; i<s.length(); i++) 614 buffer[myOffset+i] = (byte) (s.charAt(i) & 0xff); 615 } 616 } 617 618 619 623 624 static protected final class DictNumberItem extends Item { 625 public final int value; 626 public int size = 5; 627 public DictNumberItem(int value) {this.value=value;} 628 public void increment(int[] currentOffset) { 629 super.increment(currentOffset); 630 currentOffset[0] += size; 631 } 632 public void emit(byte[] buffer) { 634 if (size==5) { 635 buffer[myOffset] = 29; 636 buffer[myOffset+1] = (byte) ((value >>> 24) & 0xff); 637 buffer[myOffset+2] = (byte) ((value >>> 16) & 0xff); 638 buffer[myOffset+3] = (byte) ((value >>> 8) & 0xff); 639 buffer[myOffset+4] = (byte) ((value >>> 0) & 0xff); 640 } 641 } 642 } 643 644 647 648 static protected final class MarkerItem extends Item { 649 OffsetItem p; 650 public MarkerItem(OffsetItem pointerToMarker) {p=pointerToMarker;} 651 public void xref() { 652 p.set(this.myOffset); 653 } 654 } 655 656 661 662 protected RangeItem getEntireIndexRange(int indexOffset) { 663 seek(indexOffset); 664 int count = getCard16(); 665 if (count==0) { 666 return new RangeItem(buf,indexOffset,2); 667 } else { 668 int indexOffSize = getCard8(); 669 seek(indexOffset+2+1+count*indexOffSize); 670 int size = getOffset(indexOffSize)-1; 671 return new RangeItem(buf,indexOffset, 672 2+1+(count+1)*indexOffSize+size); 673 } 674 } 675 676 677 686 687 688 public byte[] getCID(String fontName) 689 { 691 int j; 692 for (j=0; j<fonts.length; j++) 693 if (fontName.equals(fonts[j].name)) break; 694 if (j==fonts.length) return null; 695 696 LinkedList l = new LinkedList (); 697 698 700 seek(0); 701 702 int major = getCard8(); 703 int minor = getCard8(); 704 int hdrSize = getCard8(); 705 int offSize = getCard8(); 706 nextIndexOffset = hdrSize; 707 708 l.addLast(new RangeItem(buf,0,hdrSize)); 709 710 int nglyphs=-1, nstrings=-1; 711 if ( ! fonts[j].isCID ) { 712 seek(fonts[j].charstringsOffset); 714 nglyphs = getCard16(); 715 seek(stringIndexOffset); 716 nstrings = getCard16()+standardStrings.length; 717 } 719 720 722 l.addLast(new UInt16Item((char)1)); l.addLast(new UInt8Item((char)1)); l.addLast(new UInt8Item((char)1)); l.addLast(new UInt8Item((char)( 1+fonts[j].name.length() ))); 726 l.addLast(new StringItem(fonts[j].name)); 727 728 730 731 l.addLast(new UInt16Item((char)1)); l.addLast(new UInt8Item((char)2)); l.addLast(new UInt16Item((char)1)); OffsetItem topdictIndex1Ref = new IndexOffsetItem(2); 735 l.addLast(topdictIndex1Ref); 736 IndexBaseItem topdictBase = new IndexBaseItem(); 737 l.addLast(topdictBase); 738 739 745 746 749 OffsetItem charsetRef = new DictOffsetItem(); 750 OffsetItem charstringsRef = new DictOffsetItem(); 751 OffsetItem fdarrayRef = new DictOffsetItem(); 752 OffsetItem fdselectRef = new DictOffsetItem(); 753 754 if ( !fonts[j].isCID ) { 755 l.addLast(new DictNumberItem(nstrings)); 757 l.addLast(new DictNumberItem(nstrings+1)); 758 l.addLast(new DictNumberItem(0)); 759 l.addLast(new UInt8Item((char)12)); 760 l.addLast(new UInt8Item((char)30)); 761 l.addLast(new DictNumberItem(nglyphs)); 763 l.addLast(new UInt8Item((char)12)); 764 l.addLast(new UInt8Item((char)34)); 765 } 768 769 l.addLast(fdarrayRef); 771 l.addLast(new UInt8Item((char)12)); 772 l.addLast(new UInt8Item((char)36)); 773 l.addLast(fdselectRef); 775 l.addLast(new UInt8Item((char)12)); 776 l.addLast(new UInt8Item((char)37)); 777 l.addLast(charsetRef); 779 l.addLast(new UInt8Item((char)15)); 780 l.addLast(charstringsRef); 782 l.addLast(new UInt8Item((char)17)); 783 784 seek(topdictOffsets[j]); 785 while (getPosition() < topdictOffsets[j+1]) { 786 int p1 = getPosition(); 787 getDictItem(); 788 int p2 = getPosition(); 789 if (key=="Encoding" 790 || key=="Private" 791 || key=="FDSelect" 792 || key=="FDArray" 793 || key=="charset" 794 || key=="CharStrings" 795 ) { 796 } else { 798 l.add(new RangeItem(buf,p1,p2-p1)); 799 } 800 } 801 802 l.addLast(new IndexMarkerItem(topdictIndex1Ref,topdictBase)); 803 804 808 if (fonts[j].isCID) { 809 l.addLast(getEntireIndexRange(stringIndexOffset)); 810 } else { 811 String fdFontName = fonts[j].name+"-OneRange"; 812 if (fdFontName.length() > 127) 813 fdFontName = fdFontName.substring(0,127); 814 String extraStrings = "Adobe"+"Identity"+fdFontName; 815 816 int origStringsLen = stringOffsets[stringOffsets.length-1] 817 - stringOffsets[0]; 818 int stringsBaseOffset = stringOffsets[0]-1; 819 820 byte stringsIndexOffSize; 821 if (origStringsLen+extraStrings.length() <= 0xff) stringsIndexOffSize = 1; 822 else if (origStringsLen+extraStrings.length() <= 0xffff) stringsIndexOffSize = 2; 823 else if (origStringsLen+extraStrings.length() <= 0xffffff) stringsIndexOffSize = 3; 824 else stringsIndexOffSize = 4; 825 826 l.addLast(new UInt16Item((char)((stringOffsets.length-1)+3))); l.addLast(new UInt8Item((char)stringsIndexOffSize)); for (int i=0; i<stringOffsets.length; i++) 829 l.addLast(new IndexOffsetItem(stringsIndexOffSize, 830 stringOffsets[i]-stringsBaseOffset)); 831 int currentStringsOffset = stringOffsets[stringOffsets.length-1] 832 - stringsBaseOffset; 833 currentStringsOffset += ("Adobe").length(); 835 l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); 836 currentStringsOffset += ("Identity").length(); 837 l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); 838 currentStringsOffset += fdFontName.length(); 839 l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); 840 841 l.addLast(new RangeItem(buf,stringOffsets[0],origStringsLen)); 842 l.addLast(new StringItem(extraStrings)); 843 } 844 845 847 l.addLast(getEntireIndexRange(gsubrIndexOffset)); 848 849 851 if (fonts[j].isCID) { 852 } else { 854 l.addLast(new MarkerItem(fdselectRef)); 856 l.addLast(new UInt8Item((char)3)); l.addLast(new UInt16Item((char)1)); 859 l.addLast(new UInt16Item((char)0)); l.addLast(new UInt8Item((char)0)); 862 l.addLast(new UInt16Item((char)nglyphs)); 864 867 l.addLast(new MarkerItem(charsetRef)); 868 l.addLast(new UInt8Item((char)2)); 870 l.addLast(new UInt16Item((char)1)); l.addLast(new UInt16Item((char)(nglyphs-1))); 874 876 l.addLast(new MarkerItem(fdarrayRef)); 877 l.addLast(new UInt16Item((char)1)); 878 l.addLast(new UInt8Item((char)1)); l.addLast(new UInt8Item((char)1)); 881 OffsetItem privateIndex1Ref = new IndexOffsetItem(1); 882 l.addLast(privateIndex1Ref); 883 IndexBaseItem privateBase = new IndexBaseItem(); 884 l.addLast(privateBase); 885 886 893 l.addLast(new DictNumberItem(fonts[j].privateLength)); 894 OffsetItem privateRef = new DictOffsetItem(); 895 l.addLast(privateRef); 896 l.addLast(new UInt8Item((char)18)); 898 l.addLast(new IndexMarkerItem(privateIndex1Ref,privateBase)); 899 900 902 l.addLast(new MarkerItem(privateRef)); 903 l.addLast(new RangeItem(buf,fonts[j].privateOffset,fonts[j].privateLength)); 907 if (fonts[j].privateSubrs >= 0) { 908 l.addLast(getEntireIndexRange(fonts[j].privateSubrs)); 910 } 911 } 912 913 915 l.addLast(new MarkerItem(charstringsRef)); 916 l.addLast(getEntireIndexRange(fonts[j].charstringsOffset)); 917 918 920 int[] currentOffset = new int[1]; 921 currentOffset[0] = 0; 922 923 Iterator listIter = l.iterator(); 924 while ( listIter.hasNext() ) { 925 Item item = (Item) listIter.next(); 926 item.increment(currentOffset); 927 } 928 929 listIter = l.iterator(); 930 while ( listIter.hasNext() ) { 931 Item item = (Item) listIter.next(); 932 item.xref(); 933 } 934 935 int size = currentOffset[0]; 936 byte[] b = new byte[size]; 937 938 listIter = l.iterator(); 939 while ( listIter.hasNext() ) { 940 Item item = (Item) listIter.next(); 941 item.emit(b); 942 } 943 944 return b; 945 } 946 947 948 public boolean isCID(String fontName) { 949 int j; 950 for (j=0; j<fonts.length; j++) 951 if (fontName.equals(fonts[j].name)) return fonts[j].isCID; 952 return false; 953 } 954 955 public boolean exists(String fontName) { 956 int j; 957 for (j=0; j<fonts.length; j++) 958 if (fontName.equals(fonts[j].name)) return true; 959 return false; 960 } 961 962 963 public String [] getNames() { 964 String [] names = new String [ fonts.length ]; 965 for (int i=0; i<fonts.length; i++) 966 names[i] = fonts[i].name; 967 return names; 968 } 969 972 protected RandomAccessFileOrArray buf; 973 private int offSize; 974 975 protected int nameIndexOffset; 976 protected int topdictIndexOffset; 977 protected int stringIndexOffset; 978 protected int gsubrIndexOffset; 979 protected int[] nameOffsets; 980 protected int[] topdictOffsets; 981 protected int[] stringOffsets; 982 protected int[] gsubrOffsets; 983 984 987 protected final class Font { 988 public String name; 989 public String fullName; 990 public boolean isCID = false; 991 public int privateOffset = -1; public int privateLength = -1; public int privateSubrs = -1; 994 public int charstringsOffset = -1; 995 public int encodingOffset = -1; 996 public int charsetOffset = -1; 997 public int fdarrayOffset = -1; public int fdselectOffset = -1; public int[] fdprivateOffsets; 1000 public int[] fdprivateLengths; 1001 public int[] fdprivateSubrs; 1002 1003 public int nglyphs; 1005 public int nstrings; 1006 public int CharsetLength; 1007 public int[] charstringsOffsets; 1008 public int[] charset; 1009 public int[] FDSelect; 1010 public int FDSelectLength; 1011 public int FDSelectFormat; 1012 public int CharstringType = 2; 1013 public int FDArrayCount; 1014 public int FDArrayOffsize; 1015 public int[] FDArrayOffsets; 1016 public int[] PrivateSubrsOffset; 1017 public int[][] PrivateSubrsOffsetsArray; 1018 public int[] SubrsOffsets; 1019 } 1020 protected Font[] fonts; 1022 1023 public CFFFont(RandomAccessFileOrArray inputbuffer) { 1024 1025 buf = inputbuffer; 1027 seek(0); 1028 1029 int major, minor; 1030 major = getCard8(); 1031 minor = getCard8(); 1032 1033 1035 int hdrSize = getCard8(); 1036 1037 offSize = getCard8(); 1038 1039 1041 1043 nameIndexOffset = hdrSize; 1044 nameOffsets = getIndex(nameIndexOffset); 1045 topdictIndexOffset = nameOffsets[nameOffsets.length-1]; 1046 topdictOffsets = getIndex(topdictIndexOffset); 1047 stringIndexOffset = topdictOffsets[topdictOffsets.length-1]; 1048 stringOffsets = getIndex(stringIndexOffset); 1049 gsubrIndexOffset = stringOffsets[stringOffsets.length-1]; 1050 gsubrOffsets = getIndex(gsubrIndexOffset); 1051 1052 fonts = new Font[nameOffsets.length-1]; 1053 1054 1056 1065 1066 for (int j=0; j<nameOffsets.length-1; j++) { 1067 fonts[j] = new Font(); 1068 seek(nameOffsets[j]); 1069 fonts[j].name = ""; 1070 for (int k=nameOffsets[j]; k<nameOffsets[j+1]; k++) { 1071 fonts[j].name += (char)getCard8(); 1072 } 1073 } 1075 1076 1078 1092 1093 1095 for (int j=0; j<topdictOffsets.length-1; j++) { 1096 seek(topdictOffsets[j]); 1097 while (getPosition() < topdictOffsets[j+1]) { 1098 getDictItem(); 1099 if (key=="FullName") { 1100 fonts[j].fullName = getString((char)((Integer )args[0]).intValue()); 1102 } else if (key=="ROS") 1104 fonts[j].isCID = true; 1105 else if (key=="Private") { 1106 fonts[j].privateLength = ((Integer )args[0]).intValue(); 1107 fonts[j].privateOffset = ((Integer )args[1]).intValue(); 1108 } 1109 else if (key=="charset"){ 1110 fonts[j].charsetOffset = ((Integer )args[0]).intValue(); 1111 1112 } 1113 else if (key=="Encoding"){ 1114 fonts[j].encodingOffset = ((Integer )args[0]).intValue(); 1115 ReadEncoding(fonts[j].encodingOffset); 1116 } 1117 else if (key=="CharStrings") { 1118 fonts[j].charstringsOffset = ((Integer )args[0]).intValue(); 1119 int p = getPosition(); 1122 fonts[j].charstringsOffsets = getIndex(fonts[j].charstringsOffset); 1123 seek(p); 1124 } else if (key=="FDArray") 1125 fonts[j].fdarrayOffset = ((Integer )args[0]).intValue(); 1126 else if (key=="FDSelect") 1127 fonts[j].fdselectOffset = ((Integer )args[0]).intValue(); 1128 else if (key=="CharstringType") 1129 fonts[j].CharstringType = ((Integer )args[0]).intValue(); 1130 } 1131 1132 if (fonts[j].privateOffset >= 0) { 1134 seek(fonts[j].privateOffset); 1136 while (getPosition() < fonts[j].privateOffset+fonts[j].privateLength) { 1137 getDictItem(); 1138 if (key=="Subrs") 1139 fonts[j].privateSubrs = ((Integer )args[0]).intValue()+fonts[j].privateOffset; 1142 } 1143 } 1144 1145 if (fonts[j].fdarrayOffset >= 0) { 1147 int[] fdarrayOffsets = getIndex(fonts[j].fdarrayOffset); 1148 1149 fonts[j].fdprivateOffsets = new int[fdarrayOffsets.length-1]; 1150 fonts[j].fdprivateLengths = new int[fdarrayOffsets.length-1]; 1151 1152 1154 for (int k=0; k<fdarrayOffsets.length-1; k++) { 1155 seek(fdarrayOffsets[k]); 1156 while (getPosition() < fdarrayOffsets[k+1]) 1157 getDictItem(); 1158 if (key=="Private") { 1159 fonts[j].fdprivateLengths[k] = ((Integer )args[0]).intValue(); 1160 fonts[j].fdprivateOffsets[k] = ((Integer )args[1]).intValue(); 1161 } 1162 1163 } 1164 } 1165 } 1166 } 1168 1169 1171 void ReadEncoding(int nextIndexOffset){ 1172 int format; 1173 seek(nextIndexOffset); 1174 format = getCard8(); 1175 } 1176} | Popular Tags |