fontisan 0.2.8 → 0.2.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9f774cfee2477366d97b8954c481262eedd928b1c5abae59f559e570aafb294
4
- data.tar.gz: 0f744a6ba709c5e2c6eb0e81e33ec41d4cbe78d0beb6bd3519b395568257d37c
3
+ metadata.gz: 2323e4d4ba09f0467008c48db7b781015eb9e54a271f42d4c0363d96c5e03c03
4
+ data.tar.gz: 4d39148567ce1180c0d741523f75aa919e15712b81af9952ddc522ccbf0a0a69
5
5
  SHA512:
6
- metadata.gz: 59e98be337dc89d359cdb4d7a8a80749d2b89a2d82dda2280550ccd834143f9191752cdc083179907d01f2d3a87695b9a6758b2ad3d910b4a4af79e919479767
7
- data.tar.gz: 5913d2f154cbf0961436ac7e85dad4d2f8d64ac4a52d1c9709014a33ed112eaf1a9f3a931a0b7f62e469eba0bd5e87589fe677c0e36c8971f042c850b0abe412
6
+ metadata.gz: f9e93fd99698903487869f89cfd522819418fcc23e32ecfdaf312393a52fc3ed0c93168a38f88c667561d55b7998d1101dbf5bf509bc4188c9831478b7d87a19
7
+ data.tar.gz: 4bed6191cdbf93b33792454a806e5fe33b10e99b4ee22f27e4907d5a4b50020fb0f2e6a84fe867183c4163aa6784b4ae341b804e1ecd429c8922ebd48a6dbce1
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2026-01-15 10:44:19 UTC using RuboCop version 1.82.1.
3
+ # on 2026-01-17 02:13:05 UTC using RuboCop version 1.82.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -11,48 +11,13 @@ Gemspec/RequiredRubyVersion:
11
11
  Exclude:
12
12
  - 'fontisan.gemspec'
13
13
 
14
- # Offense count: 94
15
- # This cop supports safe autocorrection (--autocorrect).
16
- Layout/EmptyLines:
17
- Exclude:
18
- - 'spec/benchmarks/subroutine_optimization_benchmark.rb'
19
- - 'spec/fontisan/converters/extended_woff2_spec.rb'
20
- - 'spec/fontisan/lazy_loading_spec.rb'
21
- - 'spec/fontisan/loading_modes_spec.rb'
22
- - 'spec/integration/subroutine_roundtrip_spec.rb'
23
- - 'spec/integration/woff2_conversion_spec.rb'
24
-
25
- # Offense count: 25
26
- # This cop supports safe autocorrection (--autocorrect).
27
- # Configuration parameters: EnforcedStyle.
28
- # SupportedStyles: empty_lines, no_empty_lines
29
- Layout/EmptyLinesAroundBlockBody:
30
- Exclude:
31
- - 'spec/benchmarks/subroutine_optimization_benchmark.rb'
32
- - 'spec/fontisan/converters/woff2_round_trip_spec.rb'
33
- - 'spec/fontisan/loading_modes_spec.rb'
34
-
35
- # Offense count: 1217
14
+ # Offense count: 1259
36
15
  # This cop supports safe autocorrection (--autocorrect).
37
16
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
38
17
  # URISchemes: http, https
39
18
  Layout/LineLength:
40
19
  Enabled: false
41
20
 
42
- # Offense count: 100
43
- # This cop supports safe autocorrection (--autocorrect).
44
- # Configuration parameters: AllowInHeredoc.
45
- Layout/TrailingWhitespace:
46
- Exclude:
47
- - 'spec/benchmarks/subroutine_optimization_benchmark.rb'
48
- - 'spec/fontisan/converters/extended_woff2_spec.rb'
49
- - 'spec/fontisan/converters/woff2_round_trip_spec.rb'
50
- - 'spec/fontisan/lazy_loading_spec.rb'
51
- - 'spec/fontisan/loading_modes_spec.rb'
52
- - 'spec/integration/outline_conversion_spec.rb'
53
- - 'spec/integration/subroutine_roundtrip_spec.rb'
54
- - 'spec/integration/woff2_conversion_spec.rb'
55
-
56
21
  # Offense count: 3
57
22
  Lint/CopDirectiveSyntax:
58
23
  Exclude:
@@ -111,13 +76,6 @@ Lint/StructNewOverride:
111
76
  Exclude:
112
77
  - 'lib/fontisan/optimizers/pattern_analyzer.rb'
