This table contains information that describes the glyphs in the font in the TrueType outline format. Information regarding the rasterizer (scaler) refers to the TrueType rasterizer.
Inheritance: TrueTypeFontTable
Beispiel #1
0
    /// <summary>
    /// Reads all required table from the font prgram.
    /// </summary>
    internal void Read()
    {
      try
      {
        // Read offset table
        this.offsetTable.Version = ReadULong();
        this.offsetTable.TableCount = ReadUShort();
        this.offsetTable.SearchRange = ReadUShort();
        this.offsetTable.EntrySelector = ReadUShort();
        this.offsetTable.RangeShift = ReadUShort();

        // Move to table dictionary at position 12
        Debug.Assert(this.pos == 12);
        //this.tableDictionary = (this.offsetTable.TableCount);
        for (int idx = 0; idx < this.offsetTable.TableCount; idx++)
        {
          TableDirectoryEntry entry = TableDirectoryEntry.ReadFrom(this);
          this.tableDictionary.Add(entry.Tag, entry);
#if VERBOSE
          Debug.WriteLine(String.Format("Font table: {0}", entry.Tag));
#endif
        }

        // PDFlib checks this, but it is not part of the OpenType spec anymore
        if (this.tableDictionary.ContainsKey("bhed"))
          throw new NotSupportedException("Bitmap fonts are not supported by PDFsharp.");

        // Read required tables
        if (Seek(CMapTable.Tag) != -1)
          this.cmap = new CMapTable(this);

        if (Seek(ControlValueTable.Tag) != -1)
          this.cvt = new ControlValueTable(this);

        if (Seek(FontProgram.Tag) != -1)
          this.fpgm = new FontProgram(this);

        if (Seek(MaximumProfileTable.Tag) != -1)
          this.maxp = new MaximumProfileTable(this);

        if (Seek(NameTable.Tag) != -1)
          this.name = new NameTable(this);

        if (Seek(FontHeaderTable.Tag) != -1)
          this.head = new FontHeaderTable(this);

        if (Seek(HorizontalHeaderTable.Tag) != -1)
          this.hhea = new HorizontalHeaderTable(this);

        if (Seek(HorizontalMetricsTable.Tag) != -1)
          this.hmtx = new HorizontalMetricsTable(this);

        if (Seek(OS2Table.Tag) != -1)
          this.os2 = new OS2Table(this);

        if (Seek(PostScriptTable.Tag) != -1)
          this.post = new PostScriptTable(this);

        if (Seek(GlyphDataTable.Tag) != -1)
          this.glyf = new GlyphDataTable(this);

        if (Seek(IndexToLocationTable.Tag) != -1)
          this.loca = new IndexToLocationTable(this);

        if (Seek(GlyphSubstitutionTable.Tag) != -1)
          this.gsub = new GlyphSubstitutionTable(this);

        if (Seek(ControlValueProgram.Tag) != -1)
          this.prep = new ControlValueProgram(this);
      }
      catch (Exception ex)
      {
        throw ex;
      }
    }
Beispiel #2
0
    /// <summary>
    /// Creates a new font image that is a subset of this font image containing only the specified glyphs.
    /// </summary>
    public FontImage CreateFontSubSet(Dictionary<int, object> glyphs, bool cidFont)
    {
      // Create new font image
      FontImage fontImage = new FontImage(this);

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

      // Add all required tables
      //fontImage.AddTable(this.os2);
      if (!cidFont)
        fontImage.AddTable(this.cmap);
      if (this.cvt != null)
        fontImage.AddTable(this.cvt);
      if (this.fpgm != null)
        fontImage.AddTable(this.fpgm);
      fontImage.AddTable(glyf);
      fontImage.AddTable(this.head);
      fontImage.AddTable(this.hhea);
      fontImage.AddTable(this.hmtx);
      fontImage.AddTable(loca);
      if (this.maxp != null)
        fontImage.AddTable(this.maxp);
      //fontImage.AddTable(this.name);
      if (this.prep != null)
        fontImage.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
      fontImage.Compile();

      return fontImage;
    }
Beispiel #3
0
    /// <summary>
    /// Adds the specified table to this font image.
    /// </summary>
    public void AddTable(TrueTypeFontTable fontTable)
    {
      if (!CanWrite)
        throw new InvalidOperationException("Font image cannot be modified.");

      if (fontTable == null)
        throw new ArgumentNullException("fontTable");

      if (fontTable.FontImage == null)
      {
        fontTable.fontImage = this;
      }
      else
      {
        Debug.Assert(fontTable.FontImage.CanRead);
        // Create a reference to this font table
        fontTable = new IRefFontTable(this, fontTable);
      }

      //Debug.Assert(fontTable.FontImage == null);
      //fontTable.fontImage = this;

      this.tableDictionary[fontTable.DirectoryEntry.Tag] = fontTable.DirectoryEntry;
      switch (fontTable.DirectoryEntry.Tag)
      {
        case TableTagNames.CMap:
          this.cmap = fontTable as CMapTable;
          break;

        case TableTagNames.Cvt:
          this.cvt = fontTable as ControlValueTable;
          break;

        case TableTagNames.Fpgm:
          this.fpgm = fontTable as FontProgram;
          break;

        case TableTagNames.MaxP:
          this.maxp = fontTable as MaximumProfileTable;
          break;

        case TableTagNames.Name:
          this.name = fontTable as NameTable;
          break;

        case TableTagNames.Head:
          this.head = fontTable as FontHeaderTable;
          break;

        case TableTagNames.HHea:
          this.hhea = fontTable as HorizontalHeaderTable;
          break;

        case TableTagNames.HMtx:
          this.hmtx = fontTable as HorizontalMetricsTable;
          break;

        case TableTagNames.OS2:
          this.os2 = fontTable as OS2Table;
          break;

        case TableTagNames.Post:
          this.post = fontTable as PostScriptTable;
          break;

        case TableTagNames.Glyf:
          this.glyf = fontTable as GlyphDataTable;
          break;

        case TableTagNames.Loca:
          this.loca = fontTable as IndexToLocationTable;
          break;

        case TableTagNames.GSUB:
          this.gsub = fontTable as GlyphSubstitutionTable;
          break;

        case TableTagNames.Prep:
          this.prep = fontTable as ControlValueProgram;
          break;
      }
    }