protected byte[] BuildNewFile(int Font)
{
// Prepare linked list for new font components
OutputList = new List<Item>();
// copy the header of the font
CopyHeader();
// create a name index
BuildIndexHeader(1,1,1);
OutputList.Add(new UInt8Item((char)( 1+fonts[Font].name.Length)));
OutputList.Add(new StringItem(fonts[Font].name));
// create the topdict Index
BuildIndexHeader(1,2,1);
OffsetItem topdictIndex1Ref = new IndexOffsetItem(2);
OutputList.Add(topdictIndex1Ref);
IndexBaseItem topdictBase = new IndexBaseItem();
OutputList.Add(topdictBase);
// Initialise the Dict Items for later use
OffsetItem charsetRef = new DictOffsetItem();
OffsetItem charstringsRef = new DictOffsetItem();
OffsetItem fdarrayRef = new DictOffsetItem();
OffsetItem fdselectRef = new DictOffsetItem();
OffsetItem privateRef = new DictOffsetItem();
// If the font is not CID create the following keys
if ( !fonts[Font].isCID ) {
// create a ROS key
OutputList.Add(new DictNumberItem(fonts[Font].nstrings));
OutputList.Add(new DictNumberItem(fonts[Font].nstrings+1));
OutputList.Add(new DictNumberItem(0));
OutputList.Add(new UInt8Item((char)12));
OutputList.Add(new UInt8Item((char)30));
// create a CIDCount key
OutputList.Add(new DictNumberItem(fonts[Font].nglyphs));
OutputList.Add(new UInt8Item((char)12));
OutputList.Add(new UInt8Item((char)34));
// Sivan's comments
// 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.
}
// Go to the TopDict of the font being processed
Seek(topdictOffsets[Font]);
// Run untill the end of the TopDict
while (GetPosition() < topdictOffsets[Font+1]) {
int p1 = GetPosition();
GetDictItem();
int p2 = GetPosition();
// The encoding key is disregarded since CID has no encoding
if (key=="Encoding"
// These keys will be added manualy by the process.
|| key=="Private"
|| key=="FDSelect"
|| key=="FDArray"
|| key=="charset"
|| key=="CharStrings"
) {
}else {
//OtherWise copy key "as is" to the output list
OutputList.Add(new RangeItem(buf,p1,p2-p1));
}
}
// Create the FDArray, FDSelect, Charset and CharStrings Keys
CreateKeys(fdarrayRef,fdselectRef,charsetRef,charstringsRef);
// Mark the end of the top dict area
OutputList.Add(new IndexMarkerItem(topdictIndex1Ref,topdictBase));
// Copy the string index
if (fonts[Font].isCID)
OutputList.Add(GetEntireIndexRange(stringIndexOffset));
// If the font is not CID we need to 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
else
CreateNewStringIndex(Font);
// copy the new subsetted global subroutine index
OutputList.Add(new RangeItem(new RandomAccessFileOrArray(NewGSubrsIndex),0,NewGSubrsIndex.Length));
// deal with fdarray, fdselect, and the font descriptors
// If the font is CID:
if (fonts[Font].isCID) {
// copy the FDArray, FDSelect, charset
// Copy FDSelect
// Mark the beginning
OutputList.Add(new MarkerItem(fdselectRef));
// If an FDSelect exists copy it
if (fonts[Font].fdselectOffset>=0)
OutputList.Add(new RangeItem(buf,fonts[Font].fdselectOffset,fonts[Font].FDSelectLength));
// Else create a new one
else
CreateFDSelect(fdselectRef,fonts[Font].nglyphs);
// Copy the Charset
// Mark the beginning and copy entirly
OutputList.Add(new MarkerItem(charsetRef));
OutputList.Add(new RangeItem(buf,fonts[Font].charsetOffset,fonts[Font].CharsetLength));
// Copy the FDArray
// If an FDArray exists
if (fonts[Font].fdarrayOffset>=0)
{
// Mark the beginning
OutputList.Add(new MarkerItem(fdarrayRef));
// Build a new FDArray with its private dicts and their LSubrs
Reconstruct(Font);
}
else
// Else create a new one
CreateFDArray(fdarrayRef,privateRef,Font);
}
// If the font is not CID
else
{
// create FDSelect
CreateFDSelect(fdselectRef,fonts[Font].nglyphs);
// recreate a new charset
CreateCharset(charsetRef,fonts[Font].nglyphs);
// create a font dict index (fdarray)
CreateFDArray(fdarrayRef,privateRef,Font);
}
// if a private dict exists insert its subsetted version
if (fonts[Font].privateOffset>=0)
{
// Mark the beginning of the private dict
IndexBaseItem PrivateBase = new IndexBaseItem();
OutputList.Add(PrivateBase);
OutputList.Add(new MarkerItem(privateRef));
OffsetItem Subr = new DictOffsetItem();
// Build and copy the new private dict
CreateNonCIDPrivate(Font,Subr);
// Copy the new LSubrs index
CreateNonCIDSubrs(Font,PrivateBase,Subr);
}
// copy the charstring index
OutputList.Add(new MarkerItem(charstringsRef));
// Add the subsetted charstring
OutputList.Add(new RangeItem(new RandomAccessFileOrArray(NewCharStringsIndex),0,NewCharStringsIndex.Length));
// now create the new CFF font
int[] currentOffset = new int[1];
currentOffset[0] = 0;
// Count and save the offset for each item
foreach (Item item in OutputList) {
item.Increment(currentOffset);
}
// Compute the Xref for each of the offset items
foreach (Item item in OutputList) {
item.Xref();
}
int size = currentOffset[0];
byte[] b = new byte[size];
// Emit all the items into the new byte array
foreach (Item item in OutputList) {
item.Emit(b);
}
// Return the new stream
return b;
}