fontisan 0.2.17 → 0.2.23
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/.rubocop_todo.yml +86 -86
- data/CHANGELOG.md +12 -2
- data/README.adoc +53 -1
- data/docs/.vitepress/config.ts +68 -8
- data/docs/.vitepress/theme/style.css +570 -272
- data/docs/CONVERSION_GUIDE.adoc +31 -8
- data/docs/EXTRACT_TTC_MIGRATION.md +1 -1
- data/docs/WOFF_WOFF2_FORMATS.adoc +53 -0
- data/docs/api/conversion-options.md +37 -14
- data/docs/cli/audit.md +337 -0
- data/docs/cli/convert.md +20 -1
- data/docs/cli/index.md +31 -0
- data/docs/guide/color.md +1 -1
- data/docs/guide/conversion/options.md +32 -3
- data/docs/guide/conversion/ttf-otf.md +1 -1
- data/docs/guide/conversion/type1.md +1 -1
- data/docs/guide/conversion/web.md +91 -32
- data/docs/guide/conversion.md +6 -5
- data/docs/guide/formats/woff.md +35 -11
- data/docs/guide/index.md +2 -2
- data/docs/guide/migrations/extract-ttc.md +1 -1
- data/docs/guide/quick-start.md +4 -4
- data/docs/guide/type1.md +4 -4
- data/docs/guide/woff.md +19 -17
- data/docs/index.md +2 -0
- data/docs/lychee.toml +5 -1
- data/docs/package.json +1 -1
- data/docs/public/robots.txt +4 -0
- data/docs/scripts/post-build.mjs +81 -0
- data/lib/fontisan/base_collection.rb +23 -9
- data/lib/fontisan/binary/structures.rb +0 -2
- data/lib/fontisan/binary.rb +11 -0
- data/lib/fontisan/cldr/aggregator.rb +33 -0
- data/lib/fontisan/cldr/cache_manager.rb +110 -0
- data/lib/fontisan/cldr/config.rb +59 -0
- data/lib/fontisan/cldr/download_error.rb +9 -0
- data/lib/fontisan/cldr/downloader.rb +79 -0
- data/lib/fontisan/cldr/error.rb +8 -0
- data/lib/fontisan/cldr/index.rb +64 -0
- data/lib/fontisan/cldr/index_builder.rb +72 -0
- data/lib/fontisan/cldr/unicode_set_parser.rb +189 -0
- data/lib/fontisan/cldr/unknown_version_error.rb +9 -0
- data/lib/fontisan/cldr/version_resolver.rb +91 -0
- data/lib/fontisan/cldr.rb +23 -0
- data/lib/fontisan/cli/cldr_cli.rb +85 -0
- data/lib/fontisan/cli.rb +31 -2
- data/lib/fontisan/collection/builder.rb +0 -4
- data/lib/fontisan/collection/dfont_builder.rb +0 -4
- data/lib/fontisan/collection/shared_logic.rb +0 -2
- data/lib/fontisan/collection/writer.rb +0 -3
- data/lib/fontisan/collection.rb +15 -0
- data/lib/fontisan/commands/base_command.rb +0 -3
- data/lib/fontisan/commands/convert_command.rb +25 -20
- data/lib/fontisan/commands/dump_table_command.rb +0 -3
- data/lib/fontisan/commands/export_command.rb +0 -4
- data/lib/fontisan/commands/features_command.rb +0 -3
- data/lib/fontisan/commands/instance_command.rb +0 -5
- data/lib/fontisan/commands/ls_command.rb +0 -6
- data/lib/fontisan/commands/optical_size_command.rb +0 -3
- data/lib/fontisan/commands/pack_command.rb +0 -5
- data/lib/fontisan/commands/scripts_command.rb +0 -2
- data/lib/fontisan/commands/subset_command.rb +0 -3
- data/lib/fontisan/commands/unicode_command.rb +0 -3
- data/lib/fontisan/commands/unpack_command.rb +0 -7
- data/lib/fontisan/commands/validate_command.rb +0 -8
- data/lib/fontisan/commands/variable_command.rb +0 -3
- data/lib/fontisan/commands.rb +26 -0
- data/lib/fontisan/config/cldr.yml +22 -0
- data/lib/fontisan/config/conversion_matrix.yml +38 -0
- data/lib/fontisan/constants.rb +19 -0
- data/lib/fontisan/conversion_options.rb +30 -19
- data/lib/fontisan/converters/cff_table_builder.rb +0 -3
- data/lib/fontisan/converters/collection_converter.rb +0 -8
- data/lib/fontisan/converters/conversion_strategy.rb +161 -46
- data/lib/fontisan/converters/format_converter.rb +143 -32
- data/lib/fontisan/converters/glyf_table_builder.rb +0 -2
- data/lib/fontisan/converters/outline_converter.rb +0 -19
- data/lib/fontisan/converters/outline_extraction.rb +0 -5
- data/lib/fontisan/converters/outline_optimizer.rb +0 -5
- data/lib/fontisan/converters/svg_generator.rb +0 -4
- data/lib/fontisan/converters/table_copier.rb +0 -2
- data/lib/fontisan/converters/type1_converter.rb +0 -11
- data/lib/fontisan/converters/woff2_encoder.rb +49 -20
- data/lib/fontisan/converters/woff_writer.rb +211 -282
- data/lib/fontisan/converters.rb +21 -0
- data/lib/fontisan/dfont_collection.rb +29 -10
- data/lib/fontisan/export/exporter.rb +0 -6
- data/lib/fontisan/export/transformers/font_to_ttx.rb +0 -9
- data/lib/fontisan/export/transformers/head_transformer.rb +0 -2
- data/lib/fontisan/export/transformers/hhea_transformer.rb +0 -2
- data/lib/fontisan/export/transformers/maxp_transformer.rb +0 -2
- data/lib/fontisan/export/transformers/name_transformer.rb +0 -2
- data/lib/fontisan/export/transformers/os2_transformer.rb +0 -2
- data/lib/fontisan/export/transformers/post_transformer.rb +0 -2
- data/lib/fontisan/export/transformers.rb +17 -0
- data/lib/fontisan/export.rb +13 -0
- data/lib/fontisan/font_loader.rb +14 -19
- data/lib/fontisan/font_writer.rb +0 -1
- data/lib/fontisan/formatters.rb +9 -0
- data/lib/fontisan/hints/hint_converter.rb +0 -1
- data/lib/fontisan/hints/postscript_hint_applier.rb +0 -9
- data/lib/fontisan/hints/postscript_hint_extractor.rb +0 -2
- data/lib/fontisan/hints/truetype_hint_extractor.rb +0 -2
- data/lib/fontisan/hints.rb +19 -0
- data/lib/fontisan/metrics_calculator.rb +0 -2
- data/lib/fontisan/models/all_scripts_features_info.rb +0 -1
- data/lib/fontisan/models/cldr/language_coverage.rb +31 -0
- data/lib/fontisan/models/cldr.rb +12 -0
- data/lib/fontisan/models/collection_brief_info.rb +0 -1
- data/lib/fontisan/models/collection_info.rb +0 -2
- data/lib/fontisan/models/collection_list_info.rb +0 -1
- data/lib/fontisan/models/collection_validation_report.rb +0 -2
- data/lib/fontisan/models/color_glyph.rb +0 -1
- data/lib/fontisan/models/font_report.rb +0 -1
- data/lib/fontisan/models/ttx/tables.rb +21 -0
- data/lib/fontisan/models/ttx/ttfont.rb +0 -8
- data/lib/fontisan/models/ttx.rb +14 -0
- data/lib/fontisan/models.rb +47 -0
- data/lib/fontisan/open_type_collection.rb +6 -5
- data/lib/fontisan/open_type_font.rb +8 -2
- data/lib/fontisan/open_type_font_extensions.rb +9 -9
- data/lib/fontisan/optimizers/pattern_analyzer.rb +0 -1
- data/lib/fontisan/optimizers.rb +14 -0
- data/lib/fontisan/outline_extractor.rb +0 -2
- data/lib/fontisan/parsers/dfont_parser.rb +0 -1
- data/lib/fontisan/parsers.rb +10 -0
- data/lib/fontisan/pipeline/format_detector.rb +29 -102
- data/lib/fontisan/pipeline/output_writer.rb +11 -9
- data/lib/fontisan/pipeline/strategies/instance_strategy.rb +0 -4
- data/lib/fontisan/pipeline/strategies/named_strategy.rb +0 -4
- data/lib/fontisan/pipeline/strategies/preserve_strategy.rb +0 -2
- data/lib/fontisan/pipeline/strategies.rb +16 -0
- data/lib/fontisan/pipeline/transformation_pipeline.rb +0 -7
- data/lib/fontisan/pipeline/variation_resolver.rb +0 -7
- data/lib/fontisan/pipeline.rb +14 -0
- data/lib/fontisan/sfnt_font.rb +29 -14
- data/lib/fontisan/sfnt_table.rb +0 -4
- data/lib/fontisan/subset/builder.rb +0 -6
- data/lib/fontisan/subset.rb +13 -0
- data/lib/fontisan/svg/font_generator.rb +0 -4
- data/lib/fontisan/svg/glyph_generator.rb +0 -2
- data/lib/fontisan/svg.rb +12 -0
- data/lib/fontisan/tables/cbdt.rb +0 -1
- data/lib/fontisan/tables/cblc.rb +0 -1
- data/lib/fontisan/tables/cff/charset.rb +0 -1
- data/lib/fontisan/tables/cff/charstring.rb +0 -1
- data/lib/fontisan/tables/cff/charstring_rebuilder.rb +0 -4
- data/lib/fontisan/tables/cff/charstrings_index.rb +0 -3
- data/lib/fontisan/tables/cff/dict.rb +0 -1
- data/lib/fontisan/tables/cff/encoding.rb +0 -1
- data/lib/fontisan/tables/cff/header.rb +0 -2
- data/lib/fontisan/tables/cff/hint_operation_injector.rb +0 -2
- data/lib/fontisan/tables/cff/index.rb +0 -1
- data/lib/fontisan/tables/cff/private_dict.rb +0 -2
- data/lib/fontisan/tables/cff/private_dict_writer.rb +0 -2
- data/lib/fontisan/tables/cff/table_builder.rb +0 -6
- data/lib/fontisan/tables/cff/top_dict.rb +0 -2
- data/lib/fontisan/tables/cff.rb +23 -15
- data/lib/fontisan/tables/cff2/charstring_parser.rb +0 -2
- data/lib/fontisan/tables/cff2/table_builder.rb +0 -11
- data/lib/fontisan/tables/cff2/table_reader.rb +0 -2
- data/lib/fontisan/tables/cff2.rb +13 -14
- data/lib/fontisan/tables/cmap.rb +24 -2
- data/lib/fontisan/tables/cmap_table.rb +0 -3
- data/lib/fontisan/tables/colr.rb +0 -1
- data/lib/fontisan/tables/cpal.rb +0 -1
- data/lib/fontisan/tables/cvar.rb +0 -2
- data/lib/fontisan/tables/fvar.rb +0 -1
- data/lib/fontisan/tables/glyf/compound_glyph_resolver.rb +0 -2
- data/lib/fontisan/tables/glyf/glyph_builder.rb +0 -3
- data/lib/fontisan/tables/glyf.rb +0 -6
- data/lib/fontisan/tables/glyf_table.rb +0 -3
- data/lib/fontisan/tables/gpos.rb +0 -2
- data/lib/fontisan/tables/gsub.rb +0 -2
- data/lib/fontisan/tables/gvar.rb +0 -2
- data/lib/fontisan/tables/head.rb +0 -2
- data/lib/fontisan/tables/head_table.rb +0 -3
- data/lib/fontisan/tables/hhea.rb +0 -2
- data/lib/fontisan/tables/hhea_table.rb +0 -3
- data/lib/fontisan/tables/hmtx.rb +0 -2
- data/lib/fontisan/tables/hmtx_table.rb +0 -3
- data/lib/fontisan/tables/hvar.rb +0 -3
- data/lib/fontisan/tables/loca.rb +0 -2
- data/lib/fontisan/tables/loca_table.rb +0 -3
- data/lib/fontisan/tables/maxp.rb +0 -2
- data/lib/fontisan/tables/maxp_table.rb +0 -3
- data/lib/fontisan/tables/mvar.rb +0 -3
- data/lib/fontisan/tables/name.rb +0 -2
- data/lib/fontisan/tables/name_table.rb +0 -3
- data/lib/fontisan/tables/os2_table.rb +0 -3
- data/lib/fontisan/tables/post_table.rb +0 -3
- data/lib/fontisan/tables/sbix.rb +0 -1
- data/lib/fontisan/tables/svg.rb +0 -1
- data/lib/fontisan/tables/variation_common.rb +0 -1
- data/lib/fontisan/tables/vvar.rb +0 -3
- data/lib/fontisan/tables.rb +55 -0
- data/lib/fontisan/true_type_collection.rb +6 -14
- data/lib/fontisan/true_type_font.rb +8 -2
- data/lib/fontisan/true_type_font_extensions.rb +9 -9
- data/lib/fontisan/type1/afm_generator.rb +0 -4
- data/lib/fontisan/type1/conversion_options.rb +0 -2
- data/lib/fontisan/type1/encodings.rb +0 -2
- data/lib/fontisan/type1/generator.rb +0 -8
- data/lib/fontisan/type1/pfa_generator.rb +0 -3
- data/lib/fontisan/type1/pfb_generator.rb +0 -5
- data/lib/fontisan/type1/pfm_generator.rb +0 -4
- data/lib/fontisan/type1.rb +42 -69
- data/lib/fontisan/type1_font.rb +40 -11
- data/lib/fontisan/utilities/checksum_calculator.rb +0 -1
- data/lib/fontisan/utilities.rb +10 -0
- data/lib/fontisan/utils.rb +10 -0
- data/lib/fontisan/validation/collection_validator.rb +0 -2
- data/lib/fontisan/validation.rb +9 -0
- data/lib/fontisan/validators/basic_validator.rb +0 -2
- data/lib/fontisan/validators/font_book_validator.rb +0 -2
- data/lib/fontisan/validators/opentype_validator.rb +0 -2
- data/lib/fontisan/validators/profile_loader.rb +0 -5
- data/lib/fontisan/validators/validator.rb +0 -2
- data/lib/fontisan/validators/web_font_validator.rb +0 -2
- data/lib/fontisan/validators.rb +14 -0
- data/lib/fontisan/variable/delta_applicator.rb +0 -4
- data/lib/fontisan/variable/instancer.rb +0 -3
- data/lib/fontisan/variable/static_font_builder.rb +0 -3
- data/lib/fontisan/variable.rb +16 -0
- data/lib/fontisan/variation/blend_applier.rb +0 -2
- data/lib/fontisan/variation/cache.rb +0 -2
- data/lib/fontisan/variation/converter.rb +0 -3
- data/lib/fontisan/variation/data_extractor.rb +0 -2
- data/lib/fontisan/variation/delta_applier.rb +0 -5
- data/lib/fontisan/variation/inspector.rb +0 -1
- data/lib/fontisan/variation/instance_generator.rb +0 -6
- data/lib/fontisan/variation/instance_writer.rb +0 -5
- data/lib/fontisan/variation/metrics_adjuster.rb +0 -4
- data/lib/fontisan/variation/optimizer.rb +0 -3
- data/lib/fontisan/variation/parallel_generator.rb +0 -3
- data/lib/fontisan/variation/subsetter.rb +0 -4
- data/lib/fontisan/variation/tuple_variation_header.rb +0 -2
- data/lib/fontisan/variation/variable_svg_generator.rb +0 -3
- data/lib/fontisan/variation/variation_context.rb +0 -3
- data/lib/fontisan/variation/variation_preserver.rb +0 -3
- data/lib/fontisan/variation.rb +31 -0
- data/lib/fontisan/version.rb +1 -1
- data/lib/fontisan/woff2.rb +13 -0
- data/lib/fontisan/woff2_font.rb +31 -9
- data/lib/fontisan/woff_font.rb +31 -2
- data/lib/fontisan.rb +121 -196
- metadata +46 -2
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "parsers/dfont_parser"
|
|
4
|
-
require_relative "error"
|
|
5
|
-
require_relative "collection/shared_logic"
|
|
6
|
-
|
|
7
3
|
module Fontisan
|
|
8
4
|
# DfontCollection represents an Apple dfont suitcase containing multiple fonts
|
|
9
5
|
#
|
|
@@ -26,6 +22,35 @@ module Fontisan
|
|
|
26
22
|
class DfontCollection
|
|
27
23
|
include Collection::SharedLogic
|
|
28
24
|
|
|
25
|
+
# High-level pipeline format identifier. Owned by the collection class
|
|
26
|
+
# so the conversion pipeline can dispatch without case statements (OCP).
|
|
27
|
+
#
|
|
28
|
+
# @return [Symbol] :dfont
|
|
29
|
+
def format = :dfont
|
|
30
|
+
|
|
31
|
+
# Whether this object represents a font collection rather than a single
|
|
32
|
+
# font. Each font class is the authority on this question.
|
|
33
|
+
#
|
|
34
|
+
# @return [Boolean]
|
|
35
|
+
def collection? = true
|
|
36
|
+
|
|
37
|
+
# Variation profile. dfonts are containers; per-font variation is not
|
|
38
|
+
# exposed at the collection level.
|
|
39
|
+
#
|
|
40
|
+
# @return [Symbol] :static
|
|
41
|
+
def variation_type = :static
|
|
42
|
+
|
|
43
|
+
# Outline representation. dfonts may contain mixed-flavor fonts;
|
|
44
|
+
# per-font outline type requires loading an individual font.
|
|
45
|
+
#
|
|
46
|
+
# @return [Symbol] :unknown
|
|
47
|
+
def outline_type = :unknown
|
|
48
|
+
|
|
49
|
+
# Collections have no single SFNT table directory.
|
|
50
|
+
#
|
|
51
|
+
# @return [Array<String>] empty
|
|
52
|
+
def table_names = []
|
|
53
|
+
|
|
29
54
|
# Path to dfont file
|
|
30
55
|
# @return [String]
|
|
31
56
|
attr_reader :path
|
|
@@ -138,9 +163,6 @@ module Fontisan
|
|
|
138
163
|
# @param io [IO] Open file handle
|
|
139
164
|
# @return [Models::CollectionListInfo] Collection list info
|
|
140
165
|
def list_fonts(io)
|
|
141
|
-
require_relative "models/collection_list_info"
|
|
142
|
-
require_relative "models/collection_font_summary"
|
|
143
|
-
|
|
144
166
|
fonts = extract_fonts(io)
|
|
145
167
|
|
|
146
168
|
summaries = fonts.map.with_index do |font, index|
|
|
@@ -227,9 +249,6 @@ module Fontisan
|
|
|
227
249
|
# puts "Format: #{info.collection_format}"
|
|
228
250
|
# end
|
|
229
251
|
def collection_info(io, path)
|
|
230
|
-
require_relative "models/collection_info"
|
|
231
|
-
require_relative "models/table_sharing_info"
|
|
232
|
-
|
|
233
252
|
# Calculate table sharing statistics
|
|
234
253
|
table_sharing = calculate_table_sharing(io)
|
|
235
254
|
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../models/font_export"
|
|
4
|
-
require_relative "table_serializer"
|
|
5
|
-
require_relative "ttx_generator"
|
|
6
|
-
require_relative "transformers/font_to_ttx"
|
|
7
|
-
require_relative "../utilities/checksum_calculator"
|
|
8
|
-
|
|
9
3
|
module Fontisan
|
|
10
4
|
module Export
|
|
11
5
|
# Exporter orchestrates font export to YAML/JSON/TTX
|
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../../models/ttx/ttfont"
|
|
4
|
-
require_relative "../../models/ttx/glyph_order"
|
|
5
|
-
require_relative "head_transformer"
|
|
6
|
-
require_relative "name_transformer"
|
|
7
|
-
require_relative "os2_transformer"
|
|
8
|
-
require_relative "post_transformer"
|
|
9
|
-
require_relative "hhea_transformer"
|
|
10
|
-
require_relative "maxp_transformer"
|
|
11
|
-
|
|
12
3
|
module Fontisan
|
|
13
4
|
module Export
|
|
14
5
|
module Transformers
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Export::Transformers namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Export
|
|
7
|
+
module Transformers
|
|
8
|
+
autoload :FontToTtx, "fontisan/export/transformers/font_to_ttx"
|
|
9
|
+
autoload :HeadTransformer, "fontisan/export/transformers/head_transformer"
|
|
10
|
+
autoload :HheaTransformer, "fontisan/export/transformers/hhea_transformer"
|
|
11
|
+
autoload :MaxpTransformer, "fontisan/export/transformers/maxp_transformer"
|
|
12
|
+
autoload :NameTransformer, "fontisan/export/transformers/name_transformer"
|
|
13
|
+
autoload :Os2Transformer, "fontisan/export/transformers/os2_transformer"
|
|
14
|
+
autoload :PostTransformer, "fontisan/export/transformers/post_transformer"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Export namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Export
|
|
7
|
+
autoload :Exporter, "fontisan/export/exporter"
|
|
8
|
+
autoload :TableSerializer, "fontisan/export/table_serializer"
|
|
9
|
+
autoload :Transformers, "fontisan/export/transformers/font_to_ttx"
|
|
10
|
+
autoload :TtxGenerator, "fontisan/export/ttx_generator"
|
|
11
|
+
autoload :TtxParser, "fontisan/export/ttx_parser"
|
|
12
|
+
end
|
|
13
|
+
end
|
data/lib/fontisan/font_loader.rb
CHANGED
|
@@ -1,18 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "stringio"
|
|
4
|
-
require_relative "constants"
|
|
5
|
-
require_relative "loading_modes"
|
|
6
|
-
require_relative "true_type_font"
|
|
7
|
-
require_relative "open_type_font"
|
|
8
|
-
require_relative "true_type_collection"
|
|
9
|
-
require_relative "open_type_collection"
|
|
10
|
-
require_relative "dfont_collection"
|
|
11
|
-
require_relative "woff_font"
|
|
12
|
-
require_relative "woff2_font"
|
|
13
|
-
require_relative "type1_font"
|
|
14
|
-
require_relative "parsers/dfont_parser"
|
|
15
|
-
require_relative "error"
|
|
16
4
|
|
|
17
5
|
module Fontisan
|
|
18
6
|
# FontLoader provides unified font loading with content-based format detection.
|
|
@@ -85,12 +73,18 @@ module Fontisan
|
|
|
85
73
|
|
|
86
74
|
format = detect(path)
|
|
87
75
|
case format
|
|
88
|
-
when :ttf then TrueTypeFont.from_file(path, mode: resolved_mode,
|
|
89
|
-
|
|
90
|
-
when :
|
|
91
|
-
|
|
92
|
-
when :
|
|
93
|
-
|
|
76
|
+
when :ttf then TrueTypeFont.from_file(path, mode: resolved_mode,
|
|
77
|
+
lazy: resolved_lazy)
|
|
78
|
+
when :otf then OpenTypeFont.from_file(path, mode: resolved_mode,
|
|
79
|
+
lazy: resolved_lazy)
|
|
80
|
+
when :woff then WoffFont.from_file(path, mode: resolved_mode,
|
|
81
|
+
lazy: resolved_lazy)
|
|
82
|
+
when :woff2 then Woff2Font.from_file(path, mode: resolved_mode,
|
|
83
|
+
lazy: resolved_lazy)
|
|
84
|
+
when :ttc, :otc then load_from_collection(path, format, font_index,
|
|
85
|
+
mode: resolved_mode)
|
|
86
|
+
when :dfont then load_dfont(path, font_index: font_index,
|
|
87
|
+
mode: resolved_mode)
|
|
94
88
|
when :pfa, :pfb then Type1Font.from_file(path, mode: resolved_mode)
|
|
95
89
|
else
|
|
96
90
|
raise InvalidFontError,
|
|
@@ -279,7 +273,8 @@ module Fontisan
|
|
|
279
273
|
# public `lazy:` flag is not threaded through this path.
|
|
280
274
|
def self.load_dfont(path, font_index:, mode:)
|
|
281
275
|
File.open(path, "rb") do |io|
|
|
282
|
-
sfnt_io = StringIO.new(Parsers::DfontParser.extract_sfnt(io,
|
|
276
|
+
sfnt_io = StringIO.new(Parsers::DfontParser.extract_sfnt(io,
|
|
277
|
+
index: font_index))
|
|
283
278
|
klass = case Constants.sfnt_format_for(sfnt_io.read(4))
|
|
284
279
|
when :ttf then TrueTypeFont
|
|
285
280
|
when :otf then OpenTypeFont
|
data/lib/fontisan/font_writer.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../models/hint"
|
|
4
3
|
require "json"
|
|
5
4
|
|
|
6
5
|
module Fontisan
|
|
@@ -80,9 +79,6 @@ module Fontisan
|
|
|
80
79
|
cff2_data = tables["CFF2"] || tables["CFF2 "]
|
|
81
80
|
|
|
82
81
|
begin
|
|
83
|
-
require_relative "../tables/cff2/table_reader"
|
|
84
|
-
require_relative "../tables/cff2/table_builder"
|
|
85
|
-
|
|
86
82
|
reader = Tables::Cff2::TableReader.new(cff2_data)
|
|
87
83
|
|
|
88
84
|
# Validate CFF2 version
|
|
@@ -131,11 +127,6 @@ module Fontisan
|
|
|
131
127
|
|
|
132
128
|
# Apply hints (both font-level and per-glyph)
|
|
133
129
|
begin
|
|
134
|
-
require_relative "../tables/cff/table_builder"
|
|
135
|
-
require_relative "../tables/cff/charstring_rebuilder"
|
|
136
|
-
require_relative "../tables/cff/hint_operation_injector"
|
|
137
|
-
require_relative "../tables/cff"
|
|
138
|
-
|
|
139
130
|
# Parse CFF binary data into Cff object if needed
|
|
140
131
|
cff_data = tables["CFF "]
|
|
141
132
|
cff_table = if cff_data.is_a?(Tables::Cff)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Hints namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Hints
|
|
7
|
+
autoload :HintConverter, "fontisan/hints/hint_converter"
|
|
8
|
+
autoload :HintValidator, "fontisan/hints/hint_validator"
|
|
9
|
+
autoload :PostScriptHintApplier, "fontisan/hints/postscript_hint_applier"
|
|
10
|
+
autoload :PostScriptHintExtractor,
|
|
11
|
+
"fontisan/hints/postscript_hint_extractor"
|
|
12
|
+
autoload :TrueTypeHintApplier, "fontisan/hints/truetype_hint_applier"
|
|
13
|
+
autoload :TrueTypeHintExtractor, "fontisan/hints/truetype_hint_extractor"
|
|
14
|
+
autoload :TrueTypeInstructionAnalyzer,
|
|
15
|
+
"fontisan/hints/truetype_instruction_analyzer"
|
|
16
|
+
autoload :TrueTypeInstructionGenerator,
|
|
17
|
+
"fontisan/hints/truetype_instruction_generator"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
module Cldr
|
|
8
|
+
# Per-language coverage for one face against a CLDR exemplar set.
|
|
9
|
+
#
|
|
10
|
+
# `coverage_ratio` is in [0.0, 1.0] rounded to 4 decimal places;
|
|
11
|
+
# `fully_supported` is true only when every required codepoint
|
|
12
|
+
# (total > 0) is covered. A language with total == 0 (empty exemplar
|
|
13
|
+
# set in the index) is reported as ratio 0.0, fully_supported false.
|
|
14
|
+
class LanguageCoverage < Lutaml::Model::Serializable
|
|
15
|
+
attribute :language, :string
|
|
16
|
+
attribute :covered, :integer
|
|
17
|
+
attribute :total, :integer
|
|
18
|
+
attribute :coverage_ratio, :float
|
|
19
|
+
attribute :fully_supported, Lutaml::Model::Type::Boolean
|
|
20
|
+
|
|
21
|
+
key_value do
|
|
22
|
+
map "language", to: :language
|
|
23
|
+
map "covered", to: :covered
|
|
24
|
+
map "total", to: :total
|
|
25
|
+
map "coverage_ratio", to: :coverage_ratio
|
|
26
|
+
map "fully_supported", to: :fully_supported
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Models::Ttx::Tables namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
module Ttx
|
|
8
|
+
module Tables
|
|
9
|
+
autoload :BinaryTable, "fontisan/models/ttx/tables/binary_table"
|
|
10
|
+
autoload :HeadTable, "fontisan/models/ttx/tables/head_table"
|
|
11
|
+
autoload :HheaTable, "fontisan/models/ttx/tables/hhea_table"
|
|
12
|
+
autoload :MaxpTable, "fontisan/models/ttx/tables/maxp_table"
|
|
13
|
+
autoload :NameRecord, "fontisan/models/ttx/tables/name_table"
|
|
14
|
+
autoload :NameTable, "fontisan/models/ttx/tables/name_table"
|
|
15
|
+
autoload :Os2Table, "fontisan/models/ttx/tables/os2_table"
|
|
16
|
+
autoload :Panose, "fontisan/models/ttx/tables/os2_table"
|
|
17
|
+
autoload :PostTable, "fontisan/models/ttx/tables/post_table"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "lutaml/model"
|
|
4
|
-
require_relative "glyph_order"
|
|
5
|
-
require_relative "tables/head_table"
|
|
6
|
-
require_relative "tables/name_table"
|
|
7
|
-
require_relative "tables/maxp_table"
|
|
8
|
-
require_relative "tables/hhea_table"
|
|
9
|
-
require_relative "tables/os2_table"
|
|
10
|
-
require_relative "tables/post_table"
|
|
11
|
-
require_relative "tables/binary_table"
|
|
12
4
|
|
|
13
5
|
module Fontisan
|
|
14
6
|
module Models
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Models::Ttx namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
module Ttx
|
|
8
|
+
autoload :GlyphId, "fontisan/models/ttx/glyph_order"
|
|
9
|
+
autoload :GlyphOrder, "fontisan/models/ttx/glyph_order"
|
|
10
|
+
autoload :Tables, "fontisan/models/ttx/tables/os2_table"
|
|
11
|
+
autoload :TtFont, "fontisan/models/ttx/ttfont"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload hub for the Fontisan::Models namespace.
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
autoload :AllScriptsFeaturesInfo,
|
|
8
|
+
"fontisan/models/all_scripts_features_info"
|
|
9
|
+
autoload :AxisInfo, "fontisan/models/variable_font_info"
|
|
10
|
+
autoload :BitmapGlyph, "fontisan/models/bitmap_glyph"
|
|
11
|
+
autoload :BitmapStrike, "fontisan/models/bitmap_strike"
|
|
12
|
+
autoload :CollectionBriefInfo, "fontisan/models/collection_brief_info"
|
|
13
|
+
autoload :CollectionFontSummary, "fontisan/models/collection_font_summary"
|
|
14
|
+
autoload :CollectionInfo, "fontisan/models/collection_info"
|
|
15
|
+
autoload :CollectionListInfo, "fontisan/models/collection_list_info"
|
|
16
|
+
autoload :CollectionValidationReport,
|
|
17
|
+
"fontisan/models/collection_validation_report"
|
|
18
|
+
autoload :Cldr, "fontisan/models/cldr"
|
|
19
|
+
autoload :ColorGlyph, "fontisan/models/color_glyph"
|
|
20
|
+
autoload :ColorLayer, "fontisan/models/color_layer"
|
|
21
|
+
autoload :ColorPalette, "fontisan/models/color_palette"
|
|
22
|
+
autoload :FeatureRecord, "fontisan/models/features_info"
|
|
23
|
+
autoload :FeaturesInfo, "fontisan/models/features_info"
|
|
24
|
+
autoload :FontExport, "fontisan/models/font_export"
|
|
25
|
+
autoload :FontInfo, "fontisan/models/font_info"
|
|
26
|
+
autoload :FontReport, "fontisan/models/font_report"
|
|
27
|
+
autoload :FontSummary, "fontisan/models/font_summary"
|
|
28
|
+
autoload :GlyphInfo, "fontisan/models/glyph_info"
|
|
29
|
+
autoload :GlyphOutline, "fontisan/models/glyph_outline"
|
|
30
|
+
autoload :Hint, "fontisan/models/hint"
|
|
31
|
+
autoload :HintSet, "fontisan/models/hint"
|
|
32
|
+
autoload :InstanceInfo, "fontisan/models/variable_font_info"
|
|
33
|
+
autoload :OpticalSizeInfo, "fontisan/models/optical_size_info"
|
|
34
|
+
autoload :Outline, "fontisan/models/outline"
|
|
35
|
+
autoload :ScriptRecord, "fontisan/models/scripts_info"
|
|
36
|
+
autoload :ScriptsInfo, "fontisan/models/scripts_info"
|
|
37
|
+
autoload :SvgGlyph, "fontisan/models/svg_glyph"
|
|
38
|
+
autoload :TableEntry, "fontisan/models/table_info"
|
|
39
|
+
autoload :TableInfo, "fontisan/models/table_info"
|
|
40
|
+
autoload :TableSharingInfo, "fontisan/models/table_sharing_info"
|
|
41
|
+
autoload :Ttx, "fontisan/models/ttx/ttfont"
|
|
42
|
+
autoload :UnicodeMapping, "fontisan/models/unicode_mappings"
|
|
43
|
+
autoload :UnicodeMappings, "fontisan/models/unicode_mappings"
|
|
44
|
+
autoload :ValidationReport, "fontisan/models/validation_report"
|
|
45
|
+
autoload :VariableFontInfo, "fontisan/models/variable_font_info"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "base_collection"
|
|
4
|
-
|
|
5
3
|
module Fontisan
|
|
6
4
|
# OpenType Collection domain object
|
|
7
5
|
#
|
|
@@ -15,11 +13,16 @@ module Fontisan
|
|
|
15
13
|
# fonts = otc.extract_fonts(io) # => [OpenTypeFont, OpenTypeFont, ...]
|
|
16
14
|
# end
|
|
17
15
|
class OpenTypeCollection < BaseCollection
|
|
16
|
+
# High-level pipeline format identifier. Owned by the collection class
|
|
17
|
+
# so the conversion pipeline can dispatch without case statements (OCP).
|
|
18
|
+
#
|
|
19
|
+
# @return [Symbol] :otc
|
|
20
|
+
def format = :otc
|
|
21
|
+
|
|
18
22
|
# Get the font class for OpenType collections
|
|
19
23
|
#
|
|
20
24
|
# @return [Class] OpenTypeFont class
|
|
21
25
|
def self.font_class
|
|
22
|
-
require_relative "open_type_font"
|
|
23
26
|
OpenTypeFont
|
|
24
27
|
end
|
|
25
28
|
|
|
@@ -38,8 +41,6 @@ module Fontisan
|
|
|
38
41
|
# @param io [IO] Open file handle to read fonts from
|
|
39
42
|
# @return [Array<OpenTypeFont>] Array of font objects
|
|
40
43
|
def extract_fonts(io)
|
|
41
|
-
require_relative "open_type_font"
|
|
42
|
-
|
|
43
44
|
font_offsets.map do |offset|
|
|
44
45
|
OpenTypeFont.from_collection(io, offset)
|
|
45
46
|
end
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "sfnt_font"
|
|
4
|
-
|
|
5
3
|
module Fontisan
|
|
6
4
|
# OpenType Font domain object
|
|
7
5
|
#
|
|
@@ -26,6 +24,14 @@ module Fontisan
|
|
|
26
24
|
# @example Reading from TTC collection
|
|
27
25
|
# otf = OpenTypeFont.from_collection(io, offset)
|
|
28
26
|
class OpenTypeFont < SfntFont
|
|
27
|
+
extend OpenTypeFontExtensions
|
|
28
|
+
|
|
29
|
+
# High-level pipeline format identifier. Owned by the font class so the
|
|
30
|
+
# conversion pipeline can dispatch without case statements (OCP).
|
|
31
|
+
#
|
|
32
|
+
# @return [Symbol] :otf
|
|
33
|
+
def format = :otf
|
|
34
|
+
|
|
29
35
|
# Page cache for lazy loading (maps page_start_offset => page_data)
|
|
30
36
|
attr_accessor :page_cache
|
|
31
37
|
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Fontisan
|
|
4
|
-
#
|
|
5
|
-
|
|
4
|
+
# Extension module for {OpenTypeFont} providing table-based construction.
|
|
5
|
+
#
|
|
6
|
+
# Extended into OpenTypeFont from +open_type_font.rb+ so that
|
|
7
|
+
# +OpenTypeFont.from_tables(...)+ is available whenever the class
|
|
8
|
+
# itself is loaded.
|
|
9
|
+
module OpenTypeFontExtensions
|
|
6
10
|
# Create font from hash of tables
|
|
7
11
|
#
|
|
8
12
|
# This is used during font conversion when we have tables but not a file.
|
|
9
13
|
#
|
|
10
14
|
# @param tables [Hash<String, String>] Map of table tag to binary data
|
|
11
15
|
# @return [OpenTypeFont] New font instance
|
|
12
|
-
def
|
|
13
|
-
# Create minimal header structure
|
|
16
|
+
def from_tables(tables)
|
|
14
17
|
font = new
|
|
15
18
|
font.initialize_storage
|
|
16
19
|
font.loading_mode = LoadingModes::FULL
|
|
17
20
|
|
|
18
|
-
# Store table data
|
|
19
21
|
font.table_data = tables
|
|
20
22
|
|
|
21
|
-
# Build header from tables
|
|
22
23
|
num_tables = tables.size
|
|
23
24
|
max_power = 0
|
|
24
25
|
n = num_tables
|
|
@@ -37,13 +38,12 @@ module Fontisan
|
|
|
37
38
|
font.header.entry_selector = entry_selector
|
|
38
39
|
font.header.range_shift = range_shift
|
|
39
40
|
|
|
40
|
-
# Build table directory
|
|
41
41
|
font.tables.clear
|
|
42
42
|
tables.each_key do |tag|
|
|
43
43
|
entry = TableDirectory.new
|
|
44
44
|
entry.tag = tag
|
|
45
|
-
entry.checksum = 0
|
|
46
|
-
entry.offset = 0
|
|
45
|
+
entry.checksum = 0
|
|
46
|
+
entry.offset = 0
|
|
47
47
|
entry.table_length = tables[tag].bytesize
|
|
48
48
|
font.tables << entry
|
|
49
49
|
end
|