📄 cfffontsubset.java
字号:
/** * Function Build the header of an index * @param Count the count field of the index * @param Offsize the offsize field of the index * @param First the first offset of the index */ protected void BuildIndexHeader(int Count,int Offsize,int First) { // Add the count field OutputList.addLast(new UInt16Item((char)Count)); // count // Add the offsize field OutputList.addLast(new UInt8Item((char)Offsize)); // offSize // Add the first offset according to the offsize switch(Offsize){ case 1: OutputList.addLast(new UInt8Item((char)First)); // first offset break; case 2: OutputList.addLast(new UInt16Item((char)First)); // first offset break; case 3: OutputList.addLast(new UInt24Item((char)First)); // first offset break; case 4: OutputList.addLast(new UInt32Item((char)First)); // first offset break; default: break; } } /** * Function adds the keys into the TopDict * @param fdarrayRef OffsetItem for the FDArray * @param fdselectRef OffsetItem for the FDSelect * @param charsetRef OffsetItem for the CharSet * @param charstringsRef OffsetItem for the CharString */ protected void CreateKeys(OffsetItem fdarrayRef,OffsetItem fdselectRef,OffsetItem charsetRef,OffsetItem charstringsRef) { // create an FDArray key OutputList.addLast(fdarrayRef); OutputList.addLast(new UInt8Item((char)12)); OutputList.addLast(new UInt8Item((char)36)); // create an FDSelect key OutputList.addLast(fdselectRef); OutputList.addLast(new UInt8Item((char)12)); OutputList.addLast(new UInt8Item((char)37)); // create an charset key OutputList.addLast(charsetRef); OutputList.addLast(new UInt8Item((char)15)); // create a CharStrings key OutputList.addLast(charstringsRef); OutputList.addLast(new UInt8Item((char)17)); } /** * Function takes the original string item and adds the new strings * to accommodate the CID rules * @param Font the font */ protected void CreateNewStringIndex(int Font) { String fdFontName = fonts[Font].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; OutputList.addLast(new UInt16Item((char)((stringOffsets.length-1)+3))); // count OutputList.addLast(new UInt8Item((char)stringsIndexOffSize)); // offSize for (int i=0; i<stringOffsets.length; i++) OutputList.addLast(new IndexOffsetItem(stringsIndexOffSize, stringOffsets[i]-stringsBaseOffset)); int currentStringsOffset = stringOffsets[stringOffsets.length-1] - stringsBaseOffset; //l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); currentStringsOffset += "Adobe".length(); OutputList.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); currentStringsOffset += "Identity".length(); OutputList.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); currentStringsOffset += fdFontName.length(); OutputList.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset)); OutputList.addLast(new RangeItem(buf,stringOffsets[0],origStringsLen)); OutputList.addLast(new StringItem(extraStrings)); } /** * Function creates new FDSelect for non-CID fonts. * The FDSelect built uses a single range for all glyphs * @param fdselectRef OffsetItem for the FDSelect * @param nglyphs the number of glyphs in the font */ protected void CreateFDSelect(OffsetItem fdselectRef,int nglyphs) { OutputList.addLast(new MarkerItem(fdselectRef)); OutputList.addLast(new UInt8Item((char)3)); // format identifier OutputList.addLast(new UInt16Item((char)1)); // nRanges OutputList.addLast(new UInt16Item((char)0)); // Range[0].firstGlyph OutputList.addLast(new UInt8Item((char)0)); // Range[0].fd OutputList.addLast(new UInt16Item((char)nglyphs)); // sentinel } /** * Function creates new CharSet for non-CID fonts. * The CharSet built uses a single range for all glyphs * @param charsetRef OffsetItem for the CharSet * @param nglyphs the number of glyphs in the font */ protected void CreateCharset(OffsetItem charsetRef,int nglyphs) { OutputList.addLast(new MarkerItem(charsetRef)); OutputList.addLast(new UInt8Item((char)2)); // format identifier OutputList.addLast(new UInt16Item((char)1)); // first glyph in range (ignore .notdef) OutputList.addLast(new UInt16Item((char)(nglyphs-1))); // nLeft } /** * Function creates new FDArray for non-CID fonts. * The FDArray built has only the "Private" operator that points to the font's * original private dict * @param fdarrayRef OffsetItem for the FDArray * @param privateRef OffsetItem for the Private Dict * @param Font the font */ protected void CreateFDArray(OffsetItem fdarrayRef,OffsetItem privateRef,int Font) { OutputList.addLast(new MarkerItem(fdarrayRef)); // Build the header (count=offsize=first=1) BuildIndexHeader(1,1,1); // Mark OffsetItem privateIndex1Ref = new IndexOffsetItem(1); OutputList.addLast(privateIndex1Ref); IndexBaseItem privateBase = new IndexBaseItem(); // Insert the private operands and operator OutputList.addLast(privateBase); // Calc the new size of the private after subsetting // Origianl size int NewSize = fonts[Font].privateLength; // Calc the original size of the Subr offset in the private int OrgSubrsOffsetSize = CalcSubrOffsetSize(fonts[Font].privateOffset,fonts[Font].privateLength); // Increase the ptivate's size if (OrgSubrsOffsetSize != 0) NewSize += 5-OrgSubrsOffsetSize; OutputList.addLast(new DictNumberItem(NewSize)); OutputList.addLast(privateRef); OutputList.addLast(new UInt8Item((char)18)); // Private OutputList.addLast(new IndexMarkerItem(privateIndex1Ref,privateBase)); } /** * Function reconstructs the FDArray, PrivateDict and LSubr for CID fonts * @param Font the font */ void Reconstruct(int Font) { // Init for later use OffsetItem[] fdPrivate = new DictOffsetItem[fonts[Font].FDArrayOffsets.length-1]; IndexBaseItem[] fdPrivateBase = new IndexBaseItem[fonts[Font].fdprivateOffsets.length]; OffsetItem[] fdSubrs = new DictOffsetItem[fonts[Font].fdprivateOffsets.length]; // Reconstruct each type ReconstructFDArray(Font,fdPrivate); ReconstructPrivateDict(Font,fdPrivate,fdPrivateBase,fdSubrs); ReconstructPrivateSubrs(Font,fdPrivateBase,fdSubrs); } /** * Function subsets the FDArray and builds the new one with new offsets * @param Font The font * @param fdPrivate OffsetItem Array (one for each FDArray) */ void ReconstructFDArray(int Font,OffsetItem[] fdPrivate) { // Build the header of the index BuildIndexHeader(fonts[Font].FDArrayCount,fonts[Font].FDArrayOffsize,1); // For each offset create an Offset Item OffsetItem[] fdOffsets = new IndexOffsetItem[fonts[Font].FDArrayOffsets.length-1]; for (int i=0;i<fonts[Font].FDArrayOffsets.length-1;i++) { fdOffsets[i] = new IndexOffsetItem(fonts[Font].FDArrayOffsize); OutputList.addLast(fdOffsets[i]); } // Declare beginning of the object array IndexBaseItem fdArrayBase = new IndexBaseItem(); OutputList.addLast(fdArrayBase); // For each object check if that FD is used. // if is used build a new one by changing the private object // Else do nothing // At the end of each object mark its ending (Even if wasn't written) for (int k=0; k<fonts[Font].FDArrayOffsets.length-1; k++) { if (FDArrayUsed.containsKey(new Integer (k))) { // Goto beginning of objects seek(fonts[Font].FDArrayOffsets[k]); while (getPosition() < fonts[Font].FDArrayOffsets[k+1]) { int p1 = getPosition(); getDictItem(); int p2 = getPosition(); // If the dictItem is the "Private" then compute and copy length, // use marker for offset and write operator number if (key=="Private") { // Save the original length of the private dict int NewSize = ((Integer)args[0]).intValue(); // Save the size of the offset to the subrs in that private int OrgSubrsOffsetSize = CalcSubrOffsetSize(fonts[Font].fdprivateOffsets[k],fonts[Font].fdprivateLengths[k]); // Increase the private's length accordingly if (OrgSubrsOffsetSize != 0) NewSize += 5-OrgSubrsOffsetSize; // Insert the new size, OffsetItem and operator key number OutputList.addLast(new DictNumberItem(NewSize)); fdPrivate[k] = new DictOffsetItem(); OutputList.addLast(fdPrivate[k]); OutputList.addLast(new UInt8Item((char)18)); // Private // Go back to place seek(p2); } // Else copy the entire range else // other than private OutputList.addLast(new RangeItem(buf,p1,p2-p1)); } } // Mark the ending of the object (even if wasn't written) OutputList.addLast(new IndexMarkerItem(fdOffsets[k],fdArrayBase)); } } /** * Function Adds the new private dicts (only for the FDs used) to the list * @param Font the font * @param fdPrivate OffsetItem array one element for each private * @param fdPrivateBase IndexBaseItem array one element for each private * @param fdSubrs OffsetItem array one element for each private */ void ReconstructPrivateDict(int Font,OffsetItem[] fdPrivate,IndexBaseItem[] fdPrivateBase, OffsetItem[] fdSubrs) { // For each fdarray private dict check if that FD is used. // if is used build a new one by changing the subrs offset // Else do nothing for (int i=0;i<fonts[Font].fdprivateOffsets.length;i++) { if (FDArrayUsed.containsKey(new Integer (i))) { // Mark beginning OutputList.addLast(new MarkerItem(fdPrivate[i])); fdPrivateBase[i] = new IndexBaseItem(); OutputList.addLast(fdPrivateBase[i]); // Goto beginning of objects seek(fonts[Font].fdprivateOffsets[i]); while (getPosition() < fonts[Font].fdprivateOffsets[i]+fonts[Font].fdprivateLengths[i]) { int p1 = getPosition(); getDictItem(); int p2 = getPosition(); // If the dictItem is the "Subrs" then, // use marker for offset and write operator number if (key=="Subrs") { fdSubrs[i] = new DictOffsetItem(); OutputList.addLast(fdSubrs[i]); OutputList.addLast(new UInt8Item((char)19)); // Subrs } // Else copy the entire range else OutputList.addLast(new RangeItem(buf,p1,p2-p1)); } } } } /** * Function Adds the new LSubrs dicts (only for the FDs used) to the list * @param Font The index of the font * @param fdPrivateBase The IndexBaseItem array for the linked list * @param fdSubrs OffsetItem array for the linked list */ void ReconstructPrivateSubrs(int Font,IndexBaseItem[] fdPrivateBase, OffsetItem[] fdSubrs) { // For each private dict for (int i=0;i<fonts[Font].fdprivateLengths.length;i++) { // If that private dict's Subrs are used insert the new LSubrs // computed earlier if (fdSubrs[i]!= null && fonts[Font].PrivateSubrsOffset[i] >= 0) { OutputList.addLast(new SubrMarkerItem(fdSubrs[i],fdPrivateBase[i])); OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewLSubrsIndex[i]),0,NewLSubrsIndex[i].length)); } } } /** * Calculates how many byte it took to write the offset for the subrs in a specific * private dict. * @param Offset The Offset for the private dict * @param Size The size of the private dict * @return The size of the offset of the subrs in the private dict */ int CalcSubrOffsetSize(int Offset,int Size) { // Set the size to 0 int OffsetSize = 0; // Go to the beginning of the private dict seek(Offset); // Go until the end of the private dict while (getPosition() < Offset+Size) { int p1 = getPosition(); getDictItem(); int p2 = getPosition(); // When reached to the subrs offset if (key=="Subrs") { // The Offsize (minus the subrs key) OffsetSize = p2-p1-1; } // All other keys are ignored } // return the size return OffsetSize; } /** * Function computes the size of an index * @param indexOffset The offset for the computed index * @return The size of the index */ protected int countEntireIndexRange(int indexOffset) { // Go to the beginning of the index seek(indexOffset); // Read the count field int count = getCard16(); // If count==0 -> size=2 if (count==0) return 2; else { // Read the offsize field int indexOffSize = getCard8(); // Go to the last element of the offset array seek(indexOffset+2+1+count*indexOffSize); // The size of the object array is the value of the last element-1 int size = getOffset(indexOffSize)-1; // Return the size of the entire index return 2+1+(count+1)*indexOffSize+size; } } /** * The function creates a private dict for a font that was not CID * All the keys are copied as is except for the subrs key * @param Font the font * @param Subr The OffsetItem for the subrs of the private */ void CreateNonCIDPrivate(int Font,OffsetItem Subr) { // Go to the beginning of the private dict and read until the end seek(fonts[Font].privateOffset); while (getPosition() < fonts[Font].privateOffset+fonts[Font].privateLength) { int p1 = getPosition(); getDictItem(); int p2 = getPosition(); // If the dictItem is the "Subrs" then, // use marker for offset and write operator number if (key=="Subrs") { OutputList.addLast(Subr); OutputList.addLast(new UInt8Item((char)19)); // Subrs } // Else copy the entire range else OutputList.addLast(new RangeItem(buf,p1,p2-p1)); } } /** * the function marks the beginning of the subrs index and adds the subsetted subrs * index to the output list. * @param Font the font * @param PrivateBase IndexBaseItem for the private that's referencing to the subrs * @param Subrs OffsetItem for the subrs */ void CreateNonCIDSubrs(int Font,IndexBaseItem PrivateBase,OffsetItem Subrs) { // Mark the beginning of the Subrs index OutputList.addLast(new SubrMarkerItem(Subrs,PrivateBase)); // Put the subsetted new subrs index OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewSubrsIndexNonCID),0,NewSubrsIndexNonCID.length)); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -