diff --git a/lib/fontcustom.rb b/lib/fontcustom.rb index 57d3822e..84973826 100644 --- a/lib/fontcustom.rb +++ b/lib/fontcustom.rb @@ -37,6 +37,7 @@ def gem_lib :autowidth => false, :no_hash => false, :css3 => false, + :ligature => false, :debug => false, :force => false, :quiet => false, diff --git a/lib/fontcustom/generator/font.rb b/lib/fontcustom/generator/font.rb index d9ffd213..f9de6c2e 100644 --- a/lib/fontcustom/generator/font.rb +++ b/lib/fontcustom/generator/font.rb @@ -68,6 +68,10 @@ def set_glyph_info data[:codepoint] = codepoint codepoint = codepoint + 1 end + + if @options[:ligature] + data[:ligature] = name.to_s.gsub(/[^a-zA-Z0-9]+/, '') + end end @manifest.set :glyphs, glyphs end diff --git a/lib/fontcustom/generator/template.rb b/lib/fontcustom/generator/template.rb index 25290baa..b9b44a2f 100644 --- a/lib/fontcustom/generator/template.rb +++ b/lib/fontcustom/generator/template.rb @@ -197,7 +197,7 @@ def glyph_selectors end def glyph_properties -%Q| display: inline-block; + properties = %Q| display: inline-block; font-family: "#{font_name}"; font-style: normal; font-weight: normal; @@ -209,11 +209,22 @@ def glyph_properties -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; font-smoothing: antialiased;| + if @options[:ligature] + properties += %Q| + -webkit-text-rendering: optimizeLegibility; + -moz-text-rendering: optimizeLegibility; + -ms-text-rendering: optimizeLegibility; + -o-text-rendering: optimizeLegibility; + text-rendering: optimizeLegibility;| + end + + properties end def glyphs output = @glyphs.map do |name, value| - %Q|#{@options[:css_selector].sub('{{glyph}}', name.to_s)}#{@pseudo_element} { content: "\\#{value[:codepoint].to_s(16)}"; }| + content = @options[:ligature] ? name.to_s : "\\#{value[:codepoint].to_s(16)}" + %Q|#{@options[:css_selector].sub('{{glyph}}', name.to_s)}#{@pseudo_element} { content: "\\#{content}"; }| end output.join "\n" end diff --git a/lib/fontcustom/scripts/generate.py b/lib/fontcustom/scripts/generate.py index dfe6bee7..a069d1f0 100755 --- a/lib/fontcustom/scripts/generate.py +++ b/lib/fontcustom/scripts/generate.py @@ -47,6 +47,22 @@ # Glyphs # +NUMBER_GLYPH_NAMES = { + "0": "zero", + "1": "one", + "2": "two", + "3": "three", + "4": "four", + "5": "five", + "6": "six", + "7": "seven", + "8": "eight", + "9": "nine" +} + +def resolveGlyphName( c ): + return NUMBER_GLYPH_NAMES[c] if c in NUMBER_GLYPH_NAMES else c + def removeSwitchFromSvg( file ): svgfile = open(file, 'r') svgtext = svgfile.read() @@ -59,31 +75,58 @@ def removeSwitchFromSvg( file ): return tmpsvgfile.name +def setGlyphWidth( glyph ): + if options['autowidth']: + glyph.left_side_bearing = glyph.right_side_bearing = 0 + glyph.round() + else: + glyph.width = options['font_em'] + width = glyph.width - glyph.left_side_bearing - glyph.right_side_bearing + aligned_to_pixel_grid = (width % design_px == 0) + if (aligned_to_pixel_grid): + shift = glyph.left_side_bearing % design_px + glyph.left_side_bearing = glyph.left_side_bearing - shift + glyph.right_side_bearing = glyph.right_side_bearing + shift + +def createEmptyGlyph(code): + glyph = font.createChar(ord(code), resolveGlyphName(code)) + pen = glyph.glyphPen() + pen.moveTo(0, 0) + pen = None + def createGlyph( name, source, code ): frag, ext = os.path.splitext(source) if ext == '.svg': temp = removeSwitchFromSvg(source) - glyph = font.createChar(code, name) + if options['ligature']: + glyph = font.createChar(code, str(name)) + else: + glyph = font.createChar(code) glyph.importOutlines(temp) os.unlink(temp) - if options['autowidth']: - glyph.left_side_bearing = glyph.right_side_bearing = 0 - glyph.round() - else: - glyph.width = options['font_em'] - width = glyph.width - glyph.left_side_bearing - glyph.right_side_bearing - aligned_to_pixel_grid = (width % design_px == 0) - if (aligned_to_pixel_grid): - shift = glyph.left_side_bearing % design_px - glyph.left_side_bearing = glyph.left_side_bearing - shift - glyph.right_side_bearing = glyph.right_side_bearing + shift + setGlyphWidth(glyph) + + if options['ligature']: + liganame = str(data['ligature']) + chars = [] + for char in liganame: + createEmptyGlyph(char) + charName = resolveGlyphName(char) + chars.append(charName) + liga = tuple(chars) + print liga + glyph.addPosSub('liga', liga) # Add valid space glyph to avoid "unknown character" box on IE11 glyph = font.createChar(32) glyph.width = 200 +if options['ligature']: + font.addLookup('liga', 'gsub_ligature', (), (('liga', (('latn', ('dflt')), )), )) + font.addLookupSubtable('liga', 'liga') + for glyph, data in manifest['glyphs'].items(): name = createGlyph(glyph, data['source'], data['codepoint']) @@ -91,14 +134,20 @@ def createGlyph( name, source, code ): # Generate Files # +def generateFont( filename ): + if options['ligature']: + font.generate(filename, flags=('opentype')) + else: + font.generate(filename) + try: fontfile = options['output']['fonts'] + '/' + options['font_name'] if not options['no_hash']: fontfile += '_' + manifest['checksum']['current'][:32] # Generate TTF and SVG - font.generate(fontfile + '.ttf') - font.generate(fontfile + '.svg') + generateFont(fontfile + '.ttf') + generateFont(fontfile + '.svg') manifest['fonts'].append(fontfile + '.ttf') manifest['fonts'].append(fontfile + '.svg') diff --git a/lib/fontcustom/templates/fontcustom-preview.html b/lib/fontcustom/templates/fontcustom-preview.html index b640ffab..6a62a520 100644 --- a/lib/fontcustom/templates/fontcustom-preview.html +++ b/lib/fontcustom/templates/fontcustom-preview.html @@ -109,7 +109,7 @@ text-align: center; } - .usage .point { width: 150px; } + .usage .point, .usage .liagture { width: 150px; } .usage .class { width: 250px; } @@ -162,6 +162,9 @@

