Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7a86cd065f | |||
| 834a086e09 | |||
| 298723b87e | |||
| 0956c0e569 | |||
| 30ef51ace3 | |||
| 8aa2677ffc | |||
| 5c25311fdf | |||
| a55ef07837 | |||
| 09bbb2bb76 | |||
| 4ff7dbde28 | |||
| 0d7089f840 | |||
| 8a32259fdc | |||
| ee481cc744 | |||
| 196e13856c | |||
| 2029e07965 | |||
| 4955c58098 | |||
| c63a5b0abb | |||
| 8f7db7bc4c | |||
| 3813319b42 | |||
| f2a61c74ad | |||
| 1fce61fe50 | |||
| 1028c96291 | |||
| 043c160546 | |||
| 445828c8bf | |||
| 66fd3f94a1 | |||
| 9bf5f6197c | |||
| bd48389313 |
@@ -66,6 +66,33 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Kilua99",
|
||||
"name": "kilua99",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/44760686?v=4",
|
||||
"profile": "https://github.com/Kilua99",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "GlorifiedBicycle",
|
||||
"name": "Reland Boyle",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/71753585?v=4",
|
||||
"profile": "https://github.com/GlorifiedBicycle",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "killua99",
|
||||
"name": "Luigi",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/457822?v=4",
|
||||
"profile": "http://killua.me/",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
es6: true,
|
||||
node: true
|
||||
node: true,
|
||||
},
|
||||
extends: 'eslint:recommended',
|
||||
extends: ['eslint:recommended', 'prettier'],
|
||||
parserOptions: {
|
||||
sourceType: 'module'
|
||||
sourceType: 'module',
|
||||
},
|
||||
rules: {
|
||||
indent: ['error', 2],
|
||||
'linebreak-style': ['error', 'unix'],
|
||||
quotes: ['error', 'single'],
|
||||
semi: ['error', 'always'],
|
||||
'no-console': 'off'
|
||||
}
|
||||
};
|
||||
'no-console': 'off',
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
build
|
||||
node_modules
|
||||
.idea
|
||||
.vscode/launch.json
|
||||
.vscode
|
||||
.DS_Store
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"semi": true,
|
||||
"singleQuote": true
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ characters properly.
|
||||
|
||||
<img src="./images/caret-position.gif" />
|
||||
|
||||
## 👀 <a href="https://htmlpreview.github.io/?https://github.com/kiliman/operator-mono-lig/blob/master/images/preview/normal/index.html">Click here to see preview images of all ligatures</a>
|
||||
|
||||
With the awesome help from [Mark Skelton](https://github.com/mskelton), we now have the full set of ligatures for
|
||||
the following fonts. Thanks Mark, and thanks to all of you who have been patiently waiting for these ligatures to be completed.
|
||||
|
||||
@@ -57,6 +59,8 @@ Which font weight of Operator Mono do you use? Also note difference between Scre
|
||||
- Node.js
|
||||
- Install _fonttools_ from https://github.com/fonttools/fonttools
|
||||
- Windows/Linux: `pip install fonttools`
|
||||
- **NOTE**: For Windows you should use a console with administrative permissions if your Python sit under `C:\PythonX`
|
||||
- **NOTE**: For Linux in WSL/WSL2, ensure that _fonttools_ is added to PATH after install. Alternatively, consider installing via `sudo apt install fonttools`.
|
||||
- Mac: `pip3 install fonttools`
|
||||
|
||||
## Installation
|
||||
@@ -152,17 +156,22 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/kiliman"><img src="https://avatars3.githubusercontent.com/u/47168?v=4" width="100px;" alt="Kiliman"/><br /><sub><b>Kiliman</b></sub></a><br /><a href="https://github.com/kiliman/operator-mono-lig/commits?author=kiliman" title="Code">💻</a> <a href="https://github.com/kiliman/operator-mono-lig/commits?author=kiliman" title="Documentation">📖</a> <a href="#design-kiliman" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://github.com/mskelton"><img src="https://avatars3.githubusercontent.com/u/25914066?v=4" width="100px;" alt="Mark Skelton"/><br /><sub><b>Mark Skelton</b></sub></a><br /><a href="#design-mskelton" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://github.com/drod3763"><img src="https://avatars2.githubusercontent.com/u/7785716?v=4" width="100px;" alt="Derick Rodriguez"/><br /><sub><b>Derick Rodriguez</b></sub></a><br /><a href="https://github.com/kiliman/operator-mono-lig/commits?author=drod3763" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://github.com/amitkparekh"><img src="https://avatars3.githubusercontent.com/u/7276308?v=4" width="100px;" alt="Amit Parekh"/><br /><sub><b>Amit Parekh</b></sub></a><br /><a href="https://github.com/kiliman/operator-mono-lig/commits?author=amitkparekh" title="Documentation">📖</a> <a href="#design-amitkparekh" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://github.com/CandySunPlus"><img src="https://avatars0.githubusercontent.com/u/502700?v=4" width="100px;" alt="NikSun"/><br /><sub><b>NikSun</b></sub></a><br /><a href="#design-CandySunPlus" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://github.com/Jakob6174"><img src="https://avatars3.githubusercontent.com/u/40262817?v=4" width="100px;" alt="Jakob Pearson"/><br /><sub><b>Jakob Pearson</b></sub></a><br /><a href="https://github.com/kiliman/operator-mono-lig/commits?author=Jakob6174" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/kiliman"><img src="https://avatars3.githubusercontent.com/u/47168?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kiliman</b></sub></a><br /><a href="https://github.com/kiliman/operator-mono-lig/commits?author=kiliman" title="Code">💻</a> <a href="https://github.com/kiliman/operator-mono-lig/commits?author=kiliman" title="Documentation">📖</a> <a href="#design-kiliman" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://github.com/mskelton"><img src="https://avatars3.githubusercontent.com/u/25914066?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mark Skelton</b></sub></a><br /><a href="#design-mskelton" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://github.com/drod3763"><img src="https://avatars2.githubusercontent.com/u/7785716?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Derick Rodriguez</b></sub></a><br /><a href="https://github.com/kiliman/operator-mono-lig/commits?author=drod3763" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://github.com/amitkparekh"><img src="https://avatars3.githubusercontent.com/u/7276308?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Amit Parekh</b></sub></a><br /><a href="https://github.com/kiliman/operator-mono-lig/commits?author=amitkparekh" title="Documentation">📖</a> <a href="#design-amitkparekh" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://github.com/CandySunPlus"><img src="https://avatars0.githubusercontent.com/u/502700?v=4?s=100" width="100px;" alt=""/><br /><sub><b>NikSun</b></sub></a><br /><a href="#design-CandySunPlus" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://github.com/Jakob6174"><img src="https://avatars3.githubusercontent.com/u/40262817?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jakob Pearson</b></sub></a><br /><a href="https://github.com/kiliman/operator-mono-lig/commits?author=Jakob6174" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://killua.me/"><img src="https://avatars.githubusercontent.com/u/457822?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Luigi</b></sub></a><br /><a href="https://github.com/kiliman/operator-mono-lig/commits?author=killua99" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/GlorifiedBicycle"><img src="https://avatars.githubusercontent.com/u/71753585?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Reland Boyle</b></sub></a><br /><a href="https://github.com/kiliman/operator-mono-lig/commits?author=GlorifiedBicycle" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-enable -->
|
||||
<!-- markdownlint-restore -->
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
||||
@@ -31,4 +31,6 @@ if not exist .\ligature\%lig%\glyphs\* exit /b
|
||||
ttx -f .\original\%otf%.otf
|
||||
node index.js %otf% %flags%
|
||||
ttx -f .\build\%lig%.ttx
|
||||
fonttools feaLib -v -o ".\build\%lig%.otf" .\features\default.fea ".\build\%lig%.otf"
|
||||
|
||||
exit /b
|
||||
|
||||
@@ -16,11 +16,13 @@ build_font() {
|
||||
return
|
||||
fi
|
||||
|
||||
echo Building $1
|
||||
echo Building "$1"
|
||||
ttx -f "./original/$otf.otf"
|
||||
node index.js $otf $flags
|
||||
node index.js "$otf" "$flags"
|
||||
|
||||
ttx -f ./build/$1.ttx
|
||||
ttx -f "./build/$1.ttx"
|
||||
|
||||
fonttools feaLib -v -o "./build/$1.otf" ./features/default.fea "./build/$1.otf"
|
||||
}
|
||||
|
||||
flags=
|
||||
@@ -32,10 +34,10 @@ fi
|
||||
if [ -n "$1" ]
|
||||
then
|
||||
# build specified font
|
||||
build_font $1 $flags
|
||||
build_font "$1" "$flags"
|
||||
else
|
||||
# build all available fonts
|
||||
for d in ./ligature/*/ ; do
|
||||
build_font $(basename $d) $flags
|
||||
build_font "$(basename "$d")" "$flags"
|
||||
done
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
const fs = require('fs')
|
||||
|
||||
const rules = [
|
||||
'',
|
||||
`
|
||||
lookup 1 {
|
||||
sub 1 by glyph;
|
||||
} 1;`,
|
||||
`
|
||||
lookup 1_2 {
|
||||
ignore sub 1 1' 2;
|
||||
ignore sub 1' 2 2;
|
||||
sub 1.spacer 2' by glyph;
|
||||
sub 1' 2 by 1.spacer;
|
||||
} 1_2;`,
|
||||
`
|
||||
lookup 1_2_3 {
|
||||
ignore sub 1 1' 2 3;
|
||||
ignore sub 1' 2 3 3;
|
||||
sub 1.spacer 2.spacer 3' by glyph;
|
||||
sub 1.spacer 2' 3 by 2.spacer;
|
||||
sub 1' 2 3 by 1.spacer;
|
||||
} 1_2_3;`,
|
||||
`
|
||||
lookup 1_2_3_4 {
|
||||
ignore sub 1 1' 2 3 4;
|
||||
ignore sub 1' 2 3 4 4;
|
||||
sub 1.spacer 2.spacer 3.spacer 4' by glyph;
|
||||
sub 1.spacer 2.spacer 3' 4 by 3.spacer;
|
||||
sub 1.spacer 2' 3 4 by 2.spacer;
|
||||
sub 1' 2 3 4 by 1.spacer;
|
||||
} 1_2_3_4;`,
|
||||
]
|
||||
|
||||
const gencalt = ligatures => {
|
||||
let calt = 'feature calt {\n'
|
||||
const ligs = {}
|
||||
|
||||
ligatures
|
||||
.filter(l => !!l.name.match(/\.liga$/) || l.name !== l.glyph)
|
||||
.map(l => l.glyph)
|
||||
.sort((a, b) => {
|
||||
const length = b.split('_').length - a.split('_').length
|
||||
if (length !== 0) return length
|
||||
return a < b ? -1 : 1
|
||||
})
|
||||
.forEach(g => {
|
||||
g.split('.')
|
||||
.slice(0, 1)
|
||||
.forEach(l => {
|
||||
if (ligs[l]) return
|
||||
ligs[l] = true
|
||||
const c = l.split('_')
|
||||
let rule = rules[c.length]
|
||||
rule = rule
|
||||
.replace(/\d/g, m => c[parseInt(m) - 1])
|
||||
.replace(/glyph/g, g)
|
||||
calt += rule + '\n'
|
||||
})
|
||||
})
|
||||
|
||||
return calt + '\n} calt;\n'
|
||||
}
|
||||
|
||||
exports.gencalt = gencalt
|
||||
@@ -0,0 +1 @@
|
||||
calt.fea
|
||||
@@ -0,0 +1,212 @@
|
||||
languagesystem DFLT dflt;
|
||||
languagesystem latn dflt;
|
||||
|
||||
lookup lookup_0 {
|
||||
sub zero by zero.num;
|
||||
sub one by one.num;
|
||||
sub two by two.num;
|
||||
sub three by three.num;
|
||||
sub four by four.num;
|
||||
sub five by five.num;
|
||||
sub six by six.num;
|
||||
sub seven by seven.num;
|
||||
sub eight by eight.num;
|
||||
sub nine by nine.num;
|
||||
sub slash by fraction;
|
||||
sub fraction by fraction.afrc;
|
||||
} lookup_0;
|
||||
|
||||
lookup lookup_1 {
|
||||
sub zero by zero.den;
|
||||
sub one by one.den;
|
||||
sub two by two.den;
|
||||
sub three by three.den;
|
||||
sub four by four.den;
|
||||
sub five by five.den;
|
||||
sub six by six.den;
|
||||
sub seven by seven.den;
|
||||
sub eight by eight.den;
|
||||
sub nine by nine.den;
|
||||
sub slash by fraction;
|
||||
} lookup_1;
|
||||
|
||||
lookup lookup_2 {
|
||||
sub L periodcentered by Ldot;
|
||||
sub l periodcentered by ldot;
|
||||
} lookup_2;
|
||||
|
||||
|
||||
feature case {
|
||||
sub guillemotleft by guillemotleft.cap;
|
||||
sub guillemotright by guillemotright.cap;
|
||||
sub guilsinglleft by guilsinglleft.cap;
|
||||
sub guilsinglright by guilsinglright.cap;
|
||||
sub parenleft by parenleft.cap;
|
||||
sub parenright by parenright.cap;
|
||||
sub bracketleft by bracketleft.cap;
|
||||
sub bracketright by bracketright.cap;
|
||||
sub braceleft by braceleft.cap;
|
||||
sub braceright by braceright.cap;
|
||||
} case;
|
||||
|
||||
feature dnom {
|
||||
sub zero by zero.den;
|
||||
sub one by one.den;
|
||||
sub two by two.den;
|
||||
sub three by three.den;
|
||||
sub four by four.den;
|
||||
sub five by five.den;
|
||||
sub six by six.den;
|
||||
sub seven by seven.den;
|
||||
sub eight by eight.den;
|
||||
sub nine by nine.den;
|
||||
} dnom;
|
||||
|
||||
feature frac {
|
||||
lookup frac0 {
|
||||
sub [zero one two three four five six seven eight nine] slash' lookup lookup_0 [zero one two three four five six seven eight nine] ;
|
||||
} frac0;
|
||||
lookup frac1 {
|
||||
ignore sub [zero one two three four five six seven eight nine zero.num one.num two.num three.num four.num five.num six.num seven.num eight.num nine.num zero.den one.den two.den three.den four.den five.den six.den seven.den eight.den nine.den] [zero one two three four five six seven eight nine zero.num one.num two.num three.num four.num five.num six.num seven.num eight.num nine.num zero.den one.den two.den three.den four.den five.den six.den seven.den eight.den nine.den] fraction' ;
|
||||
ignore sub fraction' [zero one two three four five six seven eight nine zero.num one.num two.num three.num four.num five.num six.num seven.num eight.num nine.num zero.den one.den two.den three.den four.den five.den six.den seven.den eight.den nine.den] [zero one two three four five six seven eight nine zero.num one.num two.num three.num four.num five.num six.num seven.num eight.num nine.num zero.den one.den two.den three.den four.den five.den six.den seven.den eight.den nine.den] ;
|
||||
sub [zero one two three four five six seven eight nine zero.num one.num two.num three.num four.num five.num six.num seven.num eight.num nine.num zero.den one.den two.den three.den four.den five.den six.den seven.den eight.den nine.den] fraction' lookup lookup_0 [zero one two three four five six seven eight nine zero.num one.num two.num three.num four.num five.num six.num seven.num eight.num nine.num zero.den one.den two.den three.den four.den five.den six.den seven.den eight.den nine.den] ;
|
||||
} frac1;
|
||||
lookup frac2 {
|
||||
sub [zero one two three four five six seven eight nine]' lookup lookup_0 fraction.afrc ;
|
||||
sub fraction.afrc [zero one two three four five six seven eight nine]' lookup lookup_1 ;
|
||||
} frac2;
|
||||
lookup frac3 {
|
||||
sub one.num fraction.afrc two.den by onehalf;
|
||||
sub one.num fraction.afrc three.den by onethird;
|
||||
sub one.num fraction.afrc four.den by onequarter;
|
||||
sub one.num fraction.afrc five.den by onefifth;
|
||||
sub one.num fraction.afrc six.den by onesixth;
|
||||
sub one.num fraction.afrc eight.den by oneeighth;
|
||||
sub two.num fraction.afrc three.den by twothirds;
|
||||
sub two.num fraction.afrc five.den by twofifths;
|
||||
sub three.num fraction.afrc four.den by threequarters;
|
||||
sub three.num fraction.afrc five.den by threefifths;
|
||||
sub three.num fraction.afrc eight.den by threeeighths;
|
||||
sub four.num fraction.afrc five.den by fourfifths;
|
||||
sub five.num fraction.afrc six.den by fivesixths;
|
||||
sub five.num fraction.afrc eight.den by fiveeighths;
|
||||
sub seven.num fraction.afrc eight.den by seveneighths;
|
||||
} frac3;
|
||||
} frac;
|
||||
|
||||
feature locl {
|
||||
script latn;
|
||||
language CAT ;
|
||||
sub l' lookup lookup_2 periodcentered' lookup lookup_2 l ;
|
||||
sub L' lookup lookup_2 periodcentered' lookup lookup_2 L ;
|
||||
} locl;
|
||||
|
||||
feature numr {
|
||||
sub zero by zero.num;
|
||||
sub one by one.num;
|
||||
sub two by two.num;
|
||||
sub three by three.num;
|
||||
sub four by four.num;
|
||||
sub five by five.num;
|
||||
sub six by six.num;
|
||||
sub seven by seven.num;
|
||||
sub eight by eight.num;
|
||||
sub nine by nine.num;
|
||||
} numr;
|
||||
|
||||
feature rupa {
|
||||
sub R p by R_p;
|
||||
} rupa;
|
||||
|
||||
feature ss01 {
|
||||
sub registered by registered.alt;
|
||||
} ss01;
|
||||
|
||||
feature salt {
|
||||
lookup salt0 {
|
||||
sub registered by registered.alt;
|
||||
} salt0;
|
||||
lookup salt1 {
|
||||
sub colon by colon.alt;
|
||||
} salt1;
|
||||
lookup salt2 {
|
||||
sub bullet by bullet.alt;
|
||||
} salt2;
|
||||
lookup salt3 {
|
||||
sub asterisk by asterisk.alt;
|
||||
} salt3;
|
||||
lookup salt4 {
|
||||
sub zero by zero.alt;
|
||||
} salt4;
|
||||
lookup salt5 {
|
||||
sub underscore by underscore.alt;
|
||||
} salt5;
|
||||
lookup salt6 {
|
||||
sub [zero one two three four five six seven eight nine zero.num one.num two.num three.num four.num five.num six.num seven.num eight.num nine.num zero.den one.den two.den three.den four.den five.den six.den seven.den eight.den nine.den] slash' lookup lookup_1 [zero one two three four five six seven eight nine zero.num one.num two.num three.num four.num five.num six.num seven.num eight.num nine.num zero.den one.den two.den three.den four.den five.den six.den seven.den eight.den nine.den] ;
|
||||
} salt6;
|
||||
} salt;
|
||||
|
||||
feature sinf {
|
||||
sub zero by zero.inf;
|
||||
sub one by one.inf;
|
||||
sub two by two.inf;
|
||||
sub three by three.inf;
|
||||
sub four by four.inf;
|
||||
sub five by five.inf;
|
||||
sub six by six.inf;
|
||||
sub seven by seven.inf;
|
||||
sub eight by eight.inf;
|
||||
sub nine by nine.inf;
|
||||
} sinf;
|
||||
|
||||
feature ss03 {
|
||||
sub colon by colon.alt;
|
||||
} ss03;
|
||||
|
||||
feature ss04 {
|
||||
sub bullet by bullet.alt;
|
||||
} ss04;
|
||||
|
||||
feature ss05 {
|
||||
sub asterisk by asterisk.alt;
|
||||
} ss05;
|
||||
|
||||
feature ss07 {
|
||||
sub zero by zero.alt;
|
||||
} ss07;
|
||||
|
||||
feature ss08 {
|
||||
sub underscore by underscore.alt;
|
||||
} ss08;
|
||||
|
||||
feature ss09 {
|
||||
sub [zero one two three four five six seven eight nine zero.num one.num two.num three.num four.num five.num six.num seven.num eight.num nine.num zero.den one.den two.den three.den four.den five.den six.den seven.den eight.den nine.den] slash' lookup lookup_1 [zero one two three four five six seven eight nine zero.num one.num two.num three.num four.num five.num six.num seven.num eight.num nine.num zero.den one.den two.den three.den four.den five.den six.den seven.den eight.den nine.den] ;
|
||||
} ss09;
|
||||
|
||||
feature subs {
|
||||
sub zero by zero.inf;
|
||||
sub one by one.inf;
|
||||
sub two by two.inf;
|
||||
sub three by three.inf;
|
||||
sub four by four.inf;
|
||||
sub five by five.inf;
|
||||
sub six by six.inf;
|
||||
sub seven by seven.inf;
|
||||
sub eight by eight.inf;
|
||||
sub nine by nine.inf;
|
||||
} subs;
|
||||
|
||||
feature subs {
|
||||
sub zero by zero.sup;
|
||||
sub one by one.sup;
|
||||
sub two by two.sup;
|
||||
sub three by three.sup;
|
||||
sub four by four.sup;
|
||||
sub five by five.sup;
|
||||
sub six by six.sup;
|
||||
sub seven by seven.sup;
|
||||
sub eight by eight.sup;
|
||||
sub nine by nine.sup;
|
||||
} subs;
|
||||
|
||||
include(calt.fea);
|
||||
@@ -0,0 +1,85 @@
|
||||
const fs = require('fs')
|
||||
const { createCanvas } = require('canvas')
|
||||
|
||||
const width = 64
|
||||
const height = 48
|
||||
const weight = 300
|
||||
|
||||
const map = {
|
||||
ampersand: '&',
|
||||
bar: '|',
|
||||
colon: ':',
|
||||
equal: '=',
|
||||
exclam: '!',
|
||||
greater: '>',
|
||||
hyphen: '-',
|
||||
less: '<',
|
||||
plus: '+',
|
||||
question: '?',
|
||||
slash: '/',
|
||||
underscore: '_',
|
||||
w: 'w',
|
||||
}
|
||||
|
||||
function generateLigaturePreview(style, filename) {
|
||||
const ligature = filename.split('.').slice(0, 1)[0]
|
||||
const chars = ligature.split('_')
|
||||
|
||||
const text = chars.reduce((t, c) => t + map[c], '')
|
||||
|
||||
const canvas = createCanvas(width, height)
|
||||
const context = canvas.getContext('2d')
|
||||
|
||||
context.fillStyle = '#000'
|
||||
context.fillRect(0, 0, width, height)
|
||||
|
||||
context.font = `${weight} ${style} 18pt "Operator Mono SSm Lig"`
|
||||
context.textAlign = 'center'
|
||||
context.fillStyle = '#fff'
|
||||
context.text = text
|
||||
context.fillText(text, 32, 32)
|
||||
|
||||
const buffer = canvas.toBuffer('image/png')
|
||||
console.log(ligature)
|
||||
fs.writeFileSync(`./images/preview/${style}/${ligature}.png`, buffer)
|
||||
|
||||
return { text, ligature, filename: `${ligature}.png` }
|
||||
}
|
||||
|
||||
function generate(style, filenames) {
|
||||
let html = `<html><head>
|
||||
<style>
|
||||
body { background-color: #000; color: #fff; font-family: sans-serif; margin: 16px;}
|
||||
a { color: #fff; text-decoration: none; padding: 4px;}
|
||||
a.active {color: #000; background-color: #fff;}
|
||||
.container { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
|
||||
.ligature { display: flex; flex-direction: column; align-items: center; margin: 8px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Operator Mono Ligatures</h1>
|
||||
<a href="https://htmlpreview.github.io/?https://github.com/kiliman/operator-mono-lig/blob/master/images/preview/normal/index.html" class="${
|
||||
style === 'normal' ? 'active' : ''
|
||||
}">Normal</a> |
|
||||
<a href="https://htmlpreview.github.io/?https://github.com/kiliman/operator-mono-lig/blob/master/images/preview/italic/index.html" class="${
|
||||
style === 'italic' ? 'active' : ''
|
||||
}">Italic</a>
|
||||
<div class="container">
|
||||
`
|
||||
|
||||
filenames.forEach(f => {
|
||||
const { ligature, filename } = generateLigaturePreview(style, f)
|
||||
html += `<div class="ligature"><img src="${filename}"/><div>${ligature}</div></div>`
|
||||
})
|
||||
|
||||
html += `</div></body></html>`
|
||||
|
||||
fs.writeFileSync(`./images/preview/${style}/index.html`, html)
|
||||
}
|
||||
|
||||
const filenames = fs
|
||||
.readdirSync('./ligature/OperatorMonoSSmLig-Book/glyphs')
|
||||
.filter(f => !!f.match(/[^\d]\.liga\.xml$/))
|
||||
|
||||
generate('normal', filenames)
|
||||
generate('italic', filenames)
|
||||
@@ -0,0 +1,36 @@
|
||||
const fs = require('fs');
|
||||
const lig = `<Glyph name="LIG" lsb="0" width="625">
|
||||
<CharString>
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
<GlobalSubrs/>
|
||||
</Glyph>`;
|
||||
|
||||
fs.readdirSync('./ligature')
|
||||
.filter((f) => !!f.match(/^OperatorMono/))
|
||||
.forEach((f) => {
|
||||
console.log(f);
|
||||
fs.readdirSync(`./ligature/${f}/glyphs`)
|
||||
.filter((g) => !!g.match(/\.liga\.xml$/))
|
||||
.forEach((g) => {
|
||||
console.log(g);
|
||||
g.split('.')
|
||||
.slice(0, 1)
|
||||
.forEach((l) => {
|
||||
l.split('_').forEach((c) => {
|
||||
const path = `./ligature/${f}/glyphs/${c}.spacer.xml`;
|
||||
const exists = fs.existsSync(path);
|
||||
console.log(path, exists);
|
||||
if (exists) return;
|
||||
|
||||
const width = !!f.match(/SSm/) ? 625 : 600;
|
||||
const spacer = lig
|
||||
.replace('LIG', `${c}.spacer`)
|
||||
.replace('625', width);
|
||||
console.log(f, c, width);
|
||||
fs.writeFileSync(path, spacer);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,313 +0,0 @@
|
||||
const xpath = require('xpath');
|
||||
const NodeType = {};
|
||||
NodeType.TEXT_NODE = 3;
|
||||
|
||||
let dom;
|
||||
let gsubDom;
|
||||
let scriptListDom;
|
||||
let featureListDom;
|
||||
let lookupListDom;
|
||||
let featureDom;
|
||||
let lookupIndex = 0;
|
||||
let chainIndex = 0;
|
||||
const substLookupMap = {};
|
||||
|
||||
const initGsubTables = (_dom, options) => {
|
||||
dom = _dom;
|
||||
|
||||
gsubDom = xpath.select('ttFont/GSUB', dom, true);
|
||||
|
||||
// look for 'calt' feature
|
||||
featureListDom = xpath.select('FeatureList', gsubDom, true);
|
||||
lookupListDom = xpath.select('LookupList', gsubDom, true);
|
||||
|
||||
if (options.italicsHack) {
|
||||
// remove all features from FeatureList
|
||||
Array.from(featureListDom.childNodes).forEach((c) => {
|
||||
featureListDom.removeChild(c);
|
||||
});
|
||||
|
||||
Array.from(xpath.select('ttFont/GSUB//FeatureIndex', dom)).forEach((c) => {
|
||||
c.parentNode.removeChild(c);
|
||||
});
|
||||
|
||||
// remove all lookups from LookupList
|
||||
Array.from(lookupListDom.childNodes).forEach((c) =>
|
||||
lookupListDom.removeChild(c)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const buildGsubTables = (_dom, ligature, options) => {
|
||||
dom = _dom;
|
||||
|
||||
if (/_/.test(ligature.glyph) === false) {
|
||||
// not a ligature, so see if glyph exists in font (as substitute)
|
||||
const glyphNode = xpath.select(
|
||||
`ttFont/GlyphOrder/GlyphID[@name="${ligature.name}"]`,
|
||||
dom,
|
||||
true
|
||||
);
|
||||
if (!glyphNode) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const glyphs = ligature.name.replace(/\.liga$/, '').split('_');
|
||||
const isSingleGlyph = glyphs.length == 1;
|
||||
|
||||
gsubDom = xpath.select('ttFont/GSUB', dom, true);
|
||||
|
||||
// look for 'calt' feature
|
||||
featureListDom = xpath.select('FeatureList', gsubDom, true);
|
||||
|
||||
let featureRecord;
|
||||
const featureTag = xpath.select(
|
||||
'FeatureRecord/FeatureTag[@value="calt"]',
|
||||
featureListDom,
|
||||
true
|
||||
);
|
||||
if (!featureTag) {
|
||||
const featureListCount = xpath.select(
|
||||
'count(FeatureRecord)',
|
||||
featureListDom,
|
||||
true
|
||||
);
|
||||
featureRecord = createElementWithAttributes('FeatureRecord', {
|
||||
index: featureListCount,
|
||||
});
|
||||
featureRecord.appendChild(
|
||||
createElementWithAttributes('FeatureTag', { value: 'calt' })
|
||||
);
|
||||
featureRecord.appendChild(dom.createElement('Feature'));
|
||||
featureListDom.appendChild(featureRecord);
|
||||
} else {
|
||||
featureRecord = featureTag.parentNode;
|
||||
}
|
||||
featureDom = xpath.select('Feature', featureRecord, true);
|
||||
|
||||
const featureIndex = featureRecord.getAttribute('index');
|
||||
|
||||
// add feature to scriptlist for DFLT and latn if not present
|
||||
addFeatureToScriptList('DFLT', featureIndex);
|
||||
addFeatureToScriptList('latn', featureIndex);
|
||||
|
||||
lookupIndex = xpath.select('count(Lookup)', lookupListDom, true);
|
||||
|
||||
const lookupDom = createElementWithAttributes('Lookup', {
|
||||
index: lookupIndex++,
|
||||
});
|
||||
appendChildren(
|
||||
lookupDom,
|
||||
createElementWithAttributes('LookupType', { value: isSingleGlyph ? 1 : 6 }),
|
||||
createElementWithAttributes('LookupFlag', { value: 0 })
|
||||
);
|
||||
|
||||
// add contextual lookup to feature
|
||||
const featureLookupCount = xpath.select(
|
||||
'count(LookupListIndex)',
|
||||
featureDom,
|
||||
true
|
||||
);
|
||||
featureDom.appendChild(
|
||||
createElementWithAttributes('LookupListIndex', {
|
||||
index: featureLookupCount,
|
||||
value: lookupDom.getAttribute('index'),
|
||||
})
|
||||
);
|
||||
|
||||
if (isSingleGlyph) {
|
||||
lookupDom.appendChild(
|
||||
getSubstLookup(ligature.name, ligature.glyph, lookupDom)
|
||||
);
|
||||
} else {
|
||||
lookupDom.appendChild(buildBacktrackFirst(glyphs));
|
||||
lookupDom.appendChild(buildLookAheadLast(glyphs));
|
||||
lookupDom.appendChild(buildLigatureSubst(glyphs, ligature.glyph));
|
||||
// remaining context
|
||||
for (let n = glyphs.length - 2; n >= 0; n--) {
|
||||
lookupDom.appendChild(
|
||||
buildChainContext(getLIGs(n), [glyphs[n]], glyphs.slice(n + 1), 'LIG')
|
||||
);
|
||||
}
|
||||
}
|
||||
lookupListDom.appendChild(lookupDom);
|
||||
};
|
||||
|
||||
const finalizeGsubTables = () => {
|
||||
// get current LookupList count
|
||||
let newIndex = xpath.select('count(Lookup)', lookupListDom, true);
|
||||
|
||||
// append added lookups
|
||||
Object.entries(substLookupMap).forEach(([, lookup]) => {
|
||||
// fixup existing lookups with new index
|
||||
const oldIndex = lookup.getAttribute('index');
|
||||
const substLookups = xpath.select(
|
||||
`//ChainContextSubst/SubstLookupRecord/LookupListIndex[@value="${oldIndex}"]`,
|
||||
lookupListDom,
|
||||
false
|
||||
);
|
||||
substLookups.forEach((substLookup) => {
|
||||
substLookup.setAttribute('value', newIndex);
|
||||
});
|
||||
lookup.setAttribute('index', newIndex++);
|
||||
lookupListDom.appendChild(lookup);
|
||||
});
|
||||
};
|
||||
|
||||
//const dump = dom => console.log(format(serialize(dom)));
|
||||
|
||||
const addFeatureToScriptList = (tag, featureIndex) => {
|
||||
scriptListDom = xpath.select('ScriptList', gsubDom, true);
|
||||
const defaultLangSys = xpath.select(
|
||||
`ScriptRecord/ScriptTag[@value="${tag}"]/../Script/DefaultLangSys`,
|
||||
scriptListDom,
|
||||
true
|
||||
);
|
||||
const featureIndexNode = xpath.select(
|
||||
`FeatureIndex[@value=${featureIndex}]`,
|
||||
defaultLangSys,
|
||||
true
|
||||
);
|
||||
if (!featureIndexNode) {
|
||||
const count = xpath.select('count(FeatureIndex)', defaultLangSys, true);
|
||||
defaultLangSys.appendChild(
|
||||
createElementWithAttributes('FeatureIndex', {
|
||||
index: count,
|
||||
value: featureIndex,
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const buildBacktrackFirst = (glyphs) => {
|
||||
// backtrack = first glyph
|
||||
// input = first glphy
|
||||
// lookAhead = [1..n]
|
||||
return buildChainContext([glyphs[0]], [glyphs[0]], glyphs.slice(1));
|
||||
};
|
||||
|
||||
const buildLookAheadLast = (glyphs) => {
|
||||
// backtrack = none
|
||||
// input = first glyph
|
||||
// lookAhead = [1..n] + [n]
|
||||
return buildChainContext(
|
||||
[],
|
||||
[glyphs[0]],
|
||||
[...glyphs.slice(1), glyphs.slice(-1)]
|
||||
);
|
||||
};
|
||||
|
||||
const buildLigatureSubst = (glyphs, lookup) => {
|
||||
// backtrack = LIG * n-1
|
||||
// input = last glyph
|
||||
// lookAhead = none
|
||||
return buildChainContext(
|
||||
getLIGs(glyphs.length - 1),
|
||||
glyphs.slice(-1),
|
||||
[],
|
||||
lookup
|
||||
);
|
||||
};
|
||||
|
||||
const getLIGs = (length) => new Array(length).fill('LIG', 0, length);
|
||||
|
||||
const buildChainContext = (backtrack, input, lookAhead, substitute) => {
|
||||
const chainDom = createElementWithAttributes('ChainContextSubst', {
|
||||
index: chainIndex++,
|
||||
Format: 3,
|
||||
});
|
||||
|
||||
buildCoverage(chainDom, 'BacktrackCoverage', backtrack);
|
||||
buildCoverage(chainDom, 'InputCoverage', input);
|
||||
buildCoverage(chainDom, 'LookAheadCoverage', lookAhead);
|
||||
|
||||
if (substitute) {
|
||||
const lookup = getSubstLookup(input[0], substitute);
|
||||
const listIndex = lookup.getAttribute('index');
|
||||
const substLookupRecordDom = chainDom.appendChild(
|
||||
createElementWithAttributes('SubstLookupRecord', { index: 0 })
|
||||
);
|
||||
appendChildren(
|
||||
substLookupRecordDom,
|
||||
createElementWithAttributes('SequenceIndex', { value: 0 }),
|
||||
createElementWithAttributes('LookupListIndex', { value: listIndex })
|
||||
);
|
||||
}
|
||||
return chainDom;
|
||||
};
|
||||
|
||||
const buildCoverage = (chainDom, tagName, coverage) => {
|
||||
if (coverage) {
|
||||
coverage.forEach((glyph, i) => {
|
||||
const coverageDom = createElementWithAttributes(tagName, {
|
||||
index: i++,
|
||||
Format: 1,
|
||||
});
|
||||
coverageDom.appendChild(
|
||||
createElementWithAttributes('Glyph', { value: glyph })
|
||||
);
|
||||
chainDom.appendChild(coverageDom);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const getSubstLookup = (input, output, lookupDom) => {
|
||||
if (!lookupDom) {
|
||||
lookupDom = substLookupMap[output];
|
||||
}
|
||||
|
||||
if (!lookupDom) {
|
||||
lookupDom = createElementWithAttributes('Lookup', {
|
||||
index: Object.keys(substLookupMap).length + 1,
|
||||
});
|
||||
lookupDom.appendChild(
|
||||
createElementWithAttributes('LookupType', { value: 1 })
|
||||
);
|
||||
lookupDom.appendChild(
|
||||
createElementWithAttributes('LookupFlag', { value: 0 })
|
||||
);
|
||||
substLookupMap[output] = lookupDom;
|
||||
}
|
||||
|
||||
let singleSubstDom = xpath.select('SingleSubst', lookupDom, true);
|
||||
|
||||
if (!singleSubstDom) {
|
||||
singleSubstDom = createElementWithAttributes('SingleSubst', {
|
||||
index: 0,
|
||||
Format: 2,
|
||||
});
|
||||
lookupDom.appendChild(singleSubstDom);
|
||||
}
|
||||
|
||||
// look for input subst
|
||||
const substitionDom = xpath.select(
|
||||
`Substitution[@in="${input}"]`,
|
||||
singleSubstDom,
|
||||
true
|
||||
);
|
||||
if (!substitionDom) {
|
||||
singleSubstDom.appendChild(
|
||||
createElementWithAttributes('Substitution', { in: input, out: output })
|
||||
);
|
||||
}
|
||||
return lookupDom;
|
||||
};
|
||||
|
||||
const createElementWithAttributes = (tagName, attributes) => {
|
||||
const element = dom.createElement(tagName);
|
||||
Object.entries(attributes).forEach((attribute) => {
|
||||
element.setAttribute(attribute[0], attribute[1]);
|
||||
});
|
||||
return element;
|
||||
};
|
||||
|
||||
const appendChildren = (node, ...children) => {
|
||||
children.forEach((child) => node.appendChild(child));
|
||||
};
|
||||
|
||||
//const serialize = dom => new XMLSerializer().serializeToString(dom);
|
||||
|
||||
exports.initGsubTables = initGsubTables;
|
||||
exports.buildGsubTables = buildGsubTables;
|
||||
exports.finalizeGsubTables = finalizeGsubTables;
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 618 B |
|
After Width: | Height: | Size: 776 B |
|
After Width: | Height: | Size: 427 B |
|
After Width: | Height: | Size: 293 B |
|
After Width: | Height: | Size: 338 B |
|
After Width: | Height: | Size: 566 B |
|
After Width: | Height: | Size: 564 B |
|
After Width: | Height: | Size: 828 B |
|
After Width: | Height: | Size: 678 B |
|
After Width: | Height: | Size: 724 B |
|
After Width: | Height: | Size: 808 B |
|
After Width: | Height: | Size: 691 B |
|
After Width: | Height: | Size: 853 B |
|
After Width: | Height: | Size: 518 B |
|
After Width: | Height: | Size: 279 B |
|
After Width: | Height: | Size: 521 B |
@@ -0,0 +1,15 @@
|
||||
<html><head>
|
||||
<style>
|
||||
body { background-color: #000; color: #fff; font-family: sans-serif; margin: 16px;}
|
||||
a { color: #fff; text-decoration: none; padding: 4px;}
|
||||
a.active {color: #000; background-color: #fff;}
|
||||
.container { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
|
||||
.ligature { display: flex; flex-direction: column; align-items: center; margin: 8px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Operator Mono Ligatures</h1>
|
||||
<a href="https://htmlpreview.github.io/?https://github.com/kiliman/operator-mono-lig/blob/master/images/preview/normal/index.html" class="">Normal</a> |
|
||||
<a href="https://htmlpreview.github.io/?https://github.com/kiliman/operator-mono-lig/blob/master/images/preview/italic/index.html" class="active">Italic</a>
|
||||
<div class="container">
|
||||
<div class="ligature"><img src="ampersand_ampersand.png"/><div>ampersand_ampersand</div></div><div class="ligature"><img src="bar_bar.png"/><div>bar_bar</div></div><div class="ligature"><img src="bar_greater.png"/><div>bar_greater</div></div><div class="ligature"><img src="colon_equal.png"/><div>colon_equal</div></div><div class="ligature"><img src="equal_equal.png"/><div>equal_equal</div></div><div class="ligature"><img src="equal_equal_equal.png"/><div>equal_equal_equal</div></div><div class="ligature"><img src="equal_equal_greater.png"/><div>equal_equal_greater</div></div><div class="ligature"><img src="equal_greater.png"/><div>equal_greater</div></div><div class="ligature"><img src="equal_less_less.png"/><div>equal_less_less</div></div><div class="ligature"><img src="exclam_equal.png"/><div>exclam_equal</div></div><div class="ligature"><img src="exclam_equal_equal.png"/><div>exclam_equal_equal</div></div><div class="ligature"><img src="greater_equal.png"/><div>greater_equal</div></div><div class="ligature"><img src="greater_equal_greater.png"/><div>greater_equal_greater</div></div><div class="ligature"><img src="greater_greater_equal.png"/><div>greater_greater_equal</div></div><div class="ligature"><img src="hyphen_greater.png"/><div>hyphen_greater</div></div><div class="ligature"><img src="hyphen_hyphen.png"/><div>hyphen_hyphen</div></div><div class="ligature"><img src="hyphen_hyphen_greater.png"/><div>hyphen_hyphen_greater</div></div><div class="ligature"><img src="less_bar.png"/><div>less_bar</div></div><div class="ligature"><img src="less_equal.png"/><div>less_equal</div></div><div class="ligature"><img src="less_equal_equal.png"/><div>less_equal_equal</div></div><div class="ligature"><img src="less_equal_greater.png"/><div>less_equal_greater</div></div><div class="ligature"><img src="less_equal_less.png"/><div>less_equal_less</div></div><div class="ligature"><img src="less_exclam_hyphen_hyphen.png"/><div>less_exclam_hyphen_hyphen</div></div><div class="ligature"><img src="less_hyphen.png"/><div>less_hyphen</div></div><div class="ligature"><img src="less_hyphen_greater.png"/><div>less_hyphen_greater</div></div><div class="ligature"><img src="less_hyphen_hyphen.png"/><div>less_hyphen_hyphen</div></div><div class="ligature"><img src="less_slash.png"/><div>less_slash</div></div><div class="ligature"><img src="plus_equal.png"/><div>plus_equal</div></div><div class="ligature"><img src="plus_plus.png"/><div>plus_plus</div></div><div class="ligature"><img src="question_question.png"/><div>question_question</div></div><div class="ligature"><img src="slash_greater.png"/><div>slash_greater</div></div><div class="ligature"><img src="underscore_underscore.png"/><div>underscore_underscore</div></div><div class="ligature"><img src="w_w_w.png"/><div>w_w_w</div></div></div></body></html>
|
||||
|
After Width: | Height: | Size: 809 B |
|
After Width: | Height: | Size: 779 B |
|
After Width: | Height: | Size: 571 B |
|
After Width: | Height: | Size: 798 B |
|
After Width: | Height: | Size: 692 B |
|
After Width: | Height: | Size: 730 B |
|
After Width: | Height: | Size: 529 B |
|
After Width: | Height: | Size: 754 B |
|
After Width: | Height: | Size: 527 B |
|
After Width: | Height: | Size: 795 B |
|
After Width: | Height: | Size: 480 B |
|
After Width: | Height: | Size: 519 B |
|
After Width: | Height: | Size: 782 B |
|
After Width: | Height: | Size: 791 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 678 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 283 B |
|
After Width: | Height: | Size: 628 B |
|
After Width: | Height: | Size: 369 B |
|
After Width: | Height: | Size: 281 B |
|
After Width: | Height: | Size: 320 B |
|
After Width: | Height: | Size: 571 B |
|
After Width: | Height: | Size: 579 B |
|
After Width: | Height: | Size: 838 B |
|
After Width: | Height: | Size: 650 B |
|
After Width: | Height: | Size: 720 B |
|
After Width: | Height: | Size: 695 B |
|
After Width: | Height: | Size: 690 B |
|
After Width: | Height: | Size: 855 B |
|
After Width: | Height: | Size: 527 B |
|
After Width: | Height: | Size: 275 B |
|
After Width: | Height: | Size: 523 B |
@@ -0,0 +1,15 @@
|
||||
<html><head>
|
||||
<style>
|
||||
body { background-color: #000; color: #fff; font-family: sans-serif; margin: 16px;}
|
||||
a { color: #fff; text-decoration: none; padding: 4px;}
|
||||
a.active {color: #000; background-color: #fff;}
|
||||
.container { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
|
||||
.ligature { display: flex; flex-direction: column; align-items: center; margin: 8px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Operator Mono Ligatures</h1>
|
||||
<a href="https://htmlpreview.github.io/?https://github.com/kiliman/operator-mono-lig/blob/master/images/preview/normal/index.html" class="active">Normal</a> |
|
||||
<a href="https://htmlpreview.github.io/?https://github.com/kiliman/operator-mono-lig/blob/master/images/preview/italic/index.html" class="">Italic</a>
|
||||
<div class="container">
|
||||
<div class="ligature"><img src="ampersand_ampersand.png"/><div>ampersand_ampersand</div></div><div class="ligature"><img src="bar_bar.png"/><div>bar_bar</div></div><div class="ligature"><img src="bar_greater.png"/><div>bar_greater</div></div><div class="ligature"><img src="colon_equal.png"/><div>colon_equal</div></div><div class="ligature"><img src="equal_equal.png"/><div>equal_equal</div></div><div class="ligature"><img src="equal_equal_equal.png"/><div>equal_equal_equal</div></div><div class="ligature"><img src="equal_equal_greater.png"/><div>equal_equal_greater</div></div><div class="ligature"><img src="equal_greater.png"/><div>equal_greater</div></div><div class="ligature"><img src="equal_less_less.png"/><div>equal_less_less</div></div><div class="ligature"><img src="exclam_equal.png"/><div>exclam_equal</div></div><div class="ligature"><img src="exclam_equal_equal.png"/><div>exclam_equal_equal</div></div><div class="ligature"><img src="greater_equal.png"/><div>greater_equal</div></div><div class="ligature"><img src="greater_equal_greater.png"/><div>greater_equal_greater</div></div><div class="ligature"><img src="greater_greater_equal.png"/><div>greater_greater_equal</div></div><div class="ligature"><img src="hyphen_greater.png"/><div>hyphen_greater</div></div><div class="ligature"><img src="hyphen_hyphen.png"/><div>hyphen_hyphen</div></div><div class="ligature"><img src="hyphen_hyphen_greater.png"/><div>hyphen_hyphen_greater</div></div><div class="ligature"><img src="less_bar.png"/><div>less_bar</div></div><div class="ligature"><img src="less_equal.png"/><div>less_equal</div></div><div class="ligature"><img src="less_equal_equal.png"/><div>less_equal_equal</div></div><div class="ligature"><img src="less_equal_greater.png"/><div>less_equal_greater</div></div><div class="ligature"><img src="less_equal_less.png"/><div>less_equal_less</div></div><div class="ligature"><img src="less_exclam_hyphen_hyphen.png"/><div>less_exclam_hyphen_hyphen</div></div><div class="ligature"><img src="less_hyphen.png"/><div>less_hyphen</div></div><div class="ligature"><img src="less_hyphen_greater.png"/><div>less_hyphen_greater</div></div><div class="ligature"><img src="less_hyphen_hyphen.png"/><div>less_hyphen_hyphen</div></div><div class="ligature"><img src="less_slash.png"/><div>less_slash</div></div><div class="ligature"><img src="plus_equal.png"/><div>plus_equal</div></div><div class="ligature"><img src="plus_plus.png"/><div>plus_plus</div></div><div class="ligature"><img src="question_question.png"/><div>question_question</div></div><div class="ligature"><img src="slash_greater.png"/><div>slash_greater</div></div><div class="ligature"><img src="underscore_underscore.png"/><div>underscore_underscore</div></div><div class="ligature"><img src="w_w_w.png"/><div>w_w_w</div></div></div></body></html>
|
||||
|
After Width: | Height: | Size: 673 B |
|
After Width: | Height: | Size: 724 B |
|
After Width: | Height: | Size: 584 B |
|
After Width: | Height: | Size: 812 B |
|
After Width: | Height: | Size: 696 B |
|
After Width: | Height: | Size: 710 B |
|
After Width: | Height: | Size: 509 B |
|
After Width: | Height: | Size: 755 B |
|
After Width: | Height: | Size: 510 B |
|
After Width: | Height: | Size: 779 B |
|
After Width: | Height: | Size: 386 B |
|
After Width: | Height: | Size: 355 B |
|
After Width: | Height: | Size: 748 B |
|
After Width: | Height: | Size: 783 B |
|
After Width: | Height: | Size: 240 B |
|
After Width: | Height: | Size: 609 B |
@@ -1,10 +1,11 @@
|
||||
// @ts-nocheck
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
if (!os.EOL) {
|
||||
os.EOL = process.platform === 'win32' ? '\r\n' : '\n';
|
||||
}
|
||||
|
||||
const gsub = require('./gsub');
|
||||
const calt = require('./calt');
|
||||
|
||||
const xpath = require('xpath');
|
||||
const { DOMParser, XMLSerializer } = require('xmldom');
|
||||
@@ -60,11 +61,13 @@ const buildFont = (profile, options) => {
|
||||
//[...ligatures, { name: 'LIG', glyph: 'LIG' }];
|
||||
|
||||
processPatch('names', patchNames, dom, ligatures, profile);
|
||||
processPatch('gsub', patchGsub, dom, ligatures, options);
|
||||
processPatch('charstrings', patchCharStrings, dom, ligaturesWithLIG);
|
||||
processPatch('glyphs', patchGlyphs, dom, ligaturesWithLIG);
|
||||
processPatch('hmtx', patchHmtx, dom);
|
||||
|
||||
const feature = calt.gencalt(ligatures);
|
||||
fs.writeFileSync('./features/calt.fea', feature);
|
||||
|
||||
console.log(`Writing ligature font file ${dstFileName}`);
|
||||
fs.writeFileSync(dstFileName, format(serialize(dom)));
|
||||
};
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<Glyph name="ampersand.spacer" lsb="0" width="600">
|
||||
<CharString>
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
<GlobalSubrs/>
|
||||
</Glyph>
|
||||
@@ -0,0 +1,7 @@
|
||||
<Glyph name="bar.spacer" lsb="0" width="600">
|
||||
<CharString>
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
<GlobalSubrs/>
|
||||
</Glyph>
|
||||
@@ -1,12 +1,10 @@
|
||||
<Glyph name="bar_bar.liga" lsb="-211" width="550">
|
||||
<CharString>
|
||||
-211 75 275 75 vstem
|
||||
-136 710 rmoveto
|
||||
-75 -6 rlineto
|
||||
-886 75 vlineto
|
||||
350 892 rmoveto
|
||||
-75 -6 rlineto
|
||||
-886 75 vlineto
|
||||
-211 704 rmoveto
|
||||
-886 75 892 vlineto
|
||||
275 -6 rmoveto
|
||||
-886 75 892 vlineto
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<Glyph name="bar_greater.liga" lsb="-261" width="550">
|
||||
<CharString>
|
||||
-261 75 468 74 vstem
|
||||
-186 710 rmoveto
|
||||
-75 -6 rlineto
|
||||
-261 704 rmoveto
|
||||
-886 75 vlineto
|
||||
541 440 rlineto
|
||||
69 vlineto
|
||||
-74 -40 rmoveto
|
||||
-467 -376 rlineto
|
||||
-541 383 rlineto
|
||||
-799 vmoveto
|
||||
709 vlineto
|
||||
467 -323 rlineto
|
||||
-10 vlineto
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<Glyph name="colon.spacer" lsb="0" width="600">
|
||||
<CharString>
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
<GlobalSubrs/>
|
||||
</Glyph>
|
||||
@@ -2,20 +2,18 @@
|
||||
<CharString>
|
||||
151 69 153 69 hstem
|
||||
-297 658 vstem
|
||||
-297 354 rmoveto
|
||||
118 hlineto
|
||||
-179 354 rmoveto
|
||||
2 117 rlineto
|
||||
-119 hlineto
|
||||
657 -98 rmoveto
|
||||
1 69 rlineto
|
||||
-424 -69 hlineto
|
||||
-235 -245 rmoveto
|
||||
118 hlineto
|
||||
-1 -117 rlineto
|
||||
659 88 rmoveto
|
||||
-424 -69 423 hlineto
|
||||
-540 -245 rmoveto
|
||||
2 117 rlineto
|
||||
-119 hlineto
|
||||
657 -94 rmoveto
|
||||
1 69 rlineto
|
||||
-424 -69 hlineto
|
||||
-1 -117 rlineto
|
||||
659 92 rmoveto
|
||||
-424 -69 423 hlineto
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<Glyph name="equal.spacer" lsb="0" width="600">
|
||||
<CharString>
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
<GlobalSubrs/>
|
||||
</Glyph>
|
||||
@@ -2,18 +2,14 @@
|
||||
<CharString>
|
||||
151 69 153 69 hstem
|
||||
-472 944 vstem
|
||||
-49 373 rmoveto
|
||||
1 69 rlineto
|
||||
-424 -69 hlineto
|
||||
943 hmoveto
|
||||
1 69 rlineto
|
||||
-414 -69 hlineto
|
||||
-107 -222 rmoveto
|
||||
1 69 rlineto
|
||||
-424 -69 hlineto
|
||||
943 hmoveto
|
||||
1 69 rlineto
|
||||
-414 -69 hlineto
|
||||
-48 442 rmoveto
|
||||
-424 -69 423 hlineto
|
||||
521 69 rmoveto
|
||||
-414 -69 413 hlineto
|
||||
-519 -153 rmoveto
|
||||
-424 -69 423 hlineto
|
||||
521 69 rmoveto
|
||||
-414 -69 413 hlineto
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
<CharString>
|
||||
151 69 153 69 hstem
|
||||
-472 944 vstem
|
||||
471 373 rmoveto
|
||||
1 69 rlineto
|
||||
-944 -69 hlineto
|
||||
943 -222 rmoveto
|
||||
1 69 rlineto
|
||||
-944 -69 hlineto
|
||||
472 442 rmoveto
|
||||
-944 -69 943 hlineto
|
||||
1 -153 rmoveto
|
||||
-944 -69 943 hlineto
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
|
||||
@@ -2,24 +2,18 @@
|
||||
<CharString>
|
||||
151 69 153 69 hstem
|
||||
-1022 1494 vstem
|
||||
-579 373 rmoveto
|
||||
1 69 rlineto
|
||||
-444 -69 hlineto
|
||||
968 hmoveto
|
||||
1 69 rlineto
|
||||
-444 -69 hlineto
|
||||
968 hmoveto
|
||||
1 69 rlineto
|
||||
-444 -69 hlineto
|
||||
-607 -222 rmoveto
|
||||
1 69 rlineto
|
||||
-444 -69 hlineto
|
||||
968 hmoveto
|
||||
1 69 rlineto
|
||||
-444 -69 hlineto
|
||||
968 hmoveto
|
||||
1 69 rlineto
|
||||
-444 -69 hlineto
|
||||
-578 442 rmoveto
|
||||
-444 -69 443 hlineto
|
||||
526 69 rmoveto
|
||||
-444 -69 443 hlineto
|
||||
526 69 rmoveto
|
||||
-444 -69 443 hlineto
|
||||
-1049 -153 rmoveto
|
||||
-444 -69 443 hlineto
|
||||
526 69 rmoveto
|
||||
-444 -69 443 hlineto
|
||||
526 69 rmoveto
|
||||
-444 -69 443 hlineto
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
<Glyph name="equal_equal_equal.liga" lsb="-1022" width="550">
|
||||
<CharString>
|
||||
40 69 153 69 153 69 hstem
|
||||
-1022 1494 cntrmask 11100000
|
||||
471 484 rmoveto
|
||||
1 69 rlineto
|
||||
-1494 -69 hlineto
|
||||
1493 -222 rmoveto
|
||||
1 69 rlineto
|
||||
-1494 -69 hlineto
|
||||
1493 -222 rmoveto
|
||||
1 69 rlineto
|
||||
-1494 -69 hlineto
|
||||
-1022 1494 vstem
|
||||
472 553 rmoveto
|
||||
-1494 -69 1493 hlineto
|
||||
1 -153 rmoveto
|
||||
-1494 -69 1493 hlineto
|
||||
1 -153 rmoveto
|
||||
-1494 -69 1493 hlineto
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<CharString>
|
||||
151 69 153 69 hstem
|
||||
-1022 394 1019 74 vstem
|
||||
138 602 rmoveto
|
||||
-47 -58 124 -102 rlineto
|
||||
91 544 rmoveto
|
||||
124 -102 rlineto
|
||||
-1237 -69 1321 hlineto
|
||||
92 -76 rlineto
|
||||
-10 vlineto
|
||||
@@ -11,6 +11,7 @@
|
||||
-1332 -69 1249 hlineto
|
||||
-140 -116 45 -57 333 280 rlineto
|
||||
69 vlineto
|
||||
-327 275 rlineto
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<CharString>
|
||||
151 69 153 69 hstemhm
|
||||
-472 937 -74 74 hintmask 11100000
|
||||
138 602 rmoveto
|
||||
-47 -58 124 -102 rlineto
|
||||
91 544 rmoveto
|
||||
124 -102 rlineto
|
||||
-687 -69 771 hlineto
|
||||
hintmask 11010000
|
||||
92 -76 rlineto
|
||||
@@ -13,6 +13,7 @@
|
||||
-782 -69 699 hlineto
|
||||
-140 -116 45 -57 333 280 rlineto
|
||||
69 vlineto
|
||||
-327 275 rlineto
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<CharString>
|
||||
151 69 153 69 hstemhm
|
||||
-1022 1486 -688 75 235 75 hintmask 11011000
|
||||
-149 297 rmoveto
|
||||
299 248 -45 58 -191 -161 rlineto
|
||||
150 545 rmoveto
|
||||
-45 58 -191 -161 rlineto
|
||||
hintmask 11100000
|
||||
-936 -69 854 hlineto
|
||||
hintmask 11011000
|
||||
@@ -15,13 +15,15 @@
|
||||
206 -173 46 57 rlineto
|
||||
hintmask 11011000
|
||||
-303 252 rlineto
|
||||
310 hmoveto
|
||||
10 vlineto
|
||||
310 hmoveto
|
||||
299 248 -45 58 -329 -277 rlineto
|
||||
-69 vlineto
|
||||
332 -279 rlineto
|
||||
hintmask 11100000
|
||||
46 57 rlineto
|
||||
hintmask 11011000
|
||||
-303 252 rlineto
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<Glyph name="exclam.spacer" lsb="0" width="600">
|
||||
<CharString>
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
<GlobalSubrs/>
|
||||
</Glyph>
|
||||
@@ -2,8 +2,7 @@
|
||||
<CharString>
|
||||
-189 915 -575 69 153 69 hstemhm
|
||||
-472 944 -762 534 hintmask 00110000
|
||||
76 373 rmoveto
|
||||
395 hlineto
|
||||
471 373 rmoveto
|
||||
1 69 rlineto
|
||||
-360 hlineto
|
||||
hintmask 00101000
|
||||
@@ -24,6 +23,7 @@
|
||||
512 hlineto
|
||||
1 69 rlineto
|
||||
-477 hlineto
|
||||
81 153 rlineto
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
<Glyph name="exclam_equal_equal.liga" lsb="-1022" width="550">
|
||||
<CharString>
|
||||
-189 915 -686 69 153 69 153 69 hstemhm
|
||||
-1022 1494 -1012 534 cntrmask 01110000
|
||||
hintmask 01111000
|
||||
471 262 rmoveto
|
||||
1 69 rlineto
|
||||
-1022 1494 -1012 534 hintmask 00111000
|
||||
472 331 rmoveto
|
||||
-668 hlineto
|
||||
80 153 rlineto
|
||||
587 hlineto
|
||||
1 69 rlineto
|
||||
-552 hlineto
|
||||
hintmask 01110100
|
||||
hintmask 00110100
|
||||
74 141 rlineto
|
||||
hintmask 10000100
|
||||
-69 32 rlineto
|
||||
hintmask 01110100
|
||||
hintmask 00110100
|
||||
-91 -173 rlineto
|
||||
-856 -69 820 hlineto
|
||||
-80 -153 rlineto
|
||||
-740 -69 703 hlineto
|
||||
hintmask 01110100
|
||||
-80 -153 rlineto
|
||||
-623 -69 587 hlineto
|
||||
-105 -200 rlineto
|
||||
@@ -30,6 +29,7 @@
|
||||
1 69 rlineto
|
||||
-785 hlineto
|
||||
80 153 rlineto
|
||||
704 hlineto
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<Glyph name="greater.spacer" lsb="0" width="600">
|
||||
<CharString>
|
||||
endchar
|
||||
</CharString>
|
||||
<Subrs/>
|
||||
<GlobalSubrs/>
|
||||
</Glyph>
|
||||