Comments (12)
I've been reading up on how contextual substitutions work in OpenType as well as how it's used in Fira Code. I think I understand it much better now. I'm working on an experimental font with a few ligatures for testing.
Here's an animation of how the spacing works.
Here's how the glyph is created.
Notice the negative LSB (Left Side Bearing). The way Fira Code works is that instead of substituting equal
+ equal
into a single double-wide glyph equal_equal.liga
like I currently do, it actually uses 2 glyphs, one name LIG
which is simply a single width glyph with no visual representation, plus the equal_equal.liga
with negative LSB.
So basically LIG
advances one character width, then the ligature moves back to the left with the negative LSB. The editor and terminal think there are two characters and the caret is displayed properly.
Pretty clever, but makes it a little trickier to design the glyphs because you have to calculate the proper LSB. The actual contextual substitution lookups are really nasty and will have to programmatically generated. I'm working on that now.
from operator-mono-lig.
I have a working version of the font in VS Code that supports both caret positioning and chained ligatures (#37).
Here's an example:
Now to redo all the ligatures 😣 ... I can see the finish line 🏁
from operator-mono-lig.
I'm almost done with the first set of ligatures. I even included some extra ones for fun.
from operator-mono-lig.
@dannymcgee The book is Fonts & Encodings by Yannis Haralambous[1]
Appendix D.9 The OpenType Advanced Typographic Tables (along with a bunch of trial and error) is where I got most of the info.
If you look at the gsub.js file[2] you'll see how I build up the lookup tables. I also talk about it in this comment[3].
I would also recommend this tool: OTMaster Light[4] from Dutch Type Library. It was invaluable in making sure my code was generating the correct tables.
Here's an example showing how the => ligature is rendered. It has checks for repeating characters (so multiple chains of == doesn't render the wrong glyph. Also adds LIG glyphs to support carets inside the ligature glyph.
[1] https://www.amazon.com/Fonts-Encodings-Advanced-Typography-Everything/dp/0596102429
[2] https://github.com/kiliman/operator-mono-lig/blob/features/contextsubst/gsub.js
[3] #37 (comment)
[4] https://www.fontmaster.nl/index.php/test-demo/
from operator-mono-lig.
BTW: I only had to dig through all this mess because I couldn't distribute the ligature versions of the fonts directly.
You can use a font editor like Font Forge or Glyphs to generate the tables for you. Here's the script the FiraCode uses to generated the calt tables.
https://github.com/tonsky/FiraCode/blob/master/clojure/regen_calt.clj
from operator-mono-lig.
Yes, I agree. I did try to replicate the way Fira Code does it, but was not successful. I'm not sure what trick they used. I noticed they used negative LSB, but they also must include some spacing rules.
I'm not an expert on OpenType, so this is the best I could come up with. Perhaps someone with more experience could point me in the right direction.
Other than that, I hope you're enjoying the ligatures.
Thanks!
from operator-mono-lig.
You did and still do a great job on that ;)
let's wait to see if someone can help on this!
from operator-mono-lig.
in kovidgoyal/kitty#182 I'm trying to make the ligatures in this font render in the kitty terminal emulator. From the discussion there it sounds like Fira Code uses dummy blank glyphs. Not sure how/if that helps your figure this out.
from operator-mono-lig.
This has been pushed to the features/contextsubst branch.
from operator-mono-lig.
@kiliman Are the steps still the same for this branch? The master
branch worked fine, but the build script in the features/contextsubst
branch doesn't appear to be doing anything for me. I'll have to dig deeper when I get the free time.
Might be worthwhile adding a note about this feature in the documentation as well. I just assumed this wasn't possible until I noticed it existed in Fira Code, which led me to this issue.
Appreciate your work on this!
from operator-mono-lig.
@jabacchetta currently only the Operator Mono SSm Book and Operator Mono Light (partial) work in the features/contextsubst
branch. In order to support these features, the ligatures have to be redone.
If you look at the comment above #35 (comment)
You'll see that all the glyphs have to be shifted left with negative left bearing. The original way was to have a character that was 2-3 glyphs wide. So => would be 1250 wide vs 625 for a single glyph.
The new way makes all the ligatures 625 wide, but the extra stuff is shifted to the left. When it is rendered, it actually renders an invisible character LIG followed by the ligature.
So => would be LIG + (=> glyph)... the LIG would advance 625, then the ligature glyph (due to negative left bearing) would actually start rendering over top of the invisible LIG. This is how you get the caret positioning.
Hope that makes sense. I literally had to buy a book on OpenType fonts in order to understand it.
from operator-mono-lig.
Hey @kiliman, would you be willing to share what book you bought and which chapters/sections were relevant for figuring out this issue? I'm trying to make my own original typeface with coding ligatures, and I'm having a hell of a time trying to figure out the maze of substitution/lookup rules to make this work.
from operator-mono-lig.
Related Issues (20)
- Build fails in Big Sur HOT 6
- Erro on VSCODE - letter spacing 0? HOT 12
- Operator Mono SSm Lig Book does not work with Vscode HOT 9
- Build script doesn't do anything HOT 6
- Ligatures Not Working HOT 16
- some ligatures dont work in italics. HOT 4
- build doesn't do anything HOT 10
- Create ligatures for `Operator Mono Bold` HOT 2
- Running ./build.sh just create build folder with empty HOT 10
- Glyphs are way too small HOT 3
- npm install always giving errors HOT 3
- Not an issue: meant to help to use Win 10 Npm problems HOT 2
- Create `::` ligature HOT 10
- Cannot run npm install node-pre-gyp ERR! build error HOT 2
- Got a lot of errors after npm install. (Windows 11) HOT 6
- Only two fonts in build folder HOT 6
- Does not work with Python 2.7 shipped with MacOS Montery HOT 1
- The following glyph names are referenced but are missing from the glyph set: underscore.alt HOT 1
- If you get error after error!
- Copyright to matter about? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from operator-mono-lig.