Represents an Open Type Font font in memory.
Esempio n. 1
0
 public void Read(FontData fontData)
 {
     this.Tag      = fontData.ReadTag();
     this.CheckSum = fontData.ReadULong();
     this.Offset   = fontData.ReadLong();
     this.Length   = (int)fontData.ReadULong();
 }
Esempio n. 2
0
 internal FontData[] GetFontDataList()
 {
   int count = fontDataTable.Values.Count;
   FontData[] fontDataArray = new FontData[count];
   fontDataTable.Values.CopyTo(fontDataArray, 0);
   return fontDataArray;
 }
        public static void Test()
        {
            Font     font  = new Font("Times New Roman", 10);
            FontData image = new FontData(font);

//      Font font = new Font("Isabelle", 12);
//      LOGFONT logFont = new LOGFONT();
//      font.ToLogFont(logFont);
//
//      IntPtr hfont = CreateFontIndirect(logFont);
////      IntPtr hfont2 = font.ToHfont();
////      System.Windows.Forms.MessageBox.Show(hfont2.ToString());
//
//      Graphics gfx = Graphics.FromHwnd(IntPtr.Zero);
//      IntPtr hdc = gfx.GetHdc();
//      IntPtr oldFont =  SelectObject(hdc, hfont);
//      int size = GetFontData(hdc, 0, 0, null, 0);
//
//      byte[] fontbits = new byte[size];
//      int xx = GetFontData(hdc, 0, 0, fontbits, size);
//      SelectObject(hdc, oldFont);
//      DeleteObject(hfont);
//      gfx.ReleaseHdc(hdc);
//
//      FontData image = new FontData(fontbits);
//      //image.Read();
//
//
//      //HandleRef
//
//      font.GetType();
        }
Esempio n. 4
0
        internal FontData[] GetFontDataList()
        {
            int count = fontDataTable.Values.Count;

            FontData[] fontDataArray = new FontData[count];
            fontDataTable.Values.CopyTo(fontDataArray, 0);
            return(fontDataArray);
        }
 public OpenTypeFontTable(FontData fontData, string tag)
 {
   this.fontData = fontData;
   if (fontData != null && fontData.tableDictionary.ContainsKey(tag))
     this.DirectoryEntry = fontData.tableDictionary[tag];
   else
     this.DirectoryEntry = new TableDirectoryEntry(tag);
   this.DirectoryEntry.FontTable = this;
 }
Esempio n. 6
0
        /// <summary>
        /// Creates and reads a TableDirectoryEntry from the font image.
        /// </summary>
        public static TableDirectoryEntry ReadFrom(FontData fontData)
        {
            TableDirectoryEntry entry = new TableDirectoryEntry();

            entry.Tag      = fontData.ReadTag();
            entry.CheckSum = fontData.ReadULong();
            entry.Offset   = fontData.ReadLong();
            entry.Length   = (int)fontData.ReadULong();
            return(entry);
        }
Esempio n. 7
0
 public OpenTypeDescriptor(XFont font, XPdfFontOptions options)
 {
     try
     {
         fontData = new FontData(font, options);
         fontName = font.Name;
         Initialize();
     }
     catch
     {
         throw;
     }
 }
Esempio n. 8
0
 public OpenTypeFontTable(FontData fontData, string tag)
 {
     this.fontData = fontData;
     if (fontData != null && fontData.tableDictionary.ContainsKey(tag))
     {
         DirectoryEntry = fontData.tableDictionary[tag];
     }
     else
     {
         DirectoryEntry = new TableDirectoryEntry(tag);
     }
     DirectoryEntry.FontTable = this;
 }
Esempio n. 9
0
 /// <summary>
 /// This is an external helper function.
 /// </summary>
 public static byte[] F74167FFE4044F53B28A4AF049E9EF25(XFont font, XPdfFontOptions options, bool subset)
 {
   byte[] data = null;
   if (subset)
   {
     OpenTypeDescriptor descriptor = new OpenTypeDescriptor(font, options);
     FontData image = descriptor.fontData;
     CMapInfo cmapInfo = new CMapInfo(descriptor);
     cmapInfo.AddAnsiChars();
     image = image.CreateFontSubSet(cmapInfo.GlyphIndices, false);
     data = image.Data;
   }
   else
   {
     FontData fontData = new FontData(font, options);
     data = fontData.Data;
   }
   return data;
 }
