fontforge-variable-font 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,491 @@
1
+ Metadata-Version: 2.4
2
+ Name: fontforge_variable_font
3
+ Version: 0.1.0
4
+ Summary: A FontForge_plugin to create a variable font
5
+ Home-page: https://github.com/MihailJP/fontforge-variable-font
6
+ Author: MihailJP
7
+ Author-email: mihailjp@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Topic :: Text Processing :: Fonts
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: fonttools
15
+ Requires-Dist: fontmake
16
+ Dynamic: license-file
17
+
18
+ Fontforge Variable Font Plugin
19
+ ==============================
20
+
21
+ A FontForge_plugin to create a variable font
22
+
23
+ As of October 2025, Fontforge supports legacy (maybe obsolete) multiple
24
+ master formats but not yet OpenType variable fonts. This plugin adds
25
+ frontend of [fontmake](https://pypi.org/project/fontmake/) and
26
+ [fonttools](https://pypi.org/project/fonttools/) so that variable fonts can
27
+ be created through Fontforge interface.
28
+
29
+ This module can also export to WOFF2; in this case the
30
+ [woff2](https://github.com/google/woff2) tool will be used as backend.
31
+
32
+ This module requires Python 3.10 or later.
33
+
34
+ Install
35
+ -------
36
+
37
+ ```shell
38
+ pip3 install fontforgeVF
39
+ ```
40
+
41
+ ### Make sure Fontforge Python module is usable
42
+
43
+ In interactive mode of Python, run:
44
+
45
+ ```python
46
+ import fontforge
47
+ ```
48
+
49
+ If it raises ``ModuleNotFoundError`` exception, install Fontforge first. If
50
+ installed, make sure the build option set that the Python module gets also
51
+ installed. If already so, Python interpreter does not recognize the module
52
+ path where the required module.
53
+
54
+ ```shell
55
+ export PYTHONPATH=/path/to/fontforge/python/module:$PYTHONPATH
56
+ ```
57
+
58
+ Usage
59
+ -----
60
+
61
+ ### Interactive usage
62
+
63
+ As a Fontforge plugin, fontforgeVF adds 'Variable Font' submenu to 'Tools'
64
+ menu which is dedicated for plugins.
65
+
66
+ - Variable Font
67
+ - Open a variable font
68
+ - By named instance...
69
+ - By parameter...
70
+ - Generate a variable font...
71
+ - Design axes...
72
+ - Named instances...
73
+ - Delete VF info
74
+
75
+ > [!IMPORTANT]
76
+ > Since the plugin feature has been hardly (maybe never) used (hence it can
77
+ > be tested not well,) Fontforge may crash especially after a dialog is shown.
78
+ > You are advised to back up your font project before use.
79
+
80
+ #### Open a variable font
81
+
82
+ Shows a dialog to open a variable font
83
+
84
+ > [!TIP]
85
+ > If you open a webfont (WOFF2,) the plugin will first copy it to a temporary
86
+ > directory, then decompress with calling ``woff2_decompress`` in order to
87
+ > open as a TTF.
88
+
89
+ > [!TIP]
90
+ > VF-specific metadata will be loaded to ``font.persistent``.
91
+ > Minimum, default, and maximum values of axis values are also loaded in
92
+ > ``font.persistent['VF']``, but are not used when re-exporting.
93
+
94
+ ##### By named instance
95
+
96
+ Open file dialog is shown first. If a variable font is selected, then another
97
+ dialog is shown to select (one or more) named instances. If a non-variable
98
+ font is selected, simply opens that font.
99
+
100
+ > [!NOTE]
101
+ > If an empty list gets shown, the font does not have any named instances.
102
+ > Use 'By parameter' in such case.
103
+
104
+ ##### By parameter
105
+
106
+ Like above, but the second dialog is not to select a named instance, but to
107
+ specify design axis parameters.
108
+
109
+ > [!TIP]
110
+ > Valid range will be shown together with the name for each axis.
111
+
112
+ #### Generate a variable font
113
+
114
+ Shows a dialog where you can set output file name and other options.
115
+
116
+ In order to build a variable font, SFD must be converted into UFO and
117
+ create a designspace document. This plugin will do this first, and
118
+ then required modification. The required files will be created in a
119
+ temporary directory, and deleted after everything is done. So users
120
+ won't see intermediate files.
121
+
122
+ Fontforge may export with ``postscriptIsFixedPitch`` flag clear when
123
+ it should be set. The plugin checks if monospaced font is intended and
124
+ fix the flag. Unlike Fontforge itself, only U+0020 to U+007E will be
125
+ checked their width, because combining marks may have zero width even
126
+ for monospaced fonts.
127
+
128
+ In a feature file, 'aalt' feature is specially treated. Fontforge may
129
+ export incompatible 'aalt' feature (concretely 'script' or 'language'
130
+ instructions must not be included unlike other features.) This
131
+ function fix this first.
132
+
133
+ > [!TIP]
134
+ > You do not have to add 'aalt' lookups manually. You can still do it for
135
+ > 'aalt'-only glyph substitutions.
136
+
137
+ Currently available options:
138
+
139
+ - Remove nested refs: Tell fontmake to decompose nested references into simple
140
+ ones. Nested references are known to cause problems in certain environments.
141
+ - Add 'aalt' feature: Calculate and output 'aalt' feature to UFO.
142
+
143
+ > [!TIP]
144
+ > To generate web font (instead of TTF), specify output file name ending
145
+ > with '.woff2'; in this case the plugin calls ``woff2_compress`` after
146
+ > generating TTF.
147
+
148
+ > [!IMPORTANT]
149
+ > If the font family has both roman (non-italic) and italic styles, you
150
+ > have to specify 2 output files. This is because roman and italic files
151
+ > are usually incompatible since they are designed separately.
152
+
153
+ > [!IMPORTANT]
154
+ > You need all masters open before you use this menu item. Also, make
155
+ > sure the family name is consistent among the masters, or such masters
156
+ > will be ignored.
157
+
158
+ > [!NOTE]
159
+ > This item will not be active if active font does not have VF data.
160
+
161
+ #### Design axes
162
+
163
+ Shows a dialog where you can set design axes.
164
+
165
+ > [!NOTE]
166
+ > If there is already non-``dict`` value in ``font.persistent``, warns that
167
+ > that data will be lost.
168
+
169
+ ##### This master
170
+
171
+ This section is needed for all masters.
172
+
173
+ For active font as one of VF masters, sets position in each design
174
+ axis of VF master. Leave unset for unused axes. Registered axes can
175
+ use default values which refers font properties.
176
+
177
+ * Italic: default value is whether ``font.italicangle`` is negative.
178
+ This axis is boolean: you choose the master is for italic or not.
179
+ Seldom used together with slant axis.
180
+ * Optical size: can default to ``font.design_size``. Set in points.
181
+ Must be positive.
182
+ * Slant: can default to ``font.italicangle``. 0 if upright, negative
183
+ if oblique. This value is hardly positive (left-slanted.)
184
+ * Width: can default using ``font.os2_width``. 100 if normal width,
185
+ less if condensed, greater if expanded. Must be positive.
186
+ * Weight: can default to ``font.os2_weight``. 400 if regular weight,
187
+ 700 if bold. The minimum is 1 (hairline thin) and the maximum is
188
+ 999 (extreme bold.)
189
+ * Custom axes: there is a room for 3 user-defined axes. No default
190
+ values.
191
+
192
+ > [!TIP]
193
+ > You can find an example of custom axes at [Google Fonts][1] site, and they
194
+ > are explained at the [glossary](https://fonts.google.com/knowledge/glossary).
195
+
196
+ [1]: https://fonts.google.com/?categoryFilters=Technology:%2FTechnology%2FVariable
197
+
198
+ > [!NOTE]
199
+ > 'Italic' axis is exceptionally treated. Unlike other axes, it cannot be
200
+ > interpolated (anything like "semi-italic" will never be available.)
201
+ > Roman and italic styles will be exported separately, hence you do not have
202
+ > to match numbers of points or of contours between them.
203
+
204
+ > [!IMPORTANT]
205
+ > Custom axes will not be treated like italic axis. If you want custom
206
+ > discrete axes, you must open only those masters which have the same
207
+ > positions on such axes at once. For example,
208
+ > [wonky axis](https://fonts.google.com/knowledge/glossary/wonky_axis)
209
+ > allows only 0 (off) or 1 (on;) you must open masters with WONK=0 and
210
+ > generate WONK=0 VF first, close all masters and then open WONK=1 masters
211
+ > and generate VF.
212
+
213
+ ##### Custom axes
214
+
215
+ This section is needed for default master (choose one master as
216
+ default.)
217
+
218
+ Sets the tag for each custom axis. A tag must be up to 4-letter
219
+ alphanumeric. No known axis tags use less than 4 letters; if it
220
+ happens, pad with trailing space. Leave them blank if not used.
221
+
222
+ > [!NOTE]
223
+ > You must set a tag before a custom axis can be used.
224
+
225
+ > [!NOTE]
226
+ > Axis tags with less than 4 letters are not tested.
227
+
228
+ > [!CAUTION]
229
+ > Do not set tags which is duplicate or same as predefined ones, or
230
+ > undefined behavior occurs.
231
+
232
+ ##### Axis order
233
+
234
+ This section is needed for default master (choose one master as
235
+ default.)
236
+
237
+ Sets the order of design axes.
238
+
239
+ ##### Axis map
240
+
241
+ This section is needed for default master (choose one master as
242
+ default.)
243
+
244
+ Maps user position to design position.
245
+
246
+ Input must be comma-separated values and even number of elements.
247
+ Each pair consists of user and design positions in this order.
248
+
249
+ ##### Axis name
250
+
251
+ This section is needed for default master (choose one master as
252
+ default.)
253
+
254
+ Names the design axes. For predefined axes can use default name.
255
+ Custom axes must be named if used.
256
+
257
+ * Axis name: name of axis itself.
258
+ * Labels: comma-separated list which consists of multiple of 4 of
259
+ elements. Leading and trailing spaces will be trimmed. Every
260
+ group of 4 elements:
261
+ * Axis value
262
+ * Flags
263
+ * 0: Neither
264
+ * 1: ``OLDER_SIBLING_FONT_ATTRIBUTE``
265
+ * 2: ``ELIDABLE_AXIS_VALUE_NAME``
266
+ * 3: Both
267
+ * Linked value if exist
268
+ * Name
269
+
270
+ ##### Localized names
271
+
272
+ This section is needed for default master (choose one master as
273
+ default.)
274
+
275
+ Design axes can have translated names. Each page for each language.
276
+ Set language code before you use. Choose a language from the list.
277
+
278
+ By default there is a room for 8 languages, but this will be
279
+ extended if already more than 4 languages are defined.
280
+
281
+ * Axis name: name of axis itself.
282
+ * Labels: comma-separated list which consists of even number of
283
+ elements. Leading and trailing spaces will be trimmed. Every
284
+ pair of elements:
285
+ * Axis value
286
+ * Name
287
+
288
+ > [!CAUTION]
289
+ > Do not select the same language more than once, or undefined behavior will
290
+ > occur.
291
+
292
+ #### Instance list
293
+
294
+ Shows a dialog where you can set named instances.
295
+ Instance list is needed for default master (choose one master as
296
+ default.)
297
+
298
+ > [!NOTE]
299
+ > If there is already non-``dict`` value in ``font.persistent``, warns that
300
+ > that data will be lost.
301
+
302
+ ##### Instance
303
+
304
+ At these pages you can set PostScript name, subfamily name, and
305
+ associated design positions on each axis.
306
+
307
+ By default the pages are named 'Instance 1' and so on, but will be
308
+ same as subfamily name if already set.
309
+
310
+ By default there is a room for 8 instances, but this will be
311
+ extended if already more than 4 instances are defined.
312
+
313
+ ##### Localized names
314
+
315
+ Instances can have translated names. Each page (or group or pages)
316
+ for each language. Choose a language from the list first. If there
317
+ are already 13 instances or more, multiple pages for each language.
318
+
319
+ By default there is a room for 8 languages, but this will be
320
+ extended if already more than 4 languages are defined.
321
+
322
+ > [!CAUTION]
323
+ > Do not select the same language more than once, or undefined behavior will
324
+ > occur.
325
+
326
+ #### Delete VF info
327
+
328
+ Deletes VF data.
329
+
330
+ > [!WARNING]
331
+ > You will see **no** warning.
332
+
333
+ ### Script usage
334
+
335
+ As a Python module, in addition to `fontforge` module, scripting to export
336
+ variable fonts from SFD projects will be possible.
337
+
338
+ ```python
339
+ import fontforge
340
+ import fontforgeVF
341
+
342
+ # Open all masters
343
+ fontCL = fontforge.open('MyFont-UltraCondensed-ExtraLight.sfd')
344
+ fontCB = fontforge.open('MyFont-UltraCondensed-ExtraBold.sfd')
345
+ fontXL = fontforge.open('MyFont-UltraExpanded-ExtraLight.sfd')
346
+ fontXB = fontforge.open('MyFont-UltraExpanded-ExtraBold.sfd')
347
+
348
+ # Open an instance from an existing variable font
349
+ font1 = fontforgeVF.openVariableFont('MyFont[wdth,wght].ttf', {'wdth': 100, 'wght': 400}) # by parameters
350
+ font2 = fontforgeVF.openVariableFont('MyFont[wdth,wght].ttf', 'Regular') # named instance
351
+ font3 = fontforgeVF.openVariableFont('MyFont[wdth,wght].ttf', 2) # list index (instances are listed in 'fvar' table)
352
+
353
+ # Set VF-specific metadata
354
+ fontforgeVF.initPersistentDict(fontCL)
355
+ fontforgeVF.setVFValue(fontCL, "axes.wght.active", True)
356
+ fontforgeVF.setVFValue(fontCL, "axes.wght.useDefault", False)
357
+ fontforgeVF.setVFValue(fontCL, "axes.wght.value", 200)
358
+ fontforgeVF.setVFValue(fontCL, "axes.wdth.active", True)
359
+ fontforgeVF.setVFValue(fontCL, "axes.wdth.useDefault", False)
360
+ fontforgeVF.setVFValue(fontCL, "axes.wdth.value", 50)
361
+ fontforgeVF.setVFValue(fontCL, "axes.ital.active", True)
362
+ fontforgeVF.setVFValue(fontCL, "axes.ital.useDefault", False)
363
+ fontforgeVF.setVFValue(fontCL, "axes.ital.value", False)
364
+
365
+ fontforgeVF.initPersistentDict(fontCB)
366
+ fontforgeVF.setVFValue(fontCB, "axes.wght.active", True)
367
+ fontforgeVF.setVFValue(fontCB, "axes.wght.useDefault", True)
368
+ fontforgeVF.setVFValue(fontCB, "axes.wdth.active", True)
369
+ fontforgeVF.setVFValue(fontCB, "axes.wdth.useDefault", True)
370
+ fontforgeVF.setVFValue(fontCB, "axes.ital.active", True)
371
+ fontforgeVF.setVFValue(fontCB, "axes.ital.useDefault", True)
372
+
373
+ fontforgeVF.initPersistentDict(fontXL)
374
+ fontforgeVF.setVFValue(fontXL, "axes.wght.active", True)
375
+ fontforgeVF.setVFValue(fontXL, "axes.wght.useDefault", True)
376
+ fontforgeVF.setVFValue(fontXL, "axes.wdth.active", True)
377
+ fontforgeVF.setVFValue(fontXL, "axes.wdth.useDefault", True)
378
+ fontforgeVF.setVFValue(fontXL, "axes.ital.active", True)
379
+ fontforgeVF.setVFValue(fontXL, "axes.ital.useDefault", True)
380
+
381
+ fontforgeVF.initPersistentDict(fontXB)
382
+ fontforgeVF.setVFValue(fontXB, "axes.wght.active", True)
383
+ fontforgeVF.setVFValue(fontXB, "axes.wght.useDefault", False)
384
+ fontforgeVF.setVFValue(fontXB, "axes.wght.value", 800)
385
+ fontforgeVF.setVFValue(fontXB, "axes.wdth.active", True)
386
+ fontforgeVF.setVFValue(fontXB, "axes.wdth.useDefault", False)
387
+ fontforgeVF.setVFValue(fontXB, "axes.wdth.value", 200)
388
+ fontforgeVF.setVFValue(fontXB, "axes.ital.active", True)
389
+ fontforgeVF.setVFValue(fontXB, "axes.ital.useDefault", False)
390
+ fontforgeVF.setVFValue(fontXB, "axes.ital.value", False)
391
+
392
+ # Font-family-wide metadata
393
+ # Here assume fontCL as the default font
394
+ fontforgeVF.setVFValue(fontCL, "axes.wght.name", "Weight")
395
+ fontforgeVF.setVFValue(fontCL, "axes.wght.order", 1)
396
+ fontforgeVF.setVFValue(fontCL, "axes.wght.localNames.0x407", "Strichstärke")
397
+ fontforgeVF.setVFValue(fontCL, "axes.wdth.map", [(200, 200), (400, 350), (800, 800)])
398
+ fontforgeVF.setVFValue(fontCL, "axes.wdth.name", "Width")
399
+ fontforgeVF.setVFValue(fontCL, "axes.wdth.order", 0)
400
+ fontforgeVF.setVFValue(fontCL, "axes.wdth.map[0]", (50, 50))
401
+ fontforgeVF.setVFValue(fontCL, "axes.wdth.map[1]", (200, 200))
402
+ fontforgeVF.setVFValue(fontCL, "axes.wdth.localNames.0x407", "Laufweite") # 0x407 stands for German (Germany)
403
+ fontforgeVF.setVFValue(fontCL, "axes.ital.name", "Italic")
404
+ fontforgeVF.setVFValue(fontCL, "axes.ital.order", 2)
405
+ fontforgeVF.setVFValue(fontCL, "axes.ital.localNames.0x407", "Kursiv")
406
+
407
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.200.name", "Extra Light")
408
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.300.name", "Light")
409
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.400.name", "Regular")
410
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.400.olderSibling", False)
411
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.400.elidable", True)
412
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.400.linkedValue", 700)
413
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.500.name", "Medium")
414
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.600.name", "Semibold")
415
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.700.name", "Bold")
416
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.800.name", "Extra Bold")
417
+
418
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.200.localNames.0x407", "Extramager")
419
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.300.localNames.0x407", "Mager")
420
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.400.localNames.0x407", "Standard")
421
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.500.localNames.0x407", "Mittel")
422
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.600.localNames.0x407", "Halbfett")
423
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.700.localNames.0x407", "Fett")
424
+ fontforgeVF.setVFValue(fontCL, "axes.wght.labels.800.localNames.0x407", "Extrafett")
425
+
426
+ # User-defined axes (custom1 to custom3)
427
+ fontforgeVF.setVFValue(fontCL, "axes.custom1.active", True)
428
+ fontforgeVF.setVFValue(fontCL, "axes.custom1.value", 15)
429
+ fontforgeVF.setVFValue(fontCL, "axes.custom1.tag", "abc") # needed for custom axes; will be padded with space
430
+ fontforgeVF.setVFValue(fontCL, "axes.custom1.name", "User-defined axis")
431
+ fontforgeVF.setVFValue(fontCL, "axes.custom1.order", 3)
432
+ fontforgeVF.setVFValue(fontCL, "axes.custom1.localNames.0x407", "Benutzerdefinierte Achse")
433
+
434
+ # Instances
435
+ fontforgeVF.setVFValue(fontCL, "instances[0].psName", "MyFont-ExtraLight")
436
+ fontforgeVF.setVFValue(fontCL, "instances[0].name", "ExtraLight")
437
+ fontforgeVF.setVFValue(fontCL, "instances[0].wght", 200)
438
+ fontforgeVF.setVFValue(fontCL, "instances[0].wdth", 100)
439
+ fontforgeVF.setVFValue(fontCL, "instances[0].ital", False)
440
+ fontforgeVF.setVFValue(fontCL, "instances[0].localNames.0x407", "Extramager")
441
+
442
+ # Export TTF
443
+ fontforgeVF.export(fontCL, 'MyFont.ttf')
444
+
445
+ # Export Webfont
446
+ fontforgeVF.export(fontCL, 'MyFont.woff2')
447
+
448
+ # In case you want to drop the VF info
449
+ fontforgeVF.deleteVFInfo(fontCL)
450
+ ```
451
+
452
+ #### Some example of language codes
453
+
454
+ | Code | Language |
455
+ |-------:|:-----------------------------|
456
+ | 0x401 | Arabic (Saudi Arabia) |
457
+ | 0xc01 | Arabic (Egypt) |
458
+ | 0x403 | Catalan |
459
+ | 0x404 | Chinese (Taiwan) |
460
+ | 0x804 | Chinese (Mainland) |
461
+ | 0xc04 | Chinese (Hong Kong) |
462
+ | 0x407 | German (Germany) |
463
+ | 0x807 | German (Switzerland) |
464
+ | 0x408 | Greek |
465
+ | 0x409 | English (US) (default) |
466
+ | 0x809 | English (UK) |
467
+ | 0xc09 | English (Australia) |
468
+ | 0x1009 | English (Canada) |
469
+ | 0x1409 | English (New Zealand) |
470
+ | 0x80a | Spanish (Mexico) |
471
+ | 0xc0a | Spanish (Spain, modern sort) |
472
+ | 0x40c | French (France) |
473
+ | 0x80c | French (Belgium) |
474
+ | 0xc0c | French (Canada) |
475
+ | 0x100c | French (Switzerland) |
476
+ | 0x40d | Hebrew |
477
+ | 0x410 | Italian (Italy) |
478
+ | 0x810 | Italian (Switzerland) |
479
+ | 0x411 | Japanese |
480
+ | 0x412 | Korean |
481
+ | 0x413 | Dutch |
482
+ | 0x813 | Flemish |
483
+ | 0x416 | Portuguese (Brazil) |
484
+ | 0x816 | Portuguese (Portugal) |
485
+ | 0x417 | Romansh |
486
+ | 0x419 | Russian |
487
+ | 0x420 | Urdu |
488
+ | 0x439 | Hindi |
489
+
490
+ > [!NOTE]
491
+ > Language code 0x409 (American English) is used as default and specially treated. You do not have to use it for ``localName``.
@@ -0,0 +1,6 @@
1
+ fontforge_variable_font-0.1.0.dist-info/licenses/LICENSE,sha256=PRzU0Yh5LI0yPyurwK47-vNb5UPUOlT34zuKh0MdA1o,1065
2
+ fontforge_variable_font-0.1.0.dist-info/METADATA,sha256=gSHofHcUH2VGbxusnD_mPglbbrcPFX2JxSOoqAUhCzE,18275
3
+ fontforge_variable_font-0.1.0.dist-info/WHEEL,sha256=YLJXdYXQ2FQ0Uqn2J-6iEIC-3iOey8lH3xCtvFLkd8Q,91
4
+ fontforge_variable_font-0.1.0.dist-info/entry_points.txt,sha256=KKqNeOTjAfPuXOE173skUklPIvb6QGx2D72cOJR5p2g,56
5
+ fontforge_variable_font-0.1.0.dist-info/top_level.txt,sha256=aijtzhx575E_eQq_2p4jt9HTTS6h2PEQZ81PYlst6_E,12
6
+ fontforge_variable_font-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (81.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [fontforge_plugin]
2
+ Variable Font = fontforgeVF.__main__
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 MihailJP
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ fontforgeVF