protected void ReadLoca()
        {
            TableData tdata = tables["head"];

            if (tdata == null)
            {
                throw new Exception("Table head not found");
            }
            int nindex = tdata.Location + HEAD_LOCA_FORMAT_OFFSET;

            //rf.Seek(nindex,SeekOrigin.Begin);
            locaShortTable = (ByteArrayToUShort(rfarray, nindex, 4) == 0);
            nindex         = nindex + 4;

            // Cached
            Monitor.Enter(tflag);
            try
            {
                if (CachedlocaTables == null)
                {
                    CachedlocaTables = new SortedList <string, int[]>();
                }
                if (CachedlocaTables.IndexOfKey(PostcriptName) >= 0)
                {
                    locaTable = CachedlocaTables[PostcriptName];
                }
                else
                {
                    tdata = tables["loca"];
                    if (tdata == null)
                    {
                        throw new Exception("Table loca not found");
                    }
                    nindex = tdata.Location;
                    if (locaShortTable)
                    {
                        int entries = tdata.Length / 2;
                        locaTable = new int[entries];
                        for (int k = 0; k < entries; ++k)
                        {
                            locaTable[k] = ByteArrayToUShort(rfarray, nindex, 2) * 2;
                            nindex       = nindex + 2;
                        }
                    }
                    else
                    {
                        int entries = tdata.Length / 4;
                        locaTable = new int[entries];
                        for (int k = 0; k < entries; ++k)
                        {
                            locaTable[k] = ByteArrayToInt(rfarray, nindex, 4);
                            nindex       = nindex + 4;
                        }
                    }
                    CachedlocaTables.Add(PostcriptName, locaTable);
                }
            }
            finally
            {
                Monitor.Exit(tflag);
            }
        }
        protected void AssembleFont()
        {
            int fullFontSize = 0;
            int tablesUsed   = 2;
            int len          = 0;

            for (int k = 0; k < tablenameconst.Length; ++k)
            {
                string name = tablenameconst[k];
                if (name.Equals("glyf") || name.Equals("loca"))
                {
                    continue;
                }
                TableData tdata = tables[name];
                if (tdata == null)
                {
                    continue;
                }
                ++tablesUsed;
                fullFontSize += (tdata.Length + 3) & (~3);
            }
            fullFontSize += newLocaTableOut.Length;
            fullFontSize += newGlyfTable.Length;
            int iref = 16 * tablesUsed + 12;

            fullFontSize += iref;
            outFont       = new byte[fullFontSize];
            fontPtr       = 0;
            WriteFontInt(0x00010000);
            WriteFontShort(tablesUsed);
            int selector = entryselec[tablesUsed];

            WriteFontShort((1 << selector) * 16);
            WriteFontShort(selector);
            WriteFontShort((tablesUsed - (1 << selector)) * 16);
            for (int k = 0; k < tablenameconst.Length; ++k)
            {
                string    name  = tablenameconst[k];
                TableData tdata = tables[name];
                if (tdata == null)
                {
                    continue;
                }
                WriteFontString(name);
                if (name.Equals("glyf"))
                {
                    WriteFontInt(CalculateChecksum(newGlyfTable));
                    len = glyfTableRealSize;
                }
                else if (name.Equals("loca"))
                {
                    WriteFontInt(CalculateChecksum(newLocaTableOut));
                    len = locaTableRealSize;
                }
                else
                {
                    WriteFontInt(tdata.Checksum);
                    len = tdata.Length;
                }
                WriteFontInt(iref);
                WriteFontInt(len);
                iref += (len + 3) & (~3);
            }
            for (int k = 0; k < tablenameconst.Length; ++k)
            {
                string    name  = tablenameconst[k];
                TableData tdata = tables[name];
                if (tdata == null)
                {
                    continue;
                }
                if (name.Equals("glyf"))
                {
                    Array.Copy(newGlyfTable, 0, outFont, fontPtr, newGlyfTable.Length);
                    fontPtr     += newGlyfTable.Length;
                    newGlyfTable = null;
                }
                else if (name.Equals("loca"))
                {
                    Array.Copy(newLocaTableOut, 0, outFont, fontPtr, newLocaTableOut.Length);
                    fontPtr        += newLocaTableOut.Length;
                    newLocaTableOut = null;
                }
                else
                {
                    int nindex = tdata.Location;
                    Array.Copy(rfarray, nindex, outFont, fontPtr, tdata.Length);
                    fontPtr += (tdata.Length + 3) & (~3);
                }
            }
        }