fontisan 0.1.0 → 0.2.1
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_todo.yml +672 -69
- data/Gemfile +1 -0
- data/LICENSE +5 -1
- data/README.adoc +1477 -297
- data/Rakefile +63 -41
- data/benchmark/variation_quick_bench.rb +47 -0
- data/docs/EXTRACT_TTC_MIGRATION.md +549 -0
- data/fontisan.gemspec +4 -1
- data/lib/fontisan/binary/base_record.rb +22 -1
- data/lib/fontisan/cli.rb +364 -4
- data/lib/fontisan/collection/builder.rb +341 -0
- data/lib/fontisan/collection/offset_calculator.rb +227 -0
- data/lib/fontisan/collection/table_analyzer.rb +204 -0
- data/lib/fontisan/collection/table_deduplicator.rb +317 -0
- data/lib/fontisan/collection/writer.rb +306 -0
- data/lib/fontisan/commands/base_command.rb +24 -1
- data/lib/fontisan/commands/convert_command.rb +218 -0
- data/lib/fontisan/commands/export_command.rb +161 -0
- data/lib/fontisan/commands/info_command.rb +40 -6
- data/lib/fontisan/commands/instance_command.rb +286 -0
- data/lib/fontisan/commands/ls_command.rb +113 -0
- data/lib/fontisan/commands/pack_command.rb +241 -0
- data/lib/fontisan/commands/subset_command.rb +245 -0
- data/lib/fontisan/commands/unpack_command.rb +338 -0
- data/lib/fontisan/commands/validate_command.rb +203 -0
- data/lib/fontisan/commands/variable_command.rb +30 -1
- data/lib/fontisan/config/collection_settings.yml +56 -0
- data/lib/fontisan/config/conversion_matrix.yml +212 -0
- data/lib/fontisan/config/export_settings.yml +66 -0
- data/lib/fontisan/config/subset_profiles.yml +100 -0
- data/lib/fontisan/config/svg_settings.yml +60 -0
- data/lib/fontisan/config/validation_rules.yml +149 -0
- data/lib/fontisan/config/variable_settings.yml +99 -0
- data/lib/fontisan/config/woff2_settings.yml +77 -0
- data/lib/fontisan/constants.rb +79 -0
- data/lib/fontisan/converters/conversion_strategy.rb +96 -0
- data/lib/fontisan/converters/format_converter.rb +408 -0
- data/lib/fontisan/converters/outline_converter.rb +998 -0
- data/lib/fontisan/converters/svg_generator.rb +244 -0
- data/lib/fontisan/converters/table_copier.rb +117 -0
- data/lib/fontisan/converters/woff2_encoder.rb +416 -0
- data/lib/fontisan/converters/woff_writer.rb +391 -0
- data/lib/fontisan/error.rb +203 -0
- data/lib/fontisan/export/exporter.rb +262 -0
- data/lib/fontisan/export/table_serializer.rb +255 -0
- data/lib/fontisan/export/transformers/font_to_ttx.rb +172 -0
- data/lib/fontisan/export/transformers/head_transformer.rb +96 -0
- data/lib/fontisan/export/transformers/hhea_transformer.rb +59 -0
- data/lib/fontisan/export/transformers/maxp_transformer.rb +63 -0
- data/lib/fontisan/export/transformers/name_transformer.rb +63 -0
- data/lib/fontisan/export/transformers/os2_transformer.rb +121 -0
- data/lib/fontisan/export/transformers/post_transformer.rb +51 -0
- data/lib/fontisan/export/ttx_generator.rb +527 -0
- data/lib/fontisan/export/ttx_parser.rb +300 -0
- data/lib/fontisan/font_loader.rb +122 -15
- data/lib/fontisan/font_writer.rb +302 -0
- data/lib/fontisan/formatters/text_formatter.rb +102 -0
- data/lib/fontisan/glyph_accessor.rb +503 -0
- data/lib/fontisan/hints/hint_converter.rb +310 -0
- data/lib/fontisan/hints/postscript_hint_applier.rb +266 -0
- data/lib/fontisan/hints/postscript_hint_extractor.rb +354 -0
- data/lib/fontisan/hints/truetype_hint_applier.rb +117 -0
- data/lib/fontisan/hints/truetype_hint_extractor.rb +289 -0
- data/lib/fontisan/loading_modes.rb +115 -0
- data/lib/fontisan/metrics_calculator.rb +277 -0
- data/lib/fontisan/models/collection_font_summary.rb +52 -0
- data/lib/fontisan/models/collection_info.rb +76 -0
- data/lib/fontisan/models/collection_list_info.rb +37 -0
- data/lib/fontisan/models/font_export.rb +158 -0
- data/lib/fontisan/models/font_summary.rb +48 -0
- data/lib/fontisan/models/glyph_outline.rb +343 -0
- data/lib/fontisan/models/hint.rb +405 -0
- data/lib/fontisan/models/outline.rb +664 -0
- data/lib/fontisan/models/table_sharing_info.rb +40 -0
- data/lib/fontisan/models/ttx/glyph_order.rb +31 -0
- data/lib/fontisan/models/ttx/tables/binary_table.rb +67 -0
- data/lib/fontisan/models/ttx/tables/head_table.rb +74 -0
- data/lib/fontisan/models/ttx/tables/hhea_table.rb +74 -0
- data/lib/fontisan/models/ttx/tables/maxp_table.rb +55 -0
- data/lib/fontisan/models/ttx/tables/name_table.rb +45 -0
- data/lib/fontisan/models/ttx/tables/os2_table.rb +157 -0
- data/lib/fontisan/models/ttx/tables/post_table.rb +50 -0
- data/lib/fontisan/models/ttx/ttfont.rb +49 -0
- data/lib/fontisan/models/validation_report.rb +203 -0
- data/lib/fontisan/open_type_collection.rb +156 -2
- data/lib/fontisan/open_type_font.rb +321 -19
- data/lib/fontisan/open_type_font_extensions.rb +54 -0
- data/lib/fontisan/optimizers/charstring_rewriter.rb +161 -0
- data/lib/fontisan/optimizers/pattern_analyzer.rb +308 -0
- data/lib/fontisan/optimizers/stack_tracker.rb +246 -0
- data/lib/fontisan/optimizers/subroutine_builder.rb +134 -0
- data/lib/fontisan/optimizers/subroutine_generator.rb +207 -0
- data/lib/fontisan/optimizers/subroutine_optimizer.rb +107 -0
- data/lib/fontisan/outline_extractor.rb +423 -0
- data/lib/fontisan/pipeline/format_detector.rb +249 -0
- data/lib/fontisan/pipeline/output_writer.rb +154 -0
- data/lib/fontisan/pipeline/strategies/base_strategy.rb +75 -0
- data/lib/fontisan/pipeline/strategies/instance_strategy.rb +93 -0
- data/lib/fontisan/pipeline/strategies/named_strategy.rb +118 -0
- data/lib/fontisan/pipeline/strategies/preserve_strategy.rb +56 -0
- data/lib/fontisan/pipeline/transformation_pipeline.rb +411 -0
- data/lib/fontisan/pipeline/variation_resolver.rb +165 -0
- data/lib/fontisan/subset/builder.rb +268 -0
- data/lib/fontisan/subset/glyph_mapping.rb +215 -0
- data/lib/fontisan/subset/options.rb +142 -0
- data/lib/fontisan/subset/profile.rb +152 -0
- data/lib/fontisan/subset/table_subsetter.rb +461 -0
- data/lib/fontisan/svg/font_face_generator.rb +278 -0
- data/lib/fontisan/svg/font_generator.rb +264 -0
- data/lib/fontisan/svg/glyph_generator.rb +168 -0
- data/lib/fontisan/svg/view_box_calculator.rb +137 -0
- data/lib/fontisan/tables/cff/cff_glyph.rb +176 -0
- data/lib/fontisan/tables/cff/charset.rb +282 -0
- data/lib/fontisan/tables/cff/charstring.rb +934 -0
- data/lib/fontisan/tables/cff/charstring_builder.rb +356 -0
- data/lib/fontisan/tables/cff/charstring_parser.rb +237 -0
- data/lib/fontisan/tables/cff/charstring_rebuilder.rb +172 -0
- data/lib/fontisan/tables/cff/charstrings_index.rb +162 -0
- data/lib/fontisan/tables/cff/dict.rb +351 -0
- data/lib/fontisan/tables/cff/dict_builder.rb +257 -0
- data/lib/fontisan/tables/cff/encoding.rb +274 -0
- data/lib/fontisan/tables/cff/header.rb +102 -0
- data/lib/fontisan/tables/cff/hint_operation_injector.rb +207 -0
- data/lib/fontisan/tables/cff/index.rb +237 -0
- data/lib/fontisan/tables/cff/index_builder.rb +170 -0
- data/lib/fontisan/tables/cff/offset_recalculator.rb +70 -0
- data/lib/fontisan/tables/cff/private_dict.rb +284 -0
- data/lib/fontisan/tables/cff/private_dict_writer.rb +125 -0
- data/lib/fontisan/tables/cff/table_builder.rb +221 -0
- data/lib/fontisan/tables/cff/top_dict.rb +236 -0
- data/lib/fontisan/tables/cff.rb +489 -0
- data/lib/fontisan/tables/cff2/blend_operator.rb +240 -0
- data/lib/fontisan/tables/cff2/charstring_parser.rb +591 -0
- data/lib/fontisan/tables/cff2/operand_stack.rb +232 -0
- data/lib/fontisan/tables/cff2/private_dict_blend_handler.rb +246 -0
- data/lib/fontisan/tables/cff2/region_matcher.rb +200 -0
- data/lib/fontisan/tables/cff2/table_builder.rb +574 -0
- data/lib/fontisan/tables/cff2/table_reader.rb +419 -0
- data/lib/fontisan/tables/cff2/variation_data_extractor.rb +212 -0
- data/lib/fontisan/tables/cff2.rb +346 -0
- data/lib/fontisan/tables/cvar.rb +203 -0
- data/lib/fontisan/tables/fvar.rb +2 -2
- data/lib/fontisan/tables/glyf/compound_glyph.rb +483 -0
- data/lib/fontisan/tables/glyf/compound_glyph_resolver.rb +136 -0
- data/lib/fontisan/tables/glyf/curve_converter.rb +343 -0
- data/lib/fontisan/tables/glyf/glyph_builder.rb +450 -0
- data/lib/fontisan/tables/glyf/simple_glyph.rb +382 -0
- data/lib/fontisan/tables/glyf.rb +235 -0
- data/lib/fontisan/tables/gvar.rb +231 -0
- data/lib/fontisan/tables/hhea.rb +124 -0
- data/lib/fontisan/tables/hmtx.rb +287 -0
- data/lib/fontisan/tables/hvar.rb +191 -0
- data/lib/fontisan/tables/loca.rb +322 -0
- data/lib/fontisan/tables/maxp.rb +192 -0
- data/lib/fontisan/tables/mvar.rb +185 -0
- data/lib/fontisan/tables/name.rb +99 -30
- data/lib/fontisan/tables/variation_common.rb +346 -0
- data/lib/fontisan/tables/vvar.rb +234 -0
- data/lib/fontisan/true_type_collection.rb +156 -2
- data/lib/fontisan/true_type_font.rb +321 -20
- data/lib/fontisan/true_type_font_extensions.rb +54 -0
- data/lib/fontisan/utilities/brotli_wrapper.rb +159 -0
- data/lib/fontisan/utilities/checksum_calculator.rb +60 -0
- data/lib/fontisan/utils/thread_pool.rb +134 -0
- data/lib/fontisan/validation/checksum_validator.rb +170 -0
- data/lib/fontisan/validation/consistency_validator.rb +197 -0
- data/lib/fontisan/validation/structure_validator.rb +198 -0
- data/lib/fontisan/validation/table_validator.rb +158 -0
- data/lib/fontisan/validation/validator.rb +152 -0
- data/lib/fontisan/validation/variable_font_validator.rb +218 -0
- data/lib/fontisan/variable/axis_normalizer.rb +215 -0
- data/lib/fontisan/variable/delta_applicator.rb +313 -0
- data/lib/fontisan/variable/glyph_delta_processor.rb +218 -0
- data/lib/fontisan/variable/instancer.rb +344 -0
- data/lib/fontisan/variable/metric_delta_processor.rb +282 -0
- data/lib/fontisan/variable/region_matcher.rb +208 -0
- data/lib/fontisan/variable/static_font_builder.rb +213 -0
- data/lib/fontisan/variable/table_updater.rb +219 -0
- data/lib/fontisan/variation/blend_applier.rb +199 -0
- data/lib/fontisan/variation/cache.rb +298 -0
- data/lib/fontisan/variation/cache_key_builder.rb +162 -0
- data/lib/fontisan/variation/converter.rb +375 -0
- data/lib/fontisan/variation/data_extractor.rb +86 -0
- data/lib/fontisan/variation/delta_applier.rb +266 -0
- data/lib/fontisan/variation/delta_parser.rb +228 -0
- data/lib/fontisan/variation/inspector.rb +275 -0
- data/lib/fontisan/variation/instance_generator.rb +273 -0
- data/lib/fontisan/variation/instance_writer.rb +341 -0
- data/lib/fontisan/variation/interpolator.rb +231 -0
- data/lib/fontisan/variation/metrics_adjuster.rb +318 -0
- data/lib/fontisan/variation/optimizer.rb +418 -0
- data/lib/fontisan/variation/parallel_generator.rb +150 -0
- data/lib/fontisan/variation/region_matcher.rb +221 -0
- data/lib/fontisan/variation/subsetter.rb +463 -0
- data/lib/fontisan/variation/table_accessor.rb +105 -0
- data/lib/fontisan/variation/tuple_variation_header.rb +51 -0
- data/lib/fontisan/variation/validator.rb +345 -0
- data/lib/fontisan/variation/variable_svg_generator.rb +268 -0
- data/lib/fontisan/variation/variation_context.rb +211 -0
- data/lib/fontisan/variation/variation_preserver.rb +288 -0
- data/lib/fontisan/version.rb +1 -1
- data/lib/fontisan/version.rb.orig +9 -0
- data/lib/fontisan/woff2/directory.rb +257 -0
- data/lib/fontisan/woff2/glyf_transformer.rb +666 -0
- data/lib/fontisan/woff2/header.rb +101 -0
- data/lib/fontisan/woff2/hmtx_transformer.rb +164 -0
- data/lib/fontisan/woff2/table_transformer.rb +163 -0
- data/lib/fontisan/woff2_font.rb +717 -0
- data/lib/fontisan/woff_font.rb +488 -0
- data/lib/fontisan.rb +132 -0
- data/scripts/compare_stack_aware.rb +187 -0
- data/scripts/measure_optimization.rb +141 -0
- metadata +234 -4
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
# Model for individual font summary within a collection
|
|
8
|
+
#
|
|
9
|
+
# Represents basic metadata for a single font in a TTC/OTC collection.
|
|
10
|
+
# Used by CollectionListInfo to provide per-font summaries.
|
|
11
|
+
#
|
|
12
|
+
# @example Creating a font summary
|
|
13
|
+
# summary = CollectionFontSummary.new(
|
|
14
|
+
# index: 0,
|
|
15
|
+
# family_name: "Helvetica",
|
|
16
|
+
# subfamily_name: "Regular",
|
|
17
|
+
# postscript_name: "Helvetica-Regular",
|
|
18
|
+
# font_format: "TrueType",
|
|
19
|
+
# num_glyphs: 268,
|
|
20
|
+
# num_tables: 14
|
|
21
|
+
# )
|
|
22
|
+
class CollectionFontSummary < Lutaml::Model::Serializable
|
|
23
|
+
attribute :index, :integer
|
|
24
|
+
attribute :family_name, :string
|
|
25
|
+
attribute :subfamily_name, :string
|
|
26
|
+
attribute :postscript_name, :string
|
|
27
|
+
attribute :font_format, :string
|
|
28
|
+
attribute :num_glyphs, :integer
|
|
29
|
+
attribute :num_tables, :integer
|
|
30
|
+
|
|
31
|
+
yaml do
|
|
32
|
+
map "index", to: :index
|
|
33
|
+
map "family_name", to: :family_name
|
|
34
|
+
map "subfamily_name", to: :subfamily_name
|
|
35
|
+
map "postscript_name", to: :postscript_name
|
|
36
|
+
map "font_format", to: :font_format
|
|
37
|
+
map "num_glyphs", to: :num_glyphs
|
|
38
|
+
map "num_tables", to: :num_tables
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
json do
|
|
42
|
+
map "index", to: :index
|
|
43
|
+
map "family_name", to: :family_name
|
|
44
|
+
map "subfamily_name", to: :subfamily_name
|
|
45
|
+
map "postscript_name", to: :postscript_name
|
|
46
|
+
map "font_format", to: :font_format
|
|
47
|
+
map "num_glyphs", to: :num_glyphs
|
|
48
|
+
map "num_tables", to: :num_tables
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
require_relative "table_sharing_info"
|
|
5
|
+
|
|
6
|
+
module Fontisan
|
|
7
|
+
module Models
|
|
8
|
+
# Model for collection metadata
|
|
9
|
+
#
|
|
10
|
+
# Represents comprehensive information about a TTC/OTC collection.
|
|
11
|
+
# Used by InfoCommand when operating on collection files.
|
|
12
|
+
#
|
|
13
|
+
# @example Creating collection info
|
|
14
|
+
# info = CollectionInfo.new(
|
|
15
|
+
# collection_path: "fonts.ttc",
|
|
16
|
+
# collection_format: "TTC",
|
|
17
|
+
# ttc_tag: "ttcf",
|
|
18
|
+
# major_version: 2,
|
|
19
|
+
# minor_version: 0,
|
|
20
|
+
# num_fonts: 6,
|
|
21
|
+
# font_offsets: [48, 380, 712, 1044, 1376, 1676],
|
|
22
|
+
# file_size_bytes: 2240000,
|
|
23
|
+
# table_sharing: table_sharing_obj
|
|
24
|
+
# )
|
|
25
|
+
class CollectionInfo < Lutaml::Model::Serializable
|
|
26
|
+
attribute :collection_path, :string
|
|
27
|
+
attribute :collection_format, :string
|
|
28
|
+
attribute :ttc_tag, :string
|
|
29
|
+
attribute :major_version, :integer
|
|
30
|
+
attribute :minor_version, :integer
|
|
31
|
+
attribute :num_fonts, :integer
|
|
32
|
+
attribute :font_offsets, :integer, collection: true
|
|
33
|
+
attribute :file_size_bytes, :integer
|
|
34
|
+
attribute :table_sharing, TableSharingInfo
|
|
35
|
+
|
|
36
|
+
yaml do
|
|
37
|
+
map "collection_path", to: :collection_path
|
|
38
|
+
map "collection_format", to: :collection_format
|
|
39
|
+
map "ttc_tag", to: :ttc_tag
|
|
40
|
+
map "major_version", to: :major_version
|
|
41
|
+
map "minor_version", to: :minor_version
|
|
42
|
+
map "num_fonts", to: :num_fonts
|
|
43
|
+
map "font_offsets", to: :font_offsets
|
|
44
|
+
map "file_size_bytes", to: :file_size_bytes
|
|
45
|
+
map "table_sharing", to: :table_sharing
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
json do
|
|
49
|
+
map "collection_path", to: :collection_path
|
|
50
|
+
map "collection_format", to: :collection_format
|
|
51
|
+
map "ttc_tag", to: :ttc_tag
|
|
52
|
+
map "major_version", to: :major_version
|
|
53
|
+
map "minor_version", to: :minor_version
|
|
54
|
+
map "num_fonts", to: :num_fonts
|
|
55
|
+
map "font_offsets", to: :font_offsets
|
|
56
|
+
map "file_size_bytes", to: :file_size_bytes
|
|
57
|
+
map "table_sharing", to: :table_sharing
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Get version as a formatted string
|
|
61
|
+
#
|
|
62
|
+
# @return [String] Version string (e.g., "2.0")
|
|
63
|
+
def version_string
|
|
64
|
+
"#{major_version}.#{minor_version}"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Get version as a hexadecimal string
|
|
68
|
+
#
|
|
69
|
+
# @return [String] Hex version (e.g., "0x00020000")
|
|
70
|
+
def version_hex
|
|
71
|
+
version_int = (major_version << 16) | minor_version
|
|
72
|
+
format("0x%08X", version_int)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
require_relative "collection_font_summary"
|
|
5
|
+
|
|
6
|
+
module Fontisan
|
|
7
|
+
module Models
|
|
8
|
+
# Model for collection font listing
|
|
9
|
+
#
|
|
10
|
+
# Represents a list of fonts within a TTC/OTC collection.
|
|
11
|
+
# Used by LsCommand when operating on collection files.
|
|
12
|
+
#
|
|
13
|
+
# @example Creating a collection list
|
|
14
|
+
# list = CollectionListInfo.new(
|
|
15
|
+
# collection_path: "fonts.ttc",
|
|
16
|
+
# num_fonts: 6,
|
|
17
|
+
# fonts: [summary1, summary2, ...]
|
|
18
|
+
# )
|
|
19
|
+
class CollectionListInfo < Lutaml::Model::Serializable
|
|
20
|
+
attribute :collection_path, :string
|
|
21
|
+
attribute :num_fonts, :integer
|
|
22
|
+
attribute :fonts, CollectionFontSummary, collection: true
|
|
23
|
+
|
|
24
|
+
yaml do
|
|
25
|
+
map "collection_path", to: :collection_path
|
|
26
|
+
map "num_fonts", to: :num_fonts
|
|
27
|
+
map "fonts", to: :fonts
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
json do
|
|
31
|
+
map "collection_path", to: :collection_path
|
|
32
|
+
map "num_fonts", to: :num_fonts
|
|
33
|
+
map "fonts", to: :fonts
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
# FontExport represents complete font structure for export to YAML/JSON
|
|
8
|
+
#
|
|
9
|
+
# This model encapsulates the entire font structure including header
|
|
10
|
+
# information, all tables (parsed and binary), and metadata. It supports
|
|
11
|
+
# round-trip conversion: font → export → import → font.
|
|
12
|
+
#
|
|
13
|
+
# @example Exporting a font
|
|
14
|
+
# export = FontExport.new(source_file: "font.ttf")
|
|
15
|
+
# export.extract_from_font(font)
|
|
16
|
+
# yaml_output = export.to_yaml
|
|
17
|
+
#
|
|
18
|
+
# @example Importing from YAML
|
|
19
|
+
# export = FontExport.from_yaml(yaml_string)
|
|
20
|
+
# font = export.rebuild_font
|
|
21
|
+
class FontExport < Lutaml::Model::Serializable
|
|
22
|
+
# Metadata about the export
|
|
23
|
+
class Metadata < Lutaml::Model::Serializable
|
|
24
|
+
attribute :source_file, :string
|
|
25
|
+
attribute :export_date, :string
|
|
26
|
+
attribute :exporter_version, :string
|
|
27
|
+
attribute :font_format, :string
|
|
28
|
+
|
|
29
|
+
yaml do
|
|
30
|
+
map "source_file", to: :source_file
|
|
31
|
+
map "export_date", to: :export_date
|
|
32
|
+
map "exporter_version", to: :exporter_version
|
|
33
|
+
map "font_format", to: :font_format
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
json do
|
|
37
|
+
map "source_file", to: :source_file
|
|
38
|
+
map "export_date", to: :export_date
|
|
39
|
+
map "exporter_version", to: :exporter_version
|
|
40
|
+
map "font_format", to: :font_format
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Font header information
|
|
45
|
+
class Header < Lutaml::Model::Serializable
|
|
46
|
+
attribute :sfnt_version, :string
|
|
47
|
+
attribute :num_tables, :integer
|
|
48
|
+
attribute :search_range, :integer
|
|
49
|
+
attribute :entry_selector, :integer
|
|
50
|
+
attribute :range_shift, :integer
|
|
51
|
+
|
|
52
|
+
yaml do
|
|
53
|
+
map "sfnt_version", to: :sfnt_version
|
|
54
|
+
map "num_tables", to: :num_tables
|
|
55
|
+
map "search_range", to: :search_range
|
|
56
|
+
map "entry_selector", to: :entry_selector
|
|
57
|
+
map "range_shift", to: :range_shift
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
json do
|
|
61
|
+
map "sfnt_version", to: :sfnt_version
|
|
62
|
+
map "num_tables", to: :num_tables
|
|
63
|
+
map "search_range", to: :search_range
|
|
64
|
+
map "entry_selector", to: :entry_selector
|
|
65
|
+
map "range_shift", to: :range_shift
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Individual table export
|
|
70
|
+
class TableExport < Lutaml::Model::Serializable
|
|
71
|
+
attribute :tag, :string
|
|
72
|
+
attribute :checksum, :string
|
|
73
|
+
attribute :parsed, :boolean, default: -> { false }
|
|
74
|
+
attribute :data, :string, default: -> { nil }
|
|
75
|
+
attribute :fields, :string, default: -> { nil }
|
|
76
|
+
|
|
77
|
+
yaml do
|
|
78
|
+
map "tag", to: :tag
|
|
79
|
+
map "checksum", to: :checksum
|
|
80
|
+
map "parsed", to: :parsed
|
|
81
|
+
map "data", to: :data
|
|
82
|
+
map "fields", to: :fields
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
json do
|
|
86
|
+
map "tag", to: :tag
|
|
87
|
+
map "checksum", to: :checksum
|
|
88
|
+
map "parsed", to: :parsed
|
|
89
|
+
map "data", to: :data
|
|
90
|
+
map "fields", to: :fields
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
attribute :metadata, Metadata
|
|
95
|
+
attribute :header, Header
|
|
96
|
+
attribute :tables, TableExport, collection: true, default: -> { [] }
|
|
97
|
+
|
|
98
|
+
yaml do
|
|
99
|
+
map "metadata", to: :metadata
|
|
100
|
+
map "header", to: :header
|
|
101
|
+
map "tables", to: :tables
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
json do
|
|
105
|
+
map "metadata", to: :metadata
|
|
106
|
+
map "header", to: :header
|
|
107
|
+
map "tables", to: :tables
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Find a table by tag
|
|
111
|
+
#
|
|
112
|
+
# @param tag [String] The table tag (e.g., "head", "name")
|
|
113
|
+
# @return [TableExport, nil] The table or nil if not found
|
|
114
|
+
def find_table(tag)
|
|
115
|
+
tables.find { |t| t.tag == tag }
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Get all parsed tables
|
|
119
|
+
#
|
|
120
|
+
# @return [Array<TableExport>] Array of parsed tables
|
|
121
|
+
def parsed_tables
|
|
122
|
+
tables.select(&:parsed)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Get all binary-only tables
|
|
126
|
+
#
|
|
127
|
+
# @return [Array<TableExport>] Array of binary tables
|
|
128
|
+
def binary_tables
|
|
129
|
+
tables.reject(&:parsed)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Add a table to the export
|
|
133
|
+
#
|
|
134
|
+
# @param tag [String] Table tag
|
|
135
|
+
# @param checksum [String] Table checksum
|
|
136
|
+
# @param parsed [Boolean] Whether table is parsed
|
|
137
|
+
# @param data [String, nil] Binary data (hex/base64)
|
|
138
|
+
# @param fields [Hash, nil] Parsed fields as Hash/JSON
|
|
139
|
+
# @return [void]
|
|
140
|
+
def add_table(tag:, checksum:, parsed: false, data: nil, fields: nil)
|
|
141
|
+
tables << TableExport.new(
|
|
142
|
+
tag: tag,
|
|
143
|
+
checksum: checksum,
|
|
144
|
+
parsed: parsed,
|
|
145
|
+
data: data,
|
|
146
|
+
fields: fields,
|
|
147
|
+
)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Validate export structure
|
|
151
|
+
#
|
|
152
|
+
# @return [Boolean] True if export is valid
|
|
153
|
+
def valid?
|
|
154
|
+
!metadata.nil? && !header.nil? && !tables.empty?
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Fontisan
|
|
6
|
+
module Models
|
|
7
|
+
# Model for quick font summary
|
|
8
|
+
#
|
|
9
|
+
# Represents a brief overview of an individual font file.
|
|
10
|
+
# Used by LsCommand when operating on TTF/OTF files.
|
|
11
|
+
#
|
|
12
|
+
# @example Creating a font summary
|
|
13
|
+
# summary = FontSummary.new(
|
|
14
|
+
# font_path: "font.ttf",
|
|
15
|
+
# family_name: "Helvetica",
|
|
16
|
+
# subfamily_name: "Regular",
|
|
17
|
+
# font_format: "TrueType",
|
|
18
|
+
# num_glyphs: 268,
|
|
19
|
+
# num_tables: 14
|
|
20
|
+
# )
|
|
21
|
+
class FontSummary < Lutaml::Model::Serializable
|
|
22
|
+
attribute :font_path, :string
|
|
23
|
+
attribute :family_name, :string
|
|
24
|
+
attribute :subfamily_name, :string
|
|
25
|
+
attribute :font_format, :string
|
|
26
|
+
attribute :num_glyphs, :integer
|
|
27
|
+
attribute :num_tables, :integer
|
|
28
|
+
|
|
29
|
+
yaml do
|
|
30
|
+
map "font_path", to: :font_path
|
|
31
|
+
map "family_name", to: :family_name
|
|
32
|
+
map "subfamily_name", to: :subfamily_name
|
|
33
|
+
map "font_format", to: :font_format
|
|
34
|
+
map "num_glyphs", to: :num_glyphs
|
|
35
|
+
map "num_tables", to: :num_tables
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
json do
|
|
39
|
+
map "font_path", to: :font_path
|
|
40
|
+
map "family_name", to: :family_name
|
|
41
|
+
map "subfamily_name", to: :subfamily_name
|
|
42
|
+
map "font_format", to: :font_format
|
|
43
|
+
map "num_glyphs", to: :num_glyphs
|
|
44
|
+
map "num_tables", to: :num_tables
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|