📄 cfffont.java
字号:
IndexBaseItem privateBase = new IndexBaseItem();
l.addLast(privateBase);
// looking at the PS that acrobat generates from a PDF with
// a CFF opentype font embeded 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 += (char)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 begining 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 + -