Class: Arrolio::Font::Resolver

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

Overview

Resolves font family names to absolute TTF paths using a configurable chain of resolvers. Replaces the absolute-path entries in layout_spec.yml with portable family-name declarations.

Resolution order (first hit wins):

1. FontManifest (explicit mapping in the flavor)
2. font_paths from layout_spec (legacy explicit paths)
3. fontist manifest (if the +fontist+ gem is available at
 runtime; otherwise this step is skipped silently)
4. PDF standard 14 fallback (e.g. "Helvetica" → built-in)

Strict mode (strict: true) raises RenderError listing every unresolved required font; lenient mode silently produces nil entries and the renderer falls back to a default.

Constant Summary collapse

STANDARD_14 =
[
  'Helvetica', 'Helvetica-Bold', 'Helvetica-Oblique', 'Helvetica-BoldOblique',
  'Times-Roman', 'Times-Bold', 'Times-Italic', 'Times-BoldItalic',
  'Courier', 'Courier-Bold', 'Courier-Oblique', 'Courier-BoldOblique',
  'Symbol', 'ZapfDingbats'
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(manifest: nil, font_paths: {}, use_fontist: true, strict: false) ⇒ Resolver

Returns a new instance of Resolver.



33
34
35
36
37
38
39
40
41
# File 'lib/arrolio/font/resolver.rb', line 33

def initialize(manifest: nil, font_paths: {}, use_fontist: true,
               strict: false)
  @manifest = manifest
  @font_paths = font_paths.transform_keys(&:to_s)
  @use_fontist = use_fontist
  @strict = strict
  @resolved = {}
  @unresolved = []
end

Instance Attribute Details

#font_pathsObject (readonly)

Returns the value of attribute font_paths.



30
31
32
# File 'lib/arrolio/font/resolver.rb', line 30

def font_paths
  @font_paths
end

#manifestObject (readonly)

Returns the value of attribute manifest.



30
31
32
# File 'lib/arrolio/font/resolver.rb', line 30

def manifest
  @manifest
end

#resolvedObject (readonly)

Returns the value of attribute resolved.



30
31
32
# File 'lib/arrolio/font/resolver.rb', line 30

def resolved
  @resolved
end

#strictObject (readonly)

Returns the value of attribute strict.



30
31
32
# File 'lib/arrolio/font/resolver.rb', line 30

def strict
  @strict
end

#unresolvedObject (readonly)

Returns the value of attribute unresolved.



30
31
32
# File 'lib/arrolio/font/resolver.rb', line 30

def unresolved
  @unresolved
end

#use_fontistObject (readonly)

Returns the value of attribute use_fontist.



30
31
32
# File 'lib/arrolio/font/resolver.rb', line 30

def use_fontist
  @use_fontist
end

Class Method Details

.from_layout_spec(layout_spec, strict: false) ⇒ Object



68
69
70
71
72
73
74
75
# File 'lib/arrolio/font/resolver.rb', line 68

def self.from_layout_spec(layout_spec, strict: false)
  new(
    manifest: layout_font_manifest(layout_spec),
    font_paths: layout_spec.font_paths,
    use_fontist: true,
    strict: strict
  )
end

.standard_14?(family_name) ⇒ Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/arrolio/font/resolver.rb', line 77

def self.standard_14?(family_name)
  STANDARD_14.include?(family_name.to_s)
end

Instance Method Details

#resolve(family_name) ⇒ Object

Resolve a single family name. Returns the absolute path (String) or nil if not found. Does NOT raise in strict mode — use #resolve_all! for that.



46
47
48
49
50
51
52
53
# File 'lib/arrolio/font/resolver.rb', line 46

def resolve(family_name)
  return resolved[family_name.to_s] if resolved.key?(family_name.to_s)

  path = lookup(family_name.to_s)
  resolved[family_name.to_s] = path
  track_unresolved(family_name.to_s, path)
  path
end

#resolve_all!Object

Resolve every family declared by the manifest or font_paths. In strict mode, raises RenderError with the full unresolved list. Returns a Hash { family => path } otherwise.



58
59
60
61
62
63
64
65
66
# File 'lib/arrolio/font/resolver.rb', line 58

def resolve_all!
  families_to_resolve.each { |family| resolve(family) }
  return resolved unless strict && unresolved.any?

  raise ::Arrolio::RenderError.new(
    "strict mode: unresolved required fonts: #{unresolved.join(', ')}",
    missing_fonts: unresolved.map { |name| [name, nil] }
  )
end