fontisan 0.4.11 → 0.4.12

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +27 -1
  3. data/docs/AFDKO_MIGRATION.adoc +175 -0
  4. data/docs/FEATURE_PARITY.adoc +263 -0
  5. data/docs/STITCHER_GUIDE.adoc +100 -6
  6. data/docs/TTX.adoc +176 -0
  7. data/docs/UFO_COMPILATION.adoc +281 -3
  8. data/lib/fontisan/stitcher/source.rb +11 -7
  9. data/lib/fontisan/subset/table_subsetter.rb +104 -6
  10. data/lib/fontisan/svg/standalone_glyph.rb +129 -0
  11. data/lib/fontisan/svg.rb +1 -0
  12. data/lib/fontisan/ufo/cli.rb +34 -21
  13. data/lib/fontisan/ufo/compile/feature_writers/base.rb +56 -0
  14. data/lib/fontisan/ufo/compile/feature_writers/curs.rb +72 -0
  15. data/lib/fontisan/ufo/compile/feature_writers/gdef.rb +90 -0
  16. data/lib/fontisan/ufo/compile/feature_writers/kern.rb +51 -0
  17. data/lib/fontisan/ufo/compile/feature_writers/kern2.rb +57 -0
  18. data/lib/fontisan/ufo/compile/feature_writers/mark.rb +45 -0
  19. data/lib/fontisan/ufo/compile/feature_writers/mark_family_base.rb +122 -0
  20. data/lib/fontisan/ufo/compile/feature_writers/mkmk.rb +53 -0
  21. data/lib/fontisan/ufo/compile/feature_writers.rb +37 -0
  22. data/lib/fontisan/ufo/compile/filters/propagate_anchors.rb +102 -0
  23. data/lib/fontisan/ufo/compile/filters/remove_overlaps.rb +94 -0
  24. data/lib/fontisan/ufo/compile/filters/sort_contours.rb +69 -0
  25. data/lib/fontisan/ufo/compile/filters/transformations.rb +113 -0
  26. data/lib/fontisan/ufo/compile/filters.rb +12 -0
  27. data/lib/fontisan/ufo/compile.rb +1 -0
  28. data/lib/fontisan/ufo/convert/to_dfont.rb +41 -0
  29. data/lib/fontisan/ufo/convert/to_otc.rb +37 -0
  30. data/lib/fontisan/ufo/convert/to_otf.rb +18 -0
  31. data/lib/fontisan/ufo/convert/to_otf2.rb +20 -0
  32. data/lib/fontisan/ufo/convert/to_postscript.rb +59 -0
  33. data/lib/fontisan/ufo/convert/to_ttc.rb +35 -0
  34. data/lib/fontisan/ufo/convert/to_ttf.rb +21 -0
  35. data/lib/fontisan/ufo/convert/to_woff.rb +56 -0
  36. data/lib/fontisan/ufo/convert/to_woff2.rb +45 -0
  37. data/lib/fontisan/ufo/convert.rb +68 -5
  38. data/lib/fontisan/ufo/transformation.rb +11 -0
  39. data/lib/fontisan/version.rb +1 -1
  40. metadata +27 -1
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tmpdir"
4
+
5
+ module Fontisan
6
+ module Ufo
7
+ module Convert
8
+ # UFO → OpenType Collection (.otc). Two-step:
9
+ #
10
+ # 1. Compile UFO → OTF (CFF) in tmpdir.
11
+ # 2. Load + feed to Collection::Builder with format: :otc.
12
+ #
13
+ # A single UFO produces a single-face collection.
14
+ module ToOtc
15
+ # @param ufo [Fontisan::Ufo::Font]
16
+ # @param output_path [String]
17
+ # @param compiler [Symbol] :otf (default, CFF1) or :otf2 (CFF2)
18
+ # @return [String] the output_path
19
+ def self.convert(ufo, output_path:, compiler: :otf, **_opts)
20
+ compiler_class = Convert::COMPILER_FOR_FORMAT[compiler.to_sym]
21
+ raise ArgumentError, "unknown intermediate compiler: #{compiler.inspect}" unless compiler_class
22
+
23
+ Dir.mktmpdir do |dir|
24
+ intermediate_path = File.join(dir, "intermediate.otf")
25
+ compiler_class.new(ufo).compile(output_path: intermediate_path)
26
+
27
+ loaded = Fontisan::FontLoader.load(intermediate_path)
28
+ Fontisan::Collection::Builder.new([loaded], format: :otc,
29
+ optimize: true).build_to_file(output_path)
30
+ end
31
+
32
+ output_path
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fontisan
4
+ module Ufo
5
+ module Convert
6
+ # Thin facade over Compile::OtfCompiler (CFF1 outlines).
7
+ module ToOtf
8
+ # @param ufo [Fontisan::Ufo::Font]
9
+ # @param output_path [String]
10
+ # @return [String] the output_path
11
+ def self.convert(ufo, output_path:)
12
+ Compile::OtfCompiler.new(ufo).compile(output_path: output_path)
13
+ output_path
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fontisan
4
+ module Ufo
5
+ module Convert
6
+ # Thin facade over Compile::Otf2Compiler (CFF2 outlines, used
7
+ # for variable OTF). CFF2 still inherits the 65,535-glyph cap
8
+ # because maxp.numGlyphs is uint16 — see Stitcher::GlyphLimit.
9
+ module ToOtf2
10
+ # @param ufo [Fontisan::Ufo::Font]
11
+ # @param output_path [String]
12
+ # @return [String] the output_path
13
+ def self.convert(ufo, output_path:)
14
+ Compile::Otf2Compiler.new(ufo).compile(output_path: output_path)
15
+ output_path
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tmpdir"
4
+
5
+ module Fontisan
6
+ module Ufo
7
+ module Convert
8
+ # Shared logic for UFO → PostScript Type 1 (PFB or PFA).
9
+ # Used by ToPfb and ToPfa below; not registered in
10
+ # WRAPPER_FOR_FORMAT directly. Callers should use the
11
+ # format-specific modules.
12
+ module ToPostscript
13
+ # @param ufo [Fontisan::Ufo::Font]
14
+ # @param output_path [String]
15
+ # @param compiler [Symbol] :ttf (default) or :otf
16
+ # @param generator_class [Class] Type1::PFBGenerator or Type1::PFAGenerator
17
+ # @param ps_options [Hash] forwarded to the generator
18
+ # (encoding, upm_scale, convert_curves)
19
+ # @return [String] the output_path
20
+ def self.convert(ufo, output_path:, generator_class:, compiler: :ttf, **ps_options)
21
+ compiler_class = Convert::COMPILER_FOR_FORMAT[compiler.to_sym]
22
+ raise ArgumentError, "unknown intermediate compiler: #{compiler.inspect}" unless compiler_class
23
+
24
+ Dir.mktmpdir do |dir|
25
+ intermediate_path = File.join(dir, "intermediate#{ext_for(compiler)}")
26
+ compiler_class.new(ufo).compile(output_path: intermediate_path)
27
+
28
+ loaded = Fontisan::FontLoader.load(intermediate_path)
29
+ bytes = generator_class.generate(loaded, ps_options)
30
+ File.binwrite(output_path, bytes)
31
+ end
32
+
33
+ output_path
34
+ end
35
+
36
+ def self.ext_for(compiler)
37
+ %i[otf otf2].include?(compiler) ? ".otf" : ".ttf"
38
+ end
39
+ private_class_method :ext_for
40
+ end
41
+
42
+ # UFO → PostScript Type 1 Binary (.pfb).
43
+ module ToPfb
44
+ def self.convert(ufo, output_path:, **)
45
+ ToPostscript.convert(ufo, output_path: output_path,
46
+ generator_class: Fontisan::Type1::PFBGenerator, **)
47
+ end
48
+ end
49
+
50
+ # UFO → PostScript Type 1 ASCII (.pfa).
51
+ module ToPfa
52
+ def self.convert(ufo, output_path:, **)
53
+ ToPostscript.convert(ufo, output_path: output_path,
54
+ generator_class: Fontisan::Type1::PFAGenerator, **)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tmpdir"
4
+
5
+ module Fontisan
6
+ module Ufo
7
+ module Convert
8
+ # UFO → TrueType Collection (.ttc). Two-step:
9
+ #
10
+ # 1. Compile UFO → TTF in tmpdir.
11
+ # 2. Load + feed to Collection::Builder with format: :ttc.
12
+ #
13
+ # A single UFO produces a single-face collection. Multi-face
14
+ # collections from multiple UFOs are a separate concern (the
15
+ # Stitcher pipeline handles that case).
16
+ module ToTtc
17
+ # @param ufo [Fontisan::Ufo::Font]
18
+ # @param output_path [String]
19
+ # @return [String] the output_path
20
+ def self.convert(ufo, output_path:, **_opts)
21
+ Dir.mktmpdir do |dir|
22
+ intermediate_path = File.join(dir, "intermediate.ttf")
23
+ Compile::TtfCompiler.new(ufo).compile(output_path: intermediate_path)
24
+
25
+ loaded = Fontisan::FontLoader.load(intermediate_path)
26
+ Fontisan::Collection::Builder.new([loaded], format: :ttc,
27
+ optimize: true).build_to_file(output_path)
28
+ end
29
+
30
+ output_path
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fontisan
4
+ module Ufo
5
+ module Convert
6
+ # Thin facade over Compile::TtfCompiler. Exists so callers
7
+ # have a uniform +Ufo::Convert::To{Format}.convert+ API across
8
+ # all output formats, and so the CLI's format dispatch can be
9
+ # a hash lookup instead of a case statement.
10
+ module ToTtf
11
+ # @param ufo [Fontisan::Ufo::Font]
12
+ # @param output_path [String]
13
+ # @return [String] the output_path
14
+ def self.convert(ufo, output_path:)
15
+ Compile::TtfCompiler.new(ufo).compile(output_path: output_path)
16
+ output_path
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tmpdir"
4
+
5
+ module Fontisan
6
+ module Ufo
7
+ module Convert
8
+ # UFO → WOFF. Two-step pipeline:
9
+ #
10
+ # 1. Compile the UFO to a TTF (or OTF) in a tmpdir via the
11
+ # corresponding Compile::*Compiler.
12
+ # 2. Load the compiled binary back via FontLoader, then run
13
+ # Converters::WoffWriter to wrap it in the WOFF container.
14
+ #
15
+ # The tmpfile is cleaned up automatically (Dir.mktmpdir block).
16
+ # The original UFO is never mutated.
17
+ #
18
+ # Why two steps instead of one in-memory pass: the WOFF
19
+ # encoders operate on a loaded font's table directory (they
20
+ # need checksums, offsets, alignment), not on a UFO model.
21
+ # Round-tripping through the compiled binary is the simplest
22
+ # path; an in-memory variant would duplicate the table-bytes
23
+ # extraction that FontLoader already does.
24
+ module ToWoff
25
+ # @param ufo [Fontisan::Ufo::Font]
26
+ # @param output_path [String]
27
+ # @param compiler [Symbol] which intermediate format to use:
28
+ # :ttf (default) or :otf
29
+ # @param woff_options [Hash] forwarded to WoffWriter.convert
30
+ # (zlib_level, uncompressed, compression_threshold,
31
+ # metadata_xml, etc.)
32
+ # @return [String] the output_path
33
+ def self.convert(ufo, output_path:, compiler: :ttf, **woff_options)
34
+ compiler_class = Convert::COMPILER_FOR_FORMAT[compiler.to_sym]
35
+ raise ArgumentError, "unknown intermediate compiler: #{compiler.inspect}" unless compiler_class
36
+
37
+ Dir.mktmpdir do |dir|
38
+ intermediate_path = File.join(dir, "intermediate#{format_ext(compiler)}")
39
+ compiler_class.new(ufo).compile(output_path: intermediate_path)
40
+
41
+ loaded = Fontisan::FontLoader.load(intermediate_path)
42
+ woff_bytes = Fontisan::Converters::WoffWriter.new.convert(loaded, woff_options)
43
+ File.binwrite(output_path, woff_bytes)
44
+ end
45
+
46
+ output_path
47
+ end
48
+
49
+ def self.format_ext(compiler)
50
+ %i[otf otf2].include?(compiler) ? ".otf" : ".ttf"
51
+ end
52
+ private_class_method :format_ext
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tmpdir"
4
+
5
+ module Fontisan
6
+ module Ufo
7
+ module Convert
8
+ # UFO → WOFF2. Same two-step pipeline as ToWoff, but with the
9
+ # WOFF2 encoder (Brotli compression, optional glyf/loca
10
+ # transforms) instead of WOFF (zlib).
11
+ #
12
+ # Returns the output_path; the WOFF2 binary itself lands at
13
+ # +output_path+.
14
+ module ToWoff2
15
+ # @param ufo [Fontisan::Ufo::Font]
16
+ # @param output_path [String]
17
+ # @param compiler [Symbol] which intermediate format to use:
18
+ # :ttf (default) or :otf
19
+ # @param woff2_options [Hash] forwarded to Woff2Encoder.convert
20
+ # (brotli_quality, transform_tables, quality legacy alias)
21
+ # @return [String] the output_path
22
+ def self.convert(ufo, output_path:, compiler: :ttf, **woff2_options)
23
+ compiler_class = Convert::COMPILER_FOR_FORMAT[compiler.to_sym]
24
+ raise ArgumentError, "unknown intermediate compiler: #{compiler.inspect}" unless compiler_class
25
+
26
+ Dir.mktmpdir do |dir|
27
+ intermediate_path = File.join(dir, "intermediate#{format_ext(compiler)}")
28
+ compiler_class.new(ufo).compile(output_path: intermediate_path)
29
+
30
+ loaded = Fontisan::FontLoader.load(intermediate_path)
31
+ result = Fontisan::Converters::Woff2Encoder.new.convert(loaded, woff2_options)
32
+ File.binwrite(output_path, result[:woff2_binary])
33
+ end
34
+
35
+ output_path
36
+ end
37
+
38
+ def self.format_ext(compiler)
39
+ %i[otf otf2].include?(compiler) ? ".otf" : ".ttf"
40
+ end
41
+ private_class_method :format_ext
42
+ end
43
+ end
44
+ end
45
+ end
@@ -5,14 +5,77 @@ module Fontisan
5
5
  # Conversion layer between the UFO model and fontisan's BinData
