Single-header permissively-licensed libraries for C/C++.
- kb_text_shape.h: Unicode text segmentation and OpenType shaping
kb_text_shape.h provides:
- ICU-like text segmentation (i.e. breaking Unicode text by direction, line, script, word and grapheme).
- Harfbuzz-like text shaping for OpenType fonts, which means it is capable of handling complex script layout and ligatures, among other things.
- Font coverage checking: know if a font can display a given string.
It does not handle rasterization. It does not handle paragraph layout. It does not handle selection and loading of system fonts. It will only help you know which glyphs to display where on a single, infinitely-long line, using the fonts you have provided!
(See https://www.newroadoldway.com/text1.html for an explanation of the different steps of text processing.)
For an in-depth usage example, check out refpad.
// Yours to provide:voidDrawGlyph(kbts_u16GlyphId, kbts_s32GlyphOffsetX, kbts_s32GlyphOffsetY, kbts_s32GlyphAdvanceX, kbts_s32GlyphAdvanceY,
kbts_directionParagraphDirection, kbts_directionRunDirection, kbts_scriptScript, kbts_font*Font);
voidNextLine(void);
void*CreateRenderFont(constchar*FontPath);
voidHandleText(kbts_shape_context*Context, constchar*Text, kbts_languageLanguage)
{
kbts_ShapeBegin(Context, KBTS_DIRECTION_DONT_KNOW, Language);
kbts_ShapeUtf8(Context, Text, (int)strlen(Text), KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX);
kbts_ShapeEnd(Context);
kbts_runRun;
while(kbts_ShapeRun(Context, &Run))
{
if(Run.Flags&KBTS_BREAK_FLAG_LINE_HARD)
{
NextLine();
}
kbts_glyph*Glyph;
while(kbts_GlyphIteratorNext(&Run.Glyphs, &Glyph))
{
DrawGlyph(Glyph->Id, Glyph->OffsetX, Glyph->OffsetY, Glyph->AdvanceX, Glyph->AdvanceY,
Run.ParagraphDirection, Run.Direction, Run.Script, Run.Font);
}
}
}
voidExample(void)
{
kbts_shape_context*Context=kbts_CreateShapeContext(0, 0);
kbts_font*FontA=kbts_ShapePushFontFromFile(Context, "NotoSansMyanmar-Regular.ttf", 0);
kbts_font*FontB=kbts_ShapePushFontFromFile(Context, "NotoSansArabic-Regular.ttf", 0);
FontA->UserData=CreateRenderFont("NotoSansMyanmar-Regular.ttf");
FontB->UserData=CreateRenderFont("NotoSansArabic-Regular.ttf");
HandleText(Context, (constchar*)u8"یکအမည်မရှိیک", KBTS_LANGUAGE_ARABIC);
}