113
78
 
114
- # Offense count: 2
115
- # This cop supports safe autocorrection (--autocorrect).
116
- # Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
117
- Lint/UnusedBlockArgument:
118
- Exclude:
119
- - 'spec/benchmarks/subroutine_optimization_benchmark.rb'
120
-
121
79
  # Offense count: 8
122
80
  # This cop supports safe autocorrection (--autocorrect).
123
81
  # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
@@ -132,16 +90,7 @@ Lint/UnusedMethodArgument:
132
90
  - 'lib/fontisan/woff2/glyf_transformer.rb'
133
91
  - 'lib/fontisan/woff_font.rb'
134
92
 
135
- # Offense count: 19
136
- # This cop supports safe autocorrection (--autocorrect).
137
- Lint/UselessAssignment:
138
- Exclude:
139
- - 'spec/benchmarks/subroutine_optimization_benchmark.rb'
140
- - 'spec/fontisan/loading_modes_spec.rb'
141
- - 'spec/integration/subroutine_roundtrip_spec.rb'
142
- - 'spec/integration/woff2_conversion_spec.rb'
143
-
144
- # Offense count: 466
93
+ # Offense count: 477
145
94
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
146
95
  Metrics/AbcSize:
147
96
  Enabled: false
@@ -152,17 +101,17 @@ Metrics/AbcSize:
152
101
  Metrics/BlockLength:
153
102
  Max: 80
154
103
 
155
- # Offense count: 6
104
+ # Offense count: 8
156
105
  # Configuration parameters: CountBlocks, CountModifierForms.
157
106
  Metrics/BlockNesting:
158
107
  Max: 5
159
108
 
160
- # Offense count: 231
109
+ # Offense count: 238
161
110
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
162
111
  Metrics/CyclomaticComplexity:
163
112
  Enabled: false
164
113
 
165
- # Offense count: 771
114
+ # Offense count: 786
166
115
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
167
116
  Metrics/MethodLength:
168
117
  Max: 135
@@ -173,11 +122,19 @@ Metrics/ParameterLists:
173
122
  Max: 39
174
123
  MaxOptionalParameters: 4
175
124
 
176
- # Offense count: 169
125
+ # Offense count: 175
177
126
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
178
127
  Metrics/PerceivedComplexity:
179
128
  Enabled: false
180
129
 
130
+ # Offense count: 1
131
+ # This cop supports unsafe autocorrection (--autocorrect-all).
132
+ # Configuration parameters: EnforcedStyleForLeadingUnderscores.
133
+ # SupportedStylesForLeadingUnderscores: disallowed, required, optional
134
+ Naming/MemoizedInstanceVariableName:
135
+ Exclude:
136
+ - 'lib/fontisan/sfnt_font.rb'
137
+
181
138
  # Offense count: 17
182
139
  # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
183
140
  # AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
@@ -188,7 +145,7 @@ Naming/MethodParameterName:
188
145
  - 'lib/fontisan/tables/glyf/curve_converter.rb'
189
146
  - 'lib/fontisan/variation/optimizer.rb'
190
147
 
191
- # Offense count: 11
148
+ # Offense count: 12
192
149
  # Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
193
150
  # AllowedMethods: call
194
151
  # WaywardPredicates: nonzero?
@@ -200,6 +157,7 @@ Naming/PredicateMethod:
200
157
  - 'lib/fontisan/converters/table_copier.rb'
201
158
  - 'lib/fontisan/converters/woff2_encoder.rb'
202
159
  - 'lib/fontisan/optimizers/charstring_rewriter.rb'
160
+ - 'lib/fontisan/sfnt_table.rb'
203
161
  - 'lib/fontisan/subset/options.rb'
204
162
  - 'lib/fontisan/validation/collection_validator.rb'
205
163
  - 'lib/fontisan/variation/metrics_adjuster.rb'
@@ -211,24 +169,6 @@ Naming/PredicateMethod:
211
169
  Naming/VariableNumber:
212
170
  Enabled: false
213
171
 