6
6
  # table layer. Two directions:
7
7
  #
8
- # ToBinData.convert(ufo_font) → Hash<tag, BinData record or bytes>
9
- # FromBinData.convert(loaded_font) Fontisan::Ufo::Font
8
+ # ToBinData / To{Format} .convert(ufo, output_path:) writes file
9
+ # FromBinData.convert(loaded_font) → Ufo::Font
10
10
  #
11
- # The ToBinData path is already implemented as Compile::* modules
12
- # (each table builder IS a UFO→BinData converter). This namespace
13
- # owns the reverse direction.
11
+ # The To* paths are thin facades over the corresponding
12
+ # Compile::*Compiler classes. They exist to give callers a single
13
+ # uniform convert API and to keep the CLI's format dispatch in
14
+ # one data-driven place (COMPILER_FOR_FORMAT) instead of a switch
15
+ # statement per CLI command.
14
16
  module Convert
15
17
  autoload :FromBinData, "fontisan/ufo/convert/from_bin_data"
18
+ autoload :ToTtf, "fontisan/ufo/convert/to_ttf"
19
+ autoload :ToOtf, "fontisan/ufo/convert/to_otf"
20
+ autoload :ToOtf2, "fontisan/ufo/convert/to_otf2"
21
+ autoload :ToWoff, "fontisan/ufo/convert/to_woff"
22
+ autoload :ToWoff2, "fontisan/ufo/convert/to_woff2"
23
+ autoload :ToDfont, "fontisan/ufo/convert/to_dfont"
24
+ autoload :ToTtc, "fontisan/ufo/convert/to_ttc"
25
+ autoload :ToOtc, "fontisan/ufo/convert/to_otc"
26
+ autoload :ToPostscript, "fontisan/ufo/convert/to_postscript"
27
+ autoload :ToPfb, "fontisan/ufo/convert/to_postscript"
28
+ autoload :ToPfa, "fontisan/ufo/convert/to_postscript"
29
+
30
+ # Single source of truth for "which compiler handles this
31
+ # output format?". OCP: adding a format = adding one entry
32
+ # here + one wrapper file. The CLI reads from this hash
33
+ # instead of a case statement.
34
+ COMPILER_FOR_FORMAT = {
35
+ ttf: Compile::TtfCompiler,
36
+ otf: Compile::OtfCompiler,
37
+ otf2: Compile::Otf2Compiler,
38
+ }.freeze
39
+
40
+ # Wrapper modules for 2-step pipelines (UFO → compiler →
41
+ # tmpfile → encoder → output). These don't fit the 1-step
42
+ # COMPILER_FOR_FORMAT registry because they need a tmpdir +
43
+ # a second encoder pass. OCP: adding a 2-step format =
44
+ # adding one entry here + one wrapper file.
45
+ WRAPPER_FOR_FORMAT = {
46
+ woff: ToWoff,
47
+ woff2: ToWoff2,
48
+ dfont: ToDfont,
49
+ ttc: ToTtc,
50
+ otc: ToOtc,
51
+ pfb: ToPfb,
52
+ pfa: ToPfa,
53
+ }.freeze
54
+
55
+ # Convert a UFO to a binary format, writing to +output_path+.
56
+ # Routes through either COMPILER_FOR_FORMAT (1-step: ttf/otf/
57
+ # otf2) or WRAPPER_FOR_FORMAT (2-step: woff/woff2). Raises
58
+ # +ArgumentError+ for unknown formats.
59
+ #
60
+ # @param ufo [Fontisan::Ufo::Font]
61
+ # @param to [Symbol] format key
62
+ # @param output_path [String]
63
+ # @param opts [Hash] forwarded to the compiler or wrapper
64
+ # (woff/woff2 wrappers take +compiler:+ + woff-specific opts)
65
+ # @return [String] the output_path
66
+ def self.convert(ufo, to:, output_path:, **)
67
+ format_key = to.to_sym
68
+
69
+ if (wrapper = WRAPPER_FOR_FORMAT[format_key])
70
+ return wrapper.convert(ufo, output_path: output_path, **)
71
+ end
72
+
73
+ compiler = COMPILER_FOR_FORMAT[format_key]
74
+ raise ArgumentError, "unknown UFO output format: #{to.inspect}" unless compiler
75
+
76
+ compiler.new(ufo).compile(output_path: output_path)
77
+ output_path
78
+ end
16
79
  end
