gkh-fontcustom 1.3.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.travis.yml +20 -0
- data/CHANGELOG.md +137 -0
- data/CONTRIBUTING.md +50 -0
- data/Gemfile +4 -0
- data/LICENSES.txt +60 -0
- data/README.md +112 -0
- data/Rakefile +8 -0
- data/bin/fontcustom +5 -0
- data/fontcustom.gemspec +28 -0
- data/gemfiles/Gemfile.listen_1 +6 -0
- data/lib/fontcustom.rb +43 -0
- data/lib/fontcustom/base.rb +54 -0
- data/lib/fontcustom/cli.rb +110 -0
- data/lib/fontcustom/error.rb +4 -0
- data/lib/fontcustom/generator/font.rb +109 -0
- data/lib/fontcustom/generator/template.rb +222 -0
- data/lib/fontcustom/manifest.rb +75 -0
- data/lib/fontcustom/options.rb +192 -0
- data/lib/fontcustom/scripts/eotlitetool.py +466 -0
- data/lib/fontcustom/scripts/generate.py +128 -0
- data/lib/fontcustom/scripts/sfnt2woff +0 -0
- data/lib/fontcustom/templates/_fontcustom-rails.scss +14 -0
- data/lib/fontcustom/templates/_fontcustom.scss +16 -0
- data/lib/fontcustom/templates/fontcustom-preview.html +174 -0
- data/lib/fontcustom/templates/fontcustom.css +14 -0
- data/lib/fontcustom/templates/fontcustom.yml +96 -0
- data/lib/fontcustom/utility.rb +117 -0
- data/lib/fontcustom/version.rb +3 -0
- data/lib/fontcustom/watcher.rb +90 -0
- data/spec/fixtures/example/_example-rails.scss +50 -0
- data/spec/fixtures/example/example-preview.html +253 -0
- data/spec/fixtures/example/example.css +50 -0
- data/spec/fixtures/example/example.eot +0 -0
- data/spec/fixtures/example/example.svg +75 -0
- data/spec/fixtures/example/example.ttf +0 -0
- data/spec/fixtures/example/example.woff +0 -0
- data/spec/fixtures/generators/.fontcustom-manifest-corrupted.json +25 -0
- data/spec/fixtures/generators/.fontcustom-manifest-empty.json +0 -0
- data/spec/fixtures/generators/.fontcustom-manifest.json +52 -0
- data/spec/fixtures/generators/fontcustom.yml +1 -0
- data/spec/fixtures/generators/mixed-output/another-font.ttf +0 -0
- data/spec/fixtures/generators/mixed-output/dont-delete-me.bro +0 -0
- data/spec/fixtures/generators/mixed-output/fontcustom.css +108 -0
- data/spec/fixtures/generators/mixed-output/fontcustom_82a59e769bc60192484f2620570bbb59.eot +0 -0
- data/spec/fixtures/generators/mixed-output/fontcustom_82a59e769bc60192484f2620570bbb59.svg +56 -0
- data/spec/fixtures/generators/mixed-output/fontcustom_82a59e769bc60192484f2620570bbb59.ttf +0 -0
- data/spec/fixtures/generators/mixed-output/fontcustom_82a59e769bc60192484f2620570bbb59.woff +0 -0
- data/spec/fixtures/options/any-file-name.yml +1 -0
- data/spec/fixtures/options/config-is-in-dir/fontcustom.yml +1 -0
- data/spec/fixtures/options/fontcustom-empty.yml +1 -0
- data/spec/fixtures/options/fontcustom-malformed.yml +1 -0
- data/spec/fixtures/options/fontcustom.yml +1 -0
- data/spec/fixtures/options/no-config-here/.gitkeep +0 -0
- data/spec/fixtures/options/rails-like/config/fontcustom.yml +1 -0
- data/spec/fixtures/shared/not-a-dir +0 -0
- data/spec/fixtures/shared/templates/custom.css +4 -0
- data/spec/fixtures/shared/templates/regular.css +4 -0
- data/spec/fixtures/shared/vectors-empty/no_vectors_here.txt +0 -0
- data/spec/fixtures/shared/vectors/C.svg +14 -0
- data/spec/fixtures/shared/vectors/D.svg +15 -0
- data/spec/fixtures/shared/vectors/a_R3ally-eXotic f1Le Name.svg +6 -0
- data/spec/fontcustom/base_spec.rb +45 -0
- data/spec/fontcustom/cli_spec.rb +30 -0
- data/spec/fontcustom/generator/font_spec.rb +72 -0
- data/spec/fontcustom/generator/template_spec.rb +99 -0
- data/spec/fontcustom/manifest_spec.rb +17 -0
- data/spec/fontcustom/options_spec.rb +315 -0
- data/spec/fontcustom/utility_spec.rb +82 -0
- data/spec/fontcustom/watcher_spec.rb +121 -0
- data/spec/spec_helper.rb +103 -0
- metadata +252 -0
data/lib/fontcustom.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require "fontcustom/version"
|
2
|
+
require "fontcustom/error"
|
3
|
+
require "fontcustom/utility"
|
4
|
+
require "fontcustom/base"
|
5
|
+
require "fontcustom/manifest"
|
6
|
+
require "fontcustom/options"
|
7
|
+
require "fontcustom/generator/font"
|
8
|
+
require "fontcustom/generator/template"
|
9
|
+
|
10
|
+
module Fontcustom
|
11
|
+
def gem_lib
|
12
|
+
File.expand_path(File.join(File.dirname(__FILE__), "fontcustom"))
|
13
|
+
end
|
14
|
+
module_function :gem_lib
|
15
|
+
|
16
|
+
##
|
17
|
+
# Hack to get Thor to show more helpful defaults in `fontcustom help`. These
|
18
|
+
# are overwritten in Fontcustom::Options.
|
19
|
+
EXAMPLE_OPTIONS = {
|
20
|
+
:output => "./FONT_NAME",
|
21
|
+
:config => "./fontcustom.yml -or- ./config/fontcustom.yml",
|
22
|
+
:templates => "css preview"
|
23
|
+
}
|
24
|
+
|
25
|
+
DEFAULT_OPTIONS = {
|
26
|
+
:input => nil,
|
27
|
+
:output => nil,
|
28
|
+
:config => nil,
|
29
|
+
:templates => %w|css preview|,
|
30
|
+
:font_name => "fontcustom",
|
31
|
+
:font_design_size => 16,
|
32
|
+
:font_em => 512,
|
33
|
+
:font_ascent => 448,
|
34
|
+
:font_descent => 64,
|
35
|
+
:css_selector => ".icon-{{glyph}}",
|
36
|
+
:preprocessor_path => nil,
|
37
|
+
:autowidth => false,
|
38
|
+
:no_hash => false,
|
39
|
+
:debug => false,
|
40
|
+
:force => false,
|
41
|
+
:quiet => false
|
42
|
+
}
|
43
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "digest/sha2"
|
2
|
+
|
3
|
+
module Fontcustom
|
4
|
+
class Base
|
5
|
+
include Utility
|
6
|
+
|
7
|
+
def initialize(raw_options)
|
8
|
+
check_fontforge
|
9
|
+
manifest = ".fontcustom-manifest.json"
|
10
|
+
raw_options[:manifest] = manifest
|
11
|
+
@options = Fontcustom::Options.new(raw_options).options
|
12
|
+
@manifest = Fontcustom::Manifest.new(manifest, @options)
|
13
|
+
end
|
14
|
+
|
15
|
+
def compile
|
16
|
+
current = checksum
|
17
|
+
previous = @manifest.get(:checksum)[:previous]
|
18
|
+
|
19
|
+
say_message :status, "Forcing compile." if @options[:force]
|
20
|
+
if @options[:force] || current != previous
|
21
|
+
@manifest.set :checksum, {:previous => previous, :current => current}
|
22
|
+
start_generators
|
23
|
+
@manifest.reload
|
24
|
+
@manifest.set :checksum, {:previous => current, :current => current}
|
25
|
+
else
|
26
|
+
say_message :status, "No changes detected. Skipping compile."
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def check_fontforge
|
33
|
+
fontforge = `which fontforge`
|
34
|
+
if fontforge == "" || fontforge == "fontforge not found"
|
35
|
+
raise Fontcustom::Error, "Please install fontforge first. Visit <http://fontcustom.com> for instructions."
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Calculates a hash of vectors, options, and templates (content and filenames)
|
40
|
+
def checksum
|
41
|
+
files = Dir.glob(File.join(@options[:input][:vectors], "*.svg")).select { |fn| File.file?(fn) }
|
42
|
+
files += Dir.glob(File.join(@options[:input][:templates], "*")).select { |fn| File.file?(fn) }
|
43
|
+
content = files.map { |file| File.read(file) }.join
|
44
|
+
content << files.join
|
45
|
+
content << @options.flatten(2).join
|
46
|
+
Digest::SHA2.hexdigest(content).to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
def start_generators
|
50
|
+
Fontcustom::Generator::Font.new(@manifest.manifest).generate
|
51
|
+
Fontcustom::Generator::Template.new(@manifest.manifest).generate
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "thor/actions"
|
3
|
+
require "fontcustom"
|
4
|
+
require "fontcustom/watcher"
|
5
|
+
|
6
|
+
module Fontcustom
|
7
|
+
class CLI < Thor
|
8
|
+
include Utility
|
9
|
+
|
10
|
+
default_task :show_help
|
11
|
+
|
12
|
+
class_option :output, :aliases => "-o", :type => :string,
|
13
|
+
:desc => "Where generated files are saved. Set different locations for different file types via a configuration file.",
|
14
|
+
:default => EXAMPLE_OPTIONS[:output]
|
15
|
+
|
16
|
+
class_option :config, :aliases => "-c", :type => :string,
|
17
|
+
:desc => "Optional path to a configuration file.",
|
18
|
+
:default => EXAMPLE_OPTIONS[:config]
|
19
|
+
|
20
|
+
class_option :templates, :aliases => "-t", :type => :array,
|
21
|
+
:desc => "Space-delinated list of files to generate alongside fonts. Use stock templates or choose your own.",
|
22
|
+
:enum => %w|preview css scss scss-rails|,
|
23
|
+
:default => EXAMPLE_OPTIONS[:templates]
|
24
|
+
|
25
|
+
class_option :font_name, :aliases => %w|--name -n|, :type => :string,
|
26
|
+
:desc => "The font's name. Also determines the file names of generated templates.",
|
27
|
+
:default => DEFAULT_OPTIONS[:font_name]
|
28
|
+
|
29
|
+
class_option :font_design_size, :aliases => %s|--size -s|, :type => :numeric,
|
30
|
+
:desc => "Size (in pica points) for which this font is designed.",
|
31
|
+
:default => DEFAULT_OPTIONS[:font_design_size]
|
32
|
+
|
33
|
+
class_option :font_em, :aliases => %w|--em -e|, :type => :numeric,
|
34
|
+
:desc => "The em size. Setting this will scale the entire font to the given size.",
|
35
|
+
:default => DEFAULT_OPTIONS[:font_em]
|
36
|
+
|
37
|
+
class_option :font_ascent, :aliases => %w|--ascent -a|, :type => :numeric,
|
38
|
+
:desc => "The font's ascent. Used to calculate the baseline.",
|
39
|
+
:default => DEFAULT_OPTIONS[:font_ascent]
|
40
|
+
|
41
|
+
class_option :font_descent, :aliases => %w|--descent -d|, :type => :numeric,
|
42
|
+
:desc => "The font's descent. Used to calculate the baseline.",
|
43
|
+
:default => DEFAULT_OPTIONS[:font_descent]
|
44
|
+
|
45
|
+
class_option :css_selector, :aliases => %w|--selector -S|, :type => :string,
|
46
|
+
:desc => "Format of CSS selectors. \"{{glyph}}\" is substituted for the glyph name.",
|
47
|
+
:default => DEFAULT_OPTIONS[:css_selector]
|
48
|
+
|
49
|
+
class_option :preprocessor_path, :aliases => %w|--prepath -p|, :type => :string,
|
50
|
+
:desc => "For Rails and Compass templates, set this as the relative path from your compiled CSS to your font output directory."
|
51
|
+
|
52
|
+
class_option :autowidth, :aliases => "-A", :type => :boolean,
|
53
|
+
:desc => "Horizontally fit glyphs to their individual vector widths."
|
54
|
+
|
55
|
+
class_option :no_hash, :aliases => "-h", :type => :boolean,
|
56
|
+
:desc => "Generate fonts without asset-busting hashes."
|
57
|
+
|
58
|
+
class_option :base64, :aliases => "-b", :type => :boolean,
|
59
|
+
:desc => "Encode WOFF fonts into the generated CSS."
|
60
|
+
|
61
|
+
class_option :debug, :aliases => "-D", :type => :boolean,
|
62
|
+
:desc => "Display (possibly useful) debugging messages."
|
63
|
+
|
64
|
+
class_option :force, :aliases => "-F", :type => :boolean,
|
65
|
+
:desc => "Forces compilation, even if inputs have not changed."
|
66
|
+
|
67
|
+
class_option :quiet, :aliases => "-q", :type => :boolean,
|
68
|
+
:desc => "Hide status messages."
|
69
|
+
|
70
|
+
# Required for Thor::Actions#template
|
71
|
+
def self.source_root
|
72
|
+
File.join Fontcustom.gem_lib, "templates"
|
73
|
+
end
|
74
|
+
|
75
|
+
desc "compile [INPUT] [OPTIONS]", "Generates webfonts and templates from *.svg files in INPUT. Default: `pwd`"
|
76
|
+
def compile(input = nil)
|
77
|
+
Base.new(options.merge(:input => input)).compile
|
78
|
+
rescue Fontcustom::Error => e
|
79
|
+
say_status :error, e.message, :red
|
80
|
+
puts e.backtrace.join("\n") if options[:debug]
|
81
|
+
end
|
82
|
+
|
83
|
+
desc "watch [INPUT] [OPTIONS]", "Watches INPUT for changes and regenerates files automatically. Ctrl + C to stop. Default: `pwd`"
|
84
|
+
method_option :skip_first, :type => :boolean,
|
85
|
+
:desc => "Skip the initial compile upon watching.",
|
86
|
+
:default => false
|
87
|
+
def watch(input = nil)
|
88
|
+
say "Font Custom is watching your icons. Press Ctrl + C to stop.", :yellow unless options[:quiet]
|
89
|
+
opts = options.merge :input => input, :skip_first => !! options[:skip_first]
|
90
|
+
Watcher.new(opts).watch
|
91
|
+
rescue Fontcustom::Error => e
|
92
|
+
say_status :error, e.message, :red
|
93
|
+
end
|
94
|
+
|
95
|
+
desc "config [DIR]", "Generates a starter configuration file (fontcustom.yml) in DIR. Default: `pwd`"
|
96
|
+
def config(dir = Dir.pwd)
|
97
|
+
template "fontcustom.yml", File.join(dir, "fontcustom.yml")
|
98
|
+
end
|
99
|
+
|
100
|
+
desc "hidden", "hidden", :hide => true
|
101
|
+
method_option :version, :aliases => "-v", :type => :boolean, :default => false
|
102
|
+
def show_help
|
103
|
+
if options[:version]
|
104
|
+
puts "fontcustom-#{VERSION}"
|
105
|
+
else
|
106
|
+
help
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require "json"
|
2
|
+
require "open3"
|
3
|
+
|
4
|
+
module Fontcustom
|
5
|
+
module Generator
|
6
|
+
class Font
|
7
|
+
include Utility
|
8
|
+
|
9
|
+
attr_reader :manifest
|
10
|
+
|
11
|
+
def initialize(manifest)
|
12
|
+
@manifest = Fontcustom::Manifest.new manifest
|
13
|
+
@options = @manifest.get :options
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate
|
17
|
+
create_output_dirs
|
18
|
+
delete_old_fonts
|
19
|
+
set_glyph_info
|
20
|
+
create_fonts
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def create_output_dirs
|
26
|
+
dirs = @options[:output].values.uniq
|
27
|
+
dirs.each do |dir|
|
28
|
+
unless File.directory? dir
|
29
|
+
empty_directory dir, :verbose => false
|
30
|
+
say_message :create, dir
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def delete_old_fonts
|
36
|
+
@manifest.delete :fonts
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_glyph_info
|
40
|
+
manifest_glyphs = @manifest.get :glyphs
|
41
|
+
codepoint = if ! manifest_glyphs.empty?
|
42
|
+
codepoints = manifest_glyphs.values.map { |data| data[:codepoint] }
|
43
|
+
codepoints.max + 1
|
44
|
+
else
|
45
|
+
# Offset to work around Chrome Windows bug
|
46
|
+
# https://github.com/FontCustom/fontcustom/issues/1
|
47
|
+
0xf100
|
48
|
+
end
|
49
|
+
|
50
|
+
files = Dir.glob File.join(@options[:input][:vectors], "*.svg")
|
51
|
+
glyphs = {}
|
52
|
+
files.each do |file|
|
53
|
+
next if File.symlink?(file)
|
54
|
+
name = File.basename file, ".svg"
|
55
|
+
name = name.strip.gsub(/\W/, "-")
|
56
|
+
glyphs[name.to_sym] = { :source => file }
|
57
|
+
if File.read(file).include? "rgba"
|
58
|
+
say_message :warn, "`#{file}` contains transparency and will be skipped."
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
files.each do |file|
|
63
|
+
next unless File.symlink?(file)
|
64
|
+
linked_name = File.readlink(file)
|
65
|
+
linked_name = File.basename linked_name, ".svg"
|
66
|
+
linked_name = linked_name.strip.gsub(/\W/, "-")
|
67
|
+
glyphs[linked_name.to_sym][:aliases] ||= []
|
68
|
+
alias_name = File.basename file, ".svg"
|
69
|
+
alias_name = alias_name.strip.gsub(/\W/, "-")
|
70
|
+
glyphs[linked_name.to_sym][:aliases] << alias_name
|
71
|
+
end
|
72
|
+
|
73
|
+
# Dir.glob returns a different order depending on ruby
|
74
|
+
# version/platform, so we have to sort it first
|
75
|
+
glyphs = Hash[glyphs.sort_by { |key, val| key.to_s }]
|
76
|
+
glyphs.each do |name, data|
|
77
|
+
if manifest_glyphs.has_key? name
|
78
|
+
data[:codepoint] = manifest_glyphs[name][:codepoint]
|
79
|
+
else
|
80
|
+
data[:codepoint] = codepoint
|
81
|
+
codepoint = codepoint + 1
|
82
|
+
end
|
83
|
+
end
|
84
|
+
@manifest.set :glyphs, glyphs
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_fonts
|
88
|
+
cmd = "fontforge -script #{Fontcustom.gem_lib}/scripts/generate.py #{@manifest.manifest}"
|
89
|
+
stdout, stderr, status = Open3::capture3(cmd)
|
90
|
+
stdout = stdout.split("\n")
|
91
|
+
stdout = stdout[1..-1] if stdout[0] == "CreateAllPyModules()"
|
92
|
+
|
93
|
+
debug_msg = " Try again with --debug for more details."
|
94
|
+
if @options[:debug]
|
95
|
+
messages = stderr.split("\n") + stdout
|
96
|
+
say_message :debug, messages.join(line_break)
|
97
|
+
debug_msg = ""
|
98
|
+
end
|
99
|
+
|
100
|
+
if status.success?
|
101
|
+
@manifest.reload
|
102
|
+
say_changed :create, @manifest.get(:fonts)
|
103
|
+
else
|
104
|
+
raise Fontcustom::Error, "`fontforge` compilation failed.#{debug_msg}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,222 @@
|
|
1
|
+
require "json"
|
2
|
+
require "pathname"
|
3
|
+
require "base64"
|
4
|
+
|
5
|
+
module Fontcustom
|
6
|
+
module Generator
|
7
|
+
class Template
|
8
|
+
include Utility
|
9
|
+
|
10
|
+
attr_reader :manifest
|
11
|
+
|
12
|
+
def initialize(manifest)
|
13
|
+
@manifest = Fontcustom::Manifest.new manifest
|
14
|
+
@options = @manifest.get :options
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate
|
18
|
+
if ! @manifest.get(:fonts).empty?
|
19
|
+
delete_old_templates
|
20
|
+
set_relative_paths
|
21
|
+
create_files
|
22
|
+
else
|
23
|
+
raise Fontcustom::Error, "No generated fonts were detected - aborting template generation."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def delete_old_templates
|
30
|
+
@manifest.delete :templates
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_relative_paths
|
34
|
+
fonts = @manifest.get :fonts
|
35
|
+
name = File.basename fonts.first, File.extname(fonts.first)
|
36
|
+
fonts_path = Pathname.new(@options[:output][:fonts]).realdirpath
|
37
|
+
css_path = Pathname.new(@options[:output][:css]).realdirpath
|
38
|
+
preview_path = Pathname.new(@options[:output][:preview]).realdirpath
|
39
|
+
@font_path = File.join fonts_path.relative_path_from(css_path).to_s, name
|
40
|
+
@font_path_alt = if @options[:preprocessor_path].nil?
|
41
|
+
@font_path
|
42
|
+
elsif ! @options[:preprocessor_path] || @options[:preprocessor_path].empty?
|
43
|
+
name
|
44
|
+
else
|
45
|
+
File.join(@options[:preprocessor_path], name)
|
46
|
+
end
|
47
|
+
@font_path_preview = File.join fonts_path.relative_path_from(preview_path).to_s, name
|
48
|
+
end
|
49
|
+
|
50
|
+
def create_files
|
51
|
+
@glyphs = @manifest.get :glyphs
|
52
|
+
existing = @manifest.get :templates
|
53
|
+
created = []
|
54
|
+
begin
|
55
|
+
@options[:templates].each do |template_name|
|
56
|
+
begin
|
57
|
+
source = get_source_path(template_name)
|
58
|
+
target = get_target_path(source)
|
59
|
+
template source, target, :verbose => false, :force => true
|
60
|
+
end
|
61
|
+
created << target
|
62
|
+
end
|
63
|
+
ensure
|
64
|
+
say_changed :create, created
|
65
|
+
@manifest.set :templates, (existing + created).uniq
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_source_path(template)
|
70
|
+
template_path = File.join Fontcustom.gem_lib, "templates"
|
71
|
+
|
72
|
+
case template
|
73
|
+
when "preview"
|
74
|
+
File.join template_path, "fontcustom-preview.html"
|
75
|
+
when "css"
|
76
|
+
File.join template_path, "fontcustom.css"
|
77
|
+
when "scss"
|
78
|
+
File.join template_path, "_fontcustom.scss"
|
79
|
+
when "scss-rails"
|
80
|
+
File.join template_path, "_fontcustom-rails.scss"
|
81
|
+
else
|
82
|
+
File.join @options[:input][:templates], template
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def get_target_path(source)
|
87
|
+
ext = File.extname source
|
88
|
+
base = File.basename source
|
89
|
+
css_exts = %w|.css .scss .sass .less .stylus|
|
90
|
+
packaged = %w|fontcustom-preview.html fontcustom.css _fontcustom.scss _fontcustom-rails.scss|
|
91
|
+
|
92
|
+
target = if @options[:output].keys.include? base.to_sym
|
93
|
+
File.join @options[:output][base.to_sym], base
|
94
|
+
elsif ext && css_exts.include?(ext)
|
95
|
+
File.join @options[:output][:css], base
|
96
|
+
elsif source.match(/fontcustom-preview\.html/)
|
97
|
+
File.join @options[:output][:preview], base
|
98
|
+
else
|
99
|
+
File.join @options[:output][:fonts], base
|
100
|
+
end
|
101
|
+
|
102
|
+
if packaged.include?(base) && @options[:font_name] != DEFAULT_OPTIONS[:font_name]
|
103
|
+
target.sub! DEFAULT_OPTIONS[:font_name], @options[:font_name]
|
104
|
+
end
|
105
|
+
|
106
|
+
target
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# Template Helpers
|
111
|
+
#
|
112
|
+
|
113
|
+
def font_name
|
114
|
+
@options[:font_name]
|
115
|
+
end
|
116
|
+
|
117
|
+
def font_face(style = {})
|
118
|
+
if style.is_a?(Symbol)
|
119
|
+
if style == :preprocessor
|
120
|
+
url = "font-url"
|
121
|
+
path = @font_path_alt
|
122
|
+
elsif style == :preview
|
123
|
+
url = "url"
|
124
|
+
path = @font_path_preview
|
125
|
+
else
|
126
|
+
url = "url"
|
127
|
+
path = @font_path
|
128
|
+
end
|
129
|
+
say_message :warn, "`font_face(:#{style})` is deprecated. Use `font_face(url:'url', path:'path')` instead."
|
130
|
+
else
|
131
|
+
style = {:url => "url", :path => @font_path}.merge(style)
|
132
|
+
url = style[:url]
|
133
|
+
path = style[:path]
|
134
|
+
end
|
135
|
+
|
136
|
+
# Bulletproof @Font-Face <http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax>
|
137
|
+
# With and without Base64
|
138
|
+
if @options[:base64]
|
139
|
+
string = %Q|@font-face {
|
140
|
+
font-family: "#{font_name}";
|
141
|
+
src: #{url}("#{path}.eot?") format("embedded-opentype");
|
142
|
+
font-weight: normal;
|
143
|
+
font-style: normal;
|
144
|
+
}
|
145
|
+
|
146
|
+
@font-face {
|
147
|
+
font-family: "#{font_name}";
|
148
|
+
src: url("data:application/x-font-woff;charset=utf-8;base64,#{woff_base64}") format("woff"),
|
149
|
+
#{url}("#{path}.ttf") format("truetype"),
|
150
|
+
#{url}("#{path}.svg##{font_name}") format("svg");
|
151
|
+
font-weight: normal;
|
152
|
+
font-style: normal;
|
153
|
+
}|
|
154
|
+
else
|
155
|
+
string = %Q|@font-face {
|
156
|
+
font-family: "#{font_name}";
|
157
|
+
src: #{url}("#{path}.eot");
|
158
|
+
src: #{url}("#{path}.eot?#iefix") format("embedded-opentype"),
|
159
|
+
#{url}("#{path}.woff") format("woff"),
|
160
|
+
#{url}("#{path}.ttf") format("truetype"),
|
161
|
+
#{url}("#{path}.svg##{font_name}") format("svg");
|
162
|
+
font-weight: normal;
|
163
|
+
font-style: normal;
|
164
|
+
}|
|
165
|
+
end
|
166
|
+
|
167
|
+
# For Windows/Chrome <http://stackoverflow.com/a/19247378/1202445>
|
168
|
+
string << %Q|
|
169
|
+
|
170
|
+
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
171
|
+
@font-face {
|
172
|
+
font-family: "#{font_name}";
|
173
|
+
src: #{url}("#{path}.svg##{font_name}") format("svg");
|
174
|
+
}
|
175
|
+
}|
|
176
|
+
string
|
177
|
+
end
|
178
|
+
|
179
|
+
def woff_base64
|
180
|
+
woff_path = File.join(@options[:output][:fonts], "#{@font_path}.woff")
|
181
|
+
Base64.encode64(File.binread(File.join(woff_path))).gsub("\n", "")
|
182
|
+
end
|
183
|
+
|
184
|
+
def glyph_selectors
|
185
|
+
output = @glyphs.map do |name, value|
|
186
|
+
aliases = []
|
187
|
+
aliases = @glyphs[name][:aliases].map do |alias_name|
|
188
|
+
@options[:css_selector].sub("{{glyph}}", alias_name.to_s) + ":before,\n"
|
189
|
+
end if @glyphs[name][:aliases]
|
190
|
+
aliases.join + @options[:css_selector].sub("{{glyph}}", name.to_s) + ":before"
|
191
|
+
end
|
192
|
+
output.join ",\n"
|
193
|
+
end
|
194
|
+
|
195
|
+
def glyph_properties
|
196
|
+
%Q| display: inline-block;
|
197
|
+
font-family: "#{font_name}";
|
198
|
+
font-style: normal;
|
199
|
+
font-weight: normal;
|
200
|
+
font-variant: normal;
|
201
|
+
line-height: 1;
|
202
|
+
text-decoration: inherit;
|
203
|
+
text-rendering: optimizeLegibility;
|
204
|
+
text-transform: none;
|
205
|
+
-moz-osx-font-smoothing: grayscale;
|
206
|
+
-webkit-font-smoothing: antialiased;
|
207
|
+
font-smoothing: antialiased;|
|
208
|
+
end
|
209
|
+
|
210
|
+
def glyphs
|
211
|
+
output = @glyphs.map do |name, value|
|
212
|
+
aliases = []
|
213
|
+
aliases = @glyphs[name][:aliases].map do |alias_name|
|
214
|
+
%Q|#{@options[:css_selector].sub('{{glyph}}', alias_name.to_s)}:before, |
|
215
|
+
end if @glyphs[name][:aliases]
|
216
|
+
aliases.join + %Q|#{@options[:css_selector].sub('{{glyph}}', name.to_s)}:before { content: "\\#{value[:codepoint].to_s(16)}"; }|
|
217
|
+
end
|
218
|
+
output.join "\n"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|