214
- # Offense count: 24
215
- # Configuration parameters: MinSize.
216
- Performance/CollectionLiteralInLoop:
217
- Exclude:
218
- - 'lib/fontisan/collection/builder.rb'
219
- - 'lib/fontisan/open_type_font.rb'
220
- - 'lib/fontisan/tables/cff/charstring.rb'
221
- - 'lib/fontisan/tables/cff2.rb'
222
- - 'lib/fontisan/tables/cff2/region_matcher.rb'
223
- - 'lib/fontisan/tables/sbix.rb'
224
- - 'lib/fontisan/true_type_font.rb'
225
- - 'lib/fontisan/variation/validator.rb'
226
- - 'lib/fontisan/woff2/table_transformer.rb'
227
- - 'spec/fontisan/cli_spec.rb'
228
- - 'spec/fontisan/commands/glyphs_command_spec.rb'
229
- - 'spec/fontisan/commands/info_command_spec.rb'
230
- - 'spec/fontisan/commands/tables_command_spec.rb'
231
-
232
172
  # Offense count: 23
233
173
  RSpec/AnyInstance:
234
174
  Exclude:
@@ -245,7 +185,7 @@ RSpec/AnyInstance:
245
185
  RSpec/ContextWording:
246
186
  Enabled: false
247
187
 
248
- # Offense count: 22
188
+ # Offense count: 23
249
189
  # Configuration parameters: IgnoredMetadata.
250
190
  RSpec/DescribeClass:
251
191
  Enabled: false
@@ -256,7 +196,7 @@ RSpec/DescribeMethod:
256
196
  - 'spec/fontisan/collection/variable_font_builder_spec.rb'
257
197
  - 'spec/fontisan/converters/woff2_encoder_integration_spec.rb'
258
198
 
259
- # Offense count: 1286
199
+ # Offense count: 1288
260
200
  # Configuration parameters: CountAsOne.
261
201
  RSpec/ExampleLength:
262
202
  Max: 66
@@ -354,23 +294,10 @@ RSpec/NoExpectationExample:
354
294
  - 'spec/fontisan/validators/validator_spec.rb'
355
295
  - 'spec/fontisan/variation/variable_svg_generator_spec.rb'
356
296
 
357
- # Offense count: 100
358
- # This cop supports unsafe autocorrection (--autocorrect-all).
359
- # RSpec/Output was renamed to RSpec/ExpectOutput in rubocop-rspec 3.0+
360
- RSpec/ExpectOutput:
361
- Exclude:
362
- - 'spec/benchmarks/subroutine_optimization_benchmark.rb'
363
- - 'spec/fontisan/converters/extended_woff2_spec.rb'
364
- - 'spec/fontisan/converters/woff2_round_trip_spec.rb'
365
- - 'spec/fontisan/lazy_loading_spec.rb'
366
- - 'spec/fontisan/loading_modes_spec.rb'
367
- - 'spec/integration/outline_conversion_spec.rb'
368
- - 'spec/integration/subroutine_roundtrip_spec.rb'
369
- - 'spec/integration/woff2_conversion_spec.rb'
370
-
371
- # Offense count: 11
297
+ # Offense count: 13
372
298
  RSpec/RepeatedExample:
373
299
  Exclude:
300
+ - 'spec/documentation_examples_spec.rb'
374
301
  - 'spec/fontisan/hints/truetype_instruction_generator_spec.rb'
375
302
  - 'spec/fontisan/metrics_calculator_spec.rb'
376
303
  - 'spec/fontisan/tables/os2_spec.rb'
@@ -435,16 +362,6 @@ Style/ComparableClamp:
435
362
  - 'lib/fontisan/variable/axis_normalizer.rb'
436
363
  - 'lib/fontisan/variation/interpolator.rb'
437
364
 
438
- # Offense count: 4
439
- # This cop supports safe autocorrection (--autocorrect).
440
- # Configuration parameters: EnforcedStyle, AllowComments.
441
- # SupportedStyles: empty, nil, both
442
- Style/EmptyElse:
443
- Exclude:
444
- - 'spec/fontisan/lazy_loading_spec.rb'
445
- - 'spec/fontisan/loading_modes_spec.rb'
446
- - 'spec/integration/subroutine_roundtrip_spec.rb'
447
-
448
365
  # Offense count: 11
449
366
  # This cop supports safe autocorrection (--autocorrect).
450
367
  # Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, Mode, AllowedMethods, AllowedPatterns.
