X-GIS

Concept

Labels & text.

Every place name, road number and POI is text drawn on the GPU. X-GIS stores each glyph once as a signed-distance field and reuses it at every size — so labels stay sharp from a whole-world view down to a single street, in Latin and CJK alike.

The glyph atlas

Text rendering is a pipeline: rasterise each glyph once, pack it into a texture, shape strings into glyph runs, decide which labels survive collision, then draw. Everything below walks that pipeline — each claim is true of the engine today, with the not-yet-built parts marked as roadmap.

01

Glyphs are signed-distance fields in an atlas

Each (font, codepoint, SDF radius) gets one slot in a shared texture atlas. The glyph is rasterised once at a single reference pixel size; the shader scales that one SDF for display rather than re-rasterising per zoom. The bytes use tiny-SDF packing — 0 far outside the glyph, 192 at the edge, 255 far inside.

Sharp at any zoom

A signed-distance field stores distance-to-edge, not pixels — so a single atlas slot renders crisply whether the label is 9 px or 64 px, with no bitmap blur.

02

One glyph slot, every size

The fragment shader recovers coverage by smoothstepping the distance field across the glyph edge (edge = 0.75 = 192/256, MapLibre's symbol buffer default) using a per-glyph-size analytic anti-aliasing half-width. A tiny country label and a large city label come from the same slot, both anti-aliased.
03

Halo / text-outline in the same pass

The shader composites a halo (text-halo-color / -width / -blur) behind the fill in a single pass. The halo edge is bounded to the SDF radius so it stays a thin outline that thins as text shrinks, instead of flooding the glyph cell into an opaque box at low zoom.

Where glyphs come from

04

Glyph-server PBF, or a local rasteriser

Glyphs come from a Mapbox/MapLibre-style glyph-server PBF (24-px SDF reference) or from a local Canvas2D rasteriser that computes the SDF on device. While a PBF range is still in flight, a metrics-only placeholder reserves the correct layout slot — the glyph occupies its right position but renders blank — so the frame never stalls waiting on the network.
05

In-place re-raster when a range lands

When the PBF range arrives, its slot is marked stale and re-rasterised in place. A monotonic generation counter bumps so the per-string caches miss — which is what lets a label whose glyph range landed after it was first shaped pick up the real SDF, instead of a low-zoom CJK label keeping only the few glyphs that happened to land early.
06

LRU atlas with overflow protection

The atlas evicts least-recently-used slots and drains newly rasterised glyphs to the GPU through a dirty queue. Before shaping, it verifies every pending label's glyphs are still resident; a label that would overflow the atlas this frame is dropped rather than rendered with another label's SDF bytes aliased into its slots.

CJK, Hangul & bilingual

Chinese, Japanese, Korean and Kana need handling Latin doesn't — dense ideographs, line breaking without spaces, and labels that mix scripts.

07

Ideograph-aware shaping

X-GIS detects CJK / Hangul / Kana ideographs to allow line breaks between them (no spaces required) and to apply a synthetic oblique for italic labels — Noto's CJK face ships no true italic, so the engine shears the upright glyph while leaving a Latin italic run on its real italic font. Per-glyph baked-size metadata lets one bilingual label carry a Latin run and a CJK run, each from its own slot.

Collision & placement

When labels would overlap, something has to give. X-GIS runs a greedy axis-aligned collision pass that mirrors Mapbox's placement semantics.

08

Greedy collision, Mapbox semantics

Labels claim space first-come by priority (symbol-sort-key) in a shared AABB grid; a later label that overlaps is dropped. The pass supports allowOverlap / ignorePlacement (always-visible / never-blocks), text-variable-anchor (try each candidate position, keep the first that fits), symbol-spacing along a line, collision groups (an icon never blocks its own paired text), and pre-seeded icon obstacles so text avoids already-placed icons.

Labels that follow a line

09

Curved labels that follow the road

A line label samples points along the line and places each glyph at that point's tangent angle, so the text bends with the road. A text-max-angle gate drops a label whose glyph-to-glyph turn is too sharp to read cleanly.

Where it is going

Roadmap · not yet shipped

This is planned, not built — the plumbing is in the engine but switched off today:

  • Local-ideograph generation — rasterising CJK glyphs locally at display-size buckets instead of the fixed 24-px server PBF. The routing exists but is disabled: the local SDF currently reads thicker and softer than the PBF glyphs, so CJK is served from the sharp PBF path at its authored size until the local SDF quality matches.

Tracked in the repo ROADMAP.md ↗.

See it live

Labels are everywhere a real map renders — place names, road shields and POIs all flow through this pipeline. Open a labelled map in the examples gallery and zoom in: the same atlas glyph stays crisp at every scale.

Specifications

See also