class Fontist::SystemIndex

Constants

ENCODING_MAC_ROMAN
ENCODING_MS_UNICODE_BMP
LANGUAGE_MAC_ENGLISH
LANGUAGE_MS_ENGLISH_AMERICAN
PLATFORM_MACINTOSH
PLATFORM_MICROSOFT

Attributes

font_paths[R]

Public Class Methods

fontist_index() click to toggle source
# File lib/fontist/system_index.rb, line 54
def self.fontist_index
  if Fontist.preferred_family?
    new(Fontist.fontist_preferred_family_index_path,
        SystemFont.fontist_font_paths,
        PreferredFamily.new)
  else
    new(Fontist.fontist_index_path,
        SystemFont.fontist_font_paths,
        DefaultFamily.new)
  end
end
new(index_path, font_paths, family) click to toggle source
# File lib/fontist/system_index.rb, line 66
def initialize(index_path, font_paths, family)
  @index_path = index_path
  @font_paths = font_paths
  @family = family
end
system_index() click to toggle source
# File lib/fontist/system_index.rb, line 42
def self.system_index
  if Fontist.preferred_family?
    new(Fontist.system_preferred_family_index_path,
        SystemFont.font_paths,
        PreferredFamily.new)
  else
    new(Fontist.system_index_path,
        SystemFont.font_paths,
        DefaultFamily.new)
  end
end

Public Instance Methods

find(font, style) click to toggle source
# File lib/fontist/system_index.rb, line 72
def find(font, style)
  fonts = index.select do |file|
    file[:family_name].casecmp?(font) &&
      (style.nil? || file[:type].casecmp?(style))
  end

  fonts.empty? ? nil : fonts
end
rebuild() click to toggle source
# File lib/fontist/system_index.rb, line 81
def rebuild
  build_index
end

Private Instance Methods

build_index() click to toggle source
# File lib/fontist/system_index.rb, line 91
def build_index
  lock(lock_path) do
    do_build_index
  end
end
changed?(this, other) click to toggle source
# File lib/fontist/system_index.rb, line 109
def changed?(this, other)
  this.map { |x| x[:path] }.uniq.sort != other.map { |x| x[:path] }.uniq.sort
end
check_index(index) click to toggle source
# File lib/fontist/system_index.rb, line 119
    def check_index(index)
      index.each do |item|
        missing_keys = %i[path full_name family_name type] - item.keys
        unless missing_keys.empty?
          raise(Errors::FontIndexCorrupted, <<~MSG.chomp)
            Font index is corrupted.
            Item #{item.inspect} misses required attributes: #{missing_keys.join(', ')}.
            You can remove the index file (#{@index_path}) and try again.
          MSG
        end
      end
    end
detect_collection_fonts(path) click to toggle source
# File lib/fontist/system_index.rb, line 165
def detect_collection_fonts(path)
  TTFunk::Collection.open(path) do |collection|
    collection.map do |file|
      parse_font(file, path)
    end
  end
end
detect_file_font(path) click to toggle source
# File lib/fontist/system_index.rb, line 158
def detect_file_font(path)
  content = File.read(path, mode: "rb")
  file = TTFunk::File.new(content)

  parse_font(file, path)
end
detect_fonts(path) click to toggle source
# File lib/fontist/system_index.rb, line 142
def detect_fonts(path)
  case File.extname(path).gsub(/^\./, "").downcase
  when "ttf", "otf"
    detect_file_font(path)
  when "ttc"
    detect_collection_fonts(path)
  else
    raise Errors::UnknownFontTypeError.new(path)
  end
rescue StandardError
  Fontist.ui.error($!.message)
  Fontist.ui.error(
    "Warning: File at #{path} not recognized as a font file.",
  )
end
detect_paths(paths, index) click to toggle source
# File lib/fontist/system_index.rb, line 132
def detect_paths(paths, index)
  by_path = index.group_by { |x| x[:path] }

  paths.flat_map do |path|
    next by_path[path] if by_path[path]

    detect_fonts(path)
  end.compact
end
do_build_index() click to toggle source
# File lib/fontist/system_index.rb, line 101
def do_build_index
  previous_index = load_index
  updated_index = detect_paths(font_paths, previous_index)
  updated_index.tap do |index|
    save_index(index) if changed?(updated_index, previous_index)
  end
end
english_name(name) click to toggle source
# File lib/fontist/system_index.rb, line 184
def english_name(name)
  visible_characters(find_english(name))
end
find_english(name) click to toggle source
# File lib/fontist/system_index.rb, line 188
def find_english(name)
  name.find { |x| microsoft_english?(x) } ||
    name.find { |x| mac_english?(x) } ||
    name.last
end
index() click to toggle source
# File lib/fontist/system_index.rb, line 87
def index
  @index ||= build_index
end
load_index() click to toggle source
# File lib/fontist/system_index.rb, line 113
def load_index
  index = File.exist?(@index_path) ? YAML.load_file(@index_path) : []
  check_index(index)
  index
end
lock_path() click to toggle source
# File lib/fontist/system_index.rb, line 97
def lock_path
  "#{@index_path}.lock"
end
mac_english?(string) click to toggle source
# File lib/fontist/system_index.rb, line 200
def mac_english?(string)
  string.platform_id == PLATFORM_MACINTOSH &&
    string.encoding_id == ENCODING_MAC_ROMAN &&
    string.language_id == LANGUAGE_MAC_ENGLISH
end
microsoft_english?(string) click to toggle source
# File lib/fontist/system_index.rb, line 194
def microsoft_english?(string)
  string.platform_id == PLATFORM_MICROSOFT &&
    string.encoding_id == ENCODING_MS_UNICODE_BMP &&
    string.language_id == LANGUAGE_MS_ENGLISH_AMERICAN
end
parse_font(file, path) click to toggle source
# File lib/fontist/system_index.rb, line 173
def parse_font(file, path)
  x = file.name

  {
    path: path,
    full_name: english_name(x.font_name),
    family_name: english_name(@family.family_name(x)),
    type: english_name(@family.type(x)),
  }
end
save_index(index) click to toggle source
# File lib/fontist/system_index.rb, line 210
def save_index(index)
  dir = File.dirname(@index_path)
  FileUtils.mkdir_p(dir) unless File.exist?(dir)
  File.write(@index_path, YAML.dump(index))
end
visible_characters(text) click to toggle source
# File lib/fontist/system_index.rb, line 206
def visible_characters(text)
  text.gsub(/[^[:print:]]/, "").to_s
end