data/CHANGELOG.md ADDED
@@ -0,0 +1,116 @@
1
+ # Changelog
2
+
3
+ All notable changes to Fontisan will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+ - Comprehensive documentation for WOFF/WOFF2 format support
12
+ - Color fonts documentation (COLR/CPAL, sbix, SVG tables)
13
+ - Font validation framework documentation
14
+ - Apple legacy font formats documentation ('true' signature, dfont)
15
+ - Font collection validation documentation
16
+ - Updated font hinting documentation
17
+ - Enhanced README with all v0.2.1-v0.2.7 features
18
+
19
+ ### Changed
20
+ - Improved documentation organization with dedicated feature guides
21
+ - Added more examples for command-line and Ruby API usage
22
+
23
+ ## [0.2.7] - 2026-01-06
24
+
25
+ ### Added
26
+ - Collection validation support with per-font reporting
27
+ - CollectionValidationReport model with overall status
28
+ - FontReport model for individual font validation results
29
+ - ValidateCommand.validate_collection method
30
+
31
+ ### Fixed
32
+ - Windows compatibility for collection extraction
33
+ - Various test fixes unrelated to collection validation
34
+
35
+ ## [0.2.6] - 2026-01-05
36
+
37
+ ### Added
38
+ - Apple dfont collection support
39
+ - DfontParser for reading dfont format
40
+ - DfontBuilder for writing dfont format
41
+ - Proper handling of dfont as collection in info command
42
+
43
+ ### Fixed
44
+ - Spec refactor for rubocop compliance
45
+ - Re-enabled previously skipped specs
46
+
47
+ ## [0.2.5] - 2026-01-03
48
+
49
+ ### Added
50
+ - Font validation framework
51
+ - Validator DSL for defining validation checks
52
+ - Predefined validation profiles (indexability, usability, production, web, spec_compliance)
53
+ - ValidationReport model with structured results
54
+ - 56 validation helper methods across 8 OpenType tables
55
+ - ValidateCommand with comprehensive CLI options
56
+
57
+ ### Changed
58
+ - Improved lazy loading performance
59
+ - Removed page size alignment (was causing performance issues)
60
+
61
+ ## [0.2.4] - 2026-01-03
62
+
63
+ ### Fixed
64
+ - Subroutine-related issues
65
+ - Spec fixes
66
+ - Glyph builder fixes
67
+ - Test font fixtures for validation testing
68
+
69
+ ### Added
70
+ - Color fonts support (COLR/CPAL tables)
71
+ - WOFF/WOFF2 conversion support
72
+ - WOFF/WOFF2 info command support
73
+ - WOFF2 validation support
74
+ - ColorGlyph, ColorLayer, ColorPalette models
75
+ - BitmapGlyph, BitmapStrike models
76
+ - SvgGlyph model
77
+ - CBLC, CBDT, COLR, CPAL, sbix, SVG table support
78
+
79
+ ## [0.2.3] - 2025-12-30
80
+
81
+ ### Added
82
+ - WOFF/WOFF2 font version display
83
+ - WOFF2 validation checks
84
+ - Proper TTC/OTC content info handling
85
+ - Collection info displays all fonts with metadata
86
+
87
+ ## [0.2.2] - 2025-12-30
88
+
89
+ ### Added
90
+ - Brief mode for font info command (`--brief` flag)
91
+ - 5x faster font indexing using metadata loading mode
92
+ - Only 13 essential attributes in brief mode
93
+ - Support for 5x performance improvement in batch processing
94
+
95
+ ### Changed
96
+ - README refactor for better organization
97
+
98
+ ## [0.2.1] - 2025-12-28
99
+
100
+ ### Added
101
+ - Proper font hinting implementation
102
+ - Bidirectional TrueType <-> PostScript hint conversion
103
+ - HintValidator for validating converted hints
104
+ - TrueTypeInstructionAnalyzer for analyzing instructions
105
+ - TrueTypeInstructionGenerator for generating instructions
106
+ - Hint round-trip validation
107
+ - CFF2 variable font support for PostScript hints
108
+
109
+ ## [0.2.0] - 2025-12-17
110
+
111
+ ### Added
112
+ - Initial release of Fontisan
113
+ - Basic font conversion capabilities
114
+ - Font information display
115
+ - TTC/OTC collection support
116
+ - Basic validation framework
data/README.adoc CHANGED
@@ -56,40 +56,52 @@ gem install fontisan
56
56
 
57
57
  == Features
58
58
 
59
+ Color fonts and collections::
60
+ * Color font support: COLR/CPAL layered glyphs, sbix bitmap glyphs, and SVG table (see link:docs/COLOR_FONTS.adoc[Color Fonts Guide])
61
+ * Font collection validation with per-font reporting (see link:docs/COLLECTION_VALIDATION.adoc[Collection Validation Guide])
62
+
63
+ Font analysis and information::
59
64
  * Bidirectional font hint conversion (see link:docs/FONT_HINTING.adoc[Font Hinting Guide])