17
80
  end
18
81
  end
@@ -34,6 +34,17 @@ module Fontisan
34
34
  def to_a
35
35
  [a, b, c, d, e, f]
36
36
  end
37
+
38
+ # Apply this transformation to a single (x, y) coordinate.
39
+ #
40
+ # @param x [Numeric]
41
+ # @param y [Numeric]
42
+ # @return [Array(Float, Float)] the transformed [tx, ty]
43
+ def apply(x, y)
44
+ xf = x.to_f
45
+ yf = y.to_f
46
+ [a * xf + c * yf + e, b * xf + d * yf + f]
47
+ end
37
48
  end
38
49
  end
39
50
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fontisan
4
- VERSION = "0.4.11"
4
+ VERSION = "0.4.12"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fontisan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.11
4
+ version: 0.4.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -144,15 +144,18 @@ files:
144
144
  - docs/.vitepress/theme/components/WithinHero.vue
145
145
  - docs/.vitepress/theme/index.ts
146
146
  - docs/.vitepress/theme/style.css
147
+ - docs/AFDKO_MIGRATION.adoc
147
148
  - docs/APPLE_LEGACY_FONTS.adoc
148
149
  - docs/CFF2_SUPPORT.adoc
149
150
  - docs/COLLECTION_VALIDATION.adoc
