Class: Fontisan::Subset::GlyphMapping

Inherits:
Object
  • Object
show all
Includes:
Enumerable
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



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

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



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

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



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

def old_to_new
  @old_to_new
end

#retain_gidsBoolean (readonly)

Returns whether original GIDs are retained.

Returns:

  • (Boolean)

    whether original GIDs are retained



42
43
44
# File 'lib/fontisan/subset/glyph_mapping.rb', line 42

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



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

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



116
117
118
# File 'lib/fontisan/subset/glyph_mapping.rb', line 116

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



72
73
74
# File 'lib/fontisan/subset/glyph_mapping.rb', line 72

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



138
139
140
# File 'lib/fontisan/subset/glyph_mapping.rb', line 138

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



85
86
87
# File 'lib/fontisan/subset/glyph_mapping.rb', line 85

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



127
128
129
# File 'lib/fontisan/subset/glyph_mapping.rb', line 127

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



103
104
105
# File 'lib/fontisan/subset/glyph_mapping.rb', line 103

def size
  new_to_old.size
end