📄 cfffontsubset.java
字号:
* @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 accomodate 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 begining 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 begining 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 untill 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 + -