fontisan 0.2.13 → 0.2.16

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.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +56 -196
  3. data/Gemfile +1 -1
  4. data/docs/.gitignore +17 -0
  5. data/docs/.vitepress/config.ts +317 -0
  6. data/docs/.vitepress/theme/components/ApiMethod.vue +127 -0
  7. data/docs/.vitepress/theme/components/Badge.vue +51 -0
  8. data/docs/.vitepress/theme/components/FeatureComparison.vue +87 -0
  9. data/docs/.vitepress/theme/components/HeroCodeBlock.vue +98 -0
  10. data/docs/.vitepress/theme/components/WithinHero.vue +30 -0
  11. data/docs/.vitepress/theme/index.ts +22 -0
  12. data/docs/.vitepress/theme/style.css +330 -0
  13. data/docs/api/conversion-options.md +141 -0
  14. data/docs/api/converters/curve-converter.md +34 -0
  15. data/docs/api/converters/hint-converter.md +34 -0
  16. data/docs/api/converters/outline-converter.md +27 -0
  17. data/docs/api/font-loader.md +111 -0
  18. data/docs/api/font-writer.md +103 -0
  19. data/docs/api/index.md +79 -0
  20. data/docs/api/models/glyph-accessor.md +43 -0
  21. data/docs/api/models/glyph.md +40 -0
  22. data/docs/api/models/table-analyzer.md +35 -0
  23. data/docs/api/sfnt-font.md +53 -0
  24. data/docs/api/type1-font.md +43 -0
  25. data/docs/api/validators/font-validator.md +31 -0
  26. data/docs/api/validators/helper.md +36 -0
  27. data/docs/api/validators/profile.md +39 -0
  28. data/docs/cli/convert.md +87 -0
  29. data/docs/cli/dump-table.md +110 -0
  30. data/docs/cli/export.md +176 -0
  31. data/docs/cli/features.md +124 -0
  32. data/docs/cli/glyphs.md +90 -0
  33. data/docs/cli/index.md +208 -0
  34. data/docs/cli/info.md +254 -0
  35. data/docs/cli/instance.md +122 -0
  36. data/docs/cli/ls.md +95 -0
  37. data/docs/cli/optical-size.md +94 -0
  38. data/docs/cli/pack.md +125 -0
  39. data/docs/cli/scripts.md +105 -0
  40. data/docs/cli/subset.md +39 -0
  41. data/docs/cli/tables.md +84 -0
  42. data/docs/cli/unicode.md +101 -0
  43. data/docs/cli/validate.md +48 -0
  44. data/docs/cli/variable.md +126 -0
  45. data/docs/cli/version.md +46 -0
  46. data/docs/guide/cli/convert.md +108 -0
  47. data/docs/guide/cli/export.md +138 -0
  48. data/docs/guide/cli/index.md +99 -0
  49. data/docs/guide/cli/info.md +144 -0
  50. data/docs/guide/cli/pack.md +155 -0
  51. data/docs/guide/cli/subset.md +118 -0
  52. data/docs/guide/cli/validate.md +139 -0
  53. data/docs/guide/color-fonts/bitmaps.md +177 -0
  54. data/docs/guide/color-fonts/colr-cpal.md +175 -0
  55. data/docs/guide/color-fonts/index.md +140 -0
  56. data/docs/guide/color-fonts/svg.md +154 -0
  57. data/docs/guide/color.md +51 -0
  58. data/docs/guide/comparisons/font-validator.md +222 -0
  59. data/docs/guide/comparisons/fonttools.md +200 -0
  60. data/docs/guide/comparisons/index.md +83 -0
  61. data/docs/guide/comparisons/lcdf-typetools.md +205 -0
  62. data/docs/guide/contributing.md +279 -0
  63. data/docs/guide/conversion/collections.md +251 -0
  64. data/docs/guide/conversion/curves.md +246 -0
  65. data/docs/guide/conversion/index.md +157 -0
  66. data/docs/guide/conversion/options.md +251 -0
  67. data/docs/guide/conversion/ttf-otf.md +184 -0
  68. data/docs/guide/conversion/type1.md +208 -0
  69. data/docs/guide/conversion/web.md +240 -0
  70. data/docs/guide/conversion.md +39 -0
  71. data/docs/guide/formats/collections.md +147 -0
  72. data/docs/guide/formats/dfont.md +99 -0
  73. data/docs/guide/formats/index.md +65 -0
  74. data/docs/guide/formats/otf.md +103 -0
  75. data/docs/guide/formats/svg.md +97 -0
  76. data/docs/guide/formats/ttf.md +105 -0
  77. data/docs/guide/formats/type1.md +118 -0
  78. data/docs/guide/formats/woff.md +115 -0
  79. data/docs/guide/hinting/autohint.md +141 -0
  80. data/docs/guide/hinting/conversion.md +161 -0
  81. data/docs/guide/hinting/index.md +86 -0
  82. data/docs/guide/hinting/postscript.md +149 -0
  83. data/docs/guide/hinting/truetype.md +135 -0
  84. data/docs/guide/hinting.md +44 -0
  85. data/docs/guide/index.md +152 -0
  86. data/docs/guide/installation.md +116 -0
  87. data/docs/guide/migrations/extract-ttc.md +549 -0
  88. data/docs/guide/migrations/font-validator.md +260 -0
  89. data/docs/guide/migrations/fonttools.md +208 -0
  90. data/docs/guide/migrations/index.md +64 -0
  91. data/docs/guide/migrations/otfinfo.md +197 -0
  92. data/docs/guide/quick-start.md +204 -0
  93. data/docs/guide/type1.md +58 -0
  94. data/docs/guide/universal-outline.md +151 -0
  95. data/docs/guide/validation/custom.md +195 -0
  96. data/docs/guide/validation/helpers.md +188 -0
  97. data/docs/guide/validation/index.md +132 -0
  98. data/docs/guide/validation/profiles.md +156 -0
  99. data/docs/guide/validation.md +47 -0
  100. data/docs/guide/variable-fonts/advanced.md +231 -0
  101. data/docs/guide/variable-fonts/axes.md +209 -0
  102. data/docs/guide/variable-fonts/conversion.md +197 -0
  103. data/docs/guide/variable-fonts/index.md +84 -0
  104. data/docs/guide/variable-fonts/instances.md +187 -0
  105. data/docs/guide/variable-fonts/named-instances.md +194 -0
  106. data/docs/guide/variable-fonts/static.md +168 -0
  107. data/docs/guide/variable.md +58 -0
  108. data/docs/guide/woff.md +59 -0
  109. data/docs/index.md +136 -0
  110. data/docs/lychee.toml +37 -0
  111. data/docs/package-lock.json +2560 -0
  112. data/docs/package.json +15 -0
  113. data/docs/public/apple-touch-icon.png +0 -0
  114. data/docs/public/favicon-96x96.png +0 -0
  115. data/docs/public/favicon.ico +0 -0
  116. data/docs/public/favicon.svg +1 -0
  117. data/docs/public/logo-full.svg +1 -0
  118. data/docs/public/logo.svg +1 -0
  119. data/docs/public/site.webmanifest +21 -0
  120. data/docs/public/web-app-manifest-192x192.png +0 -0
  121. data/docs/public/web-app-manifest-512x512.png +0 -0
  122. data/fontisan.gemspec +1 -1
  123. data/lib/fontisan/commands/features_command.rb +0 -1
  124. data/lib/fontisan/commands/info_command.rb +5 -5
  125. data/lib/fontisan/commands/scripts_command.rb +0 -1
  126. data/lib/fontisan/converters/format_converter.rb +2 -1
  127. data/lib/fontisan/converters/type1_converter.rb +65 -60
  128. data/lib/fontisan/hints/hint_converter.rb +2 -1
  129. data/lib/fontisan/loading_modes.rb +0 -2
  130. data/lib/fontisan/open_type_font.rb +0 -40
  131. data/lib/fontisan/sfnt_font.rb +41 -22
  132. data/lib/fontisan/tables/glyf/compound_glyph.rb +0 -1
  133. data/lib/fontisan/true_type_collection.rb +8 -8
  134. data/lib/fontisan/true_type_font.rb +1 -59
  135. data/lib/fontisan/type1/afm_parser.rb +2 -1
  136. data/lib/fontisan/type1/cff_to_type1_converter.rb +24 -19
  137. data/lib/fontisan/type1/private_dict.rb +28 -7
  138. data/lib/fontisan/type1/seac_expander.rb +22 -17
  139. data/lib/fontisan/variable/delta_applicator.rb +3 -3
  140. data/lib/fontisan/variation/optimizer.rb +0 -1
  141. data/lib/fontisan/version.rb +1 -1
  142. data/lib/fontisan/woff2_font.rb +2 -2
  143. data/lib/fontisan/woff_font.rb +3 -3
  144. data/lib/fontisan.rb +3 -2
  145. metadata +122 -4
