| 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 &n
|