fontisan 0.2.16 → 0.2.22
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 +14 -90
- data/Gemfile +6 -3
- data/README.adoc +257 -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/api/font-loader.md +21 -15
- 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/audit/codepoint_range_coalescer.rb +41 -0
- data/lib/fontisan/audit/context.rb +122 -0
- data/lib/fontisan/audit/differ.rb +124 -0
- data/lib/fontisan/audit/extractors/aggregations.rb +54 -0
- data/lib/fontisan/audit/extractors/base.rb +26 -0
- data/lib/fontisan/audit/extractors/color_capabilities.rb +141 -0
- data/lib/fontisan/audit/extractors/coverage.rb +48 -0
- data/lib/fontisan/audit/extractors/hinting.rb +197 -0
- data/lib/fontisan/audit/extractors/identity.rb +52 -0
- data/lib/fontisan/audit/extractors/language_coverage.rb +37 -0
- data/lib/fontisan/audit/extractors/licensing.rb +79 -0
- data/lib/fontisan/audit/extractors/metrics.rb +103 -0
- data/lib/fontisan/audit/extractors/opentype_layout.rb +69 -0
- data/lib/fontisan/audit/extractors/provenance.rb +29 -0
- data/lib/fontisan/audit/extractors/style.rb +32 -0
- data/lib/fontisan/audit/extractors/variation_detail.rb +99 -0
- data/lib/fontisan/audit/extractors.rb +27 -0
- data/lib/fontisan/audit/library_aggregator.rb +83 -0
- data/lib/fontisan/audit/library_auditor.rb +90 -0
- data/lib/fontisan/audit/registry.rb +60 -0
- data/lib/fontisan/audit/style_extractor.rb +80 -0
- data/lib/fontisan/audit.rb +20 -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 +172 -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/ucd_cli.rb +97 -0
- data/lib/fontisan/cli.rb +201 -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/audit_command.rb +123 -0
- data/lib/fontisan/commands/audit_compare_command.rb +66 -0
- data/lib/fontisan/commands/audit_library_command.rb +46 -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 +29 -0
- data/lib/fontisan/config/cldr.yml +22 -0
- data/lib/fontisan/config/conversion_matrix.yml +38 -0
- data/lib/fontisan/config/ucd.yml +23 -0
- data/lib/fontisan/constants.rb +48 -6
- 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 +189 -328
- data/lib/fontisan/font_writer.rb +0 -1
- data/lib/fontisan/formatters/audit_diff_text_renderer.rb +122 -0
- data/lib/fontisan/formatters/audit_text_renderer.rb +324 -0
- data/lib/fontisan/formatters/library_summary_text_renderer.rb +99 -0
- data/lib/fontisan/formatters/text_formatter.rb +6 -0
- data/lib/fontisan/formatters.rb +12 -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 +16 -0
- data/lib/fontisan/metrics_calculator.rb +0 -2
- data/lib/fontisan/models/all_scripts_features_info.rb +0 -1
- data/lib/fontisan/models/audit/audit_axis.rb +30 -0
- data/lib/fontisan/models/audit/audit_block.rb +32 -0
- data/lib/fontisan/models/audit/audit_diff.rb +77 -0
- data/lib/fontisan/models/audit/audit_report.rb +153 -0
- data/lib/fontisan/models/audit/codepoint_range.rb +40 -0
- data/lib/fontisan/models/audit/codepoint_set_diff.rb +34 -0
- data/lib/fontisan/models/audit/color_capabilities.rb +93 -0
- data/lib/fontisan/models/audit/duplicate_group.rb +23 -0
- data/lib/fontisan/models/audit/embedding_type.rb +76 -0
- data/lib/fontisan/models/audit/field_change.rb +28 -0
- data/lib/fontisan/models/audit/fs_selection_flags.rb +61 -0
- data/lib/fontisan/models/audit/gasp_range.rb +63 -0
- data/lib/fontisan/models/audit/hinting.rb +93 -0
- data/lib/fontisan/models/audit/library_summary.rb +40 -0
- data/lib/fontisan/models/audit/licensing.rb +48 -0
- data/lib/fontisan/models/audit/metrics.rb +111 -0
- data/lib/fontisan/models/audit/named_instance.rb +41 -0
- data/lib/fontisan/models/audit/opentype_layout.rb +40 -0
- data/lib/fontisan/models/audit/script_coverage_row.rb +26 -0
- data/lib/fontisan/models/audit/script_features.rb +28 -0
- data/lib/fontisan/models/audit/variation_detail.rb +44 -0
- data/lib/fontisan/models/audit.rb +33 -0
- 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/ucd/ucd.rb +38 -0
- data/lib/fontisan/models/ucd/ucd_char.rb +67 -0
- data/lib/fontisan/models/ucd.rb +19 -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 +14 -0
- data/lib/fontisan/pipeline/transformation_pipeline.rb +0 -7
- data/lib/fontisan/pipeline/variation_resolver.rb +0 -7
- data/lib/fontisan/pipeline.rb +13 -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 +22 -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 +54 -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/ucd/aggregator.rb +73 -0
- data/lib/fontisan/ucd/cache_manager.rb +111 -0
- data/lib/fontisan/ucd/config.rb +59 -0
- data/lib/fontisan/ucd/download_error.rb +9 -0
- data/lib/fontisan/ucd/downloader.rb +88 -0
- data/lib/fontisan/ucd/error.rb +8 -0
- data/lib/fontisan/ucd/index.rb +103 -0
- data/lib/fontisan/ucd/index_builder.rb +107 -0
- data/lib/fontisan/ucd/range_entry.rb +56 -0
- data/lib/fontisan/ucd/unknown_version_error.rb +9 -0
- data/lib/fontisan/ucd/version_resolver.rb +79 -0
- data/lib/fontisan/ucd.rb +23 -0
- 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 +124 -196
- metadata +128 -7
- data/fontisan.gemspec +0 -47
data/docs/cli/index.md
CHANGED
|
@@ -20,6 +20,18 @@ Always check your font's End User License Agreement (EULA) before processing. Ma
|
|
|
20
20
|
|
|
21
21
|
## Quick Reference
|
|
22
22
|
|
|
23
|
+
### Font Audit
|
|
24
|
+
|
|
25
|
+
| Command | Description | Example |
|
|
26
|
+
|---------|-------------|---------|
|
|
27
|
+
| `audit` | Comprehensive per-face audit (replaces `otfinfo`) | `fontisan audit font.ttf` |
|
|
28
|
+
|
|
29
|
+
The `audit` command covers identity, style, metrics, codepoint coverage,
|
|
30
|
+
licensing, hinting, color capabilities, variable-font detail, and
|
|
31
|
+
OpenType layout — and supports collections, `--compare` mode, and
|
|
32
|
+
whole-library `--recursive --summary` mode. See
|
|
33
|
+
[audit](/cli/audit) for details.
|
|
34
|
+
|
|
23
35
|
### Font Information Commands
|
|
24
36
|
|
|
25
37
|
| Command | Description | Example |
|
|
@@ -165,6 +177,22 @@ fontisan validate font.ttf --profile google_fonts
|
|
|
165
177
|
fontisan validate font.ttf --profile production
|
|
166
178
|
```
|
|
167
179
|
|
|
180
|
+
### Audit a Font (or Library)
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Full per-face audit
|
|
184
|
+
fontisan audit font.ttf
|
|
185
|
+
|
|
186
|
+
# Diff two fonts (or saved reports)
|
|
187
|
+
fontisan audit --compare baseline.yaml new.ttf
|
|
188
|
+
|
|
189
|
+
# Whole-library summary
|
|
190
|
+
fontisan audit lib/ --recursive --summary
|
|
191
|
+
|
|
192
|
+
# Fast inventory pass
|
|
193
|
+
fontisan audit lib/ --recursive --summary --brief
|
|
194
|
+
```
|
|
195
|
+
|
|
168
196
|
### Export Font Data
|
|
169
197
|
|
|
170
198
|
```bash
|
|
@@ -182,6 +210,9 @@ fontisan export font.ttf --format ttx --tables head,name,cmap
|
|
|
182
210
|
|
|
183
211
|
Detailed documentation for each command:
|
|
184
212
|
|
|
213
|
+
### Font Audit
|
|
214
|
+
- [audit](/cli/audit) — Comprehensive per-face audit (replaces `otfinfo`); supports collections, compare, library summary
|
|
215
|
+
|
|
185
216
|
### Font Information
|
|
186
217
|
- [info](/cli/info) — Extract font metadata and properties (includes brief mode)
|
|
187
218
|
- [ls](/cli/ls) — List fonts in collections
|
data/docs/guide/color.md
CHANGED
|
@@ -40,13 +40,22 @@ Generating options control how the output font is written.
|
|
|
40
40
|
| `optimize_tables` | Boolean | Enable table optimization | Reduce file size |
|
|
41
41
|
| `reencode_first_256` | Boolean | Reencode first 256 glyphs | Type 1 output |
|
|
42
42
|
| `encoding_vector` | String | Custom encoding vector | Type 1 output |
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
43
|
+
| `zlib_level` | Integer (0–9) | zlib compression level for WOFF | WOFF output (default 6) |
|
|
44
|
+
| `uncompressed` | Boolean | Store WOFF tables uncompressed (legal per WOFF 1.0 §5.1) | Tooling pipelines |
|
|
45
|
+
| `compression_threshold` | Integer | Skip compression for tables smaller than N bytes | Tiny-table edge cases |
|
|
46
|
+
| `brotli_quality` | Integer (0–11) | Brotli quality for WOFF2 | WOFF2 output (default 11) |
|
|
47
|
+
| `transform_tables` | Boolean | Apply WOFF2 glyf/loca + hmtx transformations | Smaller WOFF2 output |
|
|
48
|
+
| `metadata_xml` | String | Optional WOFF metadata XML block | WOFF metadata block |
|
|
49
|
+
| `private_data` | String | Optional WOFF private data block | WOFF private block |
|
|
45
50
|
| `preserve_metadata` | Boolean | Preserve copyright/license metadata | Maintain metadata |
|
|
46
51
|
| `strip_metadata` | Boolean | Remove metadata | Reduce file size |
|
|
47
52
|
| `target_format` | String | Collection target format | Collection conversions |
|
|
48
53
|
| `curve_tolerance` | Float | Curve approximation tolerance | OTF → TTF |
|
|
49
54
|
|
|
55
|
+
Compression knobs come from each strategy's `ConversionStrategy` DSL
|
|
56
|
+
declarations. Knobs that don't apply to the requested target format are
|
|
57
|
+
rejected by `FormatConverter.validate_options_for_target!`.
|
|
58
|
+
|
|
50
59
|
## CLI Option Mapping
|
|
51
60
|
|
|
52
61
|
### Opening Options
|
|
@@ -103,6 +112,16 @@ Generating options control how the output font is written.
|
|
|
103
112
|
|
|
104
113
|
# Curves
|
|
105
114
|
--curve-tolerance N # Approximation tolerance (0.1-2.0)
|
|
115
|
+
|
|
116
|
+
# WOFF only (zlib)
|
|
117
|
+
--zlib-level=N # 0–9, default 6
|
|
118
|
+
--uncompressed # Store tables uncompressed (legal per WOFF 1.0 §5.1)
|
|
119
|
+
--compression-threshold=N # Skip compression for tables < N bytes (default 100)
|
|
120
|
+
|
|
121
|
+
# WOFF2 only (Brotli)
|
|
122
|
+
--brotli-quality=N # 0–11, default 11
|
|
123
|
+
--transform-tables # Apply glyf/loca + hmtx transformations
|
|
124
|
+
--no-transform-tables # Disable transformations (default)
|
|
106
125
|
```
|
|
107
126
|
|
|
108
127
|
### Preset Option
|
|
@@ -194,10 +213,20 @@ Fonts optimized for web delivery.
|
|
|
194
213
|
Fontisan::ConversionOptions.from_preset(:web_optimized)
|
|
195
214
|
# From: :otf, To: :woff2
|
|
196
215
|
# opening: {}
|
|
197
|
-
# generating: {
|
|
216
|
+
# generating: { brotli_quality: 11, transform_tables: true,
|
|
198
217
|
# optimize_tables: true, preserve_metadata: true }
|
|
199
218
|
```
|
|
200
219
|
|
|
220
|
+
### legacy_web
|
|
221
|
+
|
|
222
|
+
WOFF with maximum zlib compression for legacy browser reach (IE 9+).
|
|
223
|
+
|
|
224
|
+
```ruby
|
|
225
|
+
Fontisan::ConversionOptions.from_preset(:legacy_web)
|
|
226
|
+
# From: :otf, To: :woff
|
|
227
|
+
# generating: { zlib_level: 9, optimize_tables: true, preserve_metadata: true }
|
|
228
|
+
```
|
|
229
|
+
|
|
201
230
|
### archive_to_modern
|
|
202
231
|
|
|
203
232
|
Collection extraction and modernization.
|
|
@@ -157,7 +157,7 @@ Result: Some precision loss unavoidable.
|
|
|
157
157
|
# Convert all TTF files in a directory
|
|
158
158
|
Dir.glob('fonts/*.ttf').each do |input|
|
|
159
159
|
output = input.sub('.ttf', '.otf')
|
|
160
|
-
Fontisan.convert(input,
|
|
160
|
+
Fontisan.convert(input, to: :otf, output: output)
|
|
161
161
|
end
|
|
162
162
|
```
|
|
163
163
|
|
|
@@ -203,6 +203,6 @@ fontisan convert font.pfb --to woff2 --output font.woff2 \
|
|
|
203
203
|
```ruby
|
|
204
204
|
Dir.glob('legacy/*.pfb').each do |input|
|
|
205
205
|
output = input.sub('.pfb', '.otf').sub('legacy/', 'modern/')
|
|
206
|
-
Fontisan.convert(input,
|
|
206
|
+
Fontisan.convert(input, to: :otf, output: output)
|
|
207
207
|
end
|
|
208
208
|
```
|
|
@@ -10,8 +10,13 @@ Fontisan supports conversion to web-optimized formats (WOFF and WOFF2) for optim
|
|
|
10
10
|
|
|
11
11
|
| Format | Compression | Browser Support | Use Case |
|
|
12
12
|
|--------|-------------|-----------------|----------|
|
|
13
|
-
| WOFF | zlib | All modern browsers | Wide compatibility |
|
|
14
|
-
| WOFF2 |
|
|
13
|
+
| WOFF | zlib | All modern browsers (IE 9+) | Wide compatibility |
|
|
14
|
+
| WOFF2 | Brotli | Modern browsers | Smallest size |
|
|
15
|
+
|
|
16
|
+
The format you pick **is** the algorithm choice — WOFF 1.0 mandates zlib,
|
|
17
|
+
WOFF2 mandates Brotli. There is no separate `--compression` flag. Each
|
|
18
|
+
format exposes its algorithm's tunable parameters instead (level, quality,
|
|
19
|
+
threshold, transform).
|
|
15
20
|
|
|
16
21
|
## WOFF2
|
|
17
22
|
|
|
@@ -34,7 +39,7 @@ fontisan convert font.pfb --to woff2 --output font.woff2
|
|
|
34
39
|
Fontisan::ConversionOptions.from_preset(:web_optimized)
|
|
35
40
|
# From: :otf, To: :woff2
|
|
36
41
|
# opening: {}
|
|
37
|
-
# generating: {
|
|
42
|
+
# generating: { brotli_quality: 11, transform_tables: true,
|
|
38
43
|
# optimize_tables: true, preserve_metadata: true }
|
|
39
44
|
```
|
|
40
45
|
|
|
@@ -61,13 +66,20 @@ fontisan convert font.ttf --to woff --output font.woff
|
|
|
61
66
|
options = Fontisan::ConversionOptions.new(
|
|
62
67
|
to: :woff,
|
|
63
68
|
generating: {
|
|
64
|
-
|
|
65
|
-
preserve_metadata: true
|
|
66
|
-
add_private_data: false
|
|
69
|
+
zlib_level: 9, # max zlib compression
|
|
70
|
+
preserve_metadata: true
|
|
67
71
|
}
|
|
68
72
|
)
|
|
69
73
|
```
|
|
70
74
|
|
|
75
|
+
For maximum legacy reach use the `:legacy_web` preset:
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
Fontisan::ConversionOptions.from_preset(:legacy_web)
|
|
79
|
+
# From: :otf, To: :woff
|
|
80
|
+
# generating: { zlib_level: 9, optimize_tables: true, preserve_metadata: true }
|
|
81
|
+
```
|
|
82
|
+
|
|
71
83
|
## web_optimized Preset
|
|
72
84
|
|
|
73
85
|
Optimize fonts for web delivery:
|
|
@@ -76,7 +88,7 @@ Optimize fonts for web delivery:
|
|
|
76
88
|
Fontisan::ConversionOptions.from_preset(:web_optimized)
|
|
77
89
|
# From: :otf, To: :woff2
|
|
78
90
|
# opening: {}
|
|
79
|
-
# generating: {
|
|
91
|
+
# generating: { brotli_quality: 11, transform_tables: true,
|
|
80
92
|
# optimize_tables: true, preserve_metadata: true }
|
|
81
93
|
```
|
|
82
94
|
|
|
@@ -113,43 +125,72 @@ fontisan convert font.otf --to woff2 --output font.woff2
|
|
|
113
125
|
# Via OTF intermediate
|
|
114
126
|
options = Fontisan::ConversionOptions.new(
|
|
115
127
|
opening: { decompose_composites: false, generate_unicode: true },
|
|
116
|
-
generating: {
|
|
117
|
-
|
|
128
|
+
generating: {
|
|
129
|
+
brotli_quality: 11 # WOFF2
|
|
130
|
+
# For WOFF instead, use: zlib_level: 9
|
|
131
|
+
}
|
|
118
132
|
)
|
|
119
133
|
```
|
|
120
134
|
|
|
121
|
-
## Compression
|
|
135
|
+
## Compression Knobs
|
|
136
|
+
|
|
137
|
+
Each web format exposes its algorithm's parameters. Knobs that don't apply
|
|
138
|
+
to the requested target are rejected up-front with a clear error.
|
|
122
139
|
|
|
123
|
-
###
|
|
140
|
+
### WOFF (zlib)
|
|
141
|
+
|
|
142
|
+
| Option | CLI | Range | Default | Notes |
|
|
143
|
+
|--------|-----|-------|---------|-------|
|
|
144
|
+
| `zlib_level` | `--zlib-level=N` | 0–9 | 6 | 0 = no compression, 9 = smallest |
|
|
145
|
+
| `uncompressed` | `--uncompressed` | bool | false | Store tables uncompressed (legal per WOFF 1.0 §5.1; `compLength == origLength`) |
|
|
146
|
+
| `compression_threshold` | `--compression-threshold=N` | bytes | 100 | Skip compression for tables smaller than N |
|
|
124
147
|
|
|
125
148
|
```ruby
|
|
126
|
-
|
|
149
|
+
# Max zlib compression
|
|
150
|
+
options = Fontisan::ConversionOptions.new(
|
|
151
|
+
to: :woff,
|
|
152
|
+
generating: { zlib_level: 9 }
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# No compression (legal per spec; useful for tooling pipelines)
|
|
156
|
+
options = Fontisan::ConversionOptions.new(
|
|
157
|
+
to: :woff,
|
|
158
|
+
generating: { uncompressed: true }
|
|
159
|
+
)
|
|
127
160
|
```
|
|
128
161
|
|
|
129
|
-
|
|
130
|
-
- Requires modern browsers
|
|
131
|
-
- Transforms tables for better compression
|
|
162
|
+
### WOFF2 (Brotli)
|
|
132
163
|
|
|
133
|
-
|
|
164
|
+
| Option | CLI | Range | Default | Notes |
|
|
165
|
+
|--------|-----|-------|---------|-------|
|
|
166
|
+
| `brotli_quality` | `--brotli-quality=N` | 0–11 | 11 | 0 = fastest, 11 = smallest |
|
|
167
|
+
| `transform_tables` | `--[no-]transform-tables` | bool | false | Apply glyf/loca and hmtx transformations |
|
|
134
168
|
|
|
135
169
|
```ruby
|
|
136
|
-
|
|
170
|
+
# Smallest possible WOFF2
|
|
171
|
+
options = Fontisan::ConversionOptions.new(
|
|
172
|
+
to: :woff2,
|
|
173
|
+
generating: { brotli_quality: 11, transform_tables: true }
|
|
174
|
+
)
|
|
137
175
|
```
|
|
138
176
|
|
|
139
|
-
-
|
|
140
|
-
- Wide browser support
|
|
141
|
-
- No table transforms
|
|
177
|
+
### Cross-format validation
|
|
142
178
|
|
|
143
|
-
|
|
179
|
+
Passing a WOFF knob to a WOFF2 target (or vice versa) is rejected at
|
|
180
|
+
conversion time by `FormatConverter.validate_options_for_target!`:
|
|
144
181
|
|
|
145
182
|
```ruby
|
|
146
|
-
|
|
183
|
+
# Rejected at convert time: brotli_quality does not apply to woff
|
|
184
|
+
Fontisan.convert('font.ttf', to: :woff, output: 'font.woff',
|
|
185
|
+
brotli_quality: 11)
|
|
186
|
+
# => Fontisan::Error: ... Option(s) :brotli_quality do not apply to --to woff.
|
|
187
|
+
# Accepted for woff: zlib_level, uncompressed, compression_threshold,
|
|
188
|
+
# metadata_xml, private_data
|
|
147
189
|
```
|
|
148
190
|
|
|
149
|
-
|
|
150
|
-
- For debugging
|
|
191
|
+
The CLI equivalent exits 1 with the same message.
|
|
151
192
|
|
|
152
|
-
## Table Transforms
|
|
193
|
+
## Table Transforms (WOFF2)
|
|
153
194
|
|
|
154
195
|
WOFF2 supports table transformations for better compression:
|
|
155
196
|
|
|
@@ -166,6 +207,12 @@ options = Fontisan::ConversionOptions.new(
|
|
|
166
207
|
)
|
|
167
208
|
```
|
|
168
209
|
|
|
210
|
+
CLI equivalent:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
fontisan convert font.ttf --to woff2 --output font.woff2 --transform-tables
|
|
214
|
+
```
|
|
215
|
+
|
|
169
216
|
## Metadata Handling
|
|
170
217
|
|
|
171
218
|
### Preserve Metadata
|
|
@@ -198,20 +245,32 @@ font = Fontisan::FontLoader.load('source.ttf')
|
|
|
198
245
|
woff2_options = Fontisan::ConversionOptions.from_preset(:web_optimized)
|
|
199
246
|
Fontisan::FontWriter.write(font, 'font.woff2', options: woff2_options)
|
|
200
247
|
|
|
201
|
-
# Create WOFF for older browsers
|
|
202
|
-
woff_options = Fontisan::ConversionOptions.
|
|
203
|
-
to: :woff,
|
|
204
|
-
generating: { compression: "zlib", preserve_metadata: true }
|
|
205
|
-
)
|
|
248
|
+
# Create WOFF for older browsers (max zlib)
|
|
249
|
+
woff_options = Fontisan::ConversionOptions.from_preset(:legacy_web)
|
|
206
250
|
Fontisan::FontWriter.write(font, 'font.woff', options: woff_options)
|
|
207
251
|
```
|
|
208
252
|
|
|
253
|
+
### Top-level Fontisan.convert
|
|
254
|
+
|
|
255
|
+
```ruby
|
|
256
|
+
# WOFF2 with max Brotli
|
|
257
|
+
Fontisan.convert('font.ttf', to: :woff2, output: 'font.woff2',
|
|
258
|
+
brotli_quality: 11, transform_tables: true)
|
|
259
|
+
|
|
260
|
+
# WOFF with max zlib (for IE / older browsers)
|
|
261
|
+
Fontisan.convert('font.ttf', to: :woff, output: 'font.woff', zlib_level: 9)
|
|
262
|
+
|
|
263
|
+
# WOFF stored uncompressed (legal per WOFF 1.0 §5.1)
|
|
264
|
+
Fontisan.convert('font.ttf', to: :woff, output: 'font.woff', uncompressed: true)
|
|
265
|
+
```
|
|
266
|
+
|
|
209
267
|
### Batch Web Conversion
|
|
210
268
|
|
|
211
269
|
```bash
|
|
212
|
-
# Convert all TTF files to WOFF2
|
|
270
|
+
# Convert all TTF files to WOFF2 with max Brotli
|
|
213
271
|
for f in fonts/*.ttf; do
|
|
214
|
-
fontisan convert "$f" --to woff2 --output "web/$(basename "${f%.ttf}.woff2")"
|
|
272
|
+
fontisan convert "$f" --to woff2 --output "web/$(basename "${f%.ttf}.woff2")" \
|
|
273
|
+
--brotli-quality 11 --transform-tables
|
|
215
274
|
done
|
|
216
275
|
```
|
|
217
276
|
|
data/docs/guide/conversion.md
CHANGED
|
@@ -18,10 +18,10 @@ Fontisan supports conversion between various font formats.
|
|
|
18
18
|
require 'fontisan'
|
|
19
19
|
|
|
20
20
|
# Convert TTF to WOFF2
|
|
21
|
-
Fontisan.convert('font.ttf',
|
|
21
|
+
Fontisan.convert('font.ttf', to: :woff2, output: 'font.woff2')
|
|
22
22
|
|
|
23
|
-
# Convert
|
|
24
|
-
Fontisan.convert('font.ttf',
|
|
23
|
+
# Convert TTF to OTF
|
|
24
|
+
Fontisan.convert('font.ttf', to: :otf, output: 'font.otf')
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
## Batch Conversion
|
|
@@ -30,10 +30,11 @@ Fontisan.convert('font.ttf', output_path: 'output/font.woff2')
|
|
|
30
30
|
# Convert multiple files
|
|
31
31
|
fonts = Dir.glob('fonts/*.ttf')
|
|
32
32
|
fonts.each do |font|
|
|
33
|
-
|
|
33
|
+
out = font.sub(/\.ttf$/, '.otf')
|
|
34
|
+
Fontisan.convert(font, to: :otf, output: out)
|
|
34
35
|
end
|
|
35
36
|
```
|
|
36
37
|
|
|
37
38
|
## Related
|
|
38
39
|
|
|
39
|
-
- [WOFF/WOFF2 Formats](/guide/
|
|
40
|
+
- [WOFF/WOFF2 Formats](/guide/conversion/web) - Details on web font formats
|
data/docs/guide/formats/woff.md
CHANGED
|
@@ -10,8 +10,13 @@ Web Open Font Format (WOFF and WOFF2) are optimized for web delivery.
|
|
|
10
10
|
|
|
11
11
|
| Format | Compression | Browser Support |
|
|
12
12
|
|--------|-------------|-----------------|
|
|
13
|
-
| WOFF | zlib | All modern browsers |
|
|
14
|
-
| WOFF2 |
|
|
13
|
+
| WOFF | zlib | All modern browsers (IE 9+) |
|
|
14
|
+
| WOFF2 | Brotli | Modern browsers |
|
|
15
|
+
|
|
16
|
+
The format you pick **is** the algorithm choice — WOFF 1.0 mandates zlib,
|
|
17
|
+
WOFF2 mandates Brotli. Each format exposes its algorithm's parameters
|
|
18
|
+
(level, quality, transform) rather than offering a separate algorithm
|
|
19
|
+
selector.
|
|
15
20
|
|
|
16
21
|
## WOFF2 Benefits
|
|
17
22
|
|
|
@@ -27,6 +32,9 @@ fontisan convert font.ttf --to woff --output font.woff
|
|
|
27
32
|
|
|
28
33
|
# From OTF
|
|
29
34
|
fontisan convert font.otf --to woff --output font.woff
|
|
35
|
+
|
|
36
|
+
# Max zlib compression
|
|
37
|
+
fontisan convert font.ttf --to woff --output font.woff --zlib-level 9
|
|
30
38
|
```
|
|
31
39
|
|
|
32
40
|
## Converting to WOFF2
|
|
@@ -40,6 +48,10 @@ fontisan convert font.otf --to woff2 --output font.woff2
|
|
|
40
48
|
|
|
41
49
|
# From Type 1
|
|
42
50
|
fontisan convert font.pfb --to woff2 --output font.woff2
|
|
51
|
+
|
|
52
|
+
# Smallest possible output (max Brotli + table transforms)
|
|
53
|
+
fontisan convert font.ttf --to woff2 --output font.woff2 \
|
|
54
|
+
--brotli-quality 11 --transform-tables
|
|
43
55
|
```
|
|
44
56
|
|
|
45
57
|
## API Usage
|
|
@@ -47,28 +59,40 @@ fontisan convert font.pfb --to woff2 --output font.woff2
|
|
|
47
59
|
```ruby
|
|
48
60
|
options = Fontisan::ConversionOptions.from_preset(:web_optimized)
|
|
49
61
|
# From: :otf, To: :woff2
|
|
50
|
-
# generating: {
|
|
62
|
+
# generating: { brotli_quality: 11, transform_tables: true,
|
|
63
|
+
# optimize_tables: true, preserve_metadata: true }
|
|
51
64
|
|
|
52
65
|
Fontisan::FontWriter.write(font, 'font.woff2', options: options)
|
|
53
66
|
```
|
|
54
67
|
|
|
55
|
-
## Compression
|
|
68
|
+
## Compression Knobs
|
|
69
|
+
|
|
70
|
+
### WOFF (zlib)
|
|
56
71
|
|
|
57
|
-
|
|
72
|
+
| Option | CLI | Range | Default |
|
|
73
|
+
|--------|-----|-------|---------|
|
|
74
|
+
| `zlib_level` | `--zlib-level=N` | 0–9 | 6 |
|
|
75
|
+
| `uncompressed` | `--uncompressed` | bool | false |
|
|
76
|
+
| `compression_threshold` | `--compression-threshold=N` | bytes | 100 |
|
|
58
77
|
|
|
59
78
|
```ruby
|
|
60
|
-
generating: {
|
|
79
|
+
generating: { zlib_level: 9 } # max zlib
|
|
80
|
+
generating: { uncompressed: true } # legal per WOFF 1.0 §5.1
|
|
61
81
|
```
|
|
62
82
|
|
|
63
|
-
|
|
83
|
+
### WOFF2 (Brotli)
|
|
64
84
|
|
|
65
|
-
|
|
85
|
+
| Option | CLI | Range | Default |
|
|
86
|
+
|--------|-----|-------|---------|
|
|
87
|
+
| `brotli_quality` | `--brotli-quality=N` | 0–11 | 11 |
|
|
88
|
+
| `transform_tables` | `--[no-]transform-tables` | bool | false |
|
|
66
89
|
|
|
67
90
|
```ruby
|
|
68
|
-
generating: {
|
|
91
|
+
generating: { brotli_quality: 11, transform_tables: true }
|
|
69
92
|
```
|
|
70
93
|
|
|
71
|
-
|
|
94
|
+
Cross-format misuse (e.g. `brotli_quality` on `:woff`) raises
|
|
95
|
+
`ArgumentError` from `FormatConverter.validate_options_for_target!`.
|
|
72
96
|
|
|
73
97
|
## Table Transforms
|
|
74
98
|
|
|
@@ -110,6 +134,6 @@ fontisan convert font.woff2 --to otf --output font.otf
|
|
|
110
134
|
## Best Practices
|
|
111
135
|
|
|
112
136
|
1. **Use WOFF2 primarily** — Best compression
|
|
113
|
-
2. **Provide WOFF fallback** — For older browsers
|
|
137
|
+
2. **Provide WOFF fallback** — For older browsers (IE 9+)
|
|
114
138
|
3. **Keep original** — For editing
|
|
115
139
|
4. **Preserve metadata** — Unless stripping for size
|
data/docs/guide/index.md
CHANGED
|
@@ -86,7 +86,7 @@ puts tables.keys
|
|
|
86
86
|
|
|
87
87
|
```ruby
|
|
88
88
|
# Simple conversion
|
|
89
|
-
Fontisan.convert('input.ttf',
|
|
89
|
+
Fontisan.convert('input.ttf', to: :woff2, output: 'output.woff2')
|
|
90
90
|
|
|
91
91
|
# With custom options
|
|
92
92
|
options = Fontisan::ConversionOptions.new(
|
|
@@ -94,7 +94,7 @@ options = Fontisan::ConversionOptions.new(
|
|
|
94
94
|
to: :otf,
|
|
95
95
|
opening: { autohint: true, convert_curves: true }
|
|
96
96
|
)
|
|
97
|
-
Fontisan.convert('input.ttf',
|
|
97
|
+
Fontisan.convert('input.ttf', to: :otf, output: 'output.otf', options: options)
|
|
98
98
|
```
|
|
99
99
|
|
|
100
100
|
### Validate Fonts
|
|
@@ -246,7 +246,7 @@ fontisan maintains 100% backward compatibility:
|
|
|
246
246
|
|
|
247
247
|
= ExtractTTC to Fontisan Migration Guide
|
|
248
248
|
|
|
249
|
-
This guide helps users migrate from https://github.com/fontist/extract_ttc
|
|
249
|
+
This guide helps users migrate from [ExtractTTC](https://github.com/fontist/extract_ttc) to Fontisan.
|
|
250
250
|
|
|
251
251
|
Fontisan provides complete compatibility with all ExtractTTC functionality while adding comprehensive font analysis, subsetting, validation, and format conversion capabilities.
|
|
252
252
|
|
data/docs/guide/quick-start.md
CHANGED
|
@@ -70,13 +70,13 @@ fontisan info font.ttf --format json
|
|
|
70
70
|
|
|
71
71
|
```ruby
|
|
72
72
|
# TTF to OTF
|
|
73
|
-
Fontisan.convert('input.ttf',
|
|
73
|
+
Fontisan.convert('input.ttf', to: :otf, output: 'output.otf')
|
|
74
74
|
|
|
75
75
|
# OTF to WOFF2
|
|
76
|
-
Fontisan.convert('input.otf',
|
|
76
|
+
Fontisan.convert('input.otf', to: :woff2, output: 'output.woff2')
|
|
77
77
|
|
|
78
78
|
# Type 1 to OTF
|
|
79
|
-
Fontisan.convert('input.pfb',
|
|
79
|
+
Fontisan.convert('input.pfb', to: :otf, output: 'output.otf')
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
### With Options
|
|
@@ -89,7 +89,7 @@ options = Fontisan::ConversionOptions.new(
|
|
|
89
89
|
generating: { hinting_mode: 'auto' }
|
|
90
90
|
)
|
|
91
91
|
|
|
92
|
-
Fontisan.convert('input.ttf',
|
|
92
|
+
Fontisan.convert('input.ttf', to: :otf, output: 'output.otf', options: options)
|
|
93
93
|
```
|
|
94
94
|
|
|
95
95
|
### Using CLI
|
data/docs/guide/type1.md
CHANGED
|
@@ -28,13 +28,13 @@ puts font.num_glyphs
|
|
|
28
28
|
|
|
29
29
|
```ruby
|
|
30
30
|
# Convert to TrueType
|
|
31
|
-
Fontisan.convert('font.pfb',
|
|
31
|
+
Fontisan.convert('font.pfb', to: :ttf, output: 'font.ttf')
|
|
32
32
|
|
|
33
33
|
# Convert to OpenType
|
|
34
|
-
Fontisan.convert('font.pfb',
|
|
34
|
+
Fontisan.convert('font.pfb', to: :otf, output: 'font.otf')
|
|
35
35
|
|
|
36
36
|
# Convert to WOFF2
|
|
37
|
-
Fontisan.convert('font.pfb',
|
|
37
|
+
Fontisan.convert('font.pfb', to: :woff2, output: 'font.woff2')
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
## Handling Encodings
|
|
@@ -55,4 +55,4 @@ end
|
|
|
55
55
|
|
|
56
56
|
## Related
|
|
57
57
|
|
|
58
|
-
- [Font Conversion](/guide/conversion) - General conversion guide
|
|
58
|
+
- [Font Conversion](/guide/conversion/) - General conversion guide
|
data/docs/guide/woff.md
CHANGED
|
@@ -9,41 +9,42 @@ WOFF and WOFF2 are web font formats optimized for use on websites:
|
|
|
9
9
|
- **WOFF** - Compressed version of TrueType/OpenType with metadata support
|
|
10
10
|
- **WOFF2** - Improved compression using Brotli algorithm (typically 30% smaller than WOFF)
|
|
11
11
|
|
|
12
|
+
The format you pick (`--to woff` vs `--to woff2`) **is** the algorithm
|
|
13
|
+
choice: WOFF mandates zlib, WOFF2 mandates Brotli. Each format exposes
|
|
14
|
+
its algorithm's parameters (level, quality, transform) rather than
|
|
15
|
+
offering a separate algorithm selector.
|
|
16
|
+
|
|
12
17
|
## Converting to WOFF
|
|
13
18
|
|
|
14
19
|
```ruby
|
|
15
20
|
require 'fontisan'
|
|
16
21
|
|
|
17
|
-
# Convert to WOFF
|
|
18
|
-
Fontisan.convert('font.ttf',
|
|
22
|
+
# Convert to WOFF (max zlib for legacy browser reach)
|
|
23
|
+
Fontisan.convert('font.ttf', to: :woff, output: 'font.woff', zlib_level: 9)
|
|
19
24
|
|
|
20
|
-
# Convert to WOFF2 (recommended for
|
|
21
|
-
Fontisan.convert('font.ttf',
|
|
25
|
+
# Convert to WOFF2 (recommended for modern browsers)
|
|
26
|
+
Fontisan.convert('font.ttf', to: :woff2, output: 'font.woff2',
|
|
27
|
+
brotli_quality: 11, transform_tables: true)
|
|
22
28
|
```
|
|
23
29
|
|
|
24
30
|
## Metadata
|
|
25
31
|
|
|
26
|
-
WOFF files can
|
|
32
|
+
WOFF files can carry an extended metadata block:
|
|
27
33
|
|
|
28
34
|
```ruby
|
|
29
|
-
# Add metadata when converting
|
|
35
|
+
# Add WOFF metadata when converting
|
|
30
36
|
Fontisan.convert('font.ttf',
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
license: 'OFL',
|
|
35
|
-
license_url: 'https://scripts.sil.org/OFL',
|
|
36
|
-
description: 'My custom font'
|
|
37
|
-
}
|
|
38
|
-
)
|
|
37
|
+
to: :woff,
|
|
38
|
+
output: 'font.woff',
|
|
39
|
+
metadata_xml: '<metadata>...</metadata>')
|
|
39
40
|
```
|
|
40
41
|
|
|
41
42
|
## Extracting from WOFF
|
|
42
43
|
|
|
43
44
|
```ruby
|
|
44
45
|
# Extract original font from WOFF
|
|
45
|
-
Fontisan.convert('font.woff',
|
|
46
|
-
Fontisan.convert('font.woff2',
|
|
46
|
+
Fontisan.convert('font.woff', to: :ttf, output: 'font.ttf')
|
|
47
|
+
Fontisan.convert('font.woff2', to: :otf, output: 'font.otf')
|
|
47
48
|
```
|
|
48
49
|
|
|
49
50
|
## Compression Comparison
|
|
@@ -56,4 +57,5 @@ Fontisan.convert('font.woff2', output_format: :otf)
|
|
|
56
57
|
|
|
57
58
|
## Related
|
|
58
59
|
|
|
59
|
-
- [Font
|
|
60
|
+
- [Web Font Formats](/guide/conversion/web) - Detailed WOFF/WOFF2 guide with all compression knobs
|
|
61
|
+
- [Font Conversion](/guide/conversion/) - General conversion guide
|
data/docs/index.md
CHANGED
|
@@ -18,6 +18,8 @@ hero:
|
|
|
18
18
|
link: /guide/migrations/fonttools
|
|
19
19
|
|
|
20
20
|
features:
|
|
21
|
+
- title: "🔍 Font Audit"
|
|
22
|
+
details: Comprehensive per-face audit (replaces otfinfo) — identity, style, metrics, coverage, licensing, hinting, color, variation, OpenType layout, UCD/CLDR aggregation, compare, and library-summary modes.
|
|
21
23
|
- title: "🔄 Font Conversion"
|
|
22
24
|
details: Convert between TTF, OTF, WOFF, WOFF2, Type 1 (PFB/PFA), and SVG formats with curve conversion and optimization.
|
|
23
25
|
- title: "✅ Font Validation"
|
data/docs/lychee.toml
CHANGED
|
@@ -23,7 +23,11 @@ include_verbatim = true
|
|
|
23
23
|
# Exclude URLs (regex patterns)
|
|
24
24
|
exclude = [
|
|
25
25
|
'github\.com/fontist/fontisan/issues',
|
|
26
|
-
'github\.com/
|
|
26
|
+
'github\.com/extract_ttc',
|
|
27
|
+
# Exclude internal /fontisan/ links — these are deployment base paths that
|
|
28
|
+
# resolve correctly when deployed but fail lychee's local file:// checks
|
|
29
|
+
# (the built HTML has /fontisan/<path>; the file lives at dist/<path>).
|
|
30
|
+
'^file://.*/fontisan/',
|
|
27
31
|
]
|
|
28
32
|
|
|
29
33
|
# Exclude paths from checking (regex patterns)
|
data/docs/package.json
CHANGED