Vixen
02b45cc4
csharp
public sealed class GlyphAtlas

A texture of glyph distance fields, packed as they are asked for and evicted least-recently used when it fills.

No guide page documents this yet — the page shows what the code says about itself.

Remarks

Dynamic rather than built ahead. CJK alone is tens of thousands of glyphs and a font may carry more; an atlas holding every glyph a font can draw is a texture nobody has the memory for, and one holding the glyphs an interface actually uses is a few hundred.

Shelf packing. Rows are opened as needed, each as tall as the first glyph that starts it, and glyphs fill along the row. It wastes the difference between a row's height and each glyph's — real, and bounded by how much glyph heights vary within one field resolution, which is not much. A skyline packer would waste less and would have to move entries to stay that way, and moving one entry invalidates a texture coordinate somebody is holding.

⚠ An evicted slot is reused only by a glyph that fits it. Eviction leaves a hole of one exact size, and a hole is worth having only if the next glyph is no larger — so the freed slots are kept per shelf and matched by width. What that cannot do is answer a glyph wider than every hole while the atlas is nominally full, which is what Compact is for: it rebuilds the packing from the live entries and changes every region, so Version moves and a caller holding coordinates has to ask again.

Fields and properties (10)

  • public int Width

    The texture's width.

  • public int Height

    The texture's height.

  • public float[] Pixels

    The three channels per pixel, row-major. What a renderer uploads.

  • public int Count

    How many glyphs are held.

  • public long Hits

    How many lookups were answered from the atlas.

  • public long Misses

    How many lookups had nothing to answer with.

  • public long Evictions

    How many entries have been evicted to make room.

  • public int Version

    Moves whenever every region changes, which only Compact does.

  • public int Revision

    Moves whenever the pixels change: a glyph added, or the whole thing repacked.

  • public bool Dirty

    Whether the texture's contents have changed since the flag was last cleared.

Methods (6)

  • public GlyphAtlas(int width = 1024, int height = 1024, int padding = 1)

    Creates an atlas.

  • public void Uploaded()

    Clears Dirty, after a renderer has uploaded the texture.

  • public bool TryGet(GlyphKey key, out AtlasRegion region)

    Finds a glyph's field, marking it as the most recently used.

  • public bool Add(GlyphKey key, DistanceFieldBitmap field, out AtlasRegion region)

    Puts a glyph's field into the atlas, making room if it has to.

  • public void Clear()

    Throws everything away.

  • public void Compact()

    Rebuilds the packing from the live entries, tightest first.

Used by (18)

  • UiHostHelloUi
  • GlyphAtlasTestsVixen.Ui.Text.Tests
  • GlyphFieldCacheVixen.Ui.Text
  • GlyphFieldCacheTestsVixen.Ui.Text.Tests
  • IconAtlasVixen.Ui
  • IconAtlasTestsVixen.Ui.Tests
  • NineSliceImageTestsVixen.Ui.Tests
  • PathTessellationCacheTestsVixen.Ui.Tests
  • SoftwareUiRasterizerVixen.Ui.Testing
  • UiFrameLifetimeTestsVixen.Graphics.Golden.Tests
  • UiGeometryBuilderVixen.Ui
  • UiGeometryTestsVixen.Ui.Tests
  • UiImageTestsVixen.Graphics.Golden.Tests
  • UiInterfaceVixen.Ui.Renderer
  • UiRendererVixen.Ui.Renderer
  • UiTestVixen.Ui.Testing
  • VideoInUiTestsVixen.Video.Rendering.Tests
  • EditorHostVixen.Editor.Host