lib/fontcustom/generator/font.rb
require "json"
require "open3"
module Fontcustom
module Generator
class Font
include Utility
attr_reader :manifest
def initialize(manifest)
@manifest = Fontcustom::Manifest.new manifest
@options = @manifest.get :options
end
def generate
create_output_dirs
delete_old_fonts
set_glyph_info
create_fonts
end
private
def create_output_dirs
dirs = @options[:output].values.uniq
dirs.each do |dir|
unless File.directory? dir
empty_directory dir, :verbose => false
say_message :create, dir
end
end
end
def delete_old_fonts
@manifest.delete :fonts
end
def set_glyph_info
manifest_glyphs = @manifest.get :glyphs
codepoint = if ! manifest_glyphs.empty?
codepoints = manifest_glyphs.values.map { |data| data[:codepoint] }
codepoints.max + 1
else
# Offset to work around Chrome Windows bug
# https://github.com/FontCustom/fontcustom/issues/1
0xf100
end
files = Dir.glob File.join(@options[:input][:vectors], "*.svg")
glyphs = {}
files.each do |file|
name = File.basename file, ".svg"
name = name.strip.gsub(/\W/, "-")
glyphs[name.to_sym] = { :source => file }
if File.read(file).include? "rgba"
say_message :warn, "`#{file}` contains transparency and will be skipped."
end
end
# Dir.glob returns a different order depending on ruby
# version/platform, so we have to sort it first
glyphs = Hash[glyphs.sort_by { |key, val| key.to_s }]
glyphs.each do |name, data|
if manifest_glyphs.has_key? name
data[:codepoint] = manifest_glyphs[name][:codepoint]
else
data[:codepoint] = codepoint
codepoint = codepoint + 1
end
end
@manifest.set :glyphs, glyphs
end
def create_fonts
cmd = "fontforge -script #{Fontcustom.gem_lib}/scripts/generate.py #{@manifest.manifest}"
stdout, stderr, status = Open3::capture3(cmd)
stdout = stdout.split("\n")
stdout = stdout[1..-1] if stdout[0] == "CreateAllPyModules()"
debug_msg = " Try again with --debug for more details."
if @options[:debug]
messages = stderr.split("\n") + stdout
say_message :debug, messages.join(line_break)
debug_msg = ""
end
if status.success?
@manifest.reload
say_changed :create, @manifest.get(:fonts)
else
raise Fontcustom::Error, "`fontforge` compilation failed.#{debug_msg}"
end
end
end
end
end