kb-text-shape: Unicode segmentation and shaping using kb_text_shape

[ bsd3, font, library ] [ Propose Tags ] [ Report a vulnerability ]
Versions [RSS] 0.1.0.0
Change log CHANGELOG.md
Dependencies base (>=4.16 && <5), bytestring, containers, text [details]
License BSD-3-Clause
Copyright 2025 IC Rainbow
Author IC Rainbow
Maintainer aenor.realm@gmail.com
Category Font
Home page https://github.com/dpwiz/kb-text-shape#readme
Bug tracker https://github.com/dpwiz/kb-text-shape/issues
Source repo head: git clone https://github.com/dpwiz/kb-text-shape
Uploaded by AlexanderBondarenko at 2025-12-30T17:20:44Z
Distributions
Downloads 1 total (1 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
All reported builds failed as of 2025-12-30 [all 1 reports]

Readme for kb-text-shape-0.1.0.0

[back to package description]

kb-text-shape

Haskell wrapper for the kb_text_shape.h unicode segmentation and shaping library.

  Your text       A        Text runs with         B       Sequence of glyphs      C
  (Probably ------------> uniform direction ------------> ready to rasterize ------------> Pixels
  UTF-8)                    and script

We call arrow A text segmentation, arrow B text shaping, and arrow C rasterization. This library does A and B.

import KB.Text.Shape where qualified as TextShape

main = do
  TextShape.withContext \ctx -> do
    _fallback <- TextShape.pushFontFromFile ctx "test/NotoSans-Regular.ttf" 0
    _main <- TextShape.pushFontFromFile ctx "test/Ubuntu-R.ttf" 0
    results <- TextShape.run ctx do
      TextShape.text_ "A bunch of characters"
      TextShape.char_ '!'
    forM_ results \(run, glyphs) ->
      forM_ glyphs \glyph ->
        print (run.font, glyph.id, glyph.gpos.advanceX)

Font blobs

The library has an internal "blob" format for the pre-processed font data for leaner files and faster loading.

import KB.Text.Shape.Font qualified as Font

main = do
  ttfData <- ByteString.readFile "test/Ubuntu-R.ttf"
  putStrLn $ "Distilling " <> show (ByteString.length ttfData `div` 1024) <> "Kb of TTF"
  blobData <- Font.extractBlob ttfData 0
  putStrLn $ "Distilled into " <> show (ByteString.length blobData `div` 1024) <> "Kb blob"
  ByteString.writeFile "test/Ubuntu-R.kbts" blobData

The savings are modest, but can be improved even further with compression.

Distilling 1047Kb of TTF
Distilled into 618Kb blob