fakelab 0.1.0__tar.gz
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.
- fakelab-0.1.0/.flake8 +7 -0
- fakelab-0.1.0/.github/FUNDING.yml +12 -0
- fakelab-0.1.0/.github/workflows/publish_to_pypi.yml +42 -0
- fakelab-0.1.0/.gitignore +13 -0
- fakelab-0.1.0/PKG-INFO +309 -0
- fakelab-0.1.0/README.md +261 -0
- fakelab-0.1.0/doc/Makefile +20 -0
- fakelab-0.1.0/doc/make.bat +35 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.FLdict.rst +23 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.cmdline.FontLab5Console.rst +34 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.cmdline.main.rst +6 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.cmdline.rst +38 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.constants.rst +23 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.fake.Base.Copyable.rst +25 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.fake.Base.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.fake.Font.FakeFont.rst +39 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.fake.Font.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.fake.Kerning.FakeKerning.rst +33 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.fake.Kerning.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.fake.KerningClass.KerningClass.rst +35 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.fake.KerningClass.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.fake.rst +35 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.fl_cmd.rst +23 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.FLList.FLList.rst +37 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.FLList.adjust_list.rst +6 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.FLList.rst +38 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.ListParent.ListParent.rst +37 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.ListParent.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.classList.ClassList.rst +48 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.classList.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.nametables.StandardNametable.rst +27 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.nametables.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.registry.parse_registry_file.rst +6 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.registry.rst +30 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.rst +37 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.tth.TTCommandDict.rst +43 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.helpers.tth.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Anchor.Anchor.rst +37 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Anchor.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.AuditRecord.AuditRecord.rst +39 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.AuditRecord.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Canvas.Canvas.rst +54 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Canvas.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Component.Component.rst +38 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Component.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Dialog.Dialog.rst +43 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Dialog.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Encoding.Encoding.rst +49 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Encoding.data.rst +6 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Encoding.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.EncodingRecord.EncodingRecord.rst +32 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.EncodingRecord.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Feature.Feature.rst +33 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Feature.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Font.Font.rst +151 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Font.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.FontLab.FakeLab.rst +83 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.FontLab.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Glyph.Glyph.rst +122 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Glyph.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Guide.Guide.rst +33 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Guide.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Hint.Hint.rst +38 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Hint.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Image.Image.rst +25 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Image.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.KerningPair.KerningPair.rst +35 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.KerningPair.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Link.Link.rst +35 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Link.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Matrix.Matrix.rst +42 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Matrix.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.NameRecord.NameRecord.rst +36 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.NameRecord.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Node.Node.rst +49 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Node.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Options.Options.rst +203 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Options.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Point.Point.rst +40 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Point.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Rect.Rect.rst +43 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Rect.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Replace.Replace.rst +33 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Replace.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTGasp.TTGasp.rst +32 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTGasp.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTH.TTH.rst +62 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTH.base_hstems.rst +6 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTH.base_vstems.rst +6 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTH.hstems.rst +6 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTH.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTH.vstems.rst +6 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTHCommand.TTHCommand.rst +32 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTHCommand.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTHPoint.TTHPoint.rst +34 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTHPoint.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTHProblem.TTHProblem.rst +34 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTHProblem.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTInfo.TTInfo.rst +75 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTInfo.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTPoint.TTPoint.rst +33 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTPoint.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTStem.TTStem.rst +38 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTStem.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTVdmx.TTVdmx.rst +33 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTVdmx.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TrueTypeTable.TrueTypeTable.rst +33 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.TrueTypeTable.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Uni.Uni.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.Uni.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.WeightVector.WeightVector.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.WeightVector.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.objects.rst +66 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.vfb.reader.VfbToFontReader.rst +27 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.vfb.reader.rst +31 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.vfb.rst +33 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.vfb.writer.FontToVfbWriter.rst +34 -0
- fakelab-0.1.0/doc/source/_autosummary/FL.vfb.writer.rst +31 -0
- fakelab-0.1.0/doc/source/_templates/custom-class-template.rst +32 -0
- fakelab-0.1.0/doc/source/_templates/custom-module-template.rst +66 -0
- fakelab-0.1.0/doc/source/api.rst +16 -0
- fakelab-0.1.0/doc/source/conf.py +36 -0
- fakelab-0.1.0/doc/source/index.rst +3 -0
- fakelab-0.1.0/doc/source/usage.rst +23 -0
- fakelab-0.1.0/doc/truetype-hinting/fdef0.md +37 -0
- fakelab-0.1.0/doc/truetype-hinting/fdef1.md +25 -0
- fakelab-0.1.0/doc/truetype-hinting/fdef2.md +17 -0
- fakelab-0.1.0/doc/truetype-hinting/fdef3.md +79 -0
- fakelab-0.1.0/doc/truetype-hinting/fdef4.md +47 -0
- fakelab-0.1.0/doc/truetype-hinting/fdef5.md +46 -0
- fakelab-0.1.0/doc/truetype-hinting/fdef6.md +33 -0
- fakelab-0.1.0/doc/truetype-hinting/fdef7.md +18 -0
- fakelab-0.1.0/doc/truetype-hinting/fdef8.md +128 -0
- fakelab-0.1.0/doc/truetype-hinting/fdef9.md +24 -0
- fakelab-0.1.0/doc/truetype-hinting/fpgm.md +14 -0
- fakelab-0.1.0/doc/truetype-hinting/index.md +617 -0
- fakelab-0.1.0/doc/truetype-hinting/prep.md +130 -0
- fakelab-0.1.0/doc/truetype-hinting/tth-colon.webp +0 -0
- fakelab-0.1.0/doc/truetype-hinting/tth-e.webp +0 -0
- fakelab-0.1.0/doc/truetype-hinting/tth-f.webp +0 -0
- fakelab-0.1.0/doc/truetype-hinting/tth-k.webp +0 -0
- fakelab-0.1.0/doc/truetype-hinting/tth-o.webp +0 -0
- fakelab-0.1.0/doc/truetype-hinting/tth-options-general.webp +0 -0
- fakelab-0.1.0/doc/truetype-hinting/tth-options-stems.webp +0 -0
- fakelab-0.1.0/doc/truetype-hinting/tth-options-zones.webp +0 -0
- fakelab-0.1.0/examples/Macros/Selection/Select composites.py +3 -0
- fakelab-0.1.0/examples/Macros/System/Modules/fakeLabDemo/__init__.py +0 -0
- fakelab-0.1.0/examples/Macros/System/Modules/fakeLabDemo/selection/__init__.py +0 -0
- fakelab-0.1.0/examples/Macros/System/Modules/fakeLabDemo/selection/composites.py +49 -0
- fakelab-0.1.0/examples/Macros/System/Modules/tests/fakeLabDemo/selection/composites_test.py +46 -0
- fakelab-0.1.0/pyproject.toml +185 -0
- fakelab-0.1.0/setup.cfg +4 -0
- fakelab-0.1.0/src/FL/FLdict.py +214 -0
- fakelab-0.1.0/src/FL/__init__.py +344 -0
- fakelab-0.1.0/src/FL/_version.py +34 -0
- fakelab-0.1.0/src/FL/cmdline.py +124 -0
- fakelab-0.1.0/src/FL/constants.py +31 -0
- fakelab-0.1.0/src/FL/fake/Base.py +20 -0
- fakelab-0.1.0/src/FL/fake/Font.py +153 -0
- fakelab-0.1.0/src/FL/fake/Kerning.py +232 -0
- fakelab-0.1.0/src/FL/fake/KerningClass.py +163 -0
- fakelab-0.1.0/src/FL/fake/__init__.py +0 -0
- fakelab-0.1.0/src/FL/fake/mixins.py +74 -0
- fakelab-0.1.0/src/FL/fl_cmd.py +494 -0
- fakelab-0.1.0/src/FL/helpers/FLList.py +40 -0
- fakelab-0.1.0/src/FL/helpers/ListParent.py +61 -0
- fakelab-0.1.0/src/FL/helpers/__init__.py +1 -0
- fakelab-0.1.0/src/FL/helpers/classList.py +186 -0
- fakelab-0.1.0/src/FL/helpers/math.py +15 -0
- fakelab-0.1.0/src/FL/helpers/nametables.py +6099 -0
- fakelab-0.1.0/src/FL/helpers/registry.py +409 -0
- fakelab-0.1.0/src/FL/helpers/tth.py +67 -0
- fakelab-0.1.0/src/FL/objects/Anchor.py +181 -0
- fakelab-0.1.0/src/FL/objects/AuditRecord.py +129 -0
- fakelab-0.1.0/src/FL/objects/Canvas.py +360 -0
- fakelab-0.1.0/src/FL/objects/Component.py +212 -0
- fakelab-0.1.0/src/FL/objects/Dialog.py +165 -0
- fakelab-0.1.0/src/FL/objects/Encoding.py +395 -0
- fakelab-0.1.0/src/FL/objects/EncodingRecord.py +56 -0
- fakelab-0.1.0/src/FL/objects/Feature.py +81 -0
- fakelab-0.1.0/src/FL/objects/Font.py +1006 -0
- fakelab-0.1.0/src/FL/objects/FontLab.py +688 -0
- fakelab-0.1.0/src/FL/objects/Glyph.py +1580 -0
- fakelab-0.1.0/src/FL/objects/Guide.py +166 -0
- fakelab-0.1.0/src/FL/objects/Hint.py +202 -0
- fakelab-0.1.0/src/FL/objects/Image.py +240 -0
- fakelab-0.1.0/src/FL/objects/KerningPair.py +106 -0
- fakelab-0.1.0/src/FL/objects/Link.py +87 -0
- fakelab-0.1.0/src/FL/objects/Matrix.py +263 -0
- fakelab-0.1.0/src/FL/objects/NameRecord.py +145 -0
- fakelab-0.1.0/src/FL/objects/Node.py +244 -0
- fakelab-0.1.0/src/FL/objects/Options.py +1818 -0
- fakelab-0.1.0/src/FL/objects/Point.py +182 -0
- fakelab-0.1.0/src/FL/objects/Rect.py +227 -0
- fakelab-0.1.0/src/FL/objects/Replace.py +123 -0
- fakelab-0.1.0/src/FL/objects/TTGasp.py +91 -0
- fakelab-0.1.0/src/FL/objects/TTH.py +450 -0
- fakelab-0.1.0/src/FL/objects/TTHCommand.py +79 -0
- fakelab-0.1.0/src/FL/objects/TTHPoint.py +132 -0
- fakelab-0.1.0/src/FL/objects/TTHProblem.py +48 -0
- fakelab-0.1.0/src/FL/objects/TTInfo.py +833 -0
- fakelab-0.1.0/src/FL/objects/TTPoint.py +80 -0
- fakelab-0.1.0/src/FL/objects/TTStem.py +189 -0
- fakelab-0.1.0/src/FL/objects/TTVdmx.py +62 -0
- fakelab-0.1.0/src/FL/objects/TrueTypeTable.py +82 -0
- fakelab-0.1.0/src/FL/objects/Uni.py +82 -0
- fakelab-0.1.0/src/FL/objects/WeightVector.py +52 -0
- fakelab-0.1.0/src/FL/objects/__init__.py +0 -0
- fakelab-0.1.0/src/FL/py.typed +0 -0
- fakelab-0.1.0/src/FL/vfb/__init__.py +0 -0
- fakelab-0.1.0/src/FL/vfb/reader.py +319 -0
- fakelab-0.1.0/src/FL/vfb/writer.py +315 -0
- fakelab-0.1.0/src/fakelab.egg-info/PKG-INFO +309 -0
- fakelab-0.1.0/src/fakelab.egg-info/SOURCES.txt +249 -0
- fakelab-0.1.0/src/fakelab.egg-info/dependency_links.txt +1 -0
- fakelab-0.1.0/src/fakelab.egg-info/entry_points.txt +2 -0
- fakelab-0.1.0/src/fakelab.egg-info/requires.txt +34 -0
- fakelab-0.1.0/src/fakelab.egg-info/top_level.txt +1 -0
- fakelab-0.1.0/tests/data/Untitled.reg +333 -0
- fakelab-0.1.0/tests/data/empty.reg +0 -0
- fakelab-0.1.0/tests/data/empty.vfb +0 -0
- fakelab-0.1.0/tests/data/mini.vfb +0 -0
- fakelab-0.1.0/tests/data/mini.vfb.json +3376 -0
- fakelab-0.1.0/tests/data/minimal.reg +6 -0
- fakelab-0.1.0/tests/data/nokey.reg +3 -0
- fakelab-0.1.0/tests/data/wrong_header.reg +3 -0
- fakelab-0.1.0/tests/data/wrong_value_type.reg +6 -0
- fakelab-0.1.0/tests/fake/classes.flc +19 -0
- fakelab-0.1.0/tests/fake/kerning_class_test.py +20 -0
- fakelab-0.1.0/tests/fake/kerning_test.py +45 -0
- fakelab-0.1.0/tests/fl_test.py +321 -0
- fakelab-0.1.0/tests/helpers/FLList_test.py +51 -0
- fakelab-0.1.0/tests/helpers/ListParent_test.py +0 -0
- fakelab-0.1.0/tests/helpers/classList_test.py +107 -0
- fakelab-0.1.0/tests/helpers/math_test.py +29 -0
- fakelab-0.1.0/tests/helpers/nametables_test.py +64 -0
- fakelab-0.1.0/tests/helpers/registry_test.py +35 -0
- fakelab-0.1.0/tests/objects/font_test.py +511 -0
- fakelab-0.1.0/tests/objects/glyph_test.py +38 -0
- fakelab-0.1.0/tests/objects/guide_test.py +54 -0
- fakelab-0.1.0/tests/objects/hint_test.py +43 -0
- fakelab-0.1.0/tests/objects/kerningpair_test.py +14 -0
- fakelab-0.1.0/tests/objects/matrix_test.py +179 -0
- fakelab-0.1.0/tests/objects/node_test.py +23 -0
- fakelab-0.1.0/tests/objects/options_test.py +41 -0
- fakelab-0.1.0/tests/objects/point_test.py +77 -0
- fakelab-0.1.0/tests/objects/rect_test.py +106 -0
- fakelab-0.1.0/tests/objects/ttgasp_test.py +29 -0
- fakelab-0.1.0/tests/objects/tthcommand_test.py +26 -0
- fakelab-0.1.0/tests/objects/ttstem_test.py +49 -0
- fakelab-0.1.0/tox.ini +40 -0
fakelab-0.1.0/.flake8
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# These are supported funding model platforms
|
|
2
|
+
|
|
3
|
+
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
|
4
|
+
patreon: # Replace with a single Patreon username
|
|
5
|
+
open_collective: # Replace with a single Open Collective username
|
|
6
|
+
ko_fi: jenskutilek
|
|
7
|
+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
|
8
|
+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
|
9
|
+
liberapay: # Replace with a single Liberapay username
|
|
10
|
+
issuehunt: # Replace with a single IssueHunt username
|
|
11
|
+
otechie: # Replace with a single Otechie username
|
|
12
|
+
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Publish packages to PyPI
|
|
2
|
+
|
|
3
|
+
on: push
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
build-n-publish:
|
|
7
|
+
name: Build and publish distribution packages
|
|
8
|
+
if: github.repository == 'jenskutilek/fakelab'
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
environment:
|
|
11
|
+
name: pypi
|
|
12
|
+
url: https://pypi.org/p/fakelab
|
|
13
|
+
permissions:
|
|
14
|
+
id-token: write
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v5
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 0
|
|
19
|
+
- name: Set up Python 3.12
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: 3.12
|
|
23
|
+
|
|
24
|
+
- name: Install pypa/build
|
|
25
|
+
run: >-
|
|
26
|
+
python -m
|
|
27
|
+
pip install
|
|
28
|
+
build
|
|
29
|
+
--user
|
|
30
|
+
|
|
31
|
+
- name: Build a binary wheel and a source tarball
|
|
32
|
+
run: >-
|
|
33
|
+
python -m
|
|
34
|
+
build
|
|
35
|
+
--sdist
|
|
36
|
+
--wheel
|
|
37
|
+
--outdir dist/
|
|
38
|
+
.
|
|
39
|
+
|
|
40
|
+
- name: Publish distribution package to PyPI
|
|
41
|
+
if: startsWith(github.ref, 'refs/tags')
|
|
42
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
fakelab-0.1.0/.gitignore
ADDED
fakelab-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fakelab
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Fake FontLab Studio 5 for automated tests and external scripting
|
|
5
|
+
Author-email: Jens Kutílek <webmail@kutilek.de>
|
|
6
|
+
License-Expression: GPL-3.0-or-later
|
|
7
|
+
Project-URL: Homepage, https://github.com/jenskutilek/fakelab
|
|
8
|
+
Project-URL: Documentation, https://fakelab.readthedocs.io/
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/jenskutilek/fakelab/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/jenskutilek/fakelab/blob/develop/docs/CHANGELOG.md
|
|
11
|
+
Keywords: vfb,fonttools
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Provides-Extra: all
|
|
22
|
+
Requires-Dist: fakelab[generate]; extra == "all"
|
|
23
|
+
Requires-Dist: fakelab[repl]; extra == "all"
|
|
24
|
+
Requires-Dist: fakelab[vfb]; extra == "all"
|
|
25
|
+
Provides-Extra: generate
|
|
26
|
+
Requires-Dist: ufo2ft>=3.6.0; extra == "generate"
|
|
27
|
+
Requires-Dist: fakelab[vfb]; extra == "generate"
|
|
28
|
+
Provides-Extra: repl
|
|
29
|
+
Requires-Dist: ptpython>=3.0.30; extra == "repl"
|
|
30
|
+
Provides-Extra: vfb
|
|
31
|
+
Requires-Dist: vfbLib>=0.10.3; extra == "vfb"
|
|
32
|
+
Provides-Extra: test
|
|
33
|
+
Requires-Dist: mypy; extra == "test"
|
|
34
|
+
Requires-Dist: pytest; extra == "test"
|
|
35
|
+
Requires-Dist: pytest-black-ng; extra == "test"
|
|
36
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
37
|
+
Requires-Dist: pytest-isort; extra == "test"
|
|
38
|
+
Requires-Dist: pytest-mock; extra == "test"
|
|
39
|
+
Requires-Dist: pytest-mypy; extra == "test"
|
|
40
|
+
Requires-Dist: pytest-pylint; extra == "test"
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: build; extra == "dev"
|
|
43
|
+
Requires-Dist: wheel; extra == "dev"
|
|
44
|
+
Requires-Dist: setuptools-scm[toml]; extra == "dev"
|
|
45
|
+
Provides-Extra: doc
|
|
46
|
+
Requires-Dist: sphinx>=8.1.3; extra == "doc"
|
|
47
|
+
Requires-Dist: sphinx_rtd_theme; extra == "doc"
|
|
48
|
+
|
|
49
|
+
# FakeLab
|
|
50
|
+
|
|
51
|
+
Test-driven development for FontLab Studio 5 Python macros and modules.
|
|
52
|
+
|
|
53
|
+
FakeLab is a FontLab Studio 5 replacement for testing Python code.
|
|
54
|
+
|
|
55
|
+
Everything is only implemented so far as to make FontLab objects importable
|
|
56
|
+
outside of FontLab Studio 5, and run tests.
|
|
57
|
+
|
|
58
|
+
It is suggested to install FakeLab in a virtual environment so FontLab won't
|
|
59
|
+
accidentally import the fake module when running the scripts in actual FontLab
|
|
60
|
+
Studio 5. If you can live with the incompatibilites between Python 2.7 and 3,
|
|
61
|
+
you can also run FakeLab in Python 3.
|
|
62
|
+
|
|
63
|
+
Saving VFBs is not supported, as the VFB format is not public, but you can save
|
|
64
|
+
`Font` objects as JSON.
|
|
65
|
+
|
|
66
|
+
The implementation of FakeLab is based on the invaluable
|
|
67
|
+
[Unofficial FontLab/Python API Reference](http://www.e-font.de/flpydoc/), and
|
|
68
|
+
from running scripts in FontLab Studio and checking what they do, apart from
|
|
69
|
+
crashing the application.
|
|
70
|
+
|
|
71
|
+
## Installation
|
|
72
|
+
|
|
73
|
+
When you have activated your virtual environment:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
$ pip install -e .
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
FL is then importable outside of FontLab Studio:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from FL import fl, Font
|
|
83
|
+
|
|
84
|
+
# Make an empty font
|
|
85
|
+
f = Font()
|
|
86
|
+
|
|
87
|
+
# Add the font to the mock app
|
|
88
|
+
fl.Add(f)
|
|
89
|
+
|
|
90
|
+
# Close the font
|
|
91
|
+
fl.Close()
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If your are running in a virtual environment, and need to make your FontLab
|
|
95
|
+
modules importable, add a `.pth` file in your virtual environment's site-packages
|
|
96
|
+
directory:
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
# fl5modules.pth
|
|
100
|
+
/Users/<yourname>/Code/FLMacros/System/Modules
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## A word of caution
|
|
104
|
+
|
|
105
|
+
FakeLab is a work in progress, and only implemented as far as I needed it in my
|
|
106
|
+
own scripts. I have to admit that the bulk of them still has no tests.
|
|
107
|
+
|
|
108
|
+
If you encounter a `NotImplementedError` while writing tests, this is where you
|
|
109
|
+
can excel at helping to improve this project ;) I'll be happy to accept your
|
|
110
|
+
[pull requests](https://github.com/jenskutilek/fakelab/pulls). Alternatively,
|
|
111
|
+
[open an issue](https://github.com/jenskutilek/fakelab/issues),
|
|
112
|
+
[buy me a coffee](https://ko-fi.com/jenskutilek), and hope that my kids leave
|
|
113
|
+
me alone so I can find some time to work on your issue.
|
|
114
|
+
|
|
115
|
+
## Writing tests
|
|
116
|
+
|
|
117
|
+
Developing scripts without automated testing is really only for very small
|
|
118
|
+
projects. To be sure of the outcomes of a module or script, you should always
|
|
119
|
+
write tests. This is usually done using
|
|
120
|
+
[pytest](https://docs.pytest.org/en/stable/).
|
|
121
|
+
|
|
122
|
+
### Tests example
|
|
123
|
+
|
|
124
|
+
Let's assume you have a FontLab script to select glyphs containing components.
|
|
125
|
+
If you have your own tools collection for FontLab, this script may consist of
|
|
126
|
+
two parts: One script that is listed in FontLab's macro toolbar, and one Python
|
|
127
|
+
module implementing the logic, which is called by the toolbar script.
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
Studio 5
|
|
131
|
+
+- Macros
|
|
132
|
+
+- Selection
|
|
133
|
+
+- Select Composites.py
|
|
134
|
+
+- System
|
|
135
|
+
+- Modules
|
|
136
|
+
+- fakeLabDemo
|
|
137
|
+
+- selection
|
|
138
|
+
+- __init__.py
|
|
139
|
+
+- composites.py
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The `Select Composites.py` script looks like this:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
#FLM: Select composites
|
|
146
|
+
# Studio 5/Macros/Selection/Select Composites.py
|
|
147
|
+
from fakeLabDemo.selection.composites import selectComposites
|
|
148
|
+
selectComposites(fl.font)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
And the module:
|
|
152
|
+
```python
|
|
153
|
+
# Studio 5/Macros/System/Modules/fakeLabDemo/selection/composites.py
|
|
154
|
+
from __future__ import absolute_import, division, print_function
|
|
155
|
+
|
|
156
|
+
from FL import fl
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def getFontIndex(font):
|
|
160
|
+
"""
|
|
161
|
+
Get the index of the supplied font.
|
|
162
|
+
We must iterate through the open fonts and compare file names,
|
|
163
|
+
because the == operator can not compare the font objects directly.
|
|
164
|
+
(FL font objects get a different id() each time they are called)
|
|
165
|
+
|
|
166
|
+
:param font: A title for the dialog.
|
|
167
|
+
:type font: :py:class:`FL.Font`
|
|
168
|
+
"""
|
|
169
|
+
for i in range(len(fl)):
|
|
170
|
+
cf = fl[i]
|
|
171
|
+
if cf.file_name == font.file_name:
|
|
172
|
+
if font.file_name is None:
|
|
173
|
+
if (
|
|
174
|
+
cf.family_name == font.family_name
|
|
175
|
+
and cf.style_name == font.style_name
|
|
176
|
+
):
|
|
177
|
+
return (cf, i)
|
|
178
|
+
else:
|
|
179
|
+
return (cf, i)
|
|
180
|
+
# Font was not found, probably there are no open fonts
|
|
181
|
+
return (None, -1)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def setSelection(font, glyph_names):
|
|
185
|
+
"""
|
|
186
|
+
Set glyphs from the glyph_names list as selected in the font window.
|
|
187
|
+
"""
|
|
188
|
+
f, i = getFontIndex(font)
|
|
189
|
+
if i > -1:
|
|
190
|
+
fl.ifont = i
|
|
191
|
+
fl.Unselect()
|
|
192
|
+
for n in glyph_names:
|
|
193
|
+
fl.Select(n)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def selectComposites(font):
|
|
197
|
+
"""
|
|
198
|
+
Select composites in font.
|
|
199
|
+
"""
|
|
200
|
+
setSelection(
|
|
201
|
+
font,
|
|
202
|
+
[
|
|
203
|
+
glyph.name
|
|
204
|
+
for glyph in font.glyphs
|
|
205
|
+
if glyph.components
|
|
206
|
+
]
|
|
207
|
+
)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
How can we be sure this script does what it is supposed to do? For pytest, we
|
|
211
|
+
add another parallel folder structure to the existing structure:
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
Studio 5
|
|
215
|
+
+- Macros
|
|
216
|
+
+- Selection
|
|
217
|
+
+- Select Composites.py
|
|
218
|
+
+- System
|
|
219
|
+
+- Modules
|
|
220
|
+
+- fakeLabDemo
|
|
221
|
+
+- selection
|
|
222
|
+
+- __init__.py
|
|
223
|
+
+- composites.py
|
|
224
|
+
+- tests
|
|
225
|
+
+- fakeLabDemo
|
|
226
|
+
+- selection
|
|
227
|
+
+- composites_test.py
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The file `composites_test.py`, which is named analogous to the module file it
|
|
231
|
+
relates to, is where we will implement our tests:
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
# Studio 5/Macros/System/Modules/tests/fakeLabDemo/selection/composites_test.py
|
|
235
|
+
import pytest
|
|
236
|
+
|
|
237
|
+
from FL import fl, Component, Font, Glyph, Point
|
|
238
|
+
from fakeLabDemo.selection.composites import selectComposites
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def test_selectComposites():
|
|
242
|
+
# Construct a fake FontLab font object
|
|
243
|
+
font = Font()
|
|
244
|
+
g = Glyph(1)
|
|
245
|
+
g.name = "A"
|
|
246
|
+
g.width = 500
|
|
247
|
+
g.unicode = 0x41
|
|
248
|
+
font.glyphs.append(g)
|
|
249
|
+
|
|
250
|
+
g = Glyph(1)
|
|
251
|
+
g.name = "dieresis"
|
|
252
|
+
g.width = 500
|
|
253
|
+
g.unicode = 0xA8
|
|
254
|
+
font.glyphs.append(g)
|
|
255
|
+
|
|
256
|
+
g = Glyph(1)
|
|
257
|
+
g.name = "Adieresis"
|
|
258
|
+
g.width = 500
|
|
259
|
+
g.unicode = 0xC4
|
|
260
|
+
g.components.append(Component(0))
|
|
261
|
+
g.components.append(Component(1, Point(0, 300)))
|
|
262
|
+
font.glyphs.append(g)
|
|
263
|
+
|
|
264
|
+
# Add the font to the FL object
|
|
265
|
+
fl.Add(font)
|
|
266
|
+
fl.UpdateFont()
|
|
267
|
+
|
|
268
|
+
# Run our script to be tested on the font
|
|
269
|
+
selectComposites(fl.font)
|
|
270
|
+
|
|
271
|
+
# You could save the fake font to JSON instead of VFB.
|
|
272
|
+
# fl.font.Save("test_composites.vfb.json")
|
|
273
|
+
|
|
274
|
+
# Test if the correct glyphs have been selected
|
|
275
|
+
assert fl.Selected(0) == 0
|
|
276
|
+
assert fl.Selected(1) == 0
|
|
277
|
+
assert fl.Selected(2) == 1
|
|
278
|
+
|
|
279
|
+
# Close the fake font
|
|
280
|
+
fl.Close()
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
As you see, you can use the objects just as you would inside FontLab. You just
|
|
284
|
+
can not open a font from an existing VFB, which would be much easier. But the
|
|
285
|
+
VFB file format is not public.
|
|
286
|
+
|
|
287
|
+
Instead, you have to construct a test font using the
|
|
288
|
+
[FL Python API](http://www.e-font.de/flpydoc/).
|
|
289
|
+
|
|
290
|
+
Invoke the test script in a Terminal window while your virtual environment is
|
|
291
|
+
active:
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
cd "Studio 5/Macros/System/Modules"
|
|
295
|
+
python -m pytest tests/fakeLabDemo/selection/composites_test.py
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
If everything works out, you will see some output like this:
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
============================ test session starts ===============================
|
|
302
|
+
platform darwin -- Python 3.8.7, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
|
|
303
|
+
rootdir: /Users/jens/Code/fakelab
|
|
304
|
+
collected 1 item
|
|
305
|
+
|
|
306
|
+
tests/fakeLabDemo/selection/composites_test.py . [100%]
|
|
307
|
+
|
|
308
|
+
============================= 1 passed in 0.02s ================================
|
|
309
|
+
```
|
fakelab-0.1.0/README.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# FakeLab
|
|
2
|
+
|
|
3
|
+
Test-driven development for FontLab Studio 5 Python macros and modules.
|
|
4
|
+
|
|
5
|
+
FakeLab is a FontLab Studio 5 replacement for testing Python code.
|
|
6
|
+
|
|
7
|
+
Everything is only implemented so far as to make FontLab objects importable
|
|
8
|
+
outside of FontLab Studio 5, and run tests.
|
|
9
|
+
|
|
10
|
+
It is suggested to install FakeLab in a virtual environment so FontLab won't
|
|
11
|
+
accidentally import the fake module when running the scripts in actual FontLab
|
|
12
|
+
Studio 5. If you can live with the incompatibilites between Python 2.7 and 3,
|
|
13
|
+
you can also run FakeLab in Python 3.
|
|
14
|
+
|
|
15
|
+
Saving VFBs is not supported, as the VFB format is not public, but you can save
|
|
16
|
+
`Font` objects as JSON.
|
|
17
|
+
|
|
18
|
+
The implementation of FakeLab is based on the invaluable
|
|
19
|
+
[Unofficial FontLab/Python API Reference](http://www.e-font.de/flpydoc/), and
|
|
20
|
+
from running scripts in FontLab Studio and checking what they do, apart from
|
|
21
|
+
crashing the application.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
When you have activated your virtual environment:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
$ pip install -e .
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
FL is then importable outside of FontLab Studio:
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from FL import fl, Font
|
|
35
|
+
|
|
36
|
+
# Make an empty font
|
|
37
|
+
f = Font()
|
|
38
|
+
|
|
39
|
+
# Add the font to the mock app
|
|
40
|
+
fl.Add(f)
|
|
41
|
+
|
|
42
|
+
# Close the font
|
|
43
|
+
fl.Close()
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
If your are running in a virtual environment, and need to make your FontLab
|
|
47
|
+
modules importable, add a `.pth` file in your virtual environment's site-packages
|
|
48
|
+
directory:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
# fl5modules.pth
|
|
52
|
+
/Users/<yourname>/Code/FLMacros/System/Modules
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## A word of caution
|
|
56
|
+
|
|
57
|
+
FakeLab is a work in progress, and only implemented as far as I needed it in my
|
|
58
|
+
own scripts. I have to admit that the bulk of them still has no tests.
|
|
59
|
+
|
|
60
|
+
If you encounter a `NotImplementedError` while writing tests, this is where you
|
|
61
|
+
can excel at helping to improve this project ;) I'll be happy to accept your
|
|
62
|
+
[pull requests](https://github.com/jenskutilek/fakelab/pulls). Alternatively,
|
|
63
|
+
[open an issue](https://github.com/jenskutilek/fakelab/issues),
|
|
64
|
+
[buy me a coffee](https://ko-fi.com/jenskutilek), and hope that my kids leave
|
|
65
|
+
me alone so I can find some time to work on your issue.
|
|
66
|
+
|
|
67
|
+
## Writing tests
|
|
68
|
+
|
|
69
|
+
Developing scripts without automated testing is really only for very small
|
|
70
|
+
projects. To be sure of the outcomes of a module or script, you should always
|
|
71
|
+
write tests. This is usually done using
|
|
72
|
+
[pytest](https://docs.pytest.org/en/stable/).
|
|
73
|
+
|
|
74
|
+
### Tests example
|
|
75
|
+
|
|
76
|
+
Let's assume you have a FontLab script to select glyphs containing components.
|
|
77
|
+
If you have your own tools collection for FontLab, this script may consist of
|
|
78
|
+
two parts: One script that is listed in FontLab's macro toolbar, and one Python
|
|
79
|
+
module implementing the logic, which is called by the toolbar script.
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
Studio 5
|
|
83
|
+
+- Macros
|
|
84
|
+
+- Selection
|
|
85
|
+
+- Select Composites.py
|
|
86
|
+
+- System
|
|
87
|
+
+- Modules
|
|
88
|
+
+- fakeLabDemo
|
|
89
|
+
+- selection
|
|
90
|
+
+- __init__.py
|
|
91
|
+
+- composites.py
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The `Select Composites.py` script looks like this:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
#FLM: Select composites
|
|
98
|
+
# Studio 5/Macros/Selection/Select Composites.py
|
|
99
|
+
from fakeLabDemo.selection.composites import selectComposites
|
|
100
|
+
selectComposites(fl.font)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
And the module:
|
|
104
|
+
```python
|
|
105
|
+
# Studio 5/Macros/System/Modules/fakeLabDemo/selection/composites.py
|
|
106
|
+
from __future__ import absolute_import, division, print_function
|
|
107
|
+
|
|
108
|
+
from FL import fl
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def getFontIndex(font):
|
|
112
|
+
"""
|
|
113
|
+
Get the index of the supplied font.
|
|
114
|
+
We must iterate through the open fonts and compare file names,
|
|
115
|
+
because the == operator can not compare the font objects directly.
|
|
116
|
+
(FL font objects get a different id() each time they are called)
|
|
117
|
+
|
|
118
|
+
:param font: A title for the dialog.
|
|
119
|
+
:type font: :py:class:`FL.Font`
|
|
120
|
+
"""
|
|
121
|
+
for i in range(len(fl)):
|
|
122
|
+
cf = fl[i]
|
|
123
|
+
if cf.file_name == font.file_name:
|
|
124
|
+
if font.file_name is None:
|
|
125
|
+
if (
|
|
126
|
+
cf.family_name == font.family_name
|
|
127
|
+
and cf.style_name == font.style_name
|
|
128
|
+
):
|
|
129
|
+
return (cf, i)
|
|
130
|
+
else:
|
|
131
|
+
return (cf, i)
|
|
132
|
+
# Font was not found, probably there are no open fonts
|
|
133
|
+
return (None, -1)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def setSelection(font, glyph_names):
|
|
137
|
+
"""
|
|
138
|
+
Set glyphs from the glyph_names list as selected in the font window.
|
|
139
|
+
"""
|
|
140
|
+
f, i = getFontIndex(font)
|
|
141
|
+
if i > -1:
|
|
142
|
+
fl.ifont = i
|
|
143
|
+
fl.Unselect()
|
|
144
|
+
for n in glyph_names:
|
|
145
|
+
fl.Select(n)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def selectComposites(font):
|
|
149
|
+
"""
|
|
150
|
+
Select composites in font.
|
|
151
|
+
"""
|
|
152
|
+
setSelection(
|
|
153
|
+
font,
|
|
154
|
+
[
|
|
155
|
+
glyph.name
|
|
156
|
+
for glyph in font.glyphs
|
|
157
|
+
if glyph.components
|
|
158
|
+
]
|
|
159
|
+
)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
How can we be sure this script does what it is supposed to do? For pytest, we
|
|
163
|
+
add another parallel folder structure to the existing structure:
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
Studio 5
|
|
167
|
+
+- Macros
|
|
168
|
+
+- Selection
|
|
169
|
+
+- Select Composites.py
|
|
170
|
+
+- System
|
|
171
|
+
+- Modules
|
|
172
|
+
+- fakeLabDemo
|
|
173
|
+
+- selection
|
|
174
|
+
+- __init__.py
|
|
175
|
+
+- composites.py
|
|
176
|
+
+- tests
|
|
177
|
+
+- fakeLabDemo
|
|
178
|
+
+- selection
|
|
179
|
+
+- composites_test.py
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The file `composites_test.py`, which is named analogous to the module file it
|
|
183
|
+
relates to, is where we will implement our tests:
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
# Studio 5/Macros/System/Modules/tests/fakeLabDemo/selection/composites_test.py
|
|
187
|
+
import pytest
|
|
188
|
+
|
|
189
|
+
from FL import fl, Component, Font, Glyph, Point
|
|
190
|
+
from fakeLabDemo.selection.composites import selectComposites
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def test_selectComposites():
|
|
194
|
+
# Construct a fake FontLab font object
|
|
195
|
+
font = Font()
|
|
196
|
+
g = Glyph(1)
|
|
197
|
+
g.name = "A"
|
|
198
|
+
g.width = 500
|
|
199
|
+
g.unicode = 0x41
|
|
200
|
+
font.glyphs.append(g)
|
|
201
|
+
|
|
202
|
+
g = Glyph(1)
|
|
203
|
+
g.name = "dieresis"
|
|
204
|
+
g.width = 500
|
|
205
|
+
g.unicode = 0xA8
|
|
206
|
+
font.glyphs.append(g)
|
|
207
|
+
|
|
208
|
+
g = Glyph(1)
|
|
209
|
+
g.name = "Adieresis"
|
|
210
|
+
g.width = 500
|
|
211
|
+
g.unicode = 0xC4
|
|
212
|
+
g.components.append(Component(0))
|
|
213
|
+
g.components.append(Component(1, Point(0, 300)))
|
|
214
|
+
font.glyphs.append(g)
|
|
215
|
+
|
|
216
|
+
# Add the font to the FL object
|
|
217
|
+
fl.Add(font)
|
|
218
|
+
fl.UpdateFont()
|
|
219
|
+
|
|
220
|
+
# Run our script to be tested on the font
|
|
221
|
+
selectComposites(fl.font)
|
|
222
|
+
|
|
223
|
+
# You could save the fake font to JSON instead of VFB.
|
|
224
|
+
# fl.font.Save("test_composites.vfb.json")
|
|
225
|
+
|
|
226
|
+
# Test if the correct glyphs have been selected
|
|
227
|
+
assert fl.Selected(0) == 0
|
|
228
|
+
assert fl.Selected(1) == 0
|
|
229
|
+
assert fl.Selected(2) == 1
|
|
230
|
+
|
|
231
|
+
# Close the fake font
|
|
232
|
+
fl.Close()
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
As you see, you can use the objects just as you would inside FontLab. You just
|
|
236
|
+
can not open a font from an existing VFB, which would be much easier. But the
|
|
237
|
+
VFB file format is not public.
|
|
238
|
+
|
|
239
|
+
Instead, you have to construct a test font using the
|
|
240
|
+
[FL Python API](http://www.e-font.de/flpydoc/).
|
|
241
|
+
|
|
242
|
+
Invoke the test script in a Terminal window while your virtual environment is
|
|
243
|
+
active:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
cd "Studio 5/Macros/System/Modules"
|
|
247
|
+
python -m pytest tests/fakeLabDemo/selection/composites_test.py
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
If everything works out, you will see some output like this:
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
============================ test session starts ===============================
|
|
254
|
+
platform darwin -- Python 3.8.7, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
|
|
255
|
+
rootdir: /Users/jens/Code/fakelab
|
|
256
|
+
collected 1 item
|
|
257
|
+
|
|
258
|
+
tests/fakeLabDemo/selection/composites_test.py . [100%]
|
|
259
|
+
|
|
260
|
+
============================= 1 passed in 0.02s ================================
|
|
261
|
+
```
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Minimal makefile for Sphinx documentation
|
|
2
|
+
#
|
|
3
|
+
|
|
4
|
+
# You can set these variables from the command line, and also
|
|
5
|
+
# from the environment for the first two.
|
|
6
|
+
SPHINXOPTS ?=
|
|
7
|
+
SPHINXBUILD ?= sphinx-build
|
|
8
|
+
SOURCEDIR = source
|
|
9
|
+
BUILDDIR = build
|
|
10
|
+
|
|
11
|
+
# Put it first so that "make" without argument is like "make help".
|
|
12
|
+
help:
|
|
13
|
+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
14
|
+
|
|
15
|
+
.PHONY: help Makefile
|
|
16
|
+
|
|
17
|
+
# Catch-all target: route all unknown targets to Sphinx using the new
|
|
18
|
+
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
|
19
|
+
%: Makefile
|
|
20
|
+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
@ECHO OFF
|
|
2
|
+
|
|
3
|
+
pushd %~dp0
|
|
4
|
+
|
|
5
|
+
REM Command file for Sphinx documentation
|
|
6
|
+
|
|
7
|
+
if "%SPHINXBUILD%" == "" (
|
|
8
|
+
set SPHINXBUILD=sphinx-build
|
|
9
|
+
)
|
|
10
|
+
set SOURCEDIR=source
|
|
11
|
+
set BUILDDIR=build
|
|
12
|
+
|
|
13
|
+
if "%1" == "" goto help
|
|
14
|
+
|
|
15
|
+
%SPHINXBUILD% >NUL 2>NUL
|
|
16
|
+
if errorlevel 9009 (
|
|
17
|
+
echo.
|
|
18
|
+
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
|
19
|
+
echo.installed, then set the SPHINXBUILD environment variable to point
|
|
20
|
+
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
|
21
|
+
echo.may add the Sphinx directory to PATH.
|
|
22
|
+
echo.
|
|
23
|
+
echo.If you don't have Sphinx installed, grab it from
|
|
24
|
+
echo.http://sphinx-doc.org/
|
|
25
|
+
exit /b 1
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
|
29
|
+
goto end
|
|
30
|
+
|
|
31
|
+
:help
|
|
32
|
+
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
|
33
|
+
|
|
34
|
+
:end
|
|
35
|
+
popd
|