1 50 package com.lowagie.text.pdf; 51 52 import java.io.IOException ; 53 import java.util.ArrayList ; 54 import java.util.HashMap ; 55 import java.util.Iterator ; 56 import java.util.LinkedList ; 57 58 68 public class CFFFontSubset extends CFFFont { 69 70 73 static final String SubrsFunctions[] = { 74 "RESERVED_0","hstem","RESERVED_2","vstem","vmoveto","rlineto","hlineto","vlineto", 75 "rrcurveto","RESERVED_9","callsubr","return","escape","RESERVED_13", 76 "endchar","RESERVED_15","RESERVED_16","RESERVED_17","hstemhm","hintmask", 77 "cntrmask","rmoveto","hmoveto","vstemhm","rcurveline","rlinecurve","vvcurveto", 78 "hhcurveto","shortint","callgsubr","vhcurveto","hvcurveto" 79 }; 80 83 static final String SubrsEscapeFuncs[] = { 84 "RESERVED_0","RESERVED_1","RESERVED_2","and","or","not","RESERVED_6", 85 "RESERVED_7","RESERVED_8","abs","add","sub","div","RESERVED_13","neg", 86 "eq","RESERVED_16","RESERVED_17","drop","RESERVED_19","put","get","ifelse", 87 "random","mul","RESERVED_25","sqrt","dup","exch","index","roll","RESERVED_31", 88 "RESERVED_32","RESERVED_33","hflex","flex","hflex1","flex1","RESERVED_REST" 89 }; 90 91 95 HashMap GlyphsUsed; 96 99 ArrayList glyphsInList; 100 103 HashMap FDArrayUsed = new HashMap (); 104 107 HashMap [] hSubrsUsed; 108 111 ArrayList [] lSubrsUsed; 112 115 HashMap hGSubrsUsed = new HashMap (); 116 119 ArrayList lGSubrsUsed = new ArrayList (); 120 123 HashMap hSubrsUsedNonCID = new HashMap (); 124 127 ArrayList lSubrsUsedNonCID = new ArrayList (); 128 131 byte[][] NewLSubrsIndex; 132 135 byte[] NewSubrsIndexNonCID; 136 139 byte[] NewGSubrsIndex; 140 143 byte[] NewCharStringsIndex; 144 145 148 int GBias = 0; 149 150 153 LinkedList OutputList; 154 155 158 int NumOfHints=0; 159 160 161 166 public CFFFontSubset(RandomAccessFileOrArray rf,HashMap GlyphsUsed){ 167 super(rf); 169 this.GlyphsUsed = GlyphsUsed; 170 glyphsInList = new ArrayList (GlyphsUsed.keySet()); 172 173 174 for (int i=0;i<fonts.length;++i) 175 { 176 seek(fonts[i].charstringsOffset); 178 fonts[i].nglyphs = getCard16(); 179 180 seek(stringIndexOffset); 182 fonts[i].nstrings = getCard16()+standardStrings.length; 183 184 fonts[i].charstringsOffsets = getIndex(fonts[i].charstringsOffset); 186 187 if (fonts[i].fdselectOffset>=0) 189 { 190 readFDSelect(i); 192 BuildFDArrayUsed(i); 194 } 195 if (fonts[i].isCID) 196 ReadFDArray(i); 198 fonts[i].CharsetLength = CountCharset(fonts[i].charsetOffset,fonts[i].nglyphs); 200 } 201 } 202 203 209 int CountCharset(int Offset,int NumofGlyphs){ 210 int format; 211 int Length=0; 212 seek(Offset); 213 format = getCard8(); 215 switch (format){ 217 case 0: 218 Length = 1+2*NumofGlyphs; 219 break; 220 case 1: 221 Length = 1+3*CountRange(NumofGlyphs,1); 222 break; 223 case 2: 224 Length = 1+4*CountRange(NumofGlyphs,2); 225 break; 226 default: 227 break; 228 } 229 return Length; 230 } 231 232 238 int CountRange(int NumofGlyphs,int Type){ 239 int num=0; 240 char Sid; 241 int i=1,nLeft; 242 while (i<NumofGlyphs){ 243 num++; 244 Sid = getCard16(); 245 if (Type==1) 246 nLeft = getCard8(); 247 else 248 nLeft = getCard16(); 249 i += nLeft+1; 250 } 251 return num; 252 } 253 254 255 259 protected void readFDSelect(int Font) 260 { 261 int NumOfGlyphs = fonts[Font].nglyphs; 263 int[] FDSelect = new int[NumOfGlyphs]; 264 seek(fonts[Font].fdselectOffset); 266 fonts[Font].FDSelectFormat = getCard8(); 268 269 switch(fonts[Font].FDSelectFormat){ 270 case 0: 273 for (int i=0;i<NumOfGlyphs;i++) 274 { 275 FDSelect[i] = getCard8(); 276 } 277 fonts[Font].FDSelectLength = fonts[Font].nglyphs+1; 280 break; 281 case 3: 282 int nRanges = getCard16(); 285 int l=0; 286 int first = getCard16(); 288 for (int i=0;i<nRanges;i++) 289 { 290 int fd = getCard8(); 292 int last = getCard16(); 294 int steps = last-first; 296 for (int k=0;k<steps;k++) 297 { 298 FDSelect[l] = fd; 299 l++; 300 } 301 first = last; 303 } 304 fonts[Font].FDSelectLength = 1+2+nRanges*3+2; 306 break; 307 default: 308 break; 309 } 310 fonts[Font].FDSelect = FDSelect; 312 } 313 314 318 protected void BuildFDArrayUsed(int Font) 319 { 320 int[] FDSelect = fonts[Font].FDSelect; 321 for (int i=0;i<glyphsInList.size();i++) 323 { 324 int glyph = ((Integer )glyphsInList.get(i)).intValue(); 326 int FD = FDSelect[glyph]; 328 FDArrayUsed.put(new Integer (FD),null); 330 } 331 } 332 333 337 protected void ReadFDArray(int Font) 338 { 339 seek(fonts[Font].fdarrayOffset); 340 fonts[Font].FDArrayCount = getCard16(); 341 fonts[Font].FDArrayOffsize = getCard8(); 342 if (fonts[Font].FDArrayOffsize < 4) 345 fonts[Font].FDArrayOffsize++; 346 fonts[Font].FDArrayOffsets = getIndex(fonts[Font].fdarrayOffset); 347 } 348 349 350 357 public byte[] Process(String fontName)throws IOException { 358 try 359 { 360 buf.reOpen(); 362 int j; 364 for (j=0; j<fonts.length; j++) 365 if (fontName.equals(fonts[j].name)) break; 366 if (j==fonts.length) return null; 367 368 if (gsubrIndexOffset >= 0) 370 GBias = CalcBias(gsubrIndexOffset,j); 371 372 BuildNewCharString(j); 374 BuildNewLGSubrs(j); 376 byte[] Ret = BuildNewFile(j); 378 return Ret; 379 } 380 finally { 381 try { 382 buf.close(); 383 } 384 catch (Exception e) { 385 } 387 } 388 } 389 390 397 protected int CalcBias(int Offset,int Font) 398 { 399 seek(Offset); 400 int nSubrs = getCard16(); 401 if (fonts[Font].CharstringType == 1) 403 return 0; 404 else if (nSubrs < 1240) 406 return 107; 407 else if (nSubrs < 33900) 408 return 1131; 409 else 410 return 32768; 411 } 412 413 418 protected void BuildNewCharString(int FontIndex) throws IOException 419 { 420 NewCharStringsIndex = BuildNewIndex(fonts[FontIndex].charstringsOffsets,GlyphsUsed); 421 } 422 423 429 protected void BuildNewLGSubrs(int Font)throws IOException 430 { 431 if(fonts[Font].isCID) 434 { 435 hSubrsUsed = new HashMap [fonts[Font].fdprivateOffsets.length]; 438 lSubrsUsed = new ArrayList [fonts[Font].fdprivateOffsets.length]; 439 NewLSubrsIndex = new byte[fonts[Font].fdprivateOffsets.length][]; 441 fonts[Font].PrivateSubrsOffset = new int[fonts[Font].fdprivateOffsets.length]; 443 fonts[Font].PrivateSubrsOffsetsArray = new int[fonts[Font].fdprivateOffsets.length][]; 445 446 ArrayList FDInList = new ArrayList (FDArrayUsed.keySet()); 448 for (int j=0;j<FDInList.size();j++) 450 { 451 int FD = ((Integer )FDInList.get(j)).intValue(); 453 hSubrsUsed[FD] = new HashMap (); 454 lSubrsUsed[FD] = new ArrayList (); 455 BuildFDSubrsOffsets(Font,FD); 458 if(fonts[Font].PrivateSubrsOffset[FD]>=0) 460 { 461 BuildSubrUsed(Font,FD,fonts[Font].PrivateSubrsOffset[FD],fonts[Font].PrivateSubrsOffsetsArray[FD],hSubrsUsed[FD],lSubrsUsed[FD]); 464 NewLSubrsIndex[FD] = BuildNewIndex(fonts[Font].PrivateSubrsOffsetsArray[FD],hSubrsUsed[FD]); 466 } 467 } 468 } 469 else if (fonts[Font].privateSubrs>=0) 471 { 472 fonts[Font].SubrsOffsets = getIndex(fonts[Font].privateSubrs); 474 BuildSubrUsed(Font,-1,fonts[Font].privateSubrs,fonts[Font].SubrsOffsets,hSubrsUsedNonCID,lSubrsUsedNonCID); 477 } 478 BuildGSubrsUsed(Font); 481 if (fonts[Font].privateSubrs>=0) 482 NewSubrsIndexNonCID = BuildNewIndex(fonts[Font].SubrsOffsets,hSubrsUsedNonCID); 484 NewGSubrsIndex = BuildNewIndex(gsubrOffsets,hGSubrsUsed); 486 } 487 488 494 protected void BuildFDSubrsOffsets(int Font,int FD) 495 { 496 fonts[Font].PrivateSubrsOffset[FD] = -1; 498 seek(fonts[Font].fdprivateOffsets[FD]); 500 while (getPosition() < fonts[Font].fdprivateOffsets[FD]+fonts[Font].fdprivateLengths[FD]) 502 { 503 getDictItem(); 504 if (key=="Subrs") 506 fonts[Font].PrivateSubrsOffset[FD] = ((Integer )args[0]).intValue()+fonts[Font].fdprivateOffsets[FD]; 507 } 508 if (fonts[Font].PrivateSubrsOffset[FD] >= 0) 510 fonts[Font].PrivateSubrsOffsetsArray[FD] = getIndex(fonts[Font].PrivateSubrsOffset[FD]); 511 } 512 513 524 protected void BuildSubrUsed(int Font,int FD,int SubrOffset,int[] SubrsOffsets,HashMap hSubr,ArrayList lSubr) 525 { 526 527 int LBias = CalcBias(SubrOffset,Font); 529 530 for (int i=0;i<glyphsInList.size();i++) 532 { 533 int glyph = ((Integer )glyphsInList.get(i)).intValue(); 534 int Start = fonts[Font].charstringsOffsets[glyph]; 535 int End = fonts[Font].charstringsOffsets[glyph+1]; 536 537 if (FD >= 0) 539 { 540 EmptyStack(); 541 NumOfHints=0; 542 int GlyphFD = fonts[Font].FDSelect[glyph]; 544 if (GlyphFD == FD) 546 ReadASubr(Start,End,GBias,LBias,hSubr,lSubr,SubrsOffsets); 548 } 549 else 550 ReadASubr(Start,End,GBias,LBias,hSubr,lSubr,SubrsOffsets); 553 } 554 for (int i=0;i<lSubr.size();i++) 556 { 557 int Subr = ((Integer )lSubr.get(i)).intValue(); 559 if (Subr < SubrsOffsets.length-1 && Subr>=0) 561 { 562 int Start = SubrsOffsets[Subr]; 564 int End = SubrsOffsets[Subr+1]; 565 ReadASubr(Start,End,GBias,LBias,hSubr,lSubr,SubrsOffsets); 566 } 567 } 568 } 569 570 575 protected void BuildGSubrsUsed(int Font) 576 { 577 int LBias = 0; 578 int SizeOfNonCIDSubrsUsed = 0; 579 if (fonts[Font].privateSubrs>=0) 580 { 581 LBias = CalcBias(fonts[Font].privateSubrs,Font); 582 SizeOfNonCIDSubrsUsed = lSubrsUsedNonCID.size(); 583 } 584 585 for (int i=0;i<lGSubrsUsed.size();i++) 587 { 588 int Subr = ((Integer )lGSubrsUsed.get(i)).intValue(); 590 if (Subr < gsubrOffsets.length-1 && Subr>=0) 591 { 592 int Start = gsubrOffsets[Subr]; 594 int End = gsubrOffsets[Subr+1]; 595 596 if (fonts[Font].isCID) 597 ReadASubr(Start,End,GBias,0,hGSubrsUsed,lGSubrsUsed,null); 598 else 599 { 600 ReadASubr(Start,End,GBias,LBias,hSubrsUsedNonCID,lSubrsUsedNonCID,fonts[Font].SubrsOffsets); 601 if (SizeOfNonCIDSubrsUsed < lSubrsUsedNonCID.size()) 602 { 603 for (int j=SizeOfNonCIDSubrsUsed;j<lSubrsUsedNonCID.size();j++) 604 { 605 int LSubr = ((Integer )lSubrsUsedNonCID.get(j)).intValue(); 607 if (LSubr < fonts[Font].SubrsOffsets.length-1 && LSubr>=0) 608 { 609 int LStart = fonts[Font].SubrsOffsets[LSubr]; 611 int LEnd = fonts[Font].SubrsOffsets[LSubr+1]; 612 ReadASubr(LStart,LEnd,GBias,LBias,hSubrsUsedNonCID,lSubrsUsedNonCID,fonts[Font].SubrsOffsets); 613 } 614 } 615 SizeOfNonCIDSubrsUsed = lSubrsUsedNonCID.size(); 616 } 617 } 618 } 619 } 620 } 621 622 633 protected void ReadASubr(int begin,int end,int GBias,int LBias,HashMap hSubr,ArrayList lSubr,int[] LSubrsOffsets) 634 { 635 EmptyStack(); 637 NumOfHints = 0; 638 seek(begin); 640 while (getPosition() < end) 641 { 642 ReadCommand(); 644 int pos = getPosition(); 645 Object TopElement=null; 646 if (arg_count > 0) 647 TopElement = args[arg_count-1]; 648 int NumOfArgs = arg_count; 649 HandelStack(); 651 if (key=="callsubr") 653 { 654 if (NumOfArgs > 0) 656 { 657 int Subr = ((Integer )TopElement).intValue() + LBias; 659 if (!hSubr.containsKey(new Integer (Subr))) 661 { 662 hSubr.put(new Integer (Subr),null); 663 lSubr.add(new Integer (Subr)); 664 } 665 CalcHints(LSubrsOffsets[Subr],LSubrsOffsets[Subr+1],LBias,GBias,LSubrsOffsets); 666 seek(pos); 667 } 668 } 669 else if (key=="callgsubr") 671 { 672 if (NumOfArgs > 0) 674 { 675 int Subr = ((Integer )TopElement).intValue() + GBias; 677 if (!hGSubrsUsed.containsKey(new Integer (Subr))) 679 { 680 hGSubrsUsed.put(new Integer (Subr),null); 681 lGSubrsUsed.add(new Integer (Subr)); 682 } 683 CalcHints(gsubrOffsets[Subr],gsubrOffsets[Subr+1],LBias,GBias,LSubrsOffsets); 684 seek(pos); 685 } 686 } 687 else if (key == "hstem" || key == "vstem" || key == "hstemhm" || key == "vstemhm") 689 NumOfHints += NumOfArgs/2; 691 else if (key == "hintmask" || key == "cntrmask") 693 { 694 int SizeOfMask = NumOfHints/8; 696 if (NumOfHints%8 != 0 || SizeOfMask == 0) 697 SizeOfMask++; 698 for (int i=0;i<SizeOfMask;i++) 700 getCard8(); 701 } 702 } 703 } 704 705 709 protected void HandelStack() 710 { 711 int StackHandel = StackOpp(); 713 if (StackHandel < 2) 714 { 715 if (StackHandel==1) 717 PushStack(); 718 else 720 { 721 StackHandel *= -1; 723 for (int i=0;i<StackHandel;i++) 724 PopStack(); 725 } 726 727 } 728 else 730 EmptyStack(); 731 } 732 733 737 protected int StackOpp() 738 { 739 if (key == "ifelse") 740 return -3; 741 if (key == "roll" || key == "put") 742 return -2; 743 if (key == "callsubr" || key == "callgsubr" || key == "add" || key == "sub" || 744 key == "div" || key == "mul" || key == "drop" || key == "and" || 745 key == "or" || key == "eq") 746 return -1; 747 if (key == "abs" || key == "neg" || key == "sqrt" || key == "exch" || 748 key == "index" || key == "get" || key == "not" || key == "return") 749 return 0; 750 if (key == "random" || key == "dup") 751 return 1; 752 return 2; 753 } 754 755 759 protected void EmptyStack() 760 { 761 for (int i=0; i<arg_count; i++) args[i]=null; 763 arg_count = 0; 764 } 765 766 770 protected void PopStack() 771 { 772 if (arg_count>0) 773 { 774 args[arg_count-1]=null; 775 arg_count--; 776 } 777 } 778 779 783 protected void PushStack() 784 { 785 arg_count++; 786 } 787 788 791 protected void ReadCommand() 792 { 793 key = null; 794 boolean gotKey = false; 795 while (!gotKey) { 797 char b0 = getCard8(); 799 if (b0 == 28) { 802 int first = getCard8(); 803 int second = getCard8(); 804 args[arg_count] = new Integer (first<<8 | second); 805 arg_count++; 806 continue; 807 } 808 if (b0 >= 32 && b0 <= 246) { 810 args[arg_count] = new Integer (b0 - 139); 811 arg_count++; 812 continue; 813 } 814 if (b0 >= 247 && b0 <= 250) { 816 int w = getCard8(); 817 args[arg_count] = new Integer ((b0-247)*256 + w + 108); 818 arg_count++; 819 continue; 820 } 821 if (b0 >= 251 && b0 <= 254) { 823 int w = getCard8(); 824 args[arg_count] = new Integer (-(b0-251)*256 - w - 108); 825 arg_count++; 826 continue; 827 } 828 if (b0 == 255) { 830 int first = getCard8(); 831 int second = getCard8(); 832 int third = getCard8(); 833 int fourth = getCard8(); 834 args[arg_count] = new Integer (first<<24 | second<<16 | third<<8 | fourth); 835 arg_count++; 836 continue; 837 } 838 if (b0<=31 && b0 != 28) { 840 gotKey=true; 841 if (b0 == 12) 844 { 845 int b1 = getCard8(); 846 if (b1>SubrsEscapeFuncs.length-1) 847 b1 = SubrsEscapeFuncs.length-1; 848 key = SubrsEscapeFuncs[b1]; 849 } 850 else 851 key = SubrsFunctions[b0]; 852 continue; 853 } 854 } 855 } 856 857 867 protected int CalcHints(int begin,int end,int LBias,int GBias,int[] LSubrsOffsets) 868 { 869 seek(begin); 871 while (getPosition() < end) 872 { 873 ReadCommand(); 875 int pos = getPosition(); 876 Object TopElement = null; 877 if (arg_count>0) 878 TopElement = args[arg_count-1]; 879 int NumOfArgs = arg_count; 880 HandelStack(); 882 if (key=="callsubr") 884 { 885 if (NumOfArgs>0) 886 { 887 int Subr = ((Integer )TopElement).intValue() + LBias; 888 CalcHints(LSubrsOffsets[Subr],LSubrsOffsets[Subr+1],LBias,GBias,LSubrsOffsets); 889 seek(pos); 890 } 891 } 892 else if (key=="callgsubr") 894 { 895 if (NumOfArgs>0) 896 { 897 int Subr = ((Integer )TopElement).intValue() + GBias; 898 CalcHints(gsubrOffsets[Subr],gsubrOffsets[Subr+1],LBias,GBias,LSubrsOffsets); 899 seek(pos); 900 } 901 } 902 else if (key == "hstem" || key == "vstem" || key == "hstemhm" || key == "vstemhm") 904 NumOfHints += NumOfArgs/2; 906 else if (key == "hintmask" || key == "cntrmask") 908 { 909 int SizeOfMask = NumOfHints/8; 911 if (NumOfHints%8 != 0 || SizeOfMask == 0) 912 SizeOfMask++; 913 for (int i=0;i<SizeOfMask;i++) 915 getCard8(); 916 } 917 } 918 return NumOfHints; 919 } 920 921 922 930 protected byte[] BuildNewIndex(int[] Offsets,HashMap Used) throws IOException 931 { 932 int Offset=0; 933 int[] NewOffsets = new int[Offsets.length]; 934 for (int i=0;i<Offsets.length;++i) 936 { 937 NewOffsets[i] = Offset; 938 if (Used.containsKey(new Integer (i))) 941 Offset += Offsets[i+1] - Offsets[i]; 942 } 944 byte[] NewObjects = new byte[Offset]; 946 for (int i=0;i<Offsets.length-1;++i) 948 { 949 int start = NewOffsets[i]; 950 int end = NewOffsets[i+1]; 951 if (start != end) 954 { 955 buf.seek(Offsets[i]); 958 buf.readFully(NewObjects, start, end-start); 960 } 961 } 962 return AssembleIndex(NewOffsets,NewObjects); 964 } 965 966 973 protected byte[] AssembleIndex(int[] NewOffsets,byte[] NewObjects) 974 { 975 char Count = (char)(NewOffsets.length-1); 977 int Size = NewOffsets[NewOffsets.length-1]; 979 byte Offsize; 981 if (Size <= 0xff) Offsize = 1; 982 else if (Size <= 0xffff) Offsize = 2; 983 else if (Size <= 0xffffff) Offsize = 3; 984 else Offsize = 4; 985 byte[] NewIndex = new byte[2+1+Offsize*(Count+1)+NewObjects.length]; 988 int Place = 0; 990 NewIndex[Place++] = (byte) ((Count >>> 8) & 0xff); 992 NewIndex[Place++] = (byte) ((Count >>> 0) & 0xff); 993 NewIndex[Place++] = Offsize; 995 for (int i=0;i<NewOffsets.length;i++) 997 { 998 int Num = NewOffsets[i]-NewOffsets[0]+1; 1000 switch (Offsize) { 1002 case 4: 1003 NewIndex[Place++] = (byte) ((Num >>> 24) & 0xff); 1004 case 3: 1005 NewIndex[Place++] = (byte) ((Num >>> 16) & 0xff); 1006 case 2: 1007 NewIndex[Place++] = (byte) ((Num >>> 8) & 0xff); 1008 case 1: 1009 NewIndex[Place++] = (byte) ((Num >>> 0) & 0xff); 1010 } 1011 } 1012 for (int i=0;i<NewObjects.length;i++) 1014 { 1015 NewIndex[Place++] = NewObjects[i]; 1016 } 1017 return NewIndex; 1019 } 1020 1021 1026 protected byte[] BuildNewFile(int Font) 1027 { 1028 OutputList = new LinkedList (); 1030 1031 CopyHeader(); 1033 1034 BuildIndexHeader(1,1,1); 1036 OutputList.addLast(new UInt8Item((char)( 1+fonts[Font].name.length() ))); 1037 OutputList.addLast(new StringItem(fonts[Font].name)); 1038 1039 BuildIndexHeader(1,2,1); 1041 OffsetItem topdictIndex1Ref = new IndexOffsetItem(2); 1042 OutputList.addLast(topdictIndex1Ref); 1043 IndexBaseItem topdictBase = new IndexBaseItem(); 1044 OutputList.addLast(topdictBase); 1045 1046 OffsetItem charsetRef = new DictOffsetItem(); 1048 OffsetItem charstringsRef = new DictOffsetItem(); 1049 OffsetItem fdarrayRef = new DictOffsetItem(); 1050 OffsetItem fdselectRef = new DictOffsetItem(); 1051 OffsetItem privateRef = new DictOffsetItem(); 1052 1053 if ( !fonts[Font].isCID ) { 1055 OutputList.addLast(new DictNumberItem(fonts[Font].nstrings)); 1057 OutputList.addLast(new DictNumberItem(fonts[Font].nstrings+1)); 1058 OutputList.addLast(new DictNumberItem(0)); 1059 OutputList.addLast(new UInt8Item((char)12)); 1060 OutputList.addLast(new UInt8Item((char)30)); 1061 OutputList.addLast(new DictNumberItem(fonts[Font].nglyphs)); 1063 OutputList.addLast(new UInt8Item((char)12)); 1064 OutputList.addLast(new UInt8Item((char)34)); 1065 } 1069 seek(topdictOffsets[Font]); 1071 while (getPosition() < topdictOffsets[Font+1]) { 1073 int p1 = getPosition(); 1074 getDictItem(); 1075 int p2 = getPosition(); 1076 if (key=="Encoding" 1078 || key=="Private" 1080 || key=="FDSelect" 1081 || key=="FDArray" 1082 || key=="charset" 1083 || key=="CharStrings" 1084 ) { 1085 }else { 1086 OutputList.add(new RangeItem(buf,p1,p2-p1)); 1088 } 1089 } 1090 CreateKeys(fdarrayRef,fdselectRef,charsetRef,charstringsRef); 1092 1093 OutputList.addLast(new IndexMarkerItem(topdictIndex1Ref,topdictBase)); 1095 1096 1098 if (fonts[Font].isCID) 1099 OutputList.addLast(getEntireIndexRange(stringIndexOffset)); 1100 else 1104 CreateNewStringIndex(Font); 1105 1106 OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewGSubrsIndex),0,NewGSubrsIndex.length)); 1108 1109 if (fonts[Font].isCID) { 1112 1114 OutputList.addLast(new MarkerItem(fdselectRef)); 1117 if (fonts[Font].fdselectOffset>=0) 1119 OutputList.addLast(new RangeItem(buf,fonts[Font].fdselectOffset,fonts[Font].FDSelectLength)); 1120 else 1122 CreateFDSelect(fdselectRef,fonts[Font].nglyphs); 1123 1124 OutputList.addLast(new MarkerItem(charsetRef)); 1127 OutputList.addLast(new RangeItem(buf,fonts[Font].charsetOffset,fonts[Font].CharsetLength)); 1128 1129 if (fonts[Font].fdarrayOffset>=0) 1132 { 1133 OutputList.addLast(new MarkerItem(fdarrayRef)); 1135 Reconstruct(Font); 1137 } 1138 else 1139 CreateFDArray(fdarrayRef,privateRef,Font); 1141 1142 } 1143 else 1145 { 1146 CreateFDSelect(fdselectRef,fonts[Font].nglyphs); 1148 CreateCharset(charsetRef,fonts[Font].nglyphs); 1150 CreateFDArray(fdarrayRef,privateRef,Font); 1152 } 1153 1154 if (fonts[Font].privateOffset>=0) 1156 { 1157 IndexBaseItem PrivateBase = new IndexBaseItem(); 1159 OutputList.addLast(PrivateBase); 1160 OutputList.addLast(new MarkerItem(privateRef)); 1161 1162 OffsetItem Subr = new DictOffsetItem(); 1163 CreateNonCIDPrivate(Font,Subr); 1165 CreateNonCIDSubrs(Font,PrivateBase,Subr); 1167 } 1168 1169 OutputList.addLast(new MarkerItem(charstringsRef)); 1171 1172 OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewCharStringsIndex),0,NewCharStringsIndex.length)); 1174 1175 int[] currentOffset = new int[1]; 1177 currentOffset[0] = 0; 1178 Iterator listIter = OutputList.iterator(); 1180 while ( listIter.hasNext() ) { 1181 Item item = (Item) listIter.next(); 1182 item.increment(currentOffset); 1183 } 1184 listIter = OutputList.iterator(); 1186 while ( listIter.hasNext() ) { 1187 Item item = (Item) listIter.next(); 1188 item.xref(); 1189 } 1190 1191 int size = currentOffset[0]; 1192 byte[] b = new byte[size]; 1193 1194 listIter = OutputList.iterator(); 1196 while ( listIter.hasNext() ) { 1197 Item item = (Item) listIter.next(); 1198 item.emit(b); 1199 } 1200 return b; 1202 } 1203 1204 1207 protected void CopyHeader() 1208 { 1209 seek(0); 1210 int major = getCard8(); 1211 int minor = getCard8(); 1212 int hdrSize = getCard8(); 1213 int offSize = getCard8(); 1214 nextIndexOffset = hdrSize; 1215 OutputList.addLast(new RangeItem(buf,0,hdrSize)); 1216 } 1217 1218 1224 protected void BuildIndexHeader(int Count,int Offsize,int First) 1225 { 1226 OutputList.addLast(new UInt16Item((char)Count)); OutputList.addLast(new UInt8Item((char)Offsize)); switch(Offsize){ 1232 case 1: 1233 OutputList.addLast(new UInt8Item((char)First)); break; 1235 case 2: 1236 OutputList.addLast(new UInt16Item((char)First)); break; 1238 case 3: 1239 OutputList.addLast(new UInt24Item((char)First)); break; 1241 case 4: 1242 OutputList.addLast(new UInt32Item((char)First)); break; 1244 default: 1245 break; 1246 } 1247 } 1248 1249 1256 protected void CreateKeys(OffsetItem fdarrayRef,OffsetItem fdselectRef,OffsetItem charsetRef,OffsetItem charstringsRef) 1257 { 1258 OutputList.addLast(fdarrayRef); 1260 OutputList.addLast(new UInt8Item((char)12)); 1261 OutputList.addLast(new UInt8Item((char)36)); 1262 OutputList.addLast(fdselectRef); 1264 OutputList.addLast(new UInt8Item((char)12)); 1265 OutputList.addLast(new UInt8Item((char)37)); 1266 OutputList.addLast(charsetRef); 1268 OutputList.addLast(new UInt8Item((char)15)); 1269 OutputList.addLast(charstringsRef); 1271 OutputList.addLast(new UInt8Item((char)17)); 1272 } 1273 1274 1279 protected void CreateNewStringIndex(int Font) 1280 { 1281 String fdFontName = fonts[Font].name+"-OneRange"; 1282 if (fdFontName.length() > 127) 1283 fdFontName = fdFontName.substring(0,127); 1284 String extraStrings = "Adobe"+"Identity"+fdFontName; 1285 1286 int origStringsLen = stringOffsets[stringOffsets.length-1] 1287 - stringOffsets[0]; 1288 int stringsBaseOffset = stringOffsets[0]-1; 1289 1290 byte stringsIndexOffSize; 1291 if (origStringsLen+extraStrings.length() <= 0xff) stringsIndexOffSize = 1; 1292 else if (origStringsLen+extraStrings.length() <= 0xffff) stringsIndexOffSize = 2; 1293 else if (origStringsLen+extraStrings.length() <= 0xffffff) stringsIndexOffSize = 3; 1294 else stringsIndexOffSize = 4; 1295 1296 OutputList.addLast(new UInt16Item((char)((stringOffsets.length-1)+3))); OutputList.addLast(new UInt8Item((char)stringsIndexOffSize)); for (int i=0; i<stringOffsets.length; i++) 1299 OutputList.addLast(new IndexOffsetItem(stringsIndexOffSize, 1300 stringOffsets[i]-stringsBaseOffset)); 1301 int currentStringsOffset = stringOffsets[stringOffsets.length-1] 1302 - stringsBaseOffset; 1303 currentStringsOffset += ("Adobe").length(); 1305 OutputList.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); 1306 currentStringsOffset += ("Identity").length(); 1307 OutputList.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); 1308 currentStringsOffset += fdFontName.length(); 1309 OutputList.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); 1310 1311 OutputList.addLast(new RangeItem(buf,stringOffsets[0],origStringsLen)); 1312 OutputList.addLast(new StringItem(extraStrings)); 1313 } 1314 1315 1321 protected void CreateFDSelect(OffsetItem fdselectRef,int nglyphs) 1322 { 1323 OutputList.addLast(new MarkerItem(fdselectRef)); 1324 OutputList.addLast(new UInt8Item((char)3)); OutputList.addLast(new UInt16Item((char)1)); 1327 OutputList.addLast(new UInt16Item((char)0)); OutputList.addLast(new UInt8Item((char)0)); 1330 OutputList.addLast(new UInt16Item((char)nglyphs)); } 1332 1333 1339 protected void CreateCharset(OffsetItem charsetRef,int nglyphs) 1340 { 1341 OutputList.addLast(new MarkerItem(charsetRef)); 1342 OutputList.addLast(new UInt8Item((char)2)); OutputList.addLast(new UInt16Item((char)1)); OutputList.addLast(new UInt16Item((char)(nglyphs-1))); } 1346 1347 1355 protected void CreateFDArray(OffsetItem fdarrayRef,OffsetItem privateRef,int Font) 1356 { 1357 OutputList.addLast(new MarkerItem(fdarrayRef)); 1358 BuildIndexHeader(1,1,1); 1360 1361 OffsetItem privateIndex1Ref = new IndexOffsetItem(1); 1363 OutputList.addLast(privateIndex1Ref); 1364 IndexBaseItem privateBase = new IndexBaseItem(); 1365 OutputList.addLast(privateBase); 1367 int NewSize = fonts[Font].privateLength; 1370 int OrgSubrsOffsetSize = CalcSubrOffsetSize(fonts[Font].privateOffset,fonts[Font].privateLength); 1372 if (OrgSubrsOffsetSize != 0) 1374 NewSize += 5-OrgSubrsOffsetSize; 1375 OutputList.addLast(new DictNumberItem(NewSize)); 1376 OutputList.addLast(privateRef); 1377 OutputList.addLast(new UInt8Item((char)18)); 1379 OutputList.addLast(new IndexMarkerItem(privateIndex1Ref,privateBase)); 1380 } 1381 1382 1386 void Reconstruct(int Font) 1387 { 1388 OffsetItem[] fdPrivate = new DictOffsetItem[fonts[Font].FDArrayOffsets.length-1]; 1390 IndexBaseItem[] fdPrivateBase = new IndexBaseItem[fonts[Font].fdprivateOffsets.length]; 1391 OffsetItem[] fdSubrs = new DictOffsetItem[fonts[Font].fdprivateOffsets.length]; 1392 ReconstructFDArray(Font,fdPrivate); 1394 ReconstructPrivateDict(Font,fdPrivate,fdPrivateBase,fdSubrs); 1395 ReconstructPrivateSubrs(Font,fdPrivateBase,fdSubrs); 1396 } 1397 1398 1403 void ReconstructFDArray(int Font,OffsetItem[] fdPrivate) 1404 { 1405 BuildIndexHeader(fonts[Font].FDArrayCount,fonts[Font].FDArrayOffsize,1); 1407 1408 OffsetItem[] fdOffsets = new IndexOffsetItem[fonts[Font].FDArrayOffsets.length-1]; 1410 for (int i=0;i<fonts[Font].FDArrayOffsets.length-1;i++) 1411 { 1412 fdOffsets[i] = new IndexOffsetItem(fonts[Font].FDArrayOffsize); 1413 OutputList.addLast(fdOffsets[i]); 1414 } 1415 1416 IndexBaseItem fdArrayBase = new IndexBaseItem(); 1418 OutputList.addLast(fdArrayBase); 1419 1420 for (int k=0; k<fonts[Font].FDArrayOffsets.length-1; k++) { 1425 if (FDArrayUsed.containsKey(new Integer (k))) 1426 { 1427 seek(fonts[Font].FDArrayOffsets[k]); 1429 while (getPosition() < fonts[Font].FDArrayOffsets[k+1]) 1430 { 1431 int p1 = getPosition(); 1432 getDictItem(); 1433 int p2 = getPosition(); 1434 if (key=="Private") { 1437 int NewSize = ((Integer )args[0]).intValue(); 1439 int OrgSubrsOffsetSize = CalcSubrOffsetSize(fonts[Font].fdprivateOffsets[k],fonts[Font].fdprivateLengths[k]); 1441 if (OrgSubrsOffsetSize != 0) 1443 NewSize += 5-OrgSubrsOffsetSize; 1444 OutputList.addLast(new DictNumberItem(NewSize)); 1446 fdPrivate[k] = new DictOffsetItem(); 1447 OutputList.addLast(fdPrivate[k]); 1448 OutputList.addLast(new UInt8Item((char)18)); seek(p2); 1451 } 1452 else OutputList.addLast(new RangeItem(buf,p1,p2-p1)); 1455 } 1456 } 1457 OutputList.addLast(new IndexMarkerItem(fdOffsets[k],fdArrayBase)); 1459 } 1460 } 1461 1468 void ReconstructPrivateDict(int Font,OffsetItem[] fdPrivate,IndexBaseItem[] fdPrivateBase, 1469 OffsetItem[] fdSubrs) 1470 { 1471 1472 for (int i=0;i<fonts[Font].fdprivateOffsets.length;i++) 1476 { 1477 if (FDArrayUsed.containsKey(new Integer (i))) 1478 { 1479 OutputList.addLast(new MarkerItem(fdPrivate[i])); 1481 fdPrivateBase[i] = new IndexBaseItem(); 1482 OutputList.addLast(fdPrivateBase[i]); 1483 seek(fonts[Font].fdprivateOffsets[i]); 1485 while (getPosition() < fonts[Font].fdprivateOffsets[i]+fonts[Font].fdprivateLengths[i]) 1486 { 1487 int p1 = getPosition(); 1488 getDictItem(); 1489 int p2 = getPosition(); 1490 if (key=="Subrs") { 1493 fdSubrs[i] = new DictOffsetItem(); 1494 OutputList.addLast(fdSubrs[i]); 1495 OutputList.addLast(new UInt8Item((char)19)); } 1497 else 1499 OutputList.addLast(new RangeItem(buf,p1,p2-p1)); 1500 } 1501 } 1502 } 1503 } 1504 1505 1511 1512 void ReconstructPrivateSubrs(int Font,IndexBaseItem[] fdPrivateBase, 1513 OffsetItem[] fdSubrs) 1514 { 1515 for (int i=0;i<fonts[Font].fdprivateLengths.length;i++) 1517 { 1518 if (fdSubrs[i]!= null && fonts[Font].PrivateSubrsOffset[i] >= 0) 1521 { 1522 OutputList.addLast(new SubrMarkerItem(fdSubrs[i],fdPrivateBase[i])); 1523 OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewLSubrsIndex[i]),0,NewLSubrsIndex[i].length)); 1524 } 1525 } 1526 } 1527 1528 1535 int CalcSubrOffsetSize(int Offset,int Size) 1536 { 1537 int OffsetSize = 0; 1539 seek(Offset); 1541 while (getPosition() < Offset+Size) 1543 { 1544 int p1 = getPosition(); 1545 getDictItem(); 1546 int p2 = getPosition(); 1547 if (key=="Subrs") { 1549 OffsetSize = p2-p1-1; 1551 } 1552 } 1554 return OffsetSize; 1556 } 1557 1558 1563 protected int countEntireIndexRange(int indexOffset) 1564 { 1565 seek(indexOffset); 1567 int count = getCard16(); 1569 if (count==0) 1571 return 2; 1572 else 1573 { 1574 int indexOffSize = getCard8(); 1576 seek(indexOffset+2+1+count*indexOffSize); 1578 int size = getOffset(indexOffSize)-1; 1580 return 2+1+(count+1)*indexOffSize+size; 1582 } 1583 } 1584 1585 1591 void CreateNonCIDPrivate(int Font,OffsetItem Subr) 1592 { 1593 seek(fonts[Font].privateOffset); 1595 while (getPosition() < fonts[Font].privateOffset+fonts[Font].privateLength) 1596 { 1597 int p1 = getPosition(); 1598 getDictItem(); 1599 int p2 = getPosition(); 1600 if (key=="Subrs") { 1603 OutputList.addLast(Subr); 1604 OutputList.addLast(new UInt8Item((char)19)); } 1606 else 1608 OutputList.addLast(new RangeItem(buf,p1,p2-p1)); 1609 } 1610 } 1611 1612 1619 void CreateNonCIDSubrs(int Font,IndexBaseItem PrivateBase,OffsetItem Subrs) 1620 { 1621 OutputList.addLast(new SubrMarkerItem(Subrs,PrivateBase)); 1623 OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewSubrsIndexNonCID),0,NewSubrsIndexNonCID.length)); 1625 } 1626} | Popular Tags |