Esempio n. 10
0
 /// <summary>
 /// This is an external helper function.
 /// </summary>
 public static byte[] F74167FFE4044F53B28A4AF049E9EF25(XFont font, XPdfFontOptions options, bool subset)
 {
     byte[] data = null;
     if (subset)
     {
         OpenTypeDescriptor descriptor = new OpenTypeDescriptor(font, options);
         FontData           image      = descriptor.fontData;
         CMapInfo           cmapInfo   = new CMapInfo(descriptor);
         cmapInfo.AddAnsiChars();
         image = image.CreateFontSubSet(cmapInfo.GlyphIndices, false);
         data  = image.Data;
     }
     else
     {
         FontData fontData = new FontData(font, options);
         data = fontData.Data;
     }
     return(data);
 }
Esempio n. 11
0
    public FontData RegisterFontData(byte[] data)
    {
      uint checksum = CalcChecksum(data);
      string key = String.Format("??{0:X}", checksum);

      FontData fontData;
      if (!this.fontDataTable.TryGetValue(key, out fontData))
      {
        lock (typeof(FontDataStock))
        {
          // may be created by other thread meanwhile
          if (!this.fontDataTable.TryGetValue(key, out fontData))
          {
            fontData = new FontData(data);
            this.fontDataTable.Add(key, fontData);
            this.lastEntry = fontData;
          }
        }
      }
      return fontData;
    }
Esempio n. 12
0
        public FontData RegisterFontData(byte[] data)
        {
            uint   checksum = CalcChecksum(data);
            string key      = String.Format("??{0:X}", checksum);

            FontData fontData;

            if (!fontDataTable.TryGetValue(key, out fontData))
            {
                lock (typeof(FontDataStock))
                {
                    // may be created by other thread meanwhile
                    if (!fontDataTable.TryGetValue(key, out fontData))
                    {
                        fontData = new FontData(data);
                        fontDataTable.Add(key, fontData);
                        lastEntry = fontData;
                    }
                }
            }
            return(fontData);
        }
Esempio n. 13
0
 public HorizontalHeaderTable(FontData fontData)
   : base(fontData, Tag)
 {
   Read();
 }
 public GenericFontTable(FontData fontData, string tag)
     : base(fontData, tag)
 {
     this.fontData = fontData;
 }
Esempio n. 15
0
 public void Read(FontData fontData)
 {
   this.Tag = fontData.ReadTag();
   this.CheckSum = fontData.ReadULong();
   this.Offset = fontData.ReadLong();
   this.Length = (int)fontData.ReadULong();
 }
Esempio n. 16
0
 public MaximumProfileTable(FontData fontData)
     : base(fontData, Tag)
 {
     Read();
 }
Esempio n. 17
0
 public HorizontalMetricsTable(FontData fontData)
     : base(fontData, Tag)
 {
     Read();
 }
Esempio n. 18
0
 public GlyphDataTable(FontData fontData)
     : base(fontData, Tag)
 {
     DirectoryEntry.Tag = TableTagNames.Glyf;
     Read();
 }
Esempio n. 19
0
 public GlyphSubstitutionTable(FontData fontData)
   : base(fontData, Tag)
 {
   DirectoryEntry.Tag = TableTagNames.GSUB;
   DirectoryEntry = fontData.tableDictionary[TableTagNames.GSUB];
   Read();
 }
Esempio n. 20
0
    byte[] bytes; // Set of instructions executed whenever point size or font or transformation change. n is the number of BYTE items that fit in the size of the table.

    public ControlValueProgram(FontData fontData)
      : base(fontData, Tag)
    {
      DirectoryEntry.Tag = TableTagNames.Prep;
      DirectoryEntry = fontData.tableDictionary[TableTagNames.Prep];
      Read();
    }
Esempio n. 21
0
    byte[] bytes; // Instructions. n is the number of BYTE items that fit in the size of the table.

    public FontProgram(FontData fontData)
      : base(fontData, Tag)
    {
      DirectoryEntry.Tag = TableTagNames.Fpgm;
      DirectoryEntry = fontData.tableDictionary[TableTagNames.Fpgm];
      Read();
    }
Esempio n. 22
0
    FWord[] array; // List of n values referenceable by instructions. n is the number of FWORD items that fit in the size of the table.

    public ControlValueTable(FontData fontData)
      : base(fontData, Tag)
    {
      DirectoryEntry.Tag = TableTagNames.Cvt;
      DirectoryEntry = fontData.tableDictionary[TableTagNames.Cvt];
      Read();
    }
Esempio n. 23
0
 public PostScriptTable(FontData fontData)
   : base(fontData, Tag)
 {
   Read();
 }
