dragonfly_fonts 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/Dockerfile +15 -0
  4. data/Gemfile +4 -0
  5. data/Guardfile +8 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +196 -0
  8. data/Rakefile +9 -0
  9. data/circle.yml +23 -0
  10. data/docker-compose.yml +15 -0
  11. data/dragonfly_fonts.gemspec +28 -0
  12. data/lib/dragonfly_fonts.rb +8 -0
  13. data/lib/dragonfly_fonts/analysers/bbox.rb +35 -0
  14. data/lib/dragonfly_fonts/analysers/font_info.rb +15 -0
  15. data/lib/dragonfly_fonts/analysers/glyphs.rb +14 -0
  16. data/lib/dragonfly_fonts/analysers/gsub_tables.rb +14 -0
  17. data/lib/dragonfly_fonts/plugin.rb +43 -0
  18. data/lib/dragonfly_fonts/processors/correct_metrics.rb +21 -0
  19. data/lib/dragonfly_fonts/processors/encode.rb +57 -0
  20. data/lib/dragonfly_fonts/processors/extract_glyph.rb +19 -0
  21. data/lib/dragonfly_fonts/processors/normalize_names.rb +17 -0
  22. data/lib/dragonfly_fonts/processors/set_dimensions.rb +24 -0
  23. data/lib/dragonfly_fonts/processors/set_ttf_names.rb +52 -0
  24. data/lib/dragonfly_fonts/processors/set_underline.rb +26 -0
  25. data/lib/dragonfly_fonts/processors/set_width.rb +25 -0
  26. data/lib/dragonfly_fonts/processors/set_woff_metadata.rb +23 -0
  27. data/lib/dragonfly_fonts/processors/ttf_autohint.rb +21 -0
  28. data/lib/dragonfly_fonts/processors/web_friendly.rb +17 -0
  29. data/lib/dragonfly_fonts/unicode_ranges.rb +89 -0
  30. data/lib/dragonfly_fonts/version.rb +3 -0
  31. data/samples/Arial.ttf +0 -0
  32. data/samples/Inconsolata.otf +0 -0
  33. data/script/dimensions.py +28 -0
  34. data/script/font_info.py +49 -0
  35. data/script/glyphs.py +25 -0
  36. data/script/gsub_tables.py +43 -0
  37. data/script/normalize_names.sh +13 -0
  38. data/script/underline.py +20 -0
  39. data/script/webfonts.pe +49 -0
  40. data/script/woff_meta.py +81 -0
  41. data/test/dragonfly_fonts/analysers/bbox_test.rb +48 -0
  42. data/test/dragonfly_fonts/analysers/font_info_test.rb +65 -0
  43. data/test/dragonfly_fonts/analysers/glyphs_test.rb +27 -0
  44. data/test/dragonfly_fonts/analysers/gsub_tables_test.rb +42 -0
  45. data/test/dragonfly_fonts/plugin_test.rb +76 -0
  46. data/test/dragonfly_fonts/processors/correct_metrics_test.rb +22 -0
  47. data/test/dragonfly_fonts/processors/encode_test.rb +36 -0
  48. data/test/dragonfly_fonts/processors/extract_glyph_test.rb +22 -0
  49. data/test/dragonfly_fonts/processors/normalize_names_test.rb +18 -0
  50. data/test/dragonfly_fonts/processors/set_dimensions_test.rb +26 -0
  51. data/test/dragonfly_fonts/processors/set_ttf_names_test.rb +23 -0
  52. data/test/dragonfly_fonts/processors/set_underline_test.rb +22 -0
  53. data/test/dragonfly_fonts/processors/set_width_test.rb +48 -0
  54. data/test/dragonfly_fonts/processors/set_woff_metadata_test.rb +28 -0
  55. data/test/dragonfly_fonts/processors/ttf_autohint_test.rb +18 -0
  56. data/test/dragonfly_fonts/processors/web_friendly_test.rb +18 -0
  57. data/test/test_helper.rb +21 -0
  58. metadata +215 -0
