Module: Fontico::ProviderFonts

Defined in:
lib/fontico/provider_fonts.rb

Overview

Providers that publish their own font alongside a name -> codepoint map.

This is the only lossless source of outlines for a stroke-based set: the provider has already expanded the strokes for their font build. Every available JS expander traces a raster and visibly degrades the geometry.

Constant Summary collapse

REGISTRY =
{
  "lucide" => {
    package: "lucide-static",
    version: "1.32.0",
    font: "package/font/lucide.ttf",
    codepoints: "package/font/codepoints.json"
  }
}.freeze

Class Method Summary collapse

Class Method Details

.available?(provider) ⇒ Boolean

Returns:

  • (Boolean)


27
# File 'lib/fontico/provider_fonts.rb', line 27

def available?(provider) = REGISTRY.key?(provider)

.download(spec) ⇒ Object

Raises:



44
45
46
47
48
49
50
51
52
# File 'lib/fontico/provider_fonts.rb', line 44

def download(spec)
  url = "https://registry.npmjs.org/#{spec[:package]}/-/#{spec[:package]}-#{spec[:version]}.tgz"
  uri = URI(url)
  res = Net::HTTP.get_response(uri)
  res = Net::HTTP.get_response(URI(res["location"])) if res.is_a?(Net::HTTPRedirection)
  raise Error, "downloading #{url}: HTTP #{res.code}" unless res.is_a?(Net::HTTPSuccess)

  res.body
end

.fetch(provider, cache_dir:) ⇒ Object

Downloads and unpacks once into the cache; returns local paths.



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/fontico/provider_fonts.rb', line 32

def fetch(provider, cache_dir:)
  spec = REGISTRY.fetch(provider) { raise Error, "no known font for provider #{provider}" }
  dir = File.join(cache_dir, "#{spec[:package]}-#{spec[:version]}")
  font = File.join(dir, File.basename(spec[:font]))
  codepoints = File.join(dir, File.basename(spec[:codepoints]))
  return [font, codepoints] if File.exist?(font) && File.exist?(codepoints)

  FileUtils.mkdir_p(dir)
  unpack(download(spec), spec, font, codepoints)
  [font, codepoints]
end

.knownObject



29
# File 'lib/fontico/provider_fonts.rb', line 29

def known = REGISTRY.keys

.unpack(tgz, spec, font_out, codepoints_out) ⇒ Object

Raises:



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/fontico/provider_fonts.rb', line 54

def unpack(tgz, spec, font_out, codepoints_out)
  wanted = { spec[:font] => font_out, spec[:codepoints] => codepoints_out }
  Gem::Package::TarReader.new(Zlib::GzipReader.new(StringIO.new(tgz))) do |tar|
    tar.each do |entry|
      dest = wanted[entry.full_name]
      File.binwrite(dest, entry.read) if dest
    end
  end
  missing = wanted.reject { File.exist?(_2) }.keys
  raise Error, "#{spec[:package]} did not contain #{missing.join(", ")}" if missing.any?
end