Esempio n. 24
0
    public ushort[] glyphIdArray;     // Glyph index array (arbitrary length)

    public CMap4(FontData fontData, WinEncodingId encodingId)
      : base(fontData, "----")
    {
      this.encodingId = encodingId;
      Read();
    }
Esempio n. 25
0
 public OS2Table(FontData fontData)
   : base(fontData, Tag)
 {
   Read();
 }
Esempio n. 26
0
    public short glyphDataFormat; // 0 for current format

    public FontHeaderTable(FontData fontData)
      : base(fontData, Tag)
    {
      Read();
    }
Esempio n. 27
0
 public VerticalMetricsTable(FontData fontData)
   : base(fontData, Tag)
 {
   Read();
   throw new NotImplementedException("VerticalMetricsTable");
 }
Esempio n. 28
0
        public short glyphDataFormat;  // 0 for current format

        public FontHeaderTable(FontData fontData)
            : base(fontData, Tag)
        {
            Read();
        }
Esempio n. 29
0
 public VerticalMetrics(FontData fontData)
   : base(fontData, Tag)
 {
   Read();
 }
Esempio n. 30
0
 public VerticalMetrics(FontData fontData)
     : base(fontData, Tag)
 {
     Read();
 }
Esempio n. 31
0
 /// <summary>
 /// Shallow copy for font subset.
 /// </summary>
 FontData(FontData fontData)
 {
     offsetTable = fontData.offsetTable;
 }
Esempio n. 32
0
 public NameTable(FontData fontData)
   : base(fontData, Tag)
 {
   Read();
 }
Esempio n. 33
0
 public VerticalHeaderTable(FontData fontData)
   : base(fontData, Tag)
 {
   Read();
 }
Esempio n. 34
0
 public IRefFontTable(FontData fontData, OpenTypeFontTable fontTable)
     : base(null, fontTable.DirectoryEntry.Tag)
 {
     this.fontData           = fontData;
     this.irefDirectoryEntry = fontTable.DirectoryEntry;
 }
Esempio n. 35
0
 public GenericFontTable(FontData fontData, string tag)
   : base(fontData, tag)
 {
   this.fontData = fontData;
 }
Esempio n. 36
0
    public static void Test()
    {
      Font font = new Font("Times New Roman", 10);
      FontData image = new FontData(font);

//      Font font = new Font("Isabelle", 12);
//      LOGFONT logFont = new LOGFONT();
//      font.ToLogFont(logFont);
//
//      IntPtr hfont = CreateFontIndirect(logFont);
////      IntPtr hfont2 = font.ToHfont();
////      System.Windows.Forms.MessageBox.Show(hfont2.ToString());
//
//      Graphics gfx = Graphics.FromImage(new Bitmap(100, 100));
//      IntPtr hdc = gfx.GetHdc();
//      IntPtr oldFont =  SelectObject(hdc, hfont);
//      int size = GetFontData(hdc, 0, 0, null, 0);
//
//      byte[] fontbits = new byte[size];
//      int xx = GetFontData(hdc, 0, 0, fontbits, size);
//      SelectObject(hdc, oldFont);
//      DeleteObject(hfont);
//      gfx.ReleaseHdc(hdc);
//
//      FontData image = new FontData(fontbits);
//      //image.Read();
//
//
//      //HandleRef
//
//      font.GetType();
    }
Esempio n. 37
0
 public HorizontalMetricsTable(FontData fontData)
   : base(fontData, Tag)
 {
   Read();
 }
Esempio n. 38
0
 public bool UnregisterFontData(FontData fontData)
 {
     Debug.Assert(false);
     return(false);
 }
