# Morphio
[](https://github.com/PRO-2684/Morphio/blob/main/LICENSE)



[](https://crates.io/crates/morphio)
[](https://crates.io/crates/morphio)
[](https://docs.rs/morphio)
Morphs the font, so it renders worda as wordb.
## 📥 Installation
> [!NOTE]
> You can try Morphio without installing it [in the browser](https://pro-2684.github.io/Morphio/).
### Using [`binstall`](https://github.com/cargo-bins/cargo-binstall)
```shell
cargo binstall morphio
```
### Downloading from Releases
Navigate to the [Releases page](https://github.com/PRO-2684/Morphio/releases) and download respective binary for your platform. Make sure to give it execute permissions.
### Compiling from Source
```shell
cargo install morphio
```
## 📖 Usage
```shell
$ morphio --help
Usage: morphio -i <input> -o <output> [-m] [-y] [pairs...]
Morphio: Morphs the font, so it renders worda as wordb.
Options:
-i, --input input font file path
-o, --output output font file path
-m, --no-word-match
disable word match
-y, --yes allow overwrite output file if it exists
-h, --help display usage information
```
> [!NOTE]
> For variable-length many-to-many morphs, Morphio appends empty placeholder glyphs to the font.
> When this happens, some legacy glyph-count-dependent tables such as `LTSH` and `hdmx` may be dropped instead of rebuilt.
> This is usually fine in modern browsers and text renderers, but very old rasterizers may render slightly differently.
## ✅ TODO
- [ ] Recipe (configuration) support
- Advanced settings
- Morph rules
- [x] Configure word matching of start and end of words separately
- [x] Reduce TTC font sizes (table sharing?)
- [x] Allow morphing multiple words in one go
- [x] Allow morphing words with different lengths
- [x] ServiceWorker
- [x] Option for enabling/disabling word matching
- Say we want to morph "banana" to "orange"
- When word matching is enabled, `xbanana` will not be morphed, because we're matching whole words, not letters
- When word matching is disabled, `xbanana` will be morphed to `xorange`
- [x] Optimization
- [x] Use `CoverageTable::Format2`, which allows for more efficient storage of contiguous ranges of glyphs
- [x] Better word matching
- Currently we consider whole words only by letters (`[a-zA-Z]+`)
- Next stage: consider digits (`[0-9]+`) and underscores (`_`)
- Maybe an option for toggling which characters to consider as part of words?
- [x] Bug fixes
- [x] Might not work with fonts with multiple language records, e.g. `IMPACT.TTF`
## 🎉 Credits
- [fontations](https://github.com/googlefonts/fontations/)
- [fonttools](https://github.com/fonttools/fonttools)
- [OpenType Layout Common Table Formats](https://learn.microsoft.com/en-us/typography/opentype/spec/chapter2)
- [GSUB — Glyph Substitution Table](https://learn.microsoft.com/en-us/typography/opentype/spec/gsub)