Skip to content

Font Rendering

Levente Santha edited this page May 11, 2026 · 2 revisions

Font Rendering

JNode's dual font rendering system supporting TrueType (TTF) and Bitmap Distribution Format (BDF) fonts.

Overview

JNode provides two distinct font rendering pipelines: a TrueType renderer for scalable outlines and a BDF renderer for fixed bitmap fonts. Both are coordinated through a plugin-based FontManager that delegates to format-specific FontProvider plugins.

Key Components

Class/File Purpose
gui/src/awt/org/jnode/awt/font/FontManager.java Central interface coordinating font providers
gui/src/awt/org/jnode/awt/font/def/DefaultFontManager.java Implementation with plugin-based provider discovery
gui/src/font/org/jnode/font/bdf/BDFParser.java JavaCC-generated parser for BDF font files
gui/src/font/org/jnode/font/bdf/BDFFontContainer.java BDF font container holding glyphs and metadata
gui/src/font/org/jnode/font/bdf/BDFGlyph.java Individual BDF glyph with bitmap data
gui/src/font/org/jnode/font/bdf/BDFMetrics.java BDF-specific font metrics
gui/src/awt/org/jnode/awt/font/truetype/TTFFontData.java Abstract TTF font data holder
gui/src/awt/org/jnode/awt/font/truetype/TTFFont.java TTF wrapper extending java.awt.Font
gui/src/awt/org/jnode/awt/font/truetype/TTFTextRenderer.java TTF glyph-to-surface rendering
gui/src/awt/org/jnode/awt/font/renderer/GlyphRenderer.java Anti-aliased glyph rendering via summed area table
gui/src/awt/org/jnode/awt/font/renderer/RenderCache.java Cache for GlyphRenderer instances
gui/src/awt/org/jnode/awt/font/truetype/tables/*.java TTF table parsers (Head, Glyph, CMap, Hhea, Hmtx, etc.)

How It Works

Font Manager Coordination

DefaultFontManager discovers FontProvider plugins via the org.jnode.font.providers extension point. Provider ordering is controlled by the jnode.font.renderer system property (default: bdf).

FontManager.getAllFonts() → iterates all providers
FontManager.getFontMetrics(font) → delegates to provider
FontManager.drawText(surface, ...) → gets TextRenderer from provider

BDF Rendering Pipeline

  1. BDFFontProvider loads .bdf files via BDFParser (JavaCC-generated)
  2. BDFParser.loadFont() parses STARTFONT through ENDFONT blocks
  3. BDFFontContainer holds the parsed glyphs in a HashMap<String, BDFGlyph>
  4. BDFFontMetrics computes ascent/descent from the bounding box
  5. BDFTextRenderer.render() iterates characters, blits glyph bitmaps pixel-by-pixel with alpha blending
BDFFontProvider.createFont(stream)
    → BDFParser.loadFont()
    → BDFFontContainer (stores glyphs)
    → BDFTextRenderer.render(surface, text, ...)

TTF Rendering Pipeline

  1. TTFFontProvider loads .ttf files via TTFFontDataFile
  2. TTFFontData.readAll() parses all required tables on demand
  3. Key tables: cmap (char→glyph), glyf (glyph outlines), head (global metrics), hhea/hmtx (horizontal metrics), loca (glyph offsets)
  4. TTFTextRenderer.render() maps characters via CMapTable, fetches glyphs via GlyphTable
  5. GlyphRenderer converts outline shapes to anti-aliased rasters using a summed area table (SAT) for sub-pixel filtering
  6. surface.drawAlphaRaster() composites the glyph to the framebuffer
TTFFontData.getGlyph(ch)
    → CMapTable.getGlyphIndex(ch)    // char→glyph index
    → GlyphTable.getGlyph(index)     // glyph outline
GlyphRenderer.createGlyphRaster(...)
    → Shape → BitSet → SummedAreaTable → 8bpp raster
TTFTextRenderer.render()
    → GlyphRenderer → drawAlphaRaster → Surface

Glyph Caching

RenderCache holds GlyphRenderer instances keyed by Glyph + font size. Each GlyphRenderer pre-computes a summed area table from the master glyph shape, enabling fast 128×128 scaling to any requested font size via createGlyphRaster().

Gotchas

  • BDF renderer defaults to higher priority (jnode.font.renderer=bdf) despite TTF being more feature-complete
  • TTF GlyphTable.getGlyph() returns org.jnode.awt.font.spi.Glyph (interface), while BDF uses org.jnode.font.bdf.BDFGlyph (concrete class) — no unified glyph abstraction
  • BDF bit depths > 1 supported via BDFGlyph.decode() per-pixel unpacking
  • GlyphRenderer uses a hardcoded MASTER_HEIGHT = 128.0 for vector scaling; all glyphs are rendered at this scale then downscaled
  • TTF composite glyphs (e.g., for accented characters) supported via CompositeGlyph handling in the glyph loader
  • No hinting applied; subpixel positioning relies on summed-area anti-aliasing quality

Related Pages

Clone this wiki locally