Esempio n. 39
0
        /// <summary>
        /// Create the font image using GDI+ functionality.
        /// </summary>
        void CreateGdiFontImage(XFont font, XPdfFontOptions options /*, XPrivateFontCollection privateFontCollection*/)
        {
            System.Drawing.Font   gdiFont = font.RealizeGdiFont();
            NativeMethods.LOGFONT logFont;
#if DEBUG_
            logFont = new NativeMethods.LOGFONT();
            gdiFont.ToLogFont(logFont);
            Debug.WriteLine("FontData: " + logFont.lfFaceName);
#endif
            this.data = null;

            // PFC
            //if (privateFontCollection != null)
            //{
            //  //XPrivateFont privateFont = privateFontCollection.FindFont(logFont.lfFaceName, logFont.lfWeight >= 700, logFont.lfItalic > 0);
            //  XGlyphTypeface privateFont = privateFontCollection.FindFont(font.Name, font.Bold, font.Italic);
            //  if (privateFont != null)
            //  {
            //    //////int size = privateFont.GetData(ref this.data);
            //    //////if (size > 0)
            //    //////{
            //    //////  this.data = new byte[size];
            //    //////  privateFont.GetData(ref this.data, size);
            //    //////}
            //  }
            //}

            // Console.WriteLine("looking for " + gdiFont.Name);
            foreach (string fontFile in NativeMethods._FontFiles)
            {
                try
                {
                    BinaryReader br     = new BinaryReader(File.OpenRead(fontFile));
                    byte[]       buffer = br.ReadBytes((int)br.BaseStream.Length);
                    br.Close();

                    FontData fd = new FontData(buffer);

                    //System.Console.WriteLine(fd.name.Name);

                    if (fd.name.Name.Trim().ToLower() == gdiFont.Name.Trim().ToLower())
                    {
                        this.data = buffer;
                        break;
                    }
                }
                catch
                {
                    //System.Console.WriteLine(exc.ToString());
                }
            }

            if (this.data == null)
            {
                int    error;
                IntPtr hfont = gdiFont.ToHfont();
                IntPtr hdc   = NativeMethods.GetDC(IntPtr.Zero);
                error = Marshal.GetLastWin32Error();
                IntPtr oldFont = NativeMethods.SelectObject(hdc, hfont);
                error = Marshal.GetLastWin32Error();
                // size is exactly the size of the font file.
                int size = NativeMethods.GetFontData(hdc, 0, 0, null, 0);
                error = Marshal.GetLastWin32Error();
                if (size > 0)
                {
                    this.data = new byte[size];
                    int effectiveSize = NativeMethods.GetFontData(hdc, 0, 0, this.data, this.data.Length);
                    Debug.Assert(size == effectiveSize);
                    NativeMethods.SelectObject(hdc, oldFont);
                    NativeMethods.ReleaseDC(IntPtr.Zero, hdc);
                    error.GetType();
                }
                else
                {
                    // Sometimes size is -1 (GDI_ERROR), but I cannot determine why. It happens only with the font 'Symbol'.
                    // The issue occurs the first time in early 2005, when I start writing PDFsharp. I could not fix it and after
                    // some code refactoring the problem disappears.
                    // There was never a report from anyone about this issue.
                    // Now I get it again (while debugging QBX 2006). Maybe it is a problem with my PC at my home office.
                    // As a work-around I create a new font handle with a different height value. This works. Maybe the
                    // font file gets locked somewhere. Very very strange.

                    // IF SOMEONE ELSE COMES HERE PLEASE LET ME KNOW!

                    // Clean up old handles
                    NativeMethods.SelectObject(hdc, oldFont);
                    NativeMethods.ReleaseDC(IntPtr.Zero, hdc);

                    // Try again with new font handle
                    logFont = new NativeMethods.LOGFONT();
                    gdiFont.ToLogFont(logFont);
                    logFont.lfHeight += 1; // force new handle
                    IntPtr hfont2 = NativeMethods.CreateFontIndirect(logFont);
                    hdc     = NativeMethods.GetDC(IntPtr.Zero);
                    error   = Marshal.GetLastWin32Error();
                    oldFont = NativeMethods.SelectObject(hdc, hfont2);
                    error   = Marshal.GetLastWin32Error();
                    // size is exactly the size of the font file.
                    size  = NativeMethods.GetFontData(hdc, 0, 0, null, 0);
                    error = Marshal.GetLastWin32Error();
                    if (size > 0)
                    {
                        this.data = new byte[size];
                        int effectiveSize = NativeMethods.GetFontData(hdc, 0, 0, this.data, this.data.Length);
                        Debug.Assert(size == effectiveSize);
                    }
                    NativeMethods.SelectObject(hdc, oldFont);
                    NativeMethods.ReleaseDC(IntPtr.Zero, hdc);
                    NativeMethods.DeleteObject(hfont2);
                    error.GetType();
                }
            }
            if (this.data == null)
            {
                throw new InvalidOperationException("Internal error. Font data could not retrieved.");
            }
        }
Esempio n. 40
0
 public IRefFontTable(FontData fontData, OpenTypeFontTable fontTable)
   : base(null, fontTable.DirectoryEntry.Tag)
 {
   this.fontData = fontData;
   this.irefDirectoryEntry = fontTable.DirectoryEntry;
 }