150
151
  - docs/COLOR_FONTS.adoc
151
152
  - docs/CONVERSION_GUIDE.adoc
152
153
  - docs/EXTRACT_TTC_MIGRATION.md
154
+ - docs/FEATURE_PARITY.adoc
153
155
  - docs/FONT_HINTING.adoc
154
156
  - docs/STITCHER_GUIDE.adoc
155
157
  - docs/SVG_TO_GLYF.adoc
158
+ - docs/TTX.adoc
156
159
  - docs/TYPE1_FONTS.adoc
157
160
  - docs/UFO_COMPILATION.adoc
158
161
  - docs/VALIDATION.adoc
@@ -460,6 +463,7 @@ files:
460
463
  - lib/fontisan/svg/font_face_generator.rb
461
464
  - lib/fontisan/svg/font_generator.rb
462
465
  - lib/fontisan/svg/glyph_generator.rb
466
+ - lib/fontisan/svg/standalone_glyph.rb
463
467
  - lib/fontisan/svg/view_box_calculator.rb
464
468
  - lib/fontisan/svg_to_glyf.rb
465
469
  - lib/fontisan/svg_to_glyf/assembler.rb
@@ -591,11 +595,24 @@ files:
591
595
  - lib/fontisan/ufo/compile/cmap.rb
