fontisan 0.2.14 → 0.2.17
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 +79 -4
- data/Gemfile +6 -3
- data/docs/.gitignore +17 -0
- data/docs/.vitepress/config.ts +317 -0
- data/docs/.vitepress/theme/components/ApiMethod.vue +127 -0
- data/docs/.vitepress/theme/components/Badge.vue +51 -0
- data/docs/.vitepress/theme/components/FeatureComparison.vue +87 -0
- data/docs/.vitepress/theme/components/HeroCodeBlock.vue +98 -0
- data/docs/.vitepress/theme/components/WithinHero.vue +30 -0
- data/docs/.vitepress/theme/index.ts +22 -0
- data/docs/.vitepress/theme/style.css +330 -0
- data/docs/api/conversion-options.md +141 -0
- data/docs/api/converters/curve-converter.md +34 -0
- data/docs/api/converters/hint-converter.md +34 -0
- data/docs/api/converters/outline-converter.md +27 -0
- data/docs/api/font-loader.md +117 -0
- data/docs/api/font-writer.md +103 -0
- data/docs/api/index.md +79 -0
- data/docs/api/models/glyph-accessor.md +43 -0
- data/docs/api/models/glyph.md +40 -0
- data/docs/api/models/table-analyzer.md +35 -0
- data/docs/api/sfnt-font.md +53 -0
- data/docs/api/type1-font.md +43 -0
- data/docs/api/validators/font-validator.md +31 -0
- data/docs/api/validators/helper.md +36 -0
- data/docs/api/validators/profile.md +39 -0
- data/docs/cli/convert.md +87 -0
- data/docs/cli/dump-table.md +110 -0
- data/docs/cli/export.md +176 -0
- data/docs/cli/features.md +124 -0
- data/docs/cli/glyphs.md +90 -0
- data/docs/cli/index.md +208 -0
- data/docs/cli/info.md +254 -0
- data/docs/cli/instance.md +122 -0
- data/docs/cli/ls.md +95 -0
- data/docs/cli/optical-size.md +94 -0
- data/docs/cli/pack.md +125 -0
- data/docs/cli/scripts.md +105 -0
- data/docs/cli/subset.md +39 -0
- data/docs/cli/tables.md +84 -0
- data/docs/cli/unicode.md +101 -0
- data/docs/cli/validate.md +48 -0
- data/docs/cli/variable.md +126 -0
- data/docs/cli/version.md +46 -0
- data/docs/guide/cli/convert.md +108 -0
- data/docs/guide/cli/export.md +138 -0
- data/docs/guide/cli/index.md +99 -0
- data/docs/guide/cli/info.md +144 -0
- data/docs/guide/cli/pack.md +155 -0
- data/docs/guide/cli/subset.md +118 -0
- data/docs/guide/cli/validate.md +139 -0
- data/docs/guide/color-fonts/bitmaps.md +177 -0
- data/docs/guide/color-fonts/colr-cpal.md +175 -0
- data/docs/guide/color-fonts/index.md +140 -0
- data/docs/guide/color-fonts/svg.md +154 -0
- data/docs/guide/color.md +51 -0
- data/docs/guide/comparisons/font-validator.md +222 -0
- data/docs/guide/comparisons/fonttools.md +200 -0
- data/docs/guide/comparisons/index.md +83 -0
- data/docs/guide/comparisons/lcdf-typetools.md +205 -0
- data/docs/guide/contributing.md +279 -0
- data/docs/guide/conversion/collections.md +251 -0
- data/docs/guide/conversion/curves.md +246 -0
- data/docs/guide/conversion/index.md +157 -0
- data/docs/guide/conversion/options.md +251 -0
- data/docs/guide/conversion/ttf-otf.md +184 -0
- data/docs/guide/conversion/type1.md +208 -0
- data/docs/guide/conversion/web.md +240 -0
- data/docs/guide/conversion.md +39 -0
- data/docs/guide/formats/collections.md +147 -0
- data/docs/guide/formats/dfont.md +99 -0
- data/docs/guide/formats/index.md +65 -0
- data/docs/guide/formats/otf.md +103 -0
- data/docs/guide/formats/svg.md +97 -0
- data/docs/guide/formats/ttf.md +105 -0
- data/docs/guide/formats/type1.md +118 -0
- data/docs/guide/formats/woff.md +115 -0
- data/docs/guide/hinting/autohint.md +141 -0
- data/docs/guide/hinting/conversion.md +161 -0
- data/docs/guide/hinting/index.md +86 -0
- data/docs/guide/hinting/postscript.md +149 -0
- data/docs/guide/hinting/truetype.md +135 -0
- data/docs/guide/hinting.md +44 -0
- data/docs/guide/index.md +152 -0
- data/docs/guide/installation.md +116 -0
- data/docs/guide/migrations/extract-ttc.md +549 -0
- data/docs/guide/migrations/font-validator.md +260 -0
- data/docs/guide/migrations/fonttools.md +208 -0
- data/docs/guide/migrations/index.md +64 -0
- data/docs/guide/migrations/otfinfo.md +197 -0
- data/docs/guide/quick-start.md +204 -0
- data/docs/guide/type1.md +58 -0
- data/docs/guide/universal-outline.md +151 -0
- data/docs/guide/validation/custom.md +195 -0
- data/docs/guide/validation/helpers.md +188 -0
- data/docs/guide/validation/index.md +132 -0
- data/docs/guide/validation/profiles.md +156 -0
- data/docs/guide/validation.md +47 -0
- data/docs/guide/variable-fonts/advanced.md +231 -0
- data/docs/guide/variable-fonts/axes.md +209 -0
- data/docs/guide/variable-fonts/conversion.md +197 -0
- data/docs/guide/variable-fonts/index.md +84 -0
- data/docs/guide/variable-fonts/instances.md +187 -0
- data/docs/guide/variable-fonts/named-instances.md +194 -0
- data/docs/guide/variable-fonts/static.md +168 -0
- data/docs/guide/variable.md +58 -0
- data/docs/guide/woff.md +59 -0
- data/docs/index.md +136 -0
- data/docs/lychee.toml +37 -0
- data/docs/package-lock.json +2560 -0
- data/docs/package.json +15 -0
- data/docs/public/apple-touch-icon.png +0 -0
- data/docs/public/favicon-96x96.png +0 -0
- data/docs/public/favicon.ico +0 -0
- data/docs/public/favicon.svg +1 -0
- data/docs/public/logo-full.svg +1 -0
- data/docs/public/logo.svg +1 -0
- data/docs/public/site.webmanifest +21 -0
- data/docs/public/web-app-manifest-192x192.png +0 -0
- data/docs/public/web-app-manifest-512x512.png +0 -0
- data/fontisan.gemspec +2 -1
- data/lib/fontisan/commands/features_command.rb +0 -1
- data/lib/fontisan/commands/scripts_command.rb +0 -1
- data/lib/fontisan/constants.rb +29 -6
- data/lib/fontisan/font_loader.rb +184 -318
- data/lib/fontisan/loading_modes.rb +0 -2
- data/lib/fontisan/sfnt_font.rb +4 -3
- data/lib/fontisan/tables/glyf/compound_glyph.rb +0 -1
- data/lib/fontisan/variable/delta_applicator.rb +3 -3
- data/lib/fontisan/variation/optimizer.rb +0 -1
- data/lib/fontisan/version.rb +1 -1
- data/lib/fontisan.rb +3 -2
- metadata +136 -4
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: ConversionOptions
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# ConversionOptions
|
|
6
|
+
|
|
7
|
+
Type-safe conversion configuration.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`Fontisan::ConversionOptions` provides a type-safe way to configure font conversions.
|
|
12
|
+
|
|
13
|
+
## Class Methods
|
|
14
|
+
|
|
15
|
+
### recommended(from:, to:)
|
|
16
|
+
|
|
17
|
+
Get recommended options for a conversion type.
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
options = Fontisan::ConversionOptions.recommended(from: :ttf, to: :otf)
|
|
21
|
+
# => #<Fontisan::ConversionOptions ...>
|
|
22
|
+
|
|
23
|
+
# Access settings
|
|
24
|
+
options.opening # => { convert_curves: true, ... }
|
|
25
|
+
options.generating # => { hinting_mode: "auto", ... }
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Parameters:**
|
|
29
|
+
|
|
30
|
+
| Name | Type | Description |
|
|
31
|
+
|------|------|-------------|
|
|
32
|
+
| from | Symbol | Source format |
|
|
33
|
+
| to | Symbol | Target format |
|
|
34
|
+
|
|
35
|
+
### from_preset(name)
|
|
36
|
+
|
|
37
|
+
Load options from a named preset.
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
# Web optimization preset
|
|
41
|
+
options = Fontisan::ConversionOptions.from_preset(:web_optimized)
|
|
42
|
+
|
|
43
|
+
# Type 1 to modern
|
|
44
|
+
options = Fontisan::ConversionOptions.from_preset(:type1_to_modern)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Available Presets:**
|
|
48
|
+
|
|
49
|
+
| Preset | From | To |
|
|
50
|
+
|--------|------|-----|
|
|
51
|
+
| `type1_to_modern` | Type 1 | OTF |
|
|
52
|
+
| `modern_to_type1` | OTF | Type 1 |
|
|
53
|
+
| `web_optimized` | OTF | WOFF2 |
|
|
54
|
+
| `archive_to_modern` | TTC | OTF |
|
|
55
|
+
|
|
56
|
+
### new(**kwargs)
|
|
57
|
+
|
|
58
|
+
Create custom options.
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
options = Fontisan::ConversionOptions.new(
|
|
62
|
+
from: :ttf,
|
|
63
|
+
to: :otf,
|
|
64
|
+
opening: {
|
|
65
|
+
convert_curves: true,
|
|
66
|
+
autohint: true
|
|
67
|
+
},
|
|
68
|
+
generating: {
|
|
69
|
+
hinting_mode: 'auto',
|
|
70
|
+
optimize_tables: true
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Instance Attributes
|
|
76
|
+
|
|
77
|
+
### opening
|
|
78
|
+
|
|
79
|
+
Opening options control source font processing.
|
|
80
|
+
|
|
81
|
+
| Option | Type | Default |
|
|
82
|
+
|--------|------|---------|
|
|
83
|
+
| `decompose_composites` | Boolean | false |
|
|
84
|
+
| `convert_curves` | Boolean | true |
|
|
85
|
+
| `scale_to_1000` | Boolean | false |
|
|
86
|
+
| `scale_from_1000` | Boolean | false |
|
|
87
|
+
| `autohint` | Boolean | false |
|
|
88
|
+
| `generate_unicode` | Boolean | false |
|
|
89
|
+
| `store_custom_tables` | Boolean | true |
|
|
90
|
+
| `store_native_hinting` | Boolean | false |
|
|
91
|
+
| `interpret_ot` | Boolean | false |
|
|
92
|
+
| `read_all_records` | Boolean | false |
|
|
93
|
+
| `preserve_encoding` | String | nil |
|
|
94
|
+
|
|
95
|
+
### generating
|
|
96
|
+
|
|
97
|
+
Generating options control output font writing.
|
|
98
|
+
|
|
99
|
+
| Option | Type | Default |
|
|
100
|
+
|--------|------|---------|
|
|
101
|
+
| `write_pfm` | Boolean | false |
|
|
102
|
+
| `write_afm` | Boolean | false |
|
|
103
|
+
| `write_inf` | Boolean | false |
|
|
104
|
+
| `select_encoding_automatically` | Boolean | false |
|
|
105
|
+
| `hinting_mode` | String | 'preserve' |
|
|
106
|
+
| `decompose_on_output` | Boolean | false |
|
|
107
|
+
| `write_custom_tables` | Boolean | true |
|
|
108
|
+
| `optimize_tables` | Boolean | false |
|
|
109
|
+
| `compression` | String | nil |
|
|
110
|
+
| `transform_tables` | Boolean | false |
|
|
111
|
+
| `preserve_metadata` | Boolean | true |
|
|
112
|
+
|
|
113
|
+
## Examples
|
|
114
|
+
|
|
115
|
+
### Basic Conversion
|
|
116
|
+
|
|
117
|
+
```ruby
|
|
118
|
+
options = Fontisan::ConversionOptions.recommended(from: :ttf, to: :otf)
|
|
119
|
+
converter = Fontisan::Converters::OutlineConverter.new
|
|
120
|
+
result = converter.convert(font, options: options)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Web Optimization
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
options = Fontisan::ConversionOptions.from_preset(:web_optimized)
|
|
127
|
+
Fontisan::FontWriter.write(font, 'output.woff2', options: options)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Custom Options
|
|
131
|
+
|
|
132
|
+
```ruby
|
|
133
|
+
options = Fontisan::ConversionOptions.new(
|
|
134
|
+
opening: { autohint: true },
|
|
135
|
+
generating: {
|
|
136
|
+
hinting_mode: 'auto',
|
|
137
|
+
optimize_tables: true,
|
|
138
|
+
compression: 'brotli'
|
|
139
|
+
}
|
|
140
|
+
)
|
|
141
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: CurveConverter
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# CurveConverter
|
|
6
|
+
|
|
7
|
+
Convert between quadratic and cubic curves.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`Fontisan::Converters::CurveConverter` handles Bézier curve conversion.
|
|
12
|
+
|
|
13
|
+
## Methods
|
|
14
|
+
|
|
15
|
+
### quadratic_to_cubic(points)
|
|
16
|
+
|
|
17
|
+
Convert quadratic points to cubic.
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
converter = Fontisan::Converters::CurveConverter.new
|
|
21
|
+
cubic = converter.quadratic_to_cubic(quadratic_points)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### cubic_to_quadratic(points, tolerance: 0.5)
|
|
25
|
+
|
|
26
|
+
Convert cubic points to quadratic.
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
quadratic = converter.cubic_to_quadratic(cubic_points, tolerance: 0.5)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## See Also
|
|
33
|
+
|
|
34
|
+
- [OutlineConverter](/api/converters/outline-converter)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: HintConverter
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# HintConverter
|
|
6
|
+
|
|
7
|
+
Convert hints between TrueType and PostScript formats.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`Fontisan::Converters::HintConverter` handles bidirectional hint conversion.
|
|
12
|
+
|
|
13
|
+
## Methods
|
|
14
|
+
|
|
15
|
+
### truetype_to_postscript(font)
|
|
16
|
+
|
|
17
|
+
Convert TrueType instructions to PostScript hints.
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
converter = Fontisan::Converters::HintConverter.new
|
|
21
|
+
ps_hints = converter.truetype_to_postscript(font)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### postscript_to_truetype(font)
|
|
25
|
+
|
|
26
|
+
Convert PostScript hints to TrueType instructions.
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
ttf_tables = converter.postscript_to_truetype(font)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## See Also
|
|
33
|
+
|
|
34
|
+
- [Font Hinting Guide](/guide/hinting/)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: OutlineConverter
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# OutlineConverter
|
|
6
|
+
|
|
7
|
+
Convert font outlines between formats.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`Fontisan::Converters::OutlineConverter` handles TTF ↔ OTF conversion.
|
|
12
|
+
|
|
13
|
+
## Methods
|
|
14
|
+
|
|
15
|
+
### convert(font, options: nil)
|
|
16
|
+
|
|
17
|
+
Convert a font to a different format.
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
converter = Fontisan::Converters::OutlineConverter.new
|
|
21
|
+
options = Fontisan::ConversionOptions.recommended(from: :ttf, to: :otf)
|
|
22
|
+
result = converter.convert(font, options: options)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## See Also
|
|
26
|
+
|
|
27
|
+
- [ConversionOptions](/api/conversion-options)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: FontLoader
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# FontLoader
|
|
6
|
+
|
|
7
|
+
Unified font loading with automatic format detection.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`Fontisan::FontLoader` provides a unified interface for loading fonts in any supported format.
|
|
12
|
+
|
|
13
|
+
## Class Methods
|
|
14
|
+
|
|
15
|
+
### load(source)
|
|
16
|
+
|
|
17
|
+
Load a font from file path or IO.
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
# From file path
|
|
21
|
+
font = Fontisan::FontLoader.load('font.ttf')
|
|
22
|
+
font = Fontisan::FontLoader.load('font.otf')
|
|
23
|
+
font = Fontisan::FontLoader.load('font.pfb')
|
|
24
|
+
font = Fontisan::FontLoader.load('font.woff2')
|
|
25
|
+
|
|
26
|
+
# From IO
|
|
27
|
+
font = Fontisan::FontLoader.load(File.open('font.ttf'))
|
|
28
|
+
|
|
29
|
+
# From string
|
|
30
|
+
font = Fontisan::FontLoader.load(File.read('font.ttf', mode: 'rb'))
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Parameters:**
|
|
34
|
+
|
|
35
|
+
| Name | Type | Description |
|
|
36
|
+
|------|------|-------------|
|
|
37
|
+
| source | String, IO | File path, IO object, or binary data |
|
|
38
|
+
|
|
39
|
+
**Returns:** SfntFont, Type1Font, or Collection
|
|
40
|
+
|
|
41
|
+
**Raises:** Fontisan::FormatError if format is unsupported
|
|
42
|
+
|
|
43
|
+
### detect_format(path)
|
|
44
|
+
|
|
45
|
+
Detect a font's on-disk format from its content (magic bytes). The file
|
|
46
|
+
extension is ignored — a `.ttc` that actually contains a single OpenType-CFF
|
|
47
|
+
font is reported as `:otf`.
|
|
48
|
+
|
|
49
|
+
```ruby
|
|
50
|
+
format = Fontisan::FontLoader.detect_format('font.ttf')
|
|
51
|
+
# => :ttf
|
|
52
|
+
|
|
53
|
+
format = Fontisan::FontLoader.detect_format('font.otf')
|
|
54
|
+
# => :otf
|
|
55
|
+
|
|
56
|
+
format = Fontisan::FontLoader.detect_format('font.pfb')
|
|
57
|
+
# => :pfb
|
|
58
|
+
|
|
59
|
+
format = Fontisan::FontLoader.detect_format('font.pfa')
|
|
60
|
+
# => :pfa
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Returns:** Symbol (`:ttf`, `:otf`, `:ttc`, `:otc`, `:woff`, `:woff2`,
|
|
64
|
+
`:dfont`, `:pfa`, `:pfb`) or `nil` if the format is not recognised.
|
|
65
|
+
|
|
66
|
+
## Supported Formats
|
|
67
|
+
|
|
68
|
+
| Symbol | Detection | Notes |
|
|
69
|
+
|---------|-------------|--------------------------------|
|
|
70
|
+
| `:ttf` | Magic bytes | TrueType |
|
|
71
|
+
| `:otf` | Magic bytes | OpenType / CFF |
|
|
72
|
+
| `:ttc` | Magic bytes | TrueType Collection |
|
|
73
|
+
| `:otc` | Magic bytes | OpenType Collection |
|
|
74
|
+
| `:woff` | Magic bytes | Web Open Font Format |
|
|
75
|
+
| `:woff2` | Magic bytes | Web Open Font Format 2 |
|
|
76
|
+
| `:pfb` | Marker byte | Adobe Type 1 Binary |
|
|
77
|
+
| `:pfa` | Text header | Adobe Type 1 ASCII |
|
|
78
|
+
| `:dfont` | Magic bytes | Apple Data-Fork resource fork |
|
|
79
|
+
|
|
80
|
+
## Examples
|
|
81
|
+
|
|
82
|
+
### Load with Error Handling
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
begin
|
|
86
|
+
font = Fontisan::FontLoader.load(path)
|
|
87
|
+
puts "Loaded: #{font.family_name}"
|
|
88
|
+
rescue Fontisan::FormatError => e
|
|
89
|
+
puts "Unsupported format: #{e.message}"
|
|
90
|
+
rescue Errno::ENOENT => e
|
|
91
|
+
puts "File not found: #{path}"
|
|
92
|
+
end
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Batch Loading
|
|
96
|
+
|
|
97
|
+
```ruby
|
|
98
|
+
fonts = Dir.glob('fonts/*.ttf').map do |path|
|
|
99
|
+
Fontisan::FontLoader.load(path)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
puts "Loaded #{fonts.length} fonts"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Detect and Load
|
|
106
|
+
|
|
107
|
+
```ruby
|
|
108
|
+
path = 'unknown.dat'
|
|
109
|
+
|
|
110
|
+
format = Fontisan::FontLoader.detect_format(path)
|
|
111
|
+
if format
|
|
112
|
+
puts "Detected format: #{format}"
|
|
113
|
+
font = Fontisan::FontLoader.load(path)
|
|
114
|
+
else
|
|
115
|
+
puts "Unknown format"
|
|
116
|
+
end
|
|
117
|
+
```
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: FontWriter
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# FontWriter
|
|
6
|
+
|
|
7
|
+
Write fonts to various formats.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`Fontisan::FontWriter` handles saving fonts to files in various formats.
|
|
12
|
+
|
|
13
|
+
## Class Methods
|
|
14
|
+
|
|
15
|
+
### write(font, path, options: {})
|
|
16
|
+
|
|
17
|
+
Write a font to a file.
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
font = Fontisan::FontLoader.load('input.ttf')
|
|
21
|
+
|
|
22
|
+
# Write as TTF
|
|
23
|
+
Fontisan::FontWriter.write(font, 'output.ttf')
|
|
24
|
+
|
|
25
|
+
# Write as OTF
|
|
26
|
+
Fontisan::FontWriter.write(font, 'output.otf')
|
|
27
|
+
|
|
28
|
+
# Write as WOFF2
|
|
29
|
+
Fontisan::FontWriter.write(font, 'output.woff2')
|
|
30
|
+
|
|
31
|
+
# With options
|
|
32
|
+
options = Fontisan::ConversionOptions.new(
|
|
33
|
+
generating: { optimize_tables: true }
|
|
34
|
+
)
|
|
35
|
+
Fontisan::FontWriter.write(font, 'output.ttf', options: options)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Parameters:**
|
|
39
|
+
|
|
40
|
+
| Name | Type | Description |
|
|
41
|
+
|------|------|-------------|
|
|
42
|
+
| font | SfntFont, Type1Font | Font object |
|
|
43
|
+
| path | String | Output file path |
|
|
44
|
+
| options | ConversionOptions | Optional settings |
|
|
45
|
+
|
|
46
|
+
**Returns:** Boolean
|
|
47
|
+
|
|
48
|
+
### write_to_file(data, path, sfnt_version: nil)
|
|
49
|
+
|
|
50
|
+
Write raw font data to a file.
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
# Write raw table data
|
|
54
|
+
Fontisan::FontWriter.write_to_file(
|
|
55
|
+
font.table_data,
|
|
56
|
+
'output.ttf',
|
|
57
|
+
sfnt_version: 0x00010000
|
|
58
|
+
)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Output Formats
|
|
62
|
+
|
|
63
|
+
| Format | Extension | Notes |
|
|
64
|
+
|--------|-----------|-------|
|
|
65
|
+
| TTF | .ttf | TrueType |
|
|
66
|
+
| OTF | .otf | OpenType/CFF |
|
|
67
|
+
| WOFF | .woff | Web Open Font Format |
|
|
68
|
+
| WOFF2 | .woff2 | Web Open Font Format 2 |
|
|
69
|
+
| PFB | .pfb | Adobe Type 1 |
|
|
70
|
+
| SVG | .svg | SVG Font |
|
|
71
|
+
|
|
72
|
+
## Examples
|
|
73
|
+
|
|
74
|
+
### Convert and Write
|
|
75
|
+
|
|
76
|
+
```ruby
|
|
77
|
+
# Load TTF
|
|
78
|
+
font = Fontisan::FontLoader.load('input.ttf')
|
|
79
|
+
|
|
80
|
+
# Convert to OTF
|
|
81
|
+
options = Fontisan::ConversionOptions.recommended(from: :ttf, to: :otf)
|
|
82
|
+
converter = Fontisan::Converters::OutlineConverter.new
|
|
83
|
+
otf_tables = converter.convert(font, options: options)
|
|
84
|
+
|
|
85
|
+
# Write OTF
|
|
86
|
+
Fontisan::FontWriter.write(otf_tables, 'output.otf')
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Batch Writing
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
fonts.each_with_index do |font, i|
|
|
93
|
+
Fontisan::FontWriter.write(font, "output-#{i}.ttf")
|
|
94
|
+
end
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Web Optimization
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
font = Fontisan::FontLoader.load('input.otf')
|
|
101
|
+
options = Fontisan::ConversionOptions.from_preset(:web_optimized)
|
|
102
|
+
Fontisan::FontWriter.write(font, 'output.woff2', options: options)
|
|
103
|
+
```
|
data/docs/api/index.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: API Reference
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# API Reference
|
|
6
|
+
|
|
7
|
+
This section provides detailed API documentation for Fontisan's core classes, converters, validators, and models.
|
|
8
|
+
|
|
9
|
+
## Core Classes
|
|
10
|
+
|
|
11
|
+
- [FontLoader](/api/font-loader) — Unified font loading with automatic format detection
|
|
12
|
+
- [FontWriter](/api/font-writer) — Write fonts to various formats
|
|
13
|
+
- [ConversionOptions](/api/conversion-options) — Type-safe conversion configuration
|
|
14
|
+
- [SfntFont](/api/sfnt-font) — Base class for TrueType/OpenType fonts
|
|
15
|
+
- [Type1Font](/api/type1-font) — Adobe Type 1 font handler
|
|
16
|
+
|
|
17
|
+
## Converters
|
|
18
|
+
|
|
19
|
+
- [OutlineConverter](/api/converters/outline-converter) — TTF ↔ OTF outline conversion
|
|
20
|
+
- [CurveConverter](/api/converters/curve-converter) — Quadratic ↔ Cubic curve conversion
|
|
21
|
+
- [HintConverter](/api/converters/hint-converter) — TrueType ↔ PostScript hint conversion
|
|
22
|
+
|
|
23
|
+
## Validators
|
|
24
|
+
|
|
25
|
+
- [FontValidator](/api/validators/font-validator) — Main validation entry point
|
|
26
|
+
- [ValidationProfile](/api/validators/profile) — Validation profile definitions
|
|
27
|
+
- [ValidationHelper](/api/validators/helper) — Individual validation helpers
|
|
28
|
+
|
|
29
|
+
## Models
|
|
30
|
+
|
|
31
|
+
- [Glyph](/api/models/glyph) — Font glyph representation
|
|
32
|
+
- [GlyphAccessor](/api/models/glyph-accessor) — Unified glyph access with caching
|
|
33
|
+
- [TableAnalyzer](/api/models/table-analyzer) — Font table analysis
|
|
34
|
+
|
|
35
|
+
## Using the API
|
|
36
|
+
|
|
37
|
+
### Loading Fonts
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
require 'fontisan'
|
|
41
|
+
|
|
42
|
+
# Automatic format detection
|
|
43
|
+
font = Fontisan::FontLoader.load('font.ttf')
|
|
44
|
+
font = Fontisan::FontLoader.load('font.otf')
|
|
45
|
+
font = Fontisan::FontLoader.load('font.pfb')
|
|
46
|
+
|
|
47
|
+
# Load from IO
|
|
48
|
+
font = Fontisan::FontLoader.load(io)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Converting Fonts
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
# Get recommended options
|
|
55
|
+
options = Fontisan::ConversionOptions.recommended(from: :ttf, to: :otf)
|
|
56
|
+
|
|
57
|
+
# Convert with options
|
|
58
|
+
converter = Fontisan::Converters::OutlineConverter.new
|
|
59
|
+
tables = converter.convert(font, options: options)
|
|
60
|
+
|
|
61
|
+
# Write the result
|
|
62
|
+
Fontisan::FontWriter.write(font, 'output.otf')
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Validating Fonts
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
# Validate with a profile
|
|
69
|
+
result = Fontisan::FontValidator.validate('font.ttf', profile: :google_fonts)
|
|
70
|
+
|
|
71
|
+
# Check results
|
|
72
|
+
if result.passed?
|
|
73
|
+
puts "Font is valid!"
|
|
74
|
+
else
|
|
75
|
+
result.errors.each do |error|
|
|
76
|
+
puts "#{error.code}: #{error.message}"
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: GlyphAccessor
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# GlyphAccessor
|
|
6
|
+
|
|
7
|
+
Unified glyph access with caching.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`Fontisan::GlyphAccessor` provides efficient glyph access.
|
|
12
|
+
|
|
13
|
+
## Methods
|
|
14
|
+
|
|
15
|
+
### at(id) / get(id)
|
|
16
|
+
|
|
17
|
+
Access glyph by ID.
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
glyph = font.glyphs[42]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### each
|
|
24
|
+
|
|
25
|
+
Iterate over all glyphs.
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
font.glyphs.each do |glyph|
|
|
29
|
+
puts glyph.name
|
|
30
|
+
end
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### count
|
|
34
|
+
|
|
35
|
+
Get glyph count.
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
count = font.glyphs.count
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## See Also
|
|
42
|
+
|
|
43
|
+
- [Glyph](/api/models/glyph)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Glyph
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Glyph
|
|
6
|
+
|
|
7
|
+
Font glyph representation.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`Fontisan::Glyph` represents a single glyph.
|
|
12
|
+
|
|
13
|
+
## Properties
|
|
14
|
+
|
|
15
|
+
| Property | Type | Description |
|
|
16
|
+
|----------|------|-------------|
|
|
17
|
+
| `id` | Integer | Glyph ID |
|
|
18
|
+
| `name` | String | Glyph name |
|
|
19
|
+
| `unicode` | Integer | Unicode codepoint |
|
|
20
|
+
| `bounds` | Hash | Bounding box |
|
|
21
|
+
| `contours` | Array | Outline contours |
|
|
22
|
+
|
|
23
|
+
## Methods
|
|
24
|
+
|
|
25
|
+
### outline
|
|
26
|
+
|
|
27
|
+
Get glyph outline.
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
outline = glyph.outline
|
|
31
|
+
outline.contours.each do |contour|
|
|
32
|
+
contour.points.each do |point|
|
|
33
|
+
puts "(#{point.x}, #{point.y})"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## See Also
|
|
39
|
+
|
|
40
|
+
- [GlyphAccessor](/api/models/glyph-accessor)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TableAnalyzer
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# TableAnalyzer
|
|
6
|
+
|
|
7
|
+
Font table analysis.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`Fontisan::TableAnalyzer` analyzes font tables.
|
|
12
|
+
|
|
13
|
+
## Methods
|
|
14
|
+
|
|
15
|
+
### analyze(fonts, parallel: false)
|
|
16
|
+
|
|
17
|
+
Analyze fonts for table sharing.
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
analyzer = Fontisan::TableAnalyzer.new(fonts, parallel: true)
|
|
21
|
+
stats = analyzer.analyze
|
|
22
|
+
puts "Shared tables: #{stats.shared_count}"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### checksum(table)
|
|
26
|
+
|
|
27
|
+
Calculate table checksum.
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
checksum = analyzer.checksum(font.tables['head'])
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## See Also
|
|
34
|
+
|
|
35
|
+
- [Collections Guide](/guide/formats/collections)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: SfntFont
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# SfntFont
|
|
6
|
+
|
|
7
|
+
Base class for TrueType and OpenType fonts.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`Fontisan::SfntFont` is the base class for sfnt-based fonts (TTF, OTF, WOFF, WOFF2).
|
|
12
|
+
|
|
13
|
+
## Properties
|
|
14
|
+
|
|
15
|
+
| Property | Type | Description |
|
|
16
|
+
|----------|------|-------------|
|
|
17
|
+
| `tables` | Hash | Font tables by tag |
|
|
18
|
+
| `glyphs` | GlyphAccessor | Glyph access object |
|
|
19
|
+
| `family_name` | String | Font family name |
|
|
20
|
+
| `style` | String | Font style |
|
|
21
|
+
| `version` | String | Font version |
|
|
22
|
+
|
|
23
|
+
## Methods
|
|
24
|
+
|
|
25
|
+
### table(tag)
|
|
26
|
+
|
|
27
|
+
Access a specific table.
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
head = font.table('head')
|
|
31
|
+
name = font.table('name')
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### glyph_name(id)
|
|
35
|
+
|
|
36
|
+
Get glyph name by ID.
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
name = font.glyph_name(42)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### glyph_count
|
|
43
|
+
|
|
44
|
+
Get total glyph count.
|
|
45
|
+
|
|
46
|
+
```ruby
|
|
47
|
+
count = font.glyph_count
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## See Also
|
|
51
|
+
|
|
52
|
+
- [FontLoader](/api/font-loader)
|
|
53
|
+
- [Type1Font](/api/type1-font)
|