Esempio n. 41
0
 public GlyphDataTable(FontData fontData)
   : base(fontData, Tag)
 {
   DirectoryEntry.Tag = TableTagNames.Glyf;
   Read();
 }
Esempio n. 42
0
 public bool UnregisterFontData(FontData fontData)
 {
   Debug.Assert(false);
   return false;
 }
Esempio n. 43
0
 public IndexToLocationTable(FontData fontData)
   : base(fontData, Tag)
 {
   DirectoryEntry = this.fontData.tableDictionary[TableTagNames.Loca];
   Read();
 }
Esempio n. 44
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CMapTable"/> class.
 /// </summary>
 public CMapTable(FontData fontData)
   : base(fontData, Tag)
 {
   Read();
 }
Esempio n. 45
0
 public OS2Table(FontData fontData)
     : base(fontData, Tag)
 {
     Read();
 }
Esempio n. 46
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CMapTable"/> class.
 /// </summary>
 public CMapTable(FontData fontData)
     : base(fontData, Tag)
 {
     Read();
 }
Esempio n. 47
0
 public PostScriptTable(FontData fontData)
     : base(fontData, Tag)
 {
     Read();
 }
Esempio n. 48
0
 public HorizontalHeaderTable(FontData fontData)
     : base(fontData, Tag)
 {
     Read();
 }
Esempio n. 49
0
 /// <summary>
 /// Shallow copy for font subset.
 /// </summary>
 FontData(FontData fontData)
 {
   this.offsetTable = fontData.offsetTable;
 }
Esempio n. 50
0
 public VerticalHeaderTable(FontData fontData)
     : base(fontData, Tag)
 {
     Read();
 }
 public IndexToLocationTable(FontData fontData)
     : base(fontData, Tag)
 {
     DirectoryEntry = this.fontData.tableDictionary[TableTagNames.Loca];
     Read();
 }
Esempio n. 52
0
 public VerticalMetricsTable(FontData fontData)
     : base(fontData, Tag)
 {
     Read();
     throw new NotImplementedException("VerticalMetricsTable");
 }
Esempio n. 53
0
 /// <summary>
 /// Creates and reads a TableDirectoryEntry from the font image.
 /// </summary>
 public static TableDirectoryEntry ReadFrom(FontData fontData)
 {
   TableDirectoryEntry entry = new TableDirectoryEntry();
   entry.Tag = fontData.ReadTag();
   entry.CheckSum = fontData.ReadULong();
   entry.Offset = fontData.ReadLong();
   entry.Length = (int)fontData.ReadULong();
   return entry;
 }
Esempio n. 54
0
 public NameTable(FontData fontData)
     : base(fontData, Tag)
 {
     Read();
 }
Esempio n. 55
0
 public MaximumProfileTable(FontData fontData)
   : base(fontData, Tag)
 {
   Read();
 }
Esempio n. 56
0
        public ushort[] glyphIdArray;    // Glyph index array (arbitrary length)

        public CMap4(FontData fontData, WinEncodingId encodingId)
            : base(fontData, "----")
        {
            this.encodingId = encodingId;
            Read();
        }
