📄 cfffont.java
字号:
static protected final class UInt8Item extends Item { public char value; public UInt8Item(char value) {this.value=value;} public void increment(int[] currentOffset) { super.increment(currentOffset); currentOffset[0] += 1; } // this is incomplete! public void emit(byte[] buffer) { buffer[myOffset+0] = (byte) ((value >>> 0) & 0xff); } } static protected final class StringItem extends Item { public String s; public StringItem(String s) {this.s=s;} public void increment(int[] currentOffset) { super.increment(currentOffset); currentOffset[0] += s.length(); } public void emit(byte[] buffer) { for (int i=0; i<s.length(); i++) buffer[myOffset+i] = (byte) (s.charAt(i) & 0xff); } } /** A dictionary number on the list. * This implementation is inefficient: it doesn't use the variable-length * representation. */ static protected final class DictNumberItem extends Item { public final int value; public int size = 5; public DictNumberItem(int value) {this.value=value;} public void increment(int[] currentOffset) { super.increment(currentOffset); currentOffset[0] += size; } // this is incomplete! public void emit(byte[] buffer) { if (size==5) { buffer[myOffset] = 29; buffer[myOffset+1] = (byte) ((value >>> 24) & 0xff); buffer[myOffset+2] = (byte) ((value >>> 16) & 0xff); buffer[myOffset+3] = (byte) ((value >>> 8) & 0xff); buffer[myOffset+4] = (byte) ((value >>> 0) & 0xff); } } } /** An offset-marker item for the list. * It is used to mark an offset and to set the offset list item. */ static protected final class MarkerItem extends Item { OffsetItem p; public MarkerItem(OffsetItem pointerToMarker) {p=pointerToMarker;} public void xref() { p.set(this.myOffset); } } /** a utility that creates a range item for an entire index * * @param indexOffset where the index is * @return a range item representing the entire index */ protected RangeItem getEntireIndexRange(int indexOffset) { seek(indexOffset); int count = getCard16(); if (count==0) { return new RangeItem(buf,indexOffset,2); } else { int indexOffSize = getCard8(); seek(indexOffset+2+1+count*indexOffSize); int size = getOffset(indexOffSize)-1; return new RangeItem(buf,indexOffset, 2+1+(count+1)*indexOffSize+size); } } /** get a single CID font. The PDF architecture (1.4) * supports 16-bit strings only with CID CFF fonts, not * in Type-1 CFF fonts, so we convert the font to CID if * it is in the Type-1 format. * Two other tasks that we need to do are to select * only a single font from the CFF package (this again is * a PDF restriction) and to subset the CharStrings glyph * description. */ public byte[] getCID(String fontName) //throws java.io.FileNotFoundException { int j; for (j=0; j<fonts.length; j++) if (fontName.equals(fonts[j].name)) break; if (j==fonts.length) return null; LinkedList l = new LinkedList(); // copy the header seek(0); int major = getCard8(); int minor = getCard8(); int hdrSize = getCard8(); int offSize = getCard8(); nextIndexOffset = hdrSize; l.addLast(new RangeItem(buf,0,hdrSize)); int nglyphs=-1, nstrings=-1; if ( ! fonts[j].isCID ) { // count the glyphs seek(fonts[j].charstringsOffset); nglyphs = getCard16(); seek(stringIndexOffset); nstrings = getCard16()+standardStrings.length; //System.err.println("number of glyphs = "+nglyphs); } // create a name index l.addLast(new UInt16Item((char)1)); // count l.addLast(new UInt8Item((char)1)); // offSize l.addLast(new UInt8Item((char)1)); // first offset l.addLast(new UInt8Item((char)( 1+fonts[j].name.length() ))); l.addLast(new StringItem(fonts[j].name)); // create the topdict Index l.addLast(new UInt16Item((char)1)); // count l.addLast(new UInt8Item((char)2)); // offSize l.addLast(new UInt16Item((char)1)); // first offset OffsetItem topdictIndex1Ref = new IndexOffsetItem(2); l.addLast(topdictIndex1Ref); IndexBaseItem topdictBase = new IndexBaseItem(); l.addLast(topdictBase); /* int maxTopdictLen = (topdictOffsets[j+1]-topdictOffsets[j]) + 9*2 // at most 9 new keys + 8*5 // 8 new integer arguments + 3*2;// 3 new SID arguments */ //int topdictNext = 0; //byte[] topdict = new byte[maxTopdictLen]; OffsetItem charsetRef = new DictOffsetItem(); OffsetItem charstringsRef = new DictOffsetItem(); OffsetItem fdarrayRef = new DictOffsetItem(); OffsetItem fdselectRef = new DictOffsetItem(); if ( !fonts[j].isCID ) { // create a ROS key l.addLast(new DictNumberItem(nstrings)); l.addLast(new DictNumberItem(nstrings+1)); l.addLast(new DictNumberItem(0)); l.addLast(new UInt8Item((char)12)); l.addLast(new UInt8Item((char)30)); // create a CIDCount key l.addLast(new DictNumberItem(nglyphs)); l.addLast(new UInt8Item((char)12)); l.addLast(new UInt8Item((char)34)); // What about UIDBase (12,35)? Don't know what is it. // I don't think we need FontName; the font I looked at didn't have it. } // create an FDArray key l.addLast(fdarrayRef); l.addLast(new UInt8Item((char)12)); l.addLast(new UInt8Item((char)36)); // create an FDSelect key l.addLast(fdselectRef); l.addLast(new UInt8Item((char)12)); l.addLast(new UInt8Item((char)37)); // create an charset key l.addLast(charsetRef); l.addLast(new UInt8Item((char)15)); // create a CharStrings key l.addLast(charstringsRef); l.addLast(new UInt8Item((char)17)); seek(topdictOffsets[j]); while (getPosition() < topdictOffsets[j+1]) { int p1 = getPosition(); getDictItem(); int p2 = getPosition(); if (key=="Encoding" || key=="Private" || key=="FDSelect" || key=="FDArray" || key=="charset" || key=="CharStrings" ) { // just drop them } else { l.add(new RangeItem(buf,p1,p2-p1)); } } l.addLast(new IndexMarkerItem(topdictIndex1Ref,topdictBase)); // Copy the string index and append new strings. // We need 3 more strings: Registry, Ordering, and a FontName for one FD. // The total length is at most "Adobe"+"Identity"+63 = 76 if (fonts[j].isCID) { l.addLast(getEntireIndexRange(stringIndexOffset)); } else { String fdFontName = fonts[j].name+"-OneRange"; if (fdFontName.length() > 127) fdFontName = fdFontName.substring(0,127); String extraStrings = "Adobe"+"Identity"+fdFontName; int origStringsLen = stringOffsets[stringOffsets.length-1] - stringOffsets[0]; int stringsBaseOffset = stringOffsets[0]-1; byte stringsIndexOffSize; if (origStringsLen+extraStrings.length() <= 0xff) stringsIndexOffSize = 1; else if (origStringsLen+extraStrings.length() <= 0xffff) stringsIndexOffSize = 2; else if (origStringsLen+extraStrings.length() <= 0xffffff) stringsIndexOffSize = 3; else stringsIndexOffSize = 4; l.addLast(new UInt16Item((char)((stringOffsets.length-1)+3))); // count l.addLast(new UInt8Item((char)stringsIndexOffSize)); // offSize for (int i=0; i<stringOffsets.length; i++) l.addLast(new IndexOffsetItem(stringsIndexOffSize, stringOffsets[i]-stringsBaseOffset)); int currentStringsOffset = stringOffsets[stringOffsets.length-1] - stringsBaseOffset; //l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); currentStringsOffset += "Adobe".length(); l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); currentStringsOffset += "Identity".length(); l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); currentStringsOffset += fdFontName.length(); l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); l.addLast(new RangeItem(buf,stringOffsets[0],origStringsLen)); l.addLast(new StringItem(extraStrings)); } // copy the global subroutine index l.addLast(getEntireIndexRange(gsubrIndexOffset)); // deal with fdarray, fdselect, and the font descriptors if (fonts[j].isCID) { // copy the FDArray, FDSelect, charset } else { // create FDSelect l.addLast(new MarkerItem(fdselectRef)); l.addLast(new UInt8Item((char)3)); // format identifier l.addLast(new UInt16Item((char)1)); // nRanges l.addLast(new UInt16Item((char)0)); // Range[0].firstGlyph l.addLast(new UInt8Item((char)0)); // Range[0].fd l.addLast(new UInt16Item((char)nglyphs)); // sentinel // recreate a new charset // This format is suitable only for fonts without subsetting l.addLast(new MarkerItem(charsetRef)); l.addLast(new UInt8Item((char)2)); // format identifier l.addLast(new UInt16Item((char)1)); // first glyph in range (ignore .notdef) l.addLast(new UInt16Item((char)(nglyphs-1))); // nLeft // now all are covered, the data structure is complete. // create a font dict index (fdarray) l.addLast(new MarkerItem(fdarrayRef)); l.addLast(new UInt16Item((char)1)); l.addLast(new UInt8Item((char)1)); // offSize l.addLast(new UInt8Item((char)1)); // first offset OffsetItem privateIndex1Ref = new IndexOffsetItem(1); l.addLast(privateIndex1Ref);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -