ktx-font-0.1.0.0: README.md
# ktx-font
A KTX2 format containing a font atlas texture, enriched with:
- [kb-text-shape](https://hackage.haskell.org/package/kb-text-shape) font shaping data.
- [msdf-astlas](https://hackage.haskell.org/package/msdf-astlas) compacted atlas.
The package also has a module to run the shaping using stacks of those font bundles.
## The pipeline
Typically you'd just use your rendering engine's utilities to do this.
To implement one, you have to address the three points in the font lifecycle:
## Preparing the font bundle
This part is the slowest one, as it takes care to distill and optimize the data for faster use later.
1. Generate an atlas with [msdf-atlas-gen](https://github.com/Chlumsky/msdf-atlas-gen)
2. [Transcode](https://gitlab.com/dpwiz/msdf-atlas/-/blob/main/test/regenerate.sh) into KTX file.
3. Preprocess and inject the extras as texture attributes.
## Loading
Since all the data are already preprocessed you only have to move it to the appropriate places on CPU/GPU.
For each font file:
* Load the texture like the usual (with [ktx-codec](https://hackage.haskell.org/package/ktx-codec)).
* Load font and atlas data from the same file/bytestring.
For each combination of fonts (font stack:
* Create a shaping context from a bunch of loaded fonts.
## Using
1. Run `Codec.Ktx2.Font.Shaping.shape` on your text.
2. Iterate over the result and convert the UV and world boxes to the data you use for rendering.
* Since the shaping library does the font picking for you, you may have to look up the associated font data from the context, like texture id.
NB: Due to font format and design shenanigans you have to use a sane "font size" metric that is shared for all the fonts in the stack.
Typically that would be "cap height", and `msdf-atlas` takes care of converting "em" units into that.
For more details on the problem see:
- https://tonsky.me/blog/font-size/
- https://tonsky.me/blog/centering/
## Demo
The repo has a demo of using the shaping results in a Gloss (Brillo) context.

- Green line: baseline, on which every font sits.
- Blue line: capital letter height, which is used for alignment. Every font rendered to have this one equal.
- Cyan circles: innermost (tiny) - cursor position. Then, "font size", then "line size".
- Red box: the bounding box for all glyph box.
- Yellow line: the initial cursor position (at 0,0) shifted to match the aligned box.
The glyphs have black boxes because the atlas is transcoded as having the single channel swizzled as `rrr1`.
This allows to see the glyph boxes against the grey background.
The `msdf-atlas-gen` is typically used to produce distance fields, but Gloss can't render them.