Esempio n. 57
0
        /// <summary>
        /// Creates a new font image that is a subset of this font image containing only the specified glyphs.
        /// </summary>
        public FontData CreateFontSubSet(Dictionary <int, object> glyphs, bool cidFont)
        {
            // Create new font image
            FontData fontData = new FontData(this);

            // Create new loca and glyf table
            IndexToLocationTable loca = new IndexToLocationTable();

            loca.ShortIndex = this.loca.ShortIndex;
            GlyphDataTable glyf = new GlyphDataTable();

            // Add all required tables
            //fontData.AddTable(this.os2);
            if (!cidFont)
            {
                fontData.AddTable(this.cmap);
            }
            if (this.cvt != null)
            {
                fontData.AddTable(this.cvt);
            }
            if (this.fpgm != null)
            {
                fontData.AddTable(this.fpgm);
            }
            fontData.AddTable(glyf);
            fontData.AddTable(this.head);
            fontData.AddTable(this.hhea);
            fontData.AddTable(this.hmtx);
            fontData.AddTable(loca);
            if (this.maxp != null)
            {
                fontData.AddTable(this.maxp);
            }
            //fontData.AddTable(this.name);
            if (this.prep != null)
            {
                fontData.AddTable(this.prep);
            }

            // Get closure of used glyphs
            this.glyf.CompleteGlyphClosure(glyphs);

            // Create a sorted array of all used glyphs
            int glyphCount = glyphs.Count;

            int[] glyphArray = new int[glyphCount];
            glyphs.Keys.CopyTo(glyphArray, 0);
            Array.Sort <int>(glyphArray);

            // Calculate new size of glyph table.
            int size = 0;

            for (int idx = 0; idx < glyphCount; idx++)
            {
                size += this.glyf.GetGlyphSize(glyphArray[idx]);
            }
            glyf.DirectoryEntry.Length = size;

            // Create new loca table
            int numGlyphs = this.maxp.numGlyphs;

            loca.locaTable = new int[numGlyphs + 1];

            // Create new glyf table
            glyf.glyphTable = new byte[glyf.DirectoryEntry.PaddedLength];

            // Fill new glyf and loca table
            int glyphOffset = 0;
            int glyphIndex  = 0;

            for (int idx = 0; idx < numGlyphs; idx++)
            {
                loca.locaTable[idx] = glyphOffset;
                if (glyphIndex < glyphCount && glyphArray[glyphIndex] == idx)
                {
                    glyphIndex++;
                    byte[] bytes  = this.glyf.GetGlyphData(idx);
                    int    length = bytes.Length;
                    if (length > 0)
                    {
                        Buffer.BlockCopy(bytes, 0, glyf.glyphTable, glyphOffset, length);
                        glyphOffset += length;
                    }
                }
            }
            loca.locaTable[numGlyphs] = glyphOffset;

            // Compile font tables into byte array
            fontData.Compile();

            return(fontData);
        }
Esempio n. 58
0
 /// <summary>
 /// Shallow copy for font subset.
 /// </summary>
 FontData(FontData fontData)
 {
     this.offsetTable = fontData.offsetTable;
 }
Esempio n. 59
0
    /// <summary>
    /// Creates a new font image that is a subset of this font image containing only the specified glyphs.
    /// </summary>
    public FontData CreateFontSubSet(Dictionary<int, object> glyphs, bool cidFont)
    {
      // Create new font image
      FontData fontData = new FontData(this);

      // Create new loca and glyf table
      IndexToLocationTable loca = new IndexToLocationTable();
      loca.ShortIndex = this.loca.ShortIndex;
      GlyphDataTable glyf = new GlyphDataTable();

      // Add all required tables
      //fontData.AddTable(this.os2);
      if (!cidFont)
        fontData.AddTable(this.cmap);
      if (this.cvt != null)
        fontData.AddTable(this.cvt);
      if (this.fpgm != null)
        fontData.AddTable(this.fpgm);
      fontData.AddTable(glyf);
      fontData.AddTable(this.head);
      fontData.AddTable(this.hhea);
      fontData.AddTable(this.hmtx);
      fontData.AddTable(loca);
      if (this.maxp != null)
        fontData.AddTable(this.maxp);
      //fontData.AddTable(this.name);
      if (this.prep != null)
        fontData.AddTable(this.prep);

      // Get closure of used glyphs
      this.glyf.CompleteGlyphClosure(glyphs);

      // Create a sorted array of all used glyphs
      int glyphCount = glyphs.Count;
      int[] glyphArray = new int[glyphCount];
      glyphs.Keys.CopyTo(glyphArray, 0);
      Array.Sort<int>(glyphArray);

      // Calculate new size of glyph table.
      int size = 0;
      for (int idx = 0; idx < glyphCount; idx++)
        size += this.glyf.GetGlyphSize(glyphArray[idx]);
      glyf.DirectoryEntry.Length = size;

      // Create new loca table
      int numGlyphs = this.maxp.numGlyphs;
      loca.locaTable = new int[numGlyphs + 1];

      // Create new glyf table
      glyf.glyphTable = new byte[glyf.DirectoryEntry.PaddedLength];

      // Fill new glyf and loca table
      int glyphOffset = 0;
      int glyphIndex = 0;
      for (int idx = 0; idx < numGlyphs; idx++)
      {
        loca.locaTable[idx] = glyphOffset;
        if (glyphIndex < glyphCount && glyphArray[glyphIndex] == idx)
        {
          glyphIndex++;
          byte[] bytes = this.glyf.GetGlyphData(idx);
          int length = bytes.Length;
          if (length > 0)
          {
            Buffer.BlockCopy(bytes, 0, glyf.glyphTable, glyphOffset, length);
            glyphOffset += length;
          }
        }
      }
      loca.locaTable[numGlyphs] = glyphOffset;

      // Compile font tables into byte array
      fontData.Compile();

      return fontData;
    }