592
596
  - lib/fontisan/ufo/compile/colr.rb
593
597
  - lib/fontisan/ufo/compile/cpal.rb
598
+ - lib/fontisan/ufo/compile/feature_writers.rb
599
+ - lib/fontisan/ufo/compile/feature_writers/base.rb
600
+ - lib/fontisan/ufo/compile/feature_writers/curs.rb
601
+ - lib/fontisan/ufo/compile/feature_writers/gdef.rb
602
+ - lib/fontisan/ufo/compile/feature_writers/kern.rb
603
+ - lib/fontisan/ufo/compile/feature_writers/kern2.rb
604
+ - lib/fontisan/ufo/compile/feature_writers/mark.rb
605
+ - lib/fontisan/ufo/compile/feature_writers/mark_family_base.rb
606
+ - lib/fontisan/ufo/compile/feature_writers/mkmk.rb
594
607
  - lib/fontisan/ufo/compile/filters.rb
595
608
  - lib/fontisan/ufo/compile/filters/cubic_to_quadratic.rb
596
609
  - lib/fontisan/ufo/compile/filters/decompose_components.rb
597
610
  - lib/fontisan/ufo/compile/filters/flatten_components.rb
611
+ - lib/fontisan/ufo/compile/filters/propagate_anchors.rb
612
+ - lib/fontisan/ufo/compile/filters/remove_overlaps.rb
598
613
  - lib/fontisan/ufo/compile/filters/reverse_contour_direction.rb