60
65
  * Extract comprehensive font metadata (name, version, designer, license, etc.)
66
+ * Brief mode for fast font indexing (5x faster, metadata-only loading)
61
67
  * List OpenType tables with checksums and offsets
62
68
  * Extract glyph names from post table
63
69
  * Display Unicode codepoint to glyph index mappings
64
70
  * Analyze variable font axes and named instances
65
- * Generate static font instances from variable fonts
66
71
  * Display optical size information
67
72
  * List supported scripts from GSUB/GPOS tables
68
73
  * List OpenType features (ligatures, kerning, etc.) by script
69
74
  * Dump raw binary table data for analysis
75
+
76
+ Font operations::
77
+ * Generate static font instances from variable fonts
70
78
  * Font subsetting with multiple profiles (PDF, web, minimal)
71
- * Font validation with multiple severity levels
72
- * Collection management (pack/unpack TTC/OTC files with table deduplication)
73
- * Support for TTF, OTF, TTC, OTC font formats (production ready)
74
- * Apple legacy font support: 'true' signature TrueType fonts and dfont (Data Fork Font) format
75
- * WOFF format support (reading complete, writing functional, pending full integration)
76
- * WOFF2 format support (reading complete with table transformations, writing planned)
79
+ * Font validation framework with multiple profiles (indexability, usability, production, web, spec_compliance) (see link:docs/VALIDATION.adoc[Validation Guide])
80
+ * Collection management (pack/unpack TTC/OTC/dfont files with table deduplication)
81
+
82
+ Font format support::
83
+ * TTF, OTF, TTC, OTC font formats (production ready)
84
+ * WOFF/WOFF2 format support with reading, writing, and conversion (see link:docs/WOFF_WOFF2_FORMATS.adoc[WOFF/WOFF2 Guide])
85
+ * Apple legacy font support: 'true' signature TrueType fonts and dfont format (see link:docs/APPLE_LEGACY_FONTS.adoc[Apple Legacy Fonts Guide])
77
86
  * SVG font generation (complete)
78
- * TTX/YAML/JSON export (complete)
79
- * Command-line interface with 18 commands
80
- * Ruby library API for programmatic access
81
- * Structured output in YAML, JSON, and text formats
82
- * Universal outline model for format-agnostic glyph representation (complete)
87
+
88
+ Font engineering::
89
+ * Universal outline model for format-agnostic glyph representation
83
90
  * CFF CharString encoding/decoding (complete)
84
91
  * CFF INDEX structure building (complete)
85
92
  * CFF DICT structure building (complete)
86
93
  * TrueType curve converter for bi-directional quadratic/cubic conversion (complete)
87
94
  * Compound glyph decomposition with transformation support (complete)
88
95
  * CFF subroutine optimization for space-efficient OTF generation (preview mode)
89
- * Various loading modes for high-performance font indexing (5x faster)
90
96
  * Bidirectional hint conversion (TrueType ↔ PostScript) with validation (complete)
91
97
  * CFF2 variable font support for PostScript hint conversion (complete)
92
98
 
99
+ Export and interfaces::
100
+ * TTX/YAML/JSON export (complete)
101
+ * Command-line interface with 18 commands
102
+ * Ruby library API for programmatic access
103
+ * Structured output in YAML, JSON, and text formats
104
+
93
105
 
94
106
  == Font information
95
107
 
