Class: TTFunk::Subset::Base

### Home Classes Methods

### In Files

- lib/ttfunk/subset/base.rb

### Parent

Object

### Methods

- ::new
- #encode
- #to_unicode_map
- #unicode?

### Class/Module Index

Quicksearch

- TTFunk
- TTFunk::Directory
- TTFunk::Encoding
- TTFunk::Encoding::MacRoman
- TTFunk::Encoding::Windows1252
- TTFunk::File
- TTFunk::Reader
- TTFunk::ResourceFile
- TTFunk::Subset
- TTFunk::Subset::Base
- TTFunk::Subset::MacRoman
- TTFunk::Subset::Unicode
- TTFunk::Subset::Unicode8Bit
- TTFunk::Subset::Windows1252
- TTFunk::SubsetCollection
- TTFunk::Table
- TTFunk::Table::Cmap
- TTFunk::Table::Cmap::Format00
- TTFunk::Table::Cmap::Format04
- TTFunk::Table::Cmap::Subtable
- TTFunk::Table::Glyf
- TTFunk::Table::Glyf::Compound
- TTFunk::Table::Glyf::Simple
- TTFunk::Table::Head
- TTFunk::Table::Hhea
- TTFunk::Table::Hmtx
- TTFunk::Table::Kern
- TTFunk::Table::Kern::Format0
- TTFunk::Table::Loca
- TTFunk::Table::Maxp
- TTFunk::Table::Name
- TTFunk::Table::Name::String
- TTFunk::Table::OS2
- TTFunk::Table::Post
- TTFunk::Table::Post::Format10
- TTFunk::Table::Post::Format20
- TTFunk::Table::Post::Format25
- TTFunk::Table::Post::Format30
- TTFunk::Table::Post::Format40
- TTFunk::Table::Simple

No matching classes.

# TTFunk::Subset::Base

### Attributes

original[R]

### Public Class Methods

new(original) click to toggle source

    # File lib/ttfunk/subset/base.rb, line 18
    def initialize(original)
      @original = original
    end

### Public Instance Methods

encode(options={}) click to toggle source

    # File lib/ttfunk/subset/base.rb, line 30
    def encode(options={})
      cmap_table = new_cmap_table(options)
      glyphs = collect_glyphs(original_glyph_ids)

      old2new_glyph = cmap_table[:charmap].inject({ 0 => 0 }) { |map, (code, ids)| map[ids[:old]] = ids[:new]; map }
      next_glyph_id = cmap_table[:max_glyph_id]

      glyphs.keys.each do |old_id|
        unless old2new_glyph.key?(old_id)
          old2new_glyph[old_id] = next_glyph_id
          next_glyph_id += 1
        end
      end

      new2old_glyph = old2new_glyph.invert

      # "mandatory" tables. Every font should ("should") have these, including
      # the cmap table (encoded above).
      glyf_table = TTFunk::Table::Glyf.encode(glyphs, new2old_glyph, old2new_glyph)
      loca_table = TTFunk::Table::Loca.encode(glyf_table[:offsets])
      hmtx_table = TTFunk::Table::Hmtx.encode(original.horizontal_metrics, new2old_glyph)
      hhea_table = TTFunk::Table::Hhea.encode(original.horizontal_header, hmtx_table)
      maxp_table = TTFunk::Table::Maxp.encode(original.maximum_profile, old2new_glyph)
      post_table = TTFunk::Table::Post.encode(original.postscript, new2old_glyph)
      name_table = TTFunk::Table::Name.encode(original.name)
      head_table = TTFunk::Table::Head.encode(original.header, loca_table)

      # "optional" tables. Fonts may omit these if they do not need them. Because they
      # apply globally, we can simply copy them over, without modification, if they
      # exist.
      os2_table  = original.os2.raw
      cvt_table  = TTFunk::Table::Simple.new(original, "cvt ").raw
      fpgm_table = TTFunk::Table::Simple.new(original, "fpgm").raw
      prep_table = TTFunk::Table::Simple.new(original, "prep").raw

      # for PDF's, the kerning info is all included in the PDF as the text is
      # drawn. Thus, the PDF readers do not actually use the kerning info in
      # embedded fonts. If the library is used for something else, the generated
      # subfont may need a kerning table... in that case, you need to opt into it.
      if options[:kerning]
        kern_table = TTFunk::Table::Kern.encode(original.kerning, old2new_glyph)
      end

      tables = { 'cmap' => cmap_table[:table],
                 'glyf' => glyf_table[:table],
                 'loca' => loca_table[:table],
                 'kern' => kern_table,
                 'hmtx' => hmtx_table[:table],
                 'hhea' => hhea_table,
                 'maxp' => maxp_table,
                 'OS/2' => os2_table,
                 'post' => post_table,
                 'name' => name_table,
                 'head' => head_table,
                 'prep' => prep_table,
                 'fpgm' => fpgm_table,
                 'cvt ' => cvt_table }

      tables.delete_if { |tag, table| table.nil? }

      search_range = (Math.log(tables.length) / Math.log(2)).to_i * 16
      entry_selector = (Math.log(search_range) / Math.log(2)).to_i
      range_shift = tables.length * 16 - search_range

      newfont = [original.directory.scaler_type, tables.length, search_range, entry_selector, range_shift].pack("Nn*")

      directory_size = tables.length * 16
      offset = newfont.length + directory_size

      table_data = ""
      head_offset = nil
      tables.each do |tag, data|
        newfont << [tag, checksum(data), offset, data.length].pack("A4N*")
        table_data << data
        head_offset = offset if tag == 'head'
        offset += data.length
        while offset % 4 != 0
          offset += 1
          table_data << "\00""
        end
      end

      newfont << table_data
      sum = checksum(newfont)
      adjustment = 0xB1B0AFBA - sum
      newfont[head_offset+8,4] = [adjustment].pack("N")

      return newfont
    end

to_unicode_map() click to toggle source

    # File lib/ttfunk/subset/base.rb, line 26
    def to_unicode_map
      {}
    end

unicode?() click to toggle source

    # File lib/ttfunk/subset/base.rb, line 22
    def unicode?
      false
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.