@@ -0,0 +1,3 @@
1
+ module DragonflyFonts
2
+ VERSION = "0.0.3"
3
+ end
Binary file
Binary file
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env python
2
+
3
+ import fontforge, sys
4
+
5
+ __version__ = '0.1'
6
+
7
+ def main():
8
+ font = fontforge.open(sys.argv[1])
9
+ output_file_name = sys.argv[2]
10
+
11
+ if sys.argv[3]:
12
+ ascent = float(sys.argv[3])
13
+ font.ascent += ascent
14
+ font.hhea_ascent += ascent
15
+ font.os2_typoascent += ascent
16
+ font.os2_winascent += ascent
17
+
18
+ if sys.argv[4]:
19
+ descent = float(sys.argv[4])
20
+ font.descent += descent
21
+ font.hhea_descent += descent
22
+ font.os2_typodescent += descent
23
+ font.os2_windescent += descent
24
+
25
+ font.generate(output_file_name)
26
+
27
+ if __name__ == '__main__':
28
+ main()
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env python
2
+
3
+ import fontforge, json, sys
4
+
5
+ def main():
6
+ for f in sys.argv[1:] :
7
+ font = fontforge.open(f)
8
+
9
+ names = {}
10
+ for n in font.sfnt_names :
11
+ if n[0] == "English (US)" :
12
+ names[n[1]] = n[2]
13
+
14
+ font_info = {
15
+ 'ascent': font.ascent,
16
+ 'cap_height': font.capHeight,
17
+ 'comment': font.comment,
18
+ 'copyright': font.copyright,
19
+ 'default_base_filename': font.default_base_filename,
20
+ 'descent': font.descent,
21
+ 'descriptor': names.get('Descriptor'),
22
+ 'designer': names.get('Designer'),
23
+ 'designer_url': names.get('Designer URL'),
24
+ 'em': font.em,
25
+ 'embedding_restrictions': font.os2_fstype,
26
+ 'encoding': font.encoding,
27
+ 'familyname': font.familyname,
28
+ 'fontlog': font.fontlog,
29
+ 'fontname': font.fontname,
30
+ 'fullname': font.fullname,
31
+ 'license': names.get('License'),
32
+ 'license_url': names.get('License URL'),
33
+ 'path': font.path,
34
+ 'sfnt_revision': font.sfntRevision,
35
+ 'trademark': names.get('Trademark'),
36
+ 'upos': font.upos,
37
+ 'uwidth': font.uwidth,
38
+ 'vendor_url': names.get('Vendor URL'),
39
+ 'version': font.version,
40
+ 'weight': font.weight,
41
+ 'woff_metadata': font.woffMetadata,
42
+ 'woff_revision': [font.woffMajor, font.woffMinor],
43
+ 'x_height': font.xHeight
44
+ }
45
+
46
+ print json.dumps(font_info)
47
+
48
+ if __name__ == '__main__':
49
+ main()
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env python
2
+
3
+ import array, fontforge, json, sys
4
+
5
+ def main():
6
+ for f in sys.argv[1:] :
7
+ font = fontforge.open(f)
8
+
9
+ glyphs = []
10
+
11
+ for (i,g) in enumerate(font.glyphs()):
12
+ glyphs.append({
13
+ 'glyphname': g.glyphname,
14
+ 'glyphclass': g.glyphclass,
15
+ 'script': g.script,
16
+ 'encoding': g.encoding,
17
+ 'unicode': g.unicode,
18
+ 'width': g.width
19
+ })
20
+
21
+ print json.dumps(glyphs)
22
+
23
+
24
+ if __name__ == '__main__':
25
+ main()
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env python
2
+
3
+ import fontforge, json, sys
4
+
5
+ def main():
6
+ for f in sys.argv[1:] :
7
+ font = fontforge.open(f)
8
+
9
+ gsub_tables = []
10
+
11
+ for gsub in font.gsub_lookups:
12
+
13
+ subtables = []
14
+ for sub in font.getLookupSubtables(gsub):
15
+
16
+ glyphs = []
17
+ for g in font.glyphs():
18
+ pos = g.getPosSub(sub)
19
+ if pos:
20
+ glyphs.append({
21
+ 'name': g.glyphname,
22
+ 'glyphclass': g.glyphclass,
23
+ 'script': g.script,
24
+ 'encoding': g.encoding,
25
+ 'unicode': g.unicode,
26
+ 'pos': pos
27
+ })
28
+
29
+ subtables.append({
30
+ 'name': sub,
31
+ 'glyphs': glyphs
32
+ })
33
+
34
+ gsub_tables.append({
35
+ 'name': gsub,
36
+ 'info': font.getLookupInfo(gsub),
37
+ 'subtables': subtables
38
+ })
39
+
40
+ print json.dumps(gsub_tables)
41
+
42
+ if __name__ == '__main__':
43
+ main()
@@ -0,0 +1,13 @@
1
+
2
+ Open($1)
3
+
4
+ fontname = $fontname
5
+ version = $fontversion
6
+
7
+ # Fix for rejected EOT's in IE8:
8
+ # http://stackoverflow.com/questions/12449512/why-does-one-of-these-font-face-render-in-ie8-but-the-others-dont/12459447#12459447
9
+ # http://fontforge.org/scripting-alpha.html#SetFontNames
10
+ SetFontNames($fontname,$fontname,$fontname,"","",version)
11
+
12
+ # Save.
13
+ Generate($2)
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env python
2
+
3
+ import fontforge, sys
4
+
5
+ __version__ = '0.1'
6
+
7
+ def main():
8
+ font = fontforge.open(sys.argv[1])
9
+ output_file_name = sys.argv[2]
10
+
11
+ if sys.argv[3]:
12
+ font.upos = float(sys.argv[3])
13
+
14
+ if sys.argv[4]:
15
+ font.uwidth = float(sys.argv[4])
16
+
17
+ font.generate(output_file_name)
18
+
19
+ if __name__ == '__main__':
20
+ main()
@@ -0,0 +1,49 @@
1
+ # webfonts.pe font-in.ttf font-out.ttf
2
+
3
+ # Generates webfont-ready files as per http://goo.gl/0qowi
4
+ # Author: Brian Zick <http://21326.info>
5
+ # Version: 1
6
+ # Date: 27 September 2011
7
+
8
+
9
+ # DESCRIPTION
10
+ # webfonts.pe saves a source file, cleans glyph outlines, coverts to tt outlines,
11
+ # and hints fonts before saving hinted and unhinted variants in both .sfd and .ttf.
12
+ # You may need to change the path variable in this script for your project;
13
+ # by default it is set to ../Release.
14
+ #
15
+ # BUGS
16
+ # Some functions are used twice in a row. This is because they
17
+ # (for some reason) did not work properly when used once.
18
+ #
19
+ # On my system, the generated *-TTF-hints.ttf has no hints? I don't know why.
20
+ # *-TTF-hints.sfd does, however, have hints. A workaround was found by
21
+ # Alexei Vanyashin <alexei.vanyashin@gmail.com>: split the script into two
22
+ # parts - one with hints, one without.
23
+ #
24
+ # I have not found a way to set "Really use Typo Metrics", and reportedly,
25
+ # fontforge doesn't export it to the TTF files anyway.
26
+ #
27
+ # It would be nice if fontforge could create a sub-folder for each version.
28
+ #
29
+ # TODO
30
+ # Options to enable or disable hinted/not hinted versions.
31
+
32
+ Open($1)
33
+
34
+ # Glyph cleanup
35
+ SelectAll()
36
+ UnlinkReference()
37
+ RemoveOverlap()
38
+ CorrectDirection()
39
+ ScaleToEm(2048)
40
+
41
+ # Convert splines to quadratic
42
+ SetFontOrder(2)
43
+ Simplify(128,2.05)
44
+ Simplify(128,2.05)
45
+ RoundToInt()
46
+ RoundToInt()
47
+
48
+ # Save.
49
+ Generate($2)
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env python
2
+
3
+ import array, fontforge, json, sys
4
+
5
+ __version__ = '0.1'
6
+
7
+ def main():
8
+ font = fontforge.open(sys.argv[1])
9
+ output_file_name = sys.argv[2]
10
+ uniqueid = sys.argv[3]
11
+ licensee_name = sys.argv[4]
12
+
13
+ names = {}
14
+ for n in font.sfnt_names :
15
+ if n[0] == "English (US)" :
16
+ names[n[1]] = n[2]
17
+
18
+ metadata = [
19
+ '<?xml version="1.0" encoding="UTF-8"?>',
20
+ '<metadata version="1.0">',
21
+ ' <uniqueid id="{}.{}.{}.{}"/>'.format(uniqueid, __version__, font.fontname, font.version),
22
+ ]
23
+
24
+ if names.get('Vendor URL'):
25
+ metadata.extend([
26
+ ' <vendor name="{}" url="{}" />'.format(names.get('Manufacturer'), names.get('Vendor URL')),
27
+ ])
28
+
29
+ if names.get('Designer'):
30
+ if names.get('Designer URL'):
31
+ metadata.extend([
32
+ ' <credits>',
33
+ ' <credit name="{}" url="{}" role="Designer" />'.format(names.get('Designer'), names.get('Designer URL')),
34
+ ' </credits>',
35
+ ])
36
+
37
+ if font.fontlog:
38
+ metadata.extend([
39
+ ' <description>',
40
+ ' <text lang="en"><![CDATA[{}]]></text>'.format(font.fontlog),
41
+ ' </description>',
42
+ ])
43
+
44
+ if names.get('License'):
45
+ if names.get('License URL'):
46
+ metadata.extend([
47
+ ' <license url="{}">'.format(names.get('License URL')),
48
+ ' <text xml:lang="en"><![CDATA[{}]]></text>'.format(names.get('License')),
49
+ ' </license>',
50
+ ])
51
+
52
+ if font.copyright:
53
+ metadata.extend([
54
+ ' <copyright>',
55
+ ' <text lang="en"><![CDATA[{}]]></text>'.format(font.copyright),
56
+ ' </copyright>',
57
+ ])
58
+
59
+ if names.get('Trademark'):
60
+ metadata.extend([
61
+ ' <trademark>',
62
+ ' <text lang="en"><![CDATA[{}]]></text>'.format(names.get('Trademark')),
63
+ ' </trademark>',
64
+ ])
65
+
66
+ if licensee_name:
67
+ metadata.extend([
68
+ ' <licensee name="{}" />'.format(licensee_name),
69
+ ])
70
+
71
+ metadata.extend([
72
+ '</metadata>',
73
+ '', # for trailing endline
74
+ ])
75
+
76
+ font.woffMetadata = '\n'.join(metadata)
77
+
78
+ font.generate(output_file_name)
79
+
80
+ if __name__ == '__main__':
81
+ main()
@@ -0,0 +1,48 @@
1
+ require 'test_helper'
2
+
3
+ module DragonflyFonts
4
+ module Analysers
5
+ describe Bbox do
6
+ let(:app) { test_app.configure_with(:fonts) }
7
+ let(:asset) { app.fetch_file SAMPLES_DIR.join('Inconsolata.otf') }
8
+
9
+ let(:analyser) { DragonflyFonts::Analysers::Bbox.new }
10
+
11
+ describe 'call' do
12
+ let(:bbox) { analyser.call(asset, 'A') }
13
+
14
+ it 'returns Hash' do
15
+ bbox.must_be_kind_of Struct
16
+ end
17
+
18
+ it '#glyph' do
19
+ bbox.glyph.must_equal 'A'
20
+ end
21
+
22
+ it '#min_x' do
23
+ bbox.min_x.must_equal 14.6709
24
+ end
25
+
26
+ it '#min_y' do
27
+ bbox.min_y.must_equal(-0.863281)
28
+ end
29
+
30
+ it '#max_x' do
31
+ bbox.max_x.must_equal 483.28
32
+ end
33
+
34
+ it '#max_y' do
35
+ bbox.max_y.must_equal 634.305
36
+ end
37
+
38
+ it '#width' do
39
+ bbox.width.must_equal 468.60909999999996
40
+ end
41
+
42
+ it '#height' do
43
+ bbox.height.must_equal 635.168281
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,65 @@
1
+ require 'test_helper'
2
+
3
+ module DragonflyFonts
4
+ module Analysers
5
+ describe FontInfo do
6
+ let(:app) { test_app.configure_with(:fonts) }
7
+ let(:analyser) { DragonflyFonts::Analysers::FontInfo.new }
8
+ let(:font) { app.fetch_file(SAMPLES_DIR.join('Inconsolata.otf')) }
9
+
10
+ describe 'call' do
11
+ it 'returns Hash' do
12
+ analyser.call(font).must_be_kind_of Hash
13
+ end
14
+
15
+ it 'includes keys' do
16
+ %w(
17
+ ascent
18
+ cap_height
19
+ comment
20
+ copyright
21
+ default_base_filename
22
+ descent
23
+ descriptor
24
+ designer
25
+ designer_url
26
+ em
27
+ embedding_restrictions
28
+ encoding
29
+ familyname
30
+ fontlog
31
+ fontname
32
+ fullname
33
+ license
34
+ license_url
35
+ path
36
+ sfnt_revision
37
+ trademark
38
+ upos
39
+ uwidth
40
+ vendor_url
41
+ version
42
+ weight
43
+ woff_metadata
44
+ woff_revision
45
+ x_height
46
+ ).each do |key|
47
+ analyser.call(font).keys.must_include key
48
+ end
49
+ end
50
+
51
+ it 'includes familyname' do
52
+ analyser.call(font)['familyname'].must_equal 'Inconsolata'
53
+ end
54
+
55
+ it 'includes fullname' do
56
+ analyser.call(font)['fullname'].must_equal 'Inconsolata'
57
+ end
58
+
59
+ it 'includes weight' do
60
+ analyser.call(font)['weight'].must_equal 'Medium'
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ module DragonflyFonts
4
+ module Analysers
5
+ describe Glyphs do
6
+ let(:app) { test_app.configure_with(:fonts) }
7
+ let(:asset) { app.fetch_file SAMPLES_DIR.join('Inconsolata.otf') }
8
+
9
+ let(:glyph_A) { asset.glyphs.find{ |g| g['glyphname'] == 'A' } }
10
+
11
+ describe 'call' do
12
+ it 'returns Array' do
13
+ asset.glyphs.must_be_kind_of Array
14
+ end
15
+
16
+ it 'returns properties per each glyph' do
17
+ glyph_A['glyphclass'].wont_be_nil
18
+ glyph_A['glyphname'].wont_be_nil
19
+ glyph_A['encoding'].wont_be_nil
20
+ glyph_A['script'].wont_be_nil
21
+ glyph_A['width'].wont_be_nil
22
+ glyph_A['unicode'].wont_be_nil
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end