@@ -0,0 +1,173 @@
1
+ = Apple Legacy Font Format Support
2
+
3
+ == General
4
+
5
+ Fontisan provides support for Apple's legacy font formats that predate modern
6
+ OpenType standards:
7
+
8
+ * **'true' signature TrueType fonts** - Older Mac fonts with 'true' sfnt version
9
+ * **dfont (Data Fork Font)** - Mac suitcase format with fonts in data fork
10
+
11
+ These formats require special handling due to their unique structures and
12
+ historical platform-specific conventions.
13
+
14
+ === 'true' signature TrueType fonts
15
+
16
+ Traditional TrueType fonts use 'true' (0x74727565) as the SFNT version instead
17
+ of the modern 0x00010000. These were common on classic Mac OS.
18
+
19
+ [source,shell]
20
+ ----
21
+ $ fontisan info legacy_font.ttf
22
+
23
+ Font type: TrueType (Not Variable)
24
+ SFNT Version: 'true' (legacy)
25
+ Family: Legacy Font
26
+ ...
27
+
28
+ Detection:
29
+ Fontisan automatically detects 'true' signature fonts
30
+ Treats them as standard TrueType for all operations
31
+ Preserves signature format when writing
32
+ ----
33
+
34
+ === dfont (Data Fork Font) format
35
+
36
+ The dfont format stores complete Mac font suitcases in the data fork, supporting
37
+ multiple fonts in a single file with resource-fork style structure.
38
+
39
+ [source,shell]
40
+ ----
41
+ $ fontisan ls family.dfont
42
+
43
+ Font 0: Arial
44
+ Family: Arial
45
+ Subfamily: Regular
46
+
47
+ Font 1: Arial
48
+ Family: Arial
49
+ Subfamily: Bold
50
+
51
+ Font 2: Arial
52
+ Family: Arial
53
+ Subfamily: Italic
54
+ ----
55
+
56
+ .dfont structure
57
+ [example]
58
+ ====
59
+ [source,text]
60
+ ----
61
+ dfont format structure:
62
+
63
+ Data Fork Map:
64
+ Resource data: Contains all font resources
65
+ Resource map: Index of resources by type and ID
66
+ Postscript names: Font name mapping
67
+
68
+ Supported fonts in dfont:
69
+ - TrueType fonts ('true' signature)
70
+ - OpenType fonts (CFF or TrueType outlines)
71
+ - Mixed formats in single dfont
72
+
73
+ Features:
74
+ - Automatic resource fork extraction
75
+ - Font list with metadata
76
+ - Extract individual fonts by index
77
+ - Unpack all fonts to directory
78
+ - Validate fonts within dfont
79
+ ====
80
+ ----
81
+
82
+ === Working with dfont files
83
+
84
+ ==== List fonts in dfont
85
+
86
+ [source,shell]
87
+ ----
88
+ $ fontisan ls family.dfont
89
+
90
+ Font 0: Arial Regular
91
+ Family: Arial
92
+ Subfamily: Regular
93
+ PostScript: Arial
94
+
95
+ Font 1: Arial Bold
96
+ Family: Arial
97
+ Subfamily: Bold
98
+ PostScript: Arial-Bold
99
+ ----
100
+
101
+ ==== Show dfont info
102
+
103
+ [source,shell]
104
+ ----
105
+ $ fontisan info family.dfont
106
+
107
+ Collection: family.dfont
108
+ Type: dfont
109
+ Fonts: 3
110
+
111
+ Font 0 (offset: 256):
112
+ Font type: TrueType (Not Variable)
113
+ Family: Arial
114
+ Subfamily: Regular
115
+ ...
116
+ ----
117
+
118
+ ==== Extract fonts from dfont
119
+
120
+ [source,shell]
121
+ ----
122
+ # Extract all fonts
123
+ $ fontisan unpack family.dfont extracted_fonts/
124
+
125
+ # Extract specific font
126
+ $ fontisan unpack family.dfont --font-index 0 Arial.ttf
127
+ ----
128
+
129
+ ==== Validate dfont
130
+
131
+ [source,shell]
132
+ ----
133
+ $ fontisan validate family.dfont -t indexability
134
+
135
+ Collection: family.dfont
136
+ Type: dfont
137
+ Fonts: 3
138
+
139
+ Summary:
140
+ Total Errors: 0
141
+ Total Warnings: 2
142
+
143
+ === Font 0: Arial Regular ===
144
+ Font: family.dfont:0
145
+ Status: VALID_WITH_WARNINGS
146
+ ...
147
+ ----
148
+
149
+ === Ruby API for dfont
150
+
151
+ [source,ruby]
152
+ ----
153
+ require 'fontisan'
154
+
155
+ # Load dfont collection
156
+ dfont = Fontisan::FontLoader.load('family.dfont')
157
+
158
+ # Access as collection
159
+ puts "Font count: #{dfont.font_count}"
160
+ File.open('family.dfont', 'rb') do |io|
161
+ fonts = dfont.extract_fonts(io)
162
+ fonts.each_with_index do |font, i|
163
+ puts "Font #{i}: #{font.family_name}"
164
+ end
165
+ end
166
+
167
+ # Extract specific font
168
+ font = Fontisan::FontLoader.load('family.dfont', font_index: 0)
169
+
170
+ # Validate dfont
171
+ report = Fontisan.validate('family.dfont')
172
+ puts report.valid? # => true/false
173
+ ----