fontisan 0.2.12 → 0.2.13
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 +185 -106
- data/Gemfile +5 -0
- data/README.adoc +3 -2
- data/docs/CONVERSION_GUIDE.adoc +633 -0
- data/docs/TYPE1_FONTS.adoc +445 -0
- data/lib/fontisan/commands/info_command.rb +83 -2
- data/lib/fontisan/converters/format_converter.rb +15 -5
- data/lib/fontisan/converters/type1_converter.rb +734 -59
- data/lib/fontisan/font_loader.rb +1 -1
- data/lib/fontisan/hints/hint_converter.rb +4 -1
- data/lib/fontisan/type1/cff_to_type1_converter.rb +302 -0
- data/lib/fontisan/type1/font_dictionary.rb +62 -0
- data/lib/fontisan/type1/pfa_generator.rb +31 -5
- data/lib/fontisan/type1/pfa_parser.rb +31 -30
- data/lib/fontisan/type1/pfb_generator.rb +28 -5
- data/lib/fontisan/type1/private_dict.rb +57 -0
- data/lib/fontisan/type1/seac_expander.rb +501 -0
- data/lib/fontisan/type1.rb +2 -0
- data/lib/fontisan/type1_font.rb +21 -34
- data/lib/fontisan/version.rb +1 -1
- metadata +6 -3
- data/docs/DOCUMENTATION_SUMMARY.md +0 -141
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
= Font Conversion Guide
|
|
2
|
+
|
|
3
|
+
This guide provides comprehensive reference for Fontisan's conversion options system, including all supported formats, options, and best practices.
|
|
4
|
+
|
|
5
|
+
== Overview
|
|
6
|
+
|
|
7
|
+
Fontisan's conversion system is based on the TypeTool 3 manual's recommended options for different font format conversions. The system provides:
|
|
8
|
+
|
|
9
|
+
* Type-safe option validation
|
|
10
|
+
* Format-specific default options
|
|
11
|
+
* Named presets for common workflows
|
|
12
|
+
* Fine-grained control over conversion behavior
|
|
13
|
+
|
|
14
|
+
== Quick Reference
|
|
15
|
+
|
|
16
|
+
=== Using the CLI
|
|
17
|
+
|
|
18
|
+
[source,shell]
|
|
19
|
+
----
|
|
20
|
+
# Basic conversion
|
|
21
|
+
fontisan convert input.ttf --to otf --output output.otf
|
|
22
|
+
|
|
23
|
+
# Show recommended options
|
|
24
|
+
fontisan convert input.ttf --to otf --show-options
|
|
25
|
+
|
|
26
|
+
# Use a preset
|
|
27
|
+
fontisan convert font.pfb --to otf --preset type1_to_modern --output output.otf
|
|
28
|
+
|
|
29
|
+
# Custom options
|
|
30
|
+
fontisan convert input.ttf --to otf --autohint --hinting-mode auto --output output.otf
|
|
31
|
+
----
|
|
32
|
+
|
|
33
|
+
=== Using the API
|
|
34
|
+
|
|
35
|
+
[source,ruby]
|
|
36
|
+
----
|
|
37
|
+
require 'fontisan'
|
|
38
|
+
|
|
39
|
+
# Get recommended options
|
|
40
|
+
options = Fontisan::ConversionOptions.recommended(from: :ttf, to: :otf)
|
|
41
|
+
|
|
42
|
+
# Use a preset
|
|
43
|
+
options = Fontisan::ConversionOptions.from_preset(:web_optimized)
|
|
44
|
+
|
|
45
|
+
# Build custom options
|
|
46
|
+
options = Fontisan::ConversionOptions.new(
|
|
47
|
+
from: :ttf,
|
|
48
|
+
to: :otf,
|
|
49
|
+
opening: { autohint: true, convert_curves: true },
|
|
50
|
+
generating: { hinting_mode: "auto" }
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# Convert with options
|
|
54
|
+
converter = Fontisan::Converters::OutlineConverter.new
|
|
55
|
+
tables = converter.convert(font, options: options)
|
|
56
|
+
----
|
|
57
|
+
|
|
58
|
+
== Supported Formats
|
|
59
|
+
|
|
60
|
+
=== Input Formats
|
|
61
|
+
|
|
62
|
+
| Format | Description | Extensions |
|
|
63
|
+
|--------|-------------|------------|
|
|
64
|
+
| TTF | TrueType Font | .ttf |
|
|
65
|
+
| OTF | OpenType/CFF Font | .otf |
|
|
66
|
+
| Type 1 | Adobe Type 1 Font | .pfb, .pfa |
|
|
67
|
+
| TTC | TrueType Collection | .ttc |
|
|
68
|
+
| OTC | OpenType Collection | .otc |
|
|
69
|
+
| dfont | Apple Data Fork Font | .dfont |
|
|
70
|
+
| WOFF | Web Open Font Format | .woff |
|
|
71
|
+
| WOFF2 | Web Open Font Format 2 | .woff2 |
|
|
72
|
+
| SVG | SVG Font | .svg |
|
|
73
|
+
|
|
74
|
+
=== Output Formats
|
|
75
|
+
|
|
76
|
+
All input formats can be converted to: TTF, OTF, WOFF, WOFF2
|
|
77
|
+
|
|
78
|
+
Collections (TTC, OTC, dfont) can be converted between each other.
|
|
79
|
+
|
|
80
|
+
== Conversion Options
|
|
81
|
+
|
|
82
|
+
=== Opening Options
|
|
83
|
+
|
|
84
|
+
Opening options control how the source font is read and processed.
|
|
85
|
+
|
|
86
|
+
| Option | Type | Description | Use Case |
|
|
87
|
+
|--------|------|-------------|----------|
|
|
88
|
+
| `decompose_composites` | Boolean | Decompose composite glyphs into simple glyphs | When target format doesn't support composites |
|
|
89
|
+
| `convert_curves` | Boolean | Convert curve types during conversion | When converting between quadratic/cubic curves |
|
|
90
|
+
| `scale_to_1000` | Boolean | Scale UPM to 1000 | Type 1 → OTF conversions |
|
|
91
|
+
| `scale_from_1000` | Boolean | Scale from 1000 UPM | OTF → TTF conversions |
|
|
92
|
+
| `autohint` | Boolean | Auto-hint the font | When source lacks hints or hints are incompatible |
|
|
93
|
+
| `generate_unicode` | Boolean | Generate Unicode mappings from glyph names | Type 1 conversions |
|
|
94
|
+
| `store_custom_tables` | Boolean | Preserve non-standard tables | When custom tables need preservation |
|
|
95
|
+
| `store_native_hinting` | Boolean | Preserve native hinting data | When hints should be preserved for source format |
|
|
96
|
+
| `interpret_ot` | Boolean | Interpret OpenType layout features | When GSUB/GPOS features need processing |
|
|
97
|
+
| `read_all_records` | Boolean | Load all font dictionary records | Type 1 conversions with custom data |
|
|
98
|
+
| `preserve_encoding` | String | Preserve specific character encoding | When custom encoding must be maintained |
|
|
99
|
+
|
|
100
|
+
=== Generating Options
|
|
101
|
+
|
|
102
|
+
Generating options control how the output font is written.
|
|
103
|
+
|
|
104
|
+
| Option | Type | Description | Use Case |
|
|
105
|
+
|--------|------|-------------|----------|
|
|
106
|
+
| `write_pfm` | Boolean | Write PFM file | Type 1 output |
|
|
107
|
+
| `write_afm` | Boolean | Write AFM file | Type 1 output |
|
|
108
|
+
| `write_inf` | Boolean | Write INF file | Type 1 output |
|
|
109
|
+
| `select_encoding_automatically` | Boolean | Auto-select encoding | Type 1 output |
|
|
110
|
+
| `hinting_mode` | String | Hint mode: preserve, auto, none, full | Control hinting behavior |
|
|
111
|
+
| `decompose_on_output` | Boolean | Decompose composites in output | When target doesn't support composites |
|
|
112
|
+
| `write_custom_tables` | Boolean | Write custom tables | Preserve non-standard tables |
|
|
113
|
+
| `optimize_tables` | Boolean | Enable table optimization | Reduce file size |
|
|
114
|
+
| `reencode_first_256` | Boolean | Reencode first 256 glyphs | Type 1 output |
|
|
115
|
+
| `encoding_vector` | String | Custom encoding vector | Type 1 output |
|
|
116
|
+
| `compression` | String | Compression: zlib, brotli, none | Web font output |
|
|
117
|
+
| `transform_tables` | Boolean | Transform tables for output | Format-specific transformations |
|
|
118
|
+
| `preserve_metadata` | Boolean | Preserve copyright/license metadata | Maintain font metadata |
|
|
119
|
+
| `strip_metadata` | Boolean | Remove metadata | Reduce file size |
|
|
120
|
+
| `target_format` | String | Collection target format | Collection conversions |
|
|
121
|
+
|
|
122
|
+
=== CLI Option Mapping
|
|
123
|
+
|
|
124
|
+
==== Opening Options
|
|
125
|
+
|
|
126
|
+
[source,shell]
|
|
127
|
+
----
|
|
128
|
+
# Decompose composite glyphs
|
|
129
|
+
--decompose # Enable decomposition
|
|
130
|
+
--no-decompose # Preserve composite glyphs
|
|
131
|
+
|
|
132
|
+
# Curve conversion
|
|
133
|
+
--convert-curves # Convert curve types (quadratic ↔ cubic)
|
|
134
|
+
|
|
135
|
+
# UPM scaling
|
|
136
|
+
--scale-to-1000 # Scale to 1000 UPM (Type 1 standard)
|
|
137
|
+
--scale-from-1000 # Scale from 1000 UPM to target
|
|
138
|
+
|
|
139
|
+
# Hinting
|
|
140
|
+
--autohint # Apply automatic hinting
|
|
141
|
+
|
|
142
|
+
# Unicode and encoding
|
|
143
|
+
--generate-unicode # Generate Unicode from glyph names
|
|
144
|
+
--preserve-encoding # Preserve character encoding
|
|
145
|
+
|
|
146
|
+
# Table handling
|
|
147
|
+
--preserve-custom-tables # Preserve non-standard tables
|
|
148
|
+
--interpret-ot # Interpret OpenType tables (GSUB/GPOS)
|
|
149
|
+
----
|
|
150
|
+
|
|
151
|
+
==== Generating Options
|
|
152
|
+
|
|
153
|
+
[source,shell]
|
|
154
|
+
----
|
|
155
|
+
# Type 1 metrics files
|
|
156
|
+
--write-pfm # Generate PFM file
|
|
157
|
+
--write-afm # Generate AFM file
|
|
158
|
+
--write-inf # Generate INF file
|
|
159
|
+
|
|
160
|
+
# Encoding
|
|
161
|
+
--auto-encoding # Auto-detect encoding
|
|
162
|
+
--encoding VECTOR # Use specific encoding vector
|
|
163
|
+
|
|
164
|
+
# Hinting
|
|
165
|
+
--hinting-mode MODE # preserve|auto|none|full
|
|
166
|
+
|
|
167
|
+
# Optimization
|
|
168
|
+
--optimize-tables # Enable table optimization
|
|
169
|
+
--no-optimization # Disable optimization
|
|
170
|
+
|
|
171
|
+
# Metadata
|
|
172
|
+
--preserve-metadata # Preserve copyright/license info
|
|
173
|
+
--strip-metadata # Remove metadata
|
|
174
|
+
|
|
175
|
+
# Collections
|
|
176
|
+
--target-format FORMAT # ttf|otf|preserve for collections
|
|
177
|
+
----
|
|
178
|
+
|
|
179
|
+
==== Preset Option
|
|
180
|
+
|
|
181
|
+
[source,shell]
|
|
182
|
+
----
|
|
183
|
+
# Use named preset
|
|
184
|
+
--preset NAME # type1_to_modern, modern_to_type1, web_optimized, archive_to_modern
|
|
185
|
+
----
|
|
186
|
+
|
|
187
|
+
== Conversion Matrix
|
|
188
|
+
|
|
189
|
+
=== Same-Format Conversions
|
|
190
|
+
|
|
191
|
+
==== TTF → TTF
|
|
192
|
+
|
|
193
|
+
Use case: Copy with optimization, metadata updates
|
|
194
|
+
|
|
195
|
+
[source,ruby]
|
|
196
|
+
----
|
|
197
|
+
Fontisan::ConversionOptions.recommended(from: :ttf, to: :ttf)
|
|
198
|
+
# opening: { convert_curves: false, scale_to_1000: false,
|
|
199
|
+
# decompose_composites: false, autohint: false,
|
|
200
|
+
# store_custom_tables: true, store_native_hinting: true }
|
|
201
|
+
# generating: { hinting_mode: "preserve", write_custom_tables: true,
|
|
202
|
+
# optimize_tables: true }
|
|
203
|
+
----
|
|
204
|
+
|
|
205
|
+
Notes: Same-format copy preserves all data. Optimization includes table reordering and checksum correction.
|
|
206
|
+
|
|
207
|
+
==== OTF → OTF
|
|
208
|
+
|
|
209
|
+
Use case: Copy with optimization, metadata updates
|
|
210
|
+
|
|
211
|
+
[source,ruby]
|
|
212
|
+
----
|
|
213
|
+
Fontisan::ConversionOptions.recommended(from: :otf, to: :otf)
|
|
214
|
+
# opening: { decompose_composites: false, store_custom_tables: true,
|
|
215
|
+
# interpret_ot: true }
|
|
216
|
+
# generating: { hinting_mode: "preserve", decompose_on_output: false,
|
|
217
|
+
# write_custom_tables: true, optimize_tables: true }
|
|
218
|
+
----
|
|
219
|
+
|
|
220
|
+
Notes: CFF-based OTF requires different handling than TTF.
|
|
221
|
+
|
|
222
|
+
=== TTF → OTF
|
|
223
|
+
|
|
224
|
+
Recommended options:
|
|
225
|
+
|
|
226
|
+
[source,ruby]
|
|
227
|
+
----
|
|
228
|
+
Fontisan::ConversionOptions.recommended(from: :ttf, to: :otf)
|
|
229
|
+
# Returns:
|
|
230
|
+
# opening: { convert_curves: true, scale_to_1000: true, autohint: true,
|
|
231
|
+
# decompose_composites: false, store_custom_tables: true }
|
|
232
|
+
# generating: { hinting_mode: "auto", decompose_on_output: true }
|
|
233
|
+
----
|
|
234
|
+
|
|
235
|
+
Key considerations:
|
|
236
|
+
|
|
237
|
+
* Curve conversion: Quadratic → Cubic (mathematically exact, but may increase point count)
|
|
238
|
+
* Hinting: TrueType instructions → CFF hints (lossy conversion)
|
|
239
|
+
* Scaling: Typically 2048 UPM → 1000 UPM
|
|
240
|
+
|
|
241
|
+
Limitations:
|
|
242
|
+
|
|
243
|
+
* TrueType hinting instructions are NOT converted to CFF hints
|
|
244
|
+
* GSUB/GPOS features preserved but table format changes
|
|
245
|
+
|
|
246
|
+
=== OTF → TTF
|
|
247
|
+
|
|
248
|
+
Recommended options:
|
|
249
|
+
|
|
250
|
+
[source,ruby]
|
|
251
|
+
----
|
|
252
|
+
Fontisan::ConversionOptions.recommended(from: :otf, to: :ttf)
|
|
253
|
+
# Returns:
|
|
254
|
+
# opening: { decompose_composites: false, read_all_records: true,
|
|
255
|
+
# interpret_ot: true, store_custom_tables: true,
|
|
256
|
+
# store_native_hinting: false }
|
|
257
|
+
# generating: { hinting_mode: "full", reencode_first_256: false }
|
|
258
|
+
----
|
|
259
|
+
|
|
260
|
+
Key considerations:
|
|
261
|
+
|
|
262
|
+
* Curve conversion: Cubic → Quadratic (requires approximation)
|
|
263
|
+
* Hinting: CFF hints → TrueType instructions (lossy conversion)
|
|
264
|
+
* OpenType features: Interpreted before conversion
|
|
265
|
+
|
|
266
|
+
Limitations:
|
|
267
|
+
|
|
268
|
+
* CFF cubic curves must be approximated as TrueType quadratic curves
|
|
269
|
+
* Multiple quadratic curves may be needed for accuracy
|
|
270
|
+
* Some precision loss in curve approximation is unavoidable
|
|
271
|
+
|
|
272
|
+
=== Type 1 Conversions
|
|
273
|
+
|
|
274
|
+
==== Type 1 → OTF
|
|
275
|
+
|
|
276
|
+
Recommended options:
|
|
277
|
+
|
|
278
|
+
[source,ruby]
|
|
279
|
+
----
|
|
280
|
+
Fontisan::ConversionOptions.recommended(from: :type1, to: :otf)
|
|
281
|
+
# Returns:
|
|
282
|
+
# opening: { decompose_composites: false, generate_unicode: true }
|
|
283
|
+
# generating: { hinting_mode: "none", decompose_on_output: true }
|
|
284
|
+
----
|
|
285
|
+
|
|
286
|
+
Key considerations:
|
|
287
|
+
|
|
288
|
+
* Unicode: Generated from Adobe Glyph List
|
|
289
|
+
* CharStrings: Type 1 → CFF format (direct conversion)
|
|
290
|
+
* Hinting: PostScript hints preserved in CFF
|
|
291
|
+
* seac composites: Must be expanded (CFF doesn't support seac)
|
|
292
|
+
|
|
293
|
+
==== Type 1 → TTF
|
|
294
|
+
|
|
295
|
+
Recommended options:
|
|
296
|
+
|
|
297
|
+
[source,ruby]
|
|
298
|
+
----
|
|
299
|
+
Fontisan::ConversionOptions.recommended(from: :type1, to: :ttf)
|
|
300
|
+
# Returns:
|
|
301
|
+
# opening: { decompose_composites: false, generate_unicode: true }
|
|
302
|
+
# generating: { hinting_mode: "full" }
|
|
303
|
+
----
|
|
304
|
+
|
|
305
|
+
Workflow: Type 1 → CFF (OTF) → TTF
|
|
306
|
+
|
|
307
|
+
Key considerations:
|
|
308
|
+
|
|
309
|
+
* Two-step conversion compounds approximation errors
|
|
310
|
+
* Curve conversion: CFF cubic → TrueType quadratic
|
|
311
|
+
* Unicode: Generated from glyph names
|
|
312
|
+
|
|
313
|
+
==== Type 1 → Type 1 (Copy)
|
|
314
|
+
|
|
315
|
+
Use case: Re-encode Type 1 font, regenerate metrics
|
|
316
|
+
|
|
317
|
+
[source,ruby]
|
|
318
|
+
----
|
|
319
|
+
Fontisan::ConversionOptions.recommended(from: :type1, to: :type1)
|
|
320
|
+
# opening: { decompose_composites: false, generate_unicode: true }
|
|
321
|
+
# generating: { write_pfm: true, write_afm: true, write_inf: true,
|
|
322
|
+
# select_encoding_automatically: true, hinting_mode: "preserve" }
|
|
323
|
+
----
|
|
324
|
+
|
|
325
|
+
==== OTF → Type 1
|
|
326
|
+
|
|
327
|
+
Use case: Generate Type 1 from OpenType for legacy workflows
|
|
328
|
+
|
|
329
|
+
[source,ruby]
|
|
330
|
+
----
|
|
331
|
+
Fontisan::ConversionOptions.recommended(from: :otf, to: :type1)
|
|
332
|
+
# opening: { decompose_composites: false }
|
|
333
|
+
# generating: { write_pfm: true, write_afm: true, write_inf: true,
|
|
334
|
+
# select_encoding_automatically: true, hinting_mode: "preserve",
|
|
335
|
+
# decompose_on_output: false }
|
|
336
|
+
----
|
|
337
|
+
|
|
338
|
+
Limitations:
|
|
339
|
+
|
|
340
|
+
* Reverse conversion from CFF to Type 1
|
|
341
|
+
* Modern OpenType features (GPOS, GSUB variations) lost in Type 1
|
|
342
|
+
* CFF hints may not translate exactly to Type 1 hints
|
|
343
|
+
|
|
344
|
+
=== Collection Conversions
|
|
345
|
+
|
|
346
|
+
==== TTC → OTC
|
|
347
|
+
|
|
348
|
+
[source,ruby]
|
|
349
|
+
----
|
|
350
|
+
Fontisan::ConversionOptions.recommended(from: :ttc, to: :otc)
|
|
351
|
+
# opening: { convert_curves: true, decompose_composites: false, autohint: false }
|
|
352
|
+
# generating: { target_format: "otf", decompose_on_output: false,
|
|
353
|
+
# hinting_mode: "preserve" }
|
|
354
|
+
----
|
|
355
|
+
|
|
356
|
+
Converts all TrueType fonts to OpenType/CFF, then repacks as OTC.
|
|
357
|
+
|
|
358
|
+
==== OTC → TTC
|
|
359
|
+
|
|
360
|
+
[source,ruby]
|
|
361
|
+
----
|
|
362
|
+
Fontisan::ConversionOptions.recommended(from: :otc, to: :ttc)
|
|
363
|
+
# opening: { convert_curves: true, decompose_composites: false, interpret_ot: true }
|
|
364
|
+
# generating: { target_format: "ttf", decompose_on_output: false,
|
|
365
|
+
# hinting_mode: "auto" }
|
|
366
|
+
----
|
|
367
|
+
|
|
368
|
+
Converts all OpenType/CFF fonts to TrueType, then repacks as TTC.
|
|
369
|
+
|
|
370
|
+
==== TTC/OTC → dfont
|
|
371
|
+
|
|
372
|
+
[source,ruby]
|
|
373
|
+
----
|
|
374
|
+
Fontisan::ConversionOptions.recommended(from: :ttc, to: :dfont)
|
|
375
|
+
# opening: {}
|
|
376
|
+
# generating: { target_format: "preserve", decompose_on_output: false,
|
|
377
|
+
# write_custom_tables: true }
|
|
378
|
+
----
|
|
379
|
+
|
|
380
|
+
Notes: dfont supports both TrueType and OpenType/CFF, or mixed formats.
|
|
381
|
+
|
|
382
|
+
=== Web Font Conversions
|
|
383
|
+
|
|
384
|
+
==== TTF/OTF → WOFF2
|
|
385
|
+
|
|
386
|
+
[source,ruby]
|
|
387
|
+
----
|
|
388
|
+
Fontisan::ConversionOptions.from_preset(:web_optimized)
|
|
389
|
+
# From: :otf, To: :woff2
|
|
390
|
+
# opening: {}
|
|
391
|
+
# generating: { compression: "brotli", transform_tables: true,
|
|
392
|
+
# optimize_tables: true, preserve_metadata: true }
|
|
393
|
+
----
|
|
394
|
+
|
|
395
|
+
Benefits: 30-50% smaller than TTF/OTF
|
|
396
|
+
|
|
397
|
+
==== TTF/OTF → WOFF
|
|
398
|
+
|
|
399
|
+
[source,ruby]
|
|
400
|
+
----
|
|
401
|
+
# generating: { compression: "zlib", preserve_metadata: true,
|
|
402
|
+
# add_private_data: false }
|
|
403
|
+
----
|
|
404
|
+
|
|
405
|
+
==== Type 1 → WOFF/WOFF2
|
|
406
|
+
|
|
407
|
+
Workflow: Type 1 → OTF → WOFF2
|
|
408
|
+
|
|
409
|
+
[source,ruby]
|
|
410
|
+
----
|
|
411
|
+
# Via OTF intermediate
|
|
412
|
+
# opening: { decompose_composites: false, generate_unicode: true }
|
|
413
|
+
# generating: { compression: "brotli" } # WOFF2
|
|
414
|
+
# OR compression: "zlib" # WOFF
|
|
415
|
+
----
|
|
416
|
+
|
|
417
|
+
=== SVG Font Generation
|
|
418
|
+
|
|
419
|
+
==== TTF/OTF → SVG
|
|
420
|
+
|
|
421
|
+
[source,ruby]
|
|
422
|
+
----
|
|
423
|
+
# opening: {}
|
|
424
|
+
# generating: { include_metadata: true, include_unicode: true }
|
|
425
|
+
----
|
|
426
|
+
|
|
427
|
+
Limitations:
|
|
428
|
+
|
|
429
|
+
* SVG fonts deprecated in favor of WOFF2
|
|
430
|
+
* No hinting information
|
|
431
|
+
* No advanced layout features
|
|
432
|
+
|
|
433
|
+
== Presets
|
|
434
|
+
|
|
435
|
+
=== type1_to_modern
|
|
436
|
+
|
|
437
|
+
Optimize Type 1 fonts for modern use:
|
|
438
|
+
|
|
439
|
+
[source,ruby]
|
|
440
|
+
----
|
|
441
|
+
Fontisan::ConversionOptions.from_preset(:type1_to_modern)
|
|
442
|
+
# From: :type1, To: :otf
|
|
443
|
+
# opening: { generate_unicode: true, decompose_composites: false }
|
|
444
|
+
# generating: { hinting_mode: "preserve", decompose_on_output: true }
|
|
445
|
+
----
|
|
446
|
+
|
|
447
|
+
Use cases:
|
|
448
|
+
|
|
449
|
+
* Modernizing legacy Type 1 fonts
|
|
450
|
+
* Preparing fonts for web use
|
|
451
|
+
* Converting fonts for modern applications
|
|
452
|
+
|
|
453
|
+
=== modern_to_type1
|
|
454
|
+
|
|
455
|
+
Convert modern fonts back to Type 1:
|
|
456
|
+
|
|
457
|
+
[source,ruby]
|
|
458
|
+
----
|
|
459
|
+
Fontisan::ConversionOptions.from_preset(:modern_to_type1)
|
|
460
|
+
# From: :otf, To: :type1
|
|
461
|
+
# opening: { convert_curves: true, scale_to_1000: true,
|
|
462
|
+
# autohint: true, decompose_composites: false,
|
|
463
|
+
# store_custom_tables: false }
|
|
464
|
+
# generating: { write_pfm: true, write_afm: true, write_inf: true,
|
|
465
|
+
# select_encoding_automatically: true,
|
|
466
|
+
# hinting_mode: "preserve" }
|
|
467
|
+
----
|
|
468
|
+
|
|
469
|
+
Use cases:
|
|
470
|
+
|
|
471
|
+
* Legacy system compatibility
|
|
472
|
+
* Font distribution for older applications
|
|
473
|
+
* Working with Type 1 workflows
|
|
474
|
+
|
|
475
|
+
=== web_optimized
|
|
476
|
+
|
|
477
|
+
Optimize fonts for web delivery:
|
|
478
|
+
|
|
479
|
+
[source,ruby]
|
|
480
|
+
----
|
|
481
|
+
Fontisan::ConversionOptions.from_preset(:web_optimized)
|
|
482
|
+
# From: :otf, To: :woff2
|
|
483
|
+
# opening: {}
|
|
484
|
+
# generating: { compression: "brotli", transform_tables: true,
|
|
485
|
+
# optimize_tables: true, preserve_metadata: true }
|
|
486
|
+
----
|
|
487
|
+
|
|
488
|
+
Use cases:
|
|
489
|
+
|
|
490
|
+
* Web font delivery
|
|
491
|
+
* Reducing page load time
|
|
492
|
+
* Bandwidth optimization
|
|
493
|
+
|
|
494
|
+
=== archive_to_modern
|
|
495
|
+
|
|
496
|
+
Convert font archives to modern format:
|
|
497
|
+
|
|
498
|
+
[source,ruby]
|
|
499
|
+
----
|
|
500
|
+
Fontisan::ConversionOptions.from_preset(:archive_to_modern)
|
|
501
|
+
# From: :ttc, To: :otf
|
|
502
|
+
# opening: { convert_curves: true, decompose_composites: false }
|
|
503
|
+
# generating: { target_format: "otf", hinting_mode: "preserve" }
|
|
504
|
+
----
|
|
505
|
+
|
|
506
|
+
Use cases:
|
|
507
|
+
|
|
508
|
+
* Extracting fonts from TTC archives
|
|
509
|
+
* Standardizing collection formats
|
|
510
|
+
* Converting legacy font collections
|
|
511
|
+
|
|
512
|
+
== Hinting Modes
|
|
513
|
+
|
|
514
|
+
=== preserve
|
|
515
|
+
|
|
516
|
+
Preserve original hinting data when possible:
|
|
517
|
+
|
|
518
|
+
* Works best when source and target formats share hinting systems
|
|
519
|
+
* TTF → TTF: TrueType instructions preserved
|
|
520
|
+
* OTF → OTF: PostScript hints preserved
|
|
521
|
+
* Cross-format: May result in lost hints
|
|
522
|
+
|
|
523
|
+
=== auto
|
|
524
|
+
|
|
525
|
+
Apply automatic hinting:
|
|
526
|
+
|
|
527
|
+
* TTF → OTF: Autohinting applied to CFF output
|
|
528
|
+
* OTF → TTF: Autohinting applied to TrueType output
|
|
529
|
+
* Type 1 → Modern: Autohinting based on outlines
|
|
530
|
+
|
|
531
|
+
=== none
|
|
532
|
+
|
|
533
|
+
Remove all hinting:
|
|
534
|
+
|
|
535
|
+
* Smallest file size
|
|
536
|
+
* No rendering optimizations
|
|
537
|
+
* Useful for web fonts where file size matters more than rendering quality
|
|
538
|
+
|
|
539
|
+
=== full
|
|
540
|
+
|
|
541
|
+
Full hinting conversion:
|
|
542
|
+
|
|
543
|
+
* Attempts to preserve all hint information
|
|
544
|
+
* May generate larger files
|
|
545
|
+
* Best quality for print applications
|
|
546
|
+
|
|
547
|
+
== Best Practices
|
|
548
|
+
|
|
549
|
+
=== Choose the Right Options
|
|
550
|
+
|
|
551
|
+
1. *Use presets when possible* - Presets are optimized for common workflows
|
|
552
|
+
2. *Show options first* - Use `--show-options` to understand what will be applied
|
|
553
|
+
3. *Test conversions* - Always verify output fonts in target applications
|
|
554
|
+
4. *Preserve metadata* - Keep copyright and license information intact
|
|
555
|
+
|
|
556
|
+
=== Performance Considerations
|
|
557
|
+
|
|
558
|
+
* Decompose composites only when necessary (increases file size)
|
|
559
|
+
* Enable optimization only for production (slower conversion)
|
|
560
|
+
* Use `--no-validate` for faster iterations during development
|
|
561
|
+
|
|
562
|
+
=== Quality Considerations
|
|
563
|
+
|
|
564
|
+
* Use `preserve` hinting mode for best rendering quality
|
|
565
|
+
* Enable autohinting when converting between incompatible hint systems
|
|
566
|
+
* Generate Unicode mappings for Type 1 fonts to ensure proper character display
|
|
567
|
+
|
|
568
|
+
== Examples
|
|
569
|
+
|
|
570
|
+
=== Convert Type 1 to Web Font
|
|
571
|
+
|
|
572
|
+
[source,shell]
|
|
573
|
+
----
|
|
574
|
+
# Convert directly to WOFF2
|
|
575
|
+
fontisan convert font.pfb --to woff2 --output font.woff2 --preset type1_to_modern
|
|
576
|
+
|
|
577
|
+
# With custom options
|
|
578
|
+
fontisan convert font.pfb --to woff2 --output font.woff2 \
|
|
579
|
+
--generate-unicode --optimize-tables
|
|
580
|
+
----
|
|
581
|
+
|
|
582
|
+
=== Convert Collection with Standardization
|
|
583
|
+
|
|
584
|
+
[source,shell]
|
|
585
|
+
----
|
|
586
|
+
# Convert TTC to OTC, standardizing all to OpenType
|
|
587
|
+
fontisan convert family.ttc --to otc --output family.otc \
|
|
588
|
+
--target-format otf --preset archive_to_modern
|
|
589
|
+
----
|
|
590
|
+
|
|
591
|
+
=== Convert with Hint Preservation
|
|
592
|
+
|
|
593
|
+
[source,shell]
|
|
594
|
+
----
|
|
595
|
+
# Convert TTF to OTF, attempting to preserve hints
|
|
596
|
+
fontisan convert font.ttf --to otf --output font.otf \
|
|
597
|
+
--hinting-mode preserve --preserve-hints
|
|
598
|
+
----
|
|
599
|
+
|
|
600
|
+
== Troubleshooting
|
|
601
|
+
|
|
602
|
+
=== Conversion Fails
|
|
603
|
+
|
|
604
|
+
1. Check if source file is valid: `fontisan info font.ttf`
|
|
605
|
+
2. Validate source font: `fontisan validate font.ttf`
|
|
606
|
+
3. Try with `--verbose` flag for detailed error messages
|
|
607
|
+
4. Use `--no-validate` to skip output validation
|
|
608
|
+
|
|
609
|
+
=== Output Font Too Large
|
|
610
|
+
|
|
611
|
+
1. Enable table optimization: `--optimize-tables`
|
|
612
|
+
2. Remove hinting: `--hinting-mode none`
|
|
613
|
+
3. Use web font compression: `--to woff2`
|
|
614
|
+
4. Decompose composites only if needed
|
|
615
|
+
|
|
616
|
+
=== Poor Rendering Quality
|
|
617
|
+
|
|
618
|
+
1. Use `--hinting-mode auto` or `preserve`
|
|
619
|
+
2. Enable autohinting: `--autohint`
|
|
620
|
+
3. Verify source font quality first
|
|
621
|
+
4. Test in target application
|
|
622
|
+
|
|
623
|
+
=== Missing Characters
|
|
624
|
+
|
|
625
|
+
1. For Type 1: Enable `--generate-unicode`
|
|
626
|
+
2. Check source font's glyph coverage
|
|
627
|
+
3. Verify cmap table in output: `fontisan unicode output.ttf`
|
|
628
|
+
|
|
629
|
+
== See Also
|
|
630
|
+
|
|
631
|
+
* link:TYPE1_FONTS.adoc[Type 1 Font Support] - Type 1 specific documentation
|
|
632
|
+
* link:README.adoc[README] - Main Fontisan documentation
|
|
633
|
+
* https://github.com/fontist/fontisan[Fontisan on GitHub] - Report issues and contribute
|