Class: Fontisan::Subset::GlyphMapping

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/subset/glyph_mapping.rb

Overview

Glyph ID mapping management

This class manages the mapping between original glyph IDs (GIDs) in the source font and new GIDs in the subset font. It supports two modes:

  1. Compact mode (retain_gids: false): Glyphs are renumbered sequentially, eliminating gaps from removed glyphs. This produces smaller fonts.

  2. Retain mode (retain_gids: true): Original glyph IDs are preserved, with removed glyphs leaving empty slots. This maintains glyph references but produces larger fonts.

Examples:

Compact mode (default)

mapping = Fontisan::Subset::GlyphMapping.new([0, 5, 10, 15])
mapping.new_id(5)  # => 1
mapping.new_id(10) # => 2
mapping.size       # => 4

Retain mode

mapping = Fontisan::Subset::GlyphMapping.new([0, 5, 10, 15], retain_gids: true)
mapping.new_id(5)  # => 5
mapping.new_id(10) # => 10
mapping.size       # => 16 (0..15)

Reverse lookup

mapping = Fontisan::Subset::GlyphMapping.new([0, 5, 10])
mapping.old_id(1) # => 5

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(old_glyph_ids, retain_gids: false) ⇒ GlyphMapping

Initialize glyph mapping

Examples:

Create compact mapping

mapping = GlyphMapping.new([0, 3, 5, 10])

Create mapping that retains GIDs

mapping = GlyphMapping.new([0, 3, 5, 10], retain_gids: true)

Parameters:

  • old_glyph_ids (Array<Integer>)

    array of glyph IDs to include in the subset, typically sorted

  • retain_gids (Boolean) (defaults to: false)

    whether to preserve original glyph IDs



53
54
55
56
57
58
59
# File 'lib/fontisan/subset/glyph_mapping.rb', line 53

def initialize(old_glyph_ids, retain_gids: false)
  @old_to_new = {}
  @new_to_old = {}
  @retain_gids = retain_gids

  build_mappings(old_glyph_ids)
end

Instance Attribute Details

#new_to_oldHash<Integer, Integer> (readonly)

Returns mapping from new GIDs to old GIDs.

Returns:

  • (Hash<Integer, Integer>)

    mapping from new GIDs to old GIDs



37
38
39
# File 'lib/fontisan/subset/glyph_mapping.rb', line 37

def new_to_old
  @new_to_old
end

#old_to_newHash<Integer, Integer> (readonly)

Returns mapping from old GIDs to new GIDs.

Returns:

  • (Hash<Integer, Integer>)

    mapping from old GIDs to new GIDs



34
35
36
# File 'lib/fontisan/subset/glyph_mapping.rb', line 34

def old_to_new
  @old_to_new
end

#retain_gidsBoolean (readonly)

Returns whether original GIDs are retained.

Returns:

  • (Boolean)

    whether original GIDs are retained



40
41
42
# File 'lib/fontisan/subset/glyph_mapping.rb', line 40

def retain_gids
  @retain_gids
end

Instance Method Details

#each {|old_id, new_id| ... } ⇒ Object

Iterate over all glyph mappings

Yields old_id and new_id pairs in order of old glyph IDs.

Examples:

mapping = GlyphMapping.new([0, 5, 10])
mapping.each do |old_id, new_id|
  puts "#{old_id} => #{new_id}"
end
# Output:
# 0 => 0
# 5 => 1
# 10 => 2

Yields:

Yield Parameters:

  • old_id (Integer)

    original glyph ID

  • new_id (Integer)

    new glyph ID



157
158
159
160
161
162
163
# File 'lib/fontisan/subset/glyph_mapping.rb', line 157

def each
  return enum_for(:each) unless block_given?

  old_ids.each do |old_id|
    yield old_id, old_to_new[old_id]
  end
end

#include?(old_id) ⇒ Boolean

Check if a glyph is included in the subset

Examples:

mapping = GlyphMapping.new([0, 5, 10])
mapping.include?(5)  # => true
mapping.include?(99) # => false

Parameters:

  • old_id (Integer)

    original glyph ID to check

Returns:

  • (Boolean)

    true if glyph is in subset



114
115
116
# File 'lib/fontisan/subset/glyph_mapping.rb', line 114

def include?(old_id)
  old_to_new.key?(old_id)
end

#new_id(old_id) ⇒ Integer?

Get new glyph ID for an old glyph ID

Examples:

mapping = GlyphMapping.new([0, 5, 10])
mapping.new_id(5)  # => 1
mapping.new_id(99) # => nil

Parameters:

  • old_id (Integer)

    original glyph ID

Returns:

  • (Integer, nil)

    new glyph ID, or nil if not in subset



70
71
72
# File 'lib/fontisan/subset/glyph_mapping.rb', line 70

def new_id(old_id)
  old_to_new[old_id]
end

#new_idsArray<Integer>

Get array of all new glyph IDs in subset

Examples:

mapping = GlyphMapping.new([0, 5, 10])
mapping.new_ids # => [0, 1, 2]

Returns:

  • (Array<Integer>)

    sorted array of new glyph IDs



136
137
138
# File 'lib/fontisan/subset/glyph_mapping.rb', line 136

def new_ids
  new_to_old.keys.sort
end

#old_id(new_id) ⇒ Integer?

Get old glyph ID for a new glyph ID

Examples:

mapping = GlyphMapping.new([0, 5, 10])
mapping.old_id(1) # => 5
mapping.old_id(99) # => nil

Parameters:

  • new_id (Integer)

    new glyph ID in subset

Returns:

  • (Integer, nil)

    original glyph ID, or nil if invalid



83
84
85
# File 'lib/fontisan/subset/glyph_mapping.rb', line 83

def old_id(new_id)
  new_to_old[new_id]
end

#old_idsArray<Integer>

Get array of all old glyph IDs in subset

Examples:

mapping = GlyphMapping.new([10, 0, 5])
mapping.old_ids # => [0, 5, 10]

Returns:

  • (Array<Integer>)

    sorted array of old glyph IDs



125
126
127
# File 'lib/fontisan/subset/glyph_mapping.rb', line 125

def old_ids
  old_to_new.keys.sort
end

#sizeInteger

Get number of glyphs in the subset

In compact mode, this is the number of included glyphs. In retain mode, this is the highest old GID + 1.

Examples:

Compact mode

mapping = GlyphMapping.new([0, 5, 10])
mapping.size # => 3

Retain mode

mapping = GlyphMapping.new([0, 5, 10], retain_gids: true)
mapping.size # => 11 (0..10)

Returns:

  • (Integer)

    number of glyphs



101
102
103
# File 'lib/fontisan/subset/glyph_mapping.rb', line 101

def size
  new_to_old.size
end