<%= font_name %> contains <%= @glyphs.length %> glyphs:

+ <% if @options[:ligature] %> + + <% end %>
<% end %> diff --git a/lib/fontcustom/templates/fontcustom.yml b/lib/fontcustom/templates/fontcustom.yml index 2452dac6..94536b4d 100644 --- a/lib/fontcustom/templates/fontcustom.yml +++ b/lib/fontcustom/templates/fontcustom.yml @@ -97,3 +97,6 @@ # Horizontally fit glyphs to their individual vector widths. #autowidth: false + +# Activate ligature mode. +#ligature: false diff --git a/spec/fontcustom/generator/template_spec.rb b/spec/fontcustom/generator/template_spec.rb index b3043974..29a853a5 100644 --- a/spec/fontcustom/generator/template_spec.rb +++ b/spec/fontcustom/generator/template_spec.rb @@ -6,7 +6,7 @@ live_test do |testdir| FileUtils.cp_r fixture("generators/mixed-output"), "fontcustom" test_manifest( - :input => "vectors", + :input => "vectors", :quiet => true, :templates => %w|preview css scss scss-rails| ) @@ -85,9 +85,9 @@ gen.send :create_files end end - + context ".font_face" do - it "should return base64 when options are set" do + it "should return base64 when options are set" do gen = Fontcustom::Generator::Template.new fixture("generators/.fontcustom-manifest.json") allow(gen).to receive(:woff_base64).and_return("3xampled4ta") options = gen.instance_variable_get :@options @@ -97,6 +97,16 @@ end end + context ".glyph_properties" do + it "should contain optimizeLegibility when options are set" do + gen = Fontcustom::Generator::Template.new fixture("generators/.fontcustom-manifest.json") + options = gen.instance_variable_get :@options + options[:ligature] = true + + expect(gen.send(:glyph_properties)).to match("optimizeLegibility") + end + end + context ".get_target_path" do it "should generate the correct preview target when using default font_name" do gen = Fontcustom::Generator::Template.new fixture("generators/.fontcustom-manifest.json")