614
+ - lib/fontisan/ufo/compile/filters/sort_contours.rb
615
+ - lib/fontisan/ufo/compile/filters/transformations.rb
599
616
  - lib/fontisan/ufo/compile/fvar.rb
600
617
  - lib/fontisan/ufo/compile/glyf_loca.rb
601
618
  - lib/fontisan/ufo/compile/gpos.rb
@@ -624,6 +641,15 @@ files:
624
641
  - lib/fontisan/ufo/contour.rb
625
642
  - lib/fontisan/ufo/convert.rb
626
643
  - lib/fontisan/ufo/convert/from_bin_data.rb
644
+ - lib/fontisan/ufo/convert/to_dfont.rb
645
+ - lib/fontisan/ufo/convert/to_otc.rb
646
+ - lib/fontisan/ufo/convert/to_otf.rb
647
+ - lib/fontisan/ufo/convert/to_otf2.rb
648
+ - lib/fontisan/ufo/convert/to_postscript.rb
649
+ - lib/fontisan/ufo/convert/to_ttc.rb
650
+ - lib/fontisan/ufo/convert/to_ttf.rb
651
+ - lib/fontisan/ufo/convert/to_woff.rb
652
+ - lib/fontisan/ufo/convert/to_woff2.rb
627
653
  - lib/fontisan/ufo/data_set.rb
628
654
  - lib/fontisan/ufo/features.rb
629
655
  - lib/fontisan/ufo/font.rb