Class: TTFunk::Table::Cff::FdSelector

Inherits:
SubTable
  • Object
show all
Includes:
Enumerable
Defined in:
lib/ttfunk/table/cff/fd_selector.rb

Overview

CFF FDSelect.

Constant Summary collapse

ARRAY_FORMAT =

Array format.

0
RANGE_FORMAT =

Range format.

3
RANGE_ENTRY_SIZE =

Range entry size.

3
ARRAY_ENTRY_SIZE =

Array entry size.

1

Instance Attribute Summary collapse

Attributes inherited from SubTable

#file, #length, #table_offset

Instance Method Summary collapse

Methods inherited from SubTable

#eot?, #read

Constructor Details

#initialize(top_dict, file, offset, length = nil) ⇒ FdSelector

Returns a new instance of FdSelector.

Parameters:

  • top_dict (TTFunk::Table:Cff::TopDict)
  • file (TTFunk::File)
  • offset (Integer)
  • length (Integer) (defaults to: nil)


43
44
45
46
# File 'lib/ttfunk/table/cff/fd_selector.rb', line 43

def initialize(top_dict, file, offset, length = nil)
  @top_dict = top_dict
  super(file, offset, length)
end

Instance Attribute Details

#entriesArray<Integer>, Array<Array(Range, Integer)> (readonly)

Number of entries.

Returns:

  • (Array<Integer>)

    if format is array.

  • (Array<Array(Range, Integer)>)

    if format is range.



33
34
35
# File 'lib/ttfunk/table/cff/fd_selector.rb', line 33

def entries
  @entries
end

#items_countInteger (readonly)

Number of encoded items.

Returns:

  • (Integer)


28
29
30
# File 'lib/ttfunk/table/cff/fd_selector.rb', line 28

def items_count
  @items_count
end

#n_glyphsInteger (readonly)

Number of glyphs.

Returns:

  • (Integer)


37
38
39
# File 'lib/ttfunk/table/cff/fd_selector.rb', line 37

def n_glyphs
  @n_glyphs
end

#top_dictTTFunk::Table::Cff::TopDict (readonly)

Top dict.



24
25
26
# File 'lib/ttfunk/table/cff/fd_selector.rb', line 24

def top_dict
  @top_dict
end

Instance Method Details

#[](glyph_id) ⇒ Integer

Get font dict index for glyph ID.

Returns:

  • (Integer)


51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/ttfunk/table/cff/fd_selector.rb', line 51

def [](glyph_id)
  case format_sym
  when :array_format
    entries[glyph_id]

  when :range_format
    if (entry = range_cache[glyph_id])
      return entry
    end

    range, entry =
      entries.bsearch { |rng, _|
        if rng.cover?(glyph_id)
          0
        elsif glyph_id < rng.first
          -1
        else
          1
        end
      }

    range.each { |i| range_cache[i] = entry }
    entry
  end
end

#each {|font| ... } ⇒ void

This method returns an undefined value.

Iterate over font dicts for each glyph ID.

Yield Parameters:

  • font (Integer)

    dict index.



81
82
83
84
85
# File 'lib/ttfunk/table/cff/fd_selector.rb', line 81

def each
  return to_enum(__method__) unless block_given?

  items_count.times { |i| yield(self[i]) }
end

#encode(charmap) ⇒ String

Encode Font dict selector.

Parameters:

  • charmap (Hash{Integer => Hash})

    keys are the charac codes, values are hashes:

    • ‘:old` (Integer) - glyph ID in the original font.

    • ‘:new` (Integer) - glyph ID in the subset font.

Returns:

  • (String)


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/ttfunk/table/cff/fd_selector.rb', line 94

def encode(charmap)
  # get list of [new_gid, fd_index] pairs
  new_indices =
    charmap
      .reject { |code, mapping| mapping[:new].zero? && !code.zero? }
      .sort_by { |_code, mapping| mapping[:new] }
      .map { |(_code, mapping)| [mapping[:new], self[mapping[:old]]] }

  ranges = rangify_gids(new_indices)
  total_range_size = ranges.size * RANGE_ENTRY_SIZE
  total_array_size = new_indices.size * ARRAY_ENTRY_SIZE

  ''.b.tap do |result|
    if total_array_size <= total_range_size
      result << [ARRAY_FORMAT].pack('C')
      result << new_indices.map(&:last).pack('C*')
    else
      result << [RANGE_FORMAT, ranges.size].pack('Cn')
      ranges.each { |range| result << range.pack('nC') }

      # "A sentinel GID follows the last range element and serves to
      # delimit the last range in the array. (The sentinel GID is set
      # equal to the number of glyphs in the font. That is, its value
      # is 1 greater than the last GID in the font)."
      result << [new_indices.size].pack('n')
    end
  end
end