Class: Arrolio::Font::Manifest

Inherits:
Object
  • Object
show all
Defined in:
lib/arrolio/font/manifest.rb

Overview

Declarative font configuration. Maps family names to variant file paths (regular, bold, italic, bold_italic) and provides fallback chain resolution. Replaces the flat font_paths hash on LayoutSpec with a richer structure.

Manifest format (YAML):

families:
"Body Font":
  regular: /path/to/times.ttf
  bold: /path/to/timesbd.ttf
  italic: /path/to/timesi.ttf
  bold_italic: /path/to/timesbi.ttf
fallback: ["Fallback1", "Fallback2"]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(families:, fallback_chain: []) ⇒ Manifest

families: Hash mapping family name (String) to a Hash of variant → file path. Variants: :regular, :bold, :italic, :bold_italic. fallback_chain: Array of family names tried in order when the primary family doesn't have a needed variant.



26
27
28
29
30
# File 'lib/arrolio/font/manifest.rb', line 26

def initialize(families:, fallback_chain: [])
  @families = normalize_families(families)
  @fallback_chain = Array(fallback_chain).map(&:to_s)
  freeze
end

Instance Attribute Details

#fallback_chainObject (readonly)

Returns the value of attribute fallback_chain.



19
20
21
# File 'lib/arrolio/font/manifest.rb', line 19

def fallback_chain
  @fallback_chain
end

#familiesObject (readonly)

Returns the value of attribute families.



19
20
21
# File 'lib/arrolio/font/manifest.rb', line 19

def families
  @families
end

Class Method Details

.from_hash(hash) ⇒ Object

Factory: builds a Manifest from a YAML/Hash representation.



61
62
63
64
65
66
# File 'lib/arrolio/font/manifest.rb', line 61

def self.from_hash(hash)
  new(
    families: hash.fetch('families', hash.fetch(:families, {})),
    fallback_chain: hash.fetch('fallback', hash.fetch(:fallback_chain, []))
  )
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



68
69
70
71
72
# File 'lib/arrolio/font/manifest.rb', line 68

def ==(other)
  other.is_a?(self.class) &&
    families == other.families &&
    fallback_chain == other.fallback_chain
end

#hashObject



75
76
77
# File 'lib/arrolio/font/manifest.rb', line 75

def hash
  [self.class, families, fallback_chain].hash
end

#resolve(font_name, weight: :regular, style: :regular) ⇒ Object

Resolves a font name + weight + style to a file path. Tries the primary family first, then the fallback chain. Returns nil if no path is found.



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/arrolio/font/manifest.rb', line 35

def resolve(font_name, weight: :regular, style: :regular)
  variant = variant_key(weight, style)
  path = lookup(@families[font_name.to_s], variant)
  return path if path

  @fallback_chain.each do |family|
    path = lookup(@families[family], variant)
    return path if path
  end
  nil
end

#to_flat_pathsObject

Returns all (family, variant, path) triples as a flat hash suitable for the existing font_paths API.



49
50
51
52
53
54
55
56
57
58
# File 'lib/arrolio/font/manifest.rb', line 49

def to_flat_paths
  result = {}
  @families.each do |family, variants|
    variants.each do |variant, path|
      key = variant_name(family, variant)
      result[key] = path if path && File.exist?(path)
    end
  end
  result
end