GGUIText/Public/TextEngine.h file

TextEngine: real text for GG-UI.

The UI core measures text through an interface and draws it from a shaped run. This is the implementation behind both: font files are read and glyphs rendered with FreeType, text is shaped with HarfBuzz, and rendered glyphs are packed into atlas pages.

  • Text in any direction: each paragraph is resolved with the Unicode bidirectional algorithm (SheenBidi), so right-to-left scripts and mixed-direction text come out in the right order.
  • A character the font does not have is drawn from the first fallback font that does.
  • Lines break at spaces and hyphens, between ideographs, and at line feeds; a word longer than a line is cut where the line ends.
  • Text is shaped once. Measuring a string shapes it, breaks it into lines, and keeps the result as a run; painting draws from the same run. Two nodes with the same text, font, size, and width share one run.
  • Glyphs are rendered hinted, at the pixel size they are shown at, the first time they are drawn, and positioned on whole pixels: the crisp small text an editor needs. A UI scale change is a different pixel size, so text is shaped again.
  • Atlas pages are plain memory here. Whoever draws uploads them: each page has a version that goes up whenever glyphs are added.

It needs no GPU, so headless tools and tests use it as it is. Documents may be updated on several threads at once, and what they ask through Measurer and Glyphs is answered at once:

  • a string that has been shaped is found by many at a time, and so is a glyph already in the atlas;
  • a string that has not is shaped by the thread that asked, with FreeType and HarfBuzz objects of its own, while the others go on;
  • only adding a run, dropping one, and giving a new glyph its place in the atlas are done one thread at a time.

Fonts and styles (LoadFont, NameFont, AddFallbackFont, SetDefaultStyle, SetClassStyle) are set before documents measure with the engine, on one thread. The atlas's pages are read by one thread, which holds the atlas still while it does (AtlasHold) if documents may be being updated.

Namespaces

namespace GGUI

Classes

struct GGUI::FontStyle
Which font, and how big.
struct GGUI::AtlasPage
One page of rendered glyphs: one byte per pixel, how much of the pixel the glyph covers.
class GGUI::TextEngine
Fonts, shaping, and the glyph atlas, behind the UI core's text interfaces. See the file description.
struct GGUI::TextEngine::Stats
What the engine has done since it was made.
class GGUI::TextEngine::AtlasHold
While one of these exists no glyph is added, so the pages stay as they are: for whoever copies them while documents may be being updated on other threads.
struct GGUI::TextEngine::ShapedGlyph
One glyph of a run as shaped, in the order it is drawn: for tests and tools.