@@ -0,0 +1,30 @@
1
+ <template>
2
+ <ClientOnly>
3
+ <Teleport to=".VPHero > .container">
4
+ <div class="within-hero__slot-container">
5
+ <slot />
6
+ </div>
7
+ </Teleport>
8
+ </ClientOnly>
9
+ </template>
10
+
11
+ <style>
12
+ .within-hero__slot-container {
13
+ order: 2;
14
+ }
15
+
16
+ .VPHero > .container > .main {
17
+ width: unset;
18
+ flex-shrink: unset;
19
+ }
20
+
21
+ .VPHero > .container {
22
+ gap: 32px;
23
+ }
24
+
25
+ @media (min-width: 960px) {
26
+ .VPHero > .container {
27
+ gap: 64px;
28
+ }
29
+ }
30
+ </style>
@@ -0,0 +1,22 @@
1
+ import DefaultTheme from "vitepress/theme";
2
+ import type { Theme } from "vitepress";
3
+ import "./style.css";
4
+
5
+ // Import custom components
6
+ import FeatureComparison from "./components/FeatureComparison.vue";
7
+ import Badge from "./components/Badge.vue";
8
+ import ApiMethod from "./components/ApiMethod.vue";
9
+ import HeroCodeBlock from "./components/HeroCodeBlock.vue";
10
+ import WithinHero from "./components/WithinHero.vue";
11
+
12
+ export default {
13
+ extends: DefaultTheme,
14
+ enhanceApp({ app }) {
15
+ // Register global components
16
+ app.component("FeatureComparison", FeatureComparison);
17
+ app.component("Badge", Badge);
18
+ app.component("ApiMethod", ApiMethod);
19
+ app.component("HeroCodeBlock", HeroCodeBlock);
20
+ app.component("WithinHero", WithinHero);
21
+ },
22
+ } satisfies Theme;
@@ -0,0 +1,330 @@
1
+ :root {
2
+ /* Brand Colors from Logo */
3
+ --fontist-rose: #bf4e6a;
4
+ --fontist-rose-light: #d4718a;
5
+ --fontist-dark: #4d4b54;
6
+ --fontist-gray: #676565;
7
+ --fontist-cream: #e1dfd2;
8
+ --fontist-beige: #bebbac;
9
+ --fontist-pale: #dddac8;
10
+
11
+ /* VitePress Theme Overrides - Light Mode */
12
+ --vp-c-brand-1: var(--fontist-rose);
13
+ --vp-c-brand-2: #a3435a;
14
+ --vp-c-brand-3: var(--fontist-dark);
15
+ --vp-c-brand-soft: rgba(191, 78, 106, 0.14);
16
+
17
+ /* Text Colors */
18
+ --vp-c-text-1: var(--fontist-dark);
19
+ --vp-c-text-2: var(--fontist-gray);
20
+ --vp-c-text-3: #8a8888;
21
+
22
+ /* Background Colors */
23
+ --vp-c-bg-soft: #f8f7f4;
24
+ --vp-c-bg-alt: #f2f1ed;
25
+ --vp-c-bg: #ffffff;
26
+
27
+ /* Hero */
28
+ --vp-home-hero-name-color: var(--fontist-rose);
29
+ --vp-home-hero-name-background: linear-gradient(
30
+ 120deg,
31
+ var(--fontist-rose) 30%,
32
+ #d4718a
33
+ );
34
+
35
+ /* Buttons */
36
+ --vp-button-brand-border: var(--fontist-rose);
37
+ --vp-button-brand-text: #ffffff;
38
+ --vp-button-brand-bg: var(--fontist-rose);
39
+ --vp-button-brand-hover-border: #a3435a;
40
+ --vp-button-brand-hover-text: #ffffff;
41
+ --vp-button-brand-hover-bg: #a3435a;
42
+ --vp-button-brand-active-border: #8a3849;
43
+ --vp-button-brand-active-text: #ffffff;
44
+ --vp-button-brand-active-bg: #8a3849;
45
+
46
+ /* Sidebar */
47
+ --vp-sidebar-bg-color: var(--vp-c-bg-soft);
48
+
49
+ /* Nav */
50
+ --vp-nav-bg-color: var(--vp-c-bg);
51
+ }
52
+
53
+ /* Dark Mode */
54
+ html.dark {
55
+ --vp-c-brand-1: var(--fontist-rose-light);
56
+ --vp-c-brand-2: var(--fontist-rose);
57
+ --vp-c-brand-3: #e1dfd2;
58
+ --vp-c-brand-soft: rgba(212, 113, 138, 0.14);
59
+
60
+ /* Text Colors - Dark Mode */
61
+ --vp-c-text-1: #e1dfd2;
62
+ --vp-c-text-2: #bebbac;
63
+ --vp-c-text-3: #8a8888;
64
+
65
+ /* Background Colors - Dark Mode */
66
+ --vp-c-bg: #1a1918;
67
+ --vp-c-bg-soft: #222120;
68
+ --vp-c-bg-alt: #2a2826;
69
+ --vp-c-bg-elv: #2a2826;
70
+
71
+ /* Hero - Dark Mode */
72
+ --vp-home-hero-name-background: linear-gradient(
73
+ 120deg,
74
+ var(--fontist-rose-light) 30%,
75
+ #e08a9e
76
+ );
77
+
78
+ /* Buttons - Dark Mode */
79
+ --vp-button-brand-border: var(--fontist-rose-light);
80
+ --vp-button-brand-text: #1a1918;
81
+ --vp-button-brand-bg: var(--fontist-rose-light);
82
+ --vp-button-brand-hover-border: var(--fontist-rose);
83
+ --vp-button-brand-hover-text: #1a1918;
84
+ --vp-button-brand-hover-bg: var(--fontist-rose);
85
+ --vp-button-brand-active-border: #a3435a;
86
+ --vp-button-brand-active-text: #1a1918;
87
+ --vp-button-brand-active-bg: #a3435a;
88
+ }
89
+
90
+ /* Feature cards on home page - Light */
91
+ .VPFeature .title {
92
+ color: var(--fontist-dark);
93
+ }
94
+
95
+ .VPFeature .details {
96
+ color: var(--fontist-gray);
97
+ }
98
+
99
+ .VPFeature:hover {
100
+ border-color: var(--fontist-rose);
101
+ }
102
+
103
+ /* Feature cards - Dark */
104
+ html.dark .VPFeature .title {
105
+ color: var(--fontist-cream);
106
+ }
107
+
108
+ html.dark .VPFeature .details {
109
+ color: var(--fontist-beige);
110
+ }
111
+
112
+ /* Links */
113
+ .vp-doc a {
114
+ color: var(--fontist-rose);
115
+ }
116
+
117
+ .vp-doc a:hover {
118
+ color: #a3435a;
119
+ }
120
+
121
+ html.dark .vp-doc a {
122
+ color: var(--fontist-rose-light);
123
+ }
124
+
125
+ html.dark .vp-doc a:hover {
126
+ color: var(--fontist-rose);
127
+ }
128
+
129
+ /* Footer */
130
+ .VPFooter {
131
+ background-color: var(--vp-c-bg-soft);
132
+ border-top: 1px solid var(--fontist-pale);
133
+ }
134
+
135
+ html.dark .VPFooter {
136
+ border-top-color: #3a3836;
137
+ }
138
+
139
+ /* Code blocks - Light */
140
+ .vp-doc [class*="language-"] {
141
+ background-color: var(--fontist-dark);
142
+ }
143
+
144
+ /* Code blocks - Dark */
145
+ html.dark .vp-doc [class*="language-"] {
146
+ background-color: #0d0c0c;
147
+ }
148
+
149
+ /* Logo sizing */
150
+ .VPNav .VPImage {
151
+ height: 39px;
152
+ }
153
+
154
+ /* Search */
155
+ .VPLocalSearchBox {
156
+ --vp-c-brand-1: var(--fontist-rose);
157
+ }
158
+
159
+ /* Feature Comparison Tables */
160
+ .feature-comparison {
161
+ width: 100%;
162
+ border-collapse: collapse;
163
+ margin: 1.5rem 0;
164
+ font-size: 0.9rem;
165
+ }
166
+
167
+ .feature-comparison th,
168
+ .feature-comparison td {
169
+ padding: 0.75rem 1rem;
170
+ text-align: left;
171
+ border-bottom: 1px solid var(--vp-c-divider);
172
+ }
173
+
174
+ .feature-comparison th {
175
+ background: var(--vp-c-bg-soft);
176
+ font-weight: 600;
177
+ white-space: nowrap;
178
+ }
179
+
180
+ .feature-comparison .feature-name {
181
+ font-weight: 500;
182
+ }
183
+
184
+ .feature-comparison .supported {
185
+ color: var(--vp-c-green-1);
186
+ }
187
+
188
+ .feature-comparison .not-supported {
189
+ color: var(--vp-c-red-1);
190
+ }
191
+
192
+ .feature-comparison .advantage {
193
+ background: linear-gradient(
194
+ 135deg,
195
+ rgba(191, 78, 106, 0.1) 0%,
196
+ rgba(212, 113, 138, 0.05) 100%
197
+ );
198
+ }
199
+
200
+ /* Badge styles */
201
+ .badge {
202
+ display: inline-flex;
203
+ align-items: center;
204
+ padding: 0.125rem 0.625rem;
205
+ border-radius: 9999px;
206
+ font-size: 0.75rem;
207
+ font-weight: 600;
208
+ line-height: 1.25rem;
209
+ vertical-align: middle;
210
+ }
211
+
212
+ .badge.pure-ruby {
213
+ background: linear-gradient(135deg, var(--fontist-rose), #d4718a);
214
+ color: white;
215
+ font-weight: 700;
216
+ text-transform: uppercase;
217
+ letter-spacing: 0.05em;
218
+ }
219
+
220
+ .badge.tip {
221
+ background-color: var(--vp-c-brand-soft);
222
+ color: var(--vp-c-brand-1);
223
+ }
224
+
225
+ .badge.preview {
226
+ background-color: rgba(255, 197, 61, 0.14);
227
+ color: #c4a226;
228
+ }
229
+
230
+ .badge.planned {
231
+ background-color: rgba(96, 165, 250, 0.14);
232
+ color: #60a5fa;
233
+ }
234
+
235
+ /* Home page enhancements */
236
+ .my-index-page .VPHero .name {
237
+ display: flex;
238
+ align-items: center;
239
+ gap: 0.5rem;
240
+ }
241
+
242
+ .my-index-page .VPHero .tagline {
243
+ font-size: 1.25rem !important;
244
+ opacity: 0.9;
245
+ }
246
+
247
+ /* Pure Ruby badge on hero */
248
+ .pure-ruby-hero {
249
+ display: inline-flex;
250
+ align-items: center;
251
+ gap: 0.5rem;
252
+ padding: 0.25rem 0.75rem;
253
+ background: linear-gradient(135deg, var(--fontist-rose), #d4718a);
254
+ color: white;
255
+ border-radius: 9999px;
256
+ font-size: 0.85rem;
257
+ font-weight: 700;
258
+ text-transform: uppercase;
259
+ letter-spacing: 0.05em;
260
+ margin-top: 1rem;
261
+ }
262
+
263
+ /* Code comparison blocks */
264
+ .code-comparison {
265
+ display: grid;
266
+ grid-template-columns: 1fr 1fr;
267
+ gap: 1rem;
268
+ margin: 1.5rem 0;
269
+ }
270
+
271
+ @media (max-width: 768px) {
272
+ .code-comparison {
273
+ grid-template-columns: 1fr;
274
+ }
275
+ }
276
+
277
+ .code-comparison > div {
278
+ background: var(--vp-c-bg-soft);
279
+ border-radius: 8px;
280
+ overflow: hidden;
281
+ }
282
+
283
+ .code-comparison h4 {
284
+ margin: 0;
285
+ padding: 0.75rem 1rem;
286
+ background: var(--vp-c-bg-alt);
287
+ font-size: 0.85rem;
288
+ font-weight: 600;
289
+ border-bottom: 1px solid var(--vp-c-divider);
290
+ }
291
+
292
+ /* CLI command reference */
293
+ .cli-command {
294
+ padding: 1rem;
295
+ margin: 1rem 0;
296
+ background: var(--vp-c-bg-soft);
297
+ border-radius: 8px;
298
+ border-left: 3px solid var(--fontist-rose);
299
+ }
300
+
301
+ .cli-command code {
302
+ font-weight: 500;
303
+ }
304
+
305
+ /* Info boxes */
306
+ .custom-block {
307
+ margin: 1.5rem 0;
308
+ padding: 1rem 1.25rem;
309
+ border-radius: 8px;
310
+ }
311
+
312
+ .custom-block.tip {
313
+ border-left: 4px solid var(--fontist-rose);
314
+ background: rgba(191, 78, 106, 0.08);
315
+ }
316
+
317
+ .custom-block.warning {
318
+ border-left: 4px solid #ffc53d;
319
+ background: rgba(255, 197, 61, 0.08);
320
+ }
321
+
322
+ .custom-block.danger {
323
+ border-left: 4px solid #f43f5e;
324
+ background: rgba(244, 63, 94, 0.08);
325
+ }
326
+
327
+ .custom-block.info {
328
+ border-left: 4px solid #60a5fa;
329
+ background: rgba(96, 165, 250, 0.08);
330
+ }
@@ -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)