diff --git a/features.js b/features.js
index 8efc23c..3bcfc98 100644
--- a/features.js
+++ b/features.js
@@ -1,7 +1,12 @@
+const withBakedDownload = document.querySelector('#wb');
+
const styles = new Map([...document.querySelectorAll('[type=checkbox]')].map(e => [e.value, e]));
for (const element of styles.values()) {
element.addEventListener('input', () => {
const settings = [...styles.entries()].flatMap(([s, e]) => e.checked ? ['"' + s + '"'] : []).join(', ');
document.body.style.fontFeatureSettings = settings.trim().length ? settings : 'unset';
+ withBakedDownload.href = `APL387-${settings.replaceAll(', ', '-').replaceAll('"', '')}.ttf`;
+ if (settings.trim().length) withBakedDownload.classList.add('s');
+ else withBakedDownload.classList.remove('s');
});
-}
\ No newline at end of file
+}
diff --git a/index.css b/index.css
index 184035a..ada3c4f 100644
--- a/index.css
+++ b/index.css
@@ -41,4 +41,10 @@ textarea {
font-size: inherit;
font-family: inherit;
}
+#wb {
+ display: none;
+}
+#wb.s {
+ display: unset;
+}
\ No newline at end of file
diff --git a/script.py b/script.py
index d81d8cc..f28c576 100644
--- a/script.py
+++ b/script.py
@@ -1,13 +1,18 @@
import fontforge
import os
import sys
+from itertools import chain, combinations
+
+def powerset(iterable):
+ s = list(iterable)
+ return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
EXTENSIONS = [
- 'ttf',
- 'otf',
- 'woff',
- 'woff2',
- 'svg',
+ 'ttf',
+ 'otf',
+ 'woff',
+ 'woff2',
+ 'svg',
]
path = sys.argv[1]
@@ -18,14 +23,14 @@
apl387.version = commit
try:
- os.mkdir(f'{path}/output')
+ os.mkdir(f'{path}/output')
except:
- pass
+ pass
features = [apl387.getLookupInfo(lookup)[2][0][0] for lookup in apl387.gsub_lookups]
with open(f'{path}/output/chars.html', 'w') as chars:
- chars.write('''
+ chars.write('''
@@ -42,17 +47,17 @@
APL385 Unicode
new APL387 Unicode
- ''')
- for gl in sorted((gl for gl in apl387.glyphs() if gl.unicode != -1), key=lambda gl: gl.unicode):
- chars.write(f'
{gl.unicode};
{gl.unicode};
\n')
- chars.write('''
+ ''')
+ for gl in sorted((gl for gl in apl387.glyphs() if gl.unicode != -1), key=lambda gl: gl.unicode):
+ chars.write(f'
{gl.unicode};
{gl.unicode};
\n')
+ chars.write('''
- ''')
+ ''')
with open(f'{path}/output/compare.html', 'w', encoding='utf-8') as compare:
- compare.write('''
+ compare.write('''
@@ -62,7 +67,7 @@
@font-face {font-family: 'APL385';src: url('APL385.ttf');}
* {
font-weight: unset;
- font-feature-settings: inherit;
+ font-feature-settings: inherit;
}
body {
@@ -93,11 +98,11 @@
- ''')
- for feature in features:
- compare.write(f'')
- compare.write(' compare characters individually')
- same = '''
+ ''')
+ for feature in features:
+ compare.write(f'')
+ compare.write(' compare characters individually')
+ same = '''
Class
@@ -181,27 +186,27 @@
APL (named after the book A Programming Language) is a programming language developed in the 1960s by Kenneth E. Iverson. Its central datatype is the multidimensional array. It uses a large range of special graphic symbols to represent most functions and operators, leading to very concise code. It has been an important influence on the development of concept modeling, spreadsheets, functional programming, and computer math packages. It has also inspired several other programming languages.
All supported characters:
- '''
- for idx, gl in enumerate(sorted((gl for gl in apl387.glyphs() if gl.unicode != -1), key=lambda gl: gl.unicode)):
- if idx != 0 and idx % 16 == 0: same += '\n'
- same += f'{gl.unicode};'
- same += '
'
- compare.write(f'''
+ '''
+ for idx, gl in enumerate(sorted((gl for gl in apl387.glyphs() if gl.unicode != -1), key=lambda gl: gl.unicode)):
+ if idx != 0 and idx % 16 == 0: same += '\n'
+ same += f'{gl.unicode};'
+ same += ''
+ compare.write(f'''
A redrawn and extended version of Adrian Smith's classic APL385 font with clean rounded look.
@@ -307,9 +312,47 @@
Sample text:
APL (named after the book A Programming Language) is a programming language developed in the 1960s by Kenneth E. Iverson. Its central datatype is the multidimensional array. It uses a large range of special graphic symbols to represent most functions and operators, leading to very concise code. It has been an important influence on the development of concept modeling, spreadsheets, functional programming, and computer math packages. It has also inspired several other programming languages.
-
+
- ''')
+ ''')
+
+def bake_feature(lookup: str):
+ subtable = apl387.getLookupSubtables(lookup)[0]
+ to_swap = []
+ for glyph in apl387.glyphs():
+ lookups = glyph.getPosSub(subtable)
+ if len(lookups) == 0: continue
+ elif len(lookups) == 1:
+ to_swap.append((glyph, apl387.createMappedChar(lookups[0][2])))
+ else:
+ raise RuntimeError(f'Glyph {glyph.glyphname} has more than one lookup, I don\'t know what to do.')
+ for a, b in to_swap:
+ swap_glyphs(a, b)
+
+temp = apl387.createChar(-1, 'swapTemp')
+
+def swap_glyphs(a, b):
+ apl387.selection.select(a)
+ apl387.copy()
+ apl387.selection.select(temp)
+ apl387.paste()
+ apl387.selection.select(b)
+ apl387.copy()
+ apl387.selection.select(a)
+ apl387.paste()
+ apl387.selection.select(temp)
+ apl387.copy()
+ apl387.selection.select(b)
+ apl387.paste()
-for ext in EXTENSIONS:
- apl387.generate(f'{path}/output/APL387.{ext}')
+for subset in powerset(apl387.gsub_lookups):
+ baked_features = [apl387.getLookupInfo(lookup)[2][0][0] for lookup in subset]
+ apl387.familyname = f'APL387 Unicode {" ".join(baked_features)}' if len(subset) else 'APL387 Unicode'
+ file_name = f'APL387-{"-".join(baked_features)}' if len(subset) else 'APL387'
+ for lookup in subset:
+ bake_feature(lookup)
+ for ext in EXTENSIONS:
+ apl387.generate(f'{path}/output/{file_name}.{ext}')
+ # undo swaps
+ for lookup in subset:
+ bake_feature(lookup)