📄 cfffont.java
字号:
IndexBaseItem privateBase = new IndexBaseItem(); l.addLast(privateBase); // looking at the PS that acrobat generates from a PDF with // a CFF opentype font embedded with an identity-H encoding, // it seems that it does not need a FontName. //l.addLast(new DictNumberItem((standardStrings.length+(stringOffsets.length-1)+2))); //l.addLast(new UInt8Item((char)12)); //l.addLast(new UInt8Item((char)38)); // FontName l.addLast(new DictNumberItem(fonts[j].privateLength)); OffsetItem privateRef = new DictOffsetItem(); l.addLast(privateRef); l.addLast(new UInt8Item((char)18)); // Private l.addLast(new IndexMarkerItem(privateIndex1Ref,privateBase)); // copy the private index & local subroutines l.addLast(new MarkerItem(privateRef)); // copy the private dict and the local subroutines. // the length of the private dict seems to NOT include // the local subroutines. l.addLast(new RangeItem(buf,fonts[j].privateOffset,fonts[j].privateLength)); if (fonts[j].privateSubrs >= 0) { //System.err.println("has subrs="+fonts[j].privateSubrs+" ,len="+fonts[j].privateLength); l.addLast(getEntireIndexRange(fonts[j].privateSubrs)); } } // copy the charstring index l.addLast(new MarkerItem(charstringsRef)); l.addLast(getEntireIndexRange(fonts[j].charstringsOffset)); // now create the new CFF font int[] currentOffset = new int[1]; currentOffset[0] = 0; Iterator listIter = l.iterator(); while ( listIter.hasNext() ) { Item item = (Item) listIter.next(); item.increment(currentOffset); } listIter = l.iterator(); while ( listIter.hasNext() ) { Item item = (Item) listIter.next(); item.xref(); } int size = currentOffset[0]; byte[] b = new byte[size]; listIter = l.iterator(); while ( listIter.hasNext() ) { Item item = (Item) listIter.next(); item.emit(b); } return b; } public boolean isCID(String fontName) { int j; for (j=0; j<fonts.length; j++) if (fontName.equals(fonts[j].name)) return fonts[j].isCID; return false; } public boolean exists(String fontName) { int j; for (j=0; j<fonts.length; j++) if (fontName.equals(fonts[j].name)) return true; return false; } public String[] getNames() { String[] names = new String[ fonts.length ]; for (int i=0; i<fonts.length; i++) names[i] = fonts[i].name; return names; } /** * A random Access File or an array */ protected RandomAccessFileOrArray buf; private int offSize; protected int nameIndexOffset; protected int topdictIndexOffset; protected int stringIndexOffset; protected int gsubrIndexOffset; protected int[] nameOffsets; protected int[] topdictOffsets; protected int[] stringOffsets; protected int[] gsubrOffsets; /** * TODO Changed from private to protected by Ygal&Oren */ protected final class Font { public String name; public String fullName; public boolean isCID = false; public int privateOffset = -1; // only if not CID public int privateLength = -1; // only if not CID public int privateSubrs = -1; public int charstringsOffset = -1; public int encodingOffset = -1; public int charsetOffset = -1; public int fdarrayOffset = -1; // only if CID public int fdselectOffset = -1; // only if CID public int[] fdprivateOffsets; public int[] fdprivateLengths; public int[] fdprivateSubrs; // Added by Oren & Ygal public int nglyphs; public int nstrings; public int CharsetLength; public int[] charstringsOffsets; public int[] charset; public int[] FDSelect; public int FDSelectLength; public int FDSelectFormat; public int CharstringType = 2; public int FDArrayCount; public int FDArrayOffsize; public int[] FDArrayOffsets; public int[] PrivateSubrsOffset; public int[][] PrivateSubrsOffsetsArray; public int[] SubrsOffsets; } // Changed from private to protected by Ygal&Oren protected Font[] fonts; public CFFFont(RandomAccessFileOrArray inputbuffer) { //System.err.println("CFF: nStdString = "+standardStrings.length); buf = inputbuffer; seek(0); int major, minor; major = getCard8(); minor = getCard8(); //System.err.println("CFF Major-Minor = "+major+"-"+minor); int hdrSize = getCard8(); offSize = getCard8(); //System.err.println("offSize = "+offSize); //int count, indexOffSize, indexOffset, nextOffset; nameIndexOffset = hdrSize; nameOffsets = getIndex(nameIndexOffset); topdictIndexOffset = nameOffsets[nameOffsets.length-1]; topdictOffsets = getIndex(topdictIndexOffset); stringIndexOffset = topdictOffsets[topdictOffsets.length-1]; stringOffsets = getIndex(stringIndexOffset); gsubrIndexOffset = stringOffsets[stringOffsets.length-1]; gsubrOffsets = getIndex(gsubrIndexOffset); fonts = new Font[nameOffsets.length-1]; // now get the name index /* names = new String[nfonts]; privateOffset = new int[nfonts]; charsetOffset = new int[nfonts]; encodingOffset = new int[nfonts]; charstringsOffset = new int[nfonts]; fdarrayOffset = new int[nfonts]; fdselectOffset = new int[nfonts]; */ for (int j=0; j<nameOffsets.length-1; j++) { fonts[j] = new Font(); seek(nameOffsets[j]); fonts[j].name = ""; for (int k=nameOffsets[j]; k<nameOffsets[j+1]; k++) { fonts[j].name += getCard8(); } //System.err.println("name["+j+"]=<"+fonts[j].name+">"); } // string index //strings = new String[stringOffsets.length-1]; /* System.err.println("std strings = "+standardStrings.length); System.err.println("fnt strings = "+(stringOffsets.length-1)); for (char j=0; j<standardStrings.length+(stringOffsets.length-1); j++) { //seek(stringOffsets[j]); //strings[j] = ""; //for (int k=stringOffsets[j]; k<stringOffsets[j+1]; k++) { // strings[j] += (char)getCard8(); //} System.err.println("j="+(int)j+" <? "+(standardStrings.length+(stringOffsets.length-1))); System.err.println("strings["+(int)j+"]=<"+getString(j)+">"); } */ // top dict for (int j=0; j<topdictOffsets.length-1; j++) { seek(topdictOffsets[j]); while (getPosition() < topdictOffsets[j+1]) { getDictItem(); if (key=="FullName") { //System.err.println("getting fullname sid = "+((Integer)args[0]).intValue()); fonts[j].fullName = getString((char)((Integer)args[0]).intValue()); //System.err.println("got it"); } else if (key=="ROS") fonts[j].isCID = true; else if (key=="Private") { fonts[j].privateLength = ((Integer)args[0]).intValue(); fonts[j].privateOffset = ((Integer)args[1]).intValue(); } else if (key=="charset"){ fonts[j].charsetOffset = ((Integer)args[0]).intValue(); } else if (key=="Encoding"){ fonts[j].encodingOffset = ((Integer)args[0]).intValue(); ReadEncoding(fonts[j].encodingOffset); } else if (key=="CharStrings") { fonts[j].charstringsOffset = ((Integer)args[0]).intValue(); //System.err.println("charstrings "+fonts[j].charstringsOffset); // Added by Oren & Ygal int p = getPosition(); fonts[j].charstringsOffsets = getIndex(fonts[j].charstringsOffset); seek(p); } else if (key=="FDArray") fonts[j].fdarrayOffset = ((Integer)args[0]).intValue(); else if (key=="FDSelect") fonts[j].fdselectOffset = ((Integer)args[0]).intValue(); else if (key=="CharstringType") fonts[j].CharstringType = ((Integer)args[0]).intValue(); } // private dict if (fonts[j].privateOffset >= 0) { //System.err.println("PRIVATE::"); seek(fonts[j].privateOffset); while (getPosition() < fonts[j].privateOffset+fonts[j].privateLength) { getDictItem(); if (key=="Subrs") //Add the private offset to the lsubrs since the offset is // relative to the beginning of the PrivateDict fonts[j].privateSubrs = ((Integer)args[0]).intValue()+fonts[j].privateOffset; } } // fdarray index if (fonts[j].fdarrayOffset >= 0) { int[] fdarrayOffsets = getIndex(fonts[j].fdarrayOffset); fonts[j].fdprivateOffsets = new int[fdarrayOffsets.length-1]; fonts[j].fdprivateLengths = new int[fdarrayOffsets.length-1]; //System.err.println("FD Font::"); for (int k=0; k<fdarrayOffsets.length-1; k++) { seek(fdarrayOffsets[k]); while (getPosition() < fdarrayOffsets[k+1]) getDictItem(); if (key=="Private") { fonts[j].fdprivateLengths[k] = ((Integer)args[0]).intValue(); fonts[j].fdprivateOffsets[k] = ((Integer)args[1]).intValue(); } } } } //System.err.println("CFF: done"); } // ADDED BY Oren & Ygal void ReadEncoding(int nextIndexOffset){ int format; seek(nextIndexOffset); format = getCard8(); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -