Integrate ab_glyph-based font rendering with bundled Noto Sans fonts (Regular, Bold, Italic, BoldItalic, Mono) to replace the fixed-width text measurer in golden tests. Thread font-weight, font-style, and font-family through the entire rendering pipeline: CSS parsing → style computation → layout → display list → rasterizer. Key changes: - fonts crate: font database, shaper, and rasterizer with bundled fonts - CSS: parse font-family (comma-separated lists), font-weight, font-style - shared: FontWeight and FontStyle types - style: font property inheritance and computation - layout: ProportionalTextMeasurer using real font metrics - display_list: font properties on Text items (conditional dump output) - render: font-aware text drawing - Golden tests regenerated with proportional font measurements - New golden tests (137-141) for font weight, style, family, and headings - Golden test regeneration infrastructure (regen_goldens.rs) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.4 KiB
Known Limitations Log
Items consciously deferred during implementation for simplicity. Not for planned features.
HTML Entity Decoding
- Only ~200 common named entities supported; full HTML5 spec defines 2,125+ named character references
CSS Variables
- Shorthand properties with
var()now supported for: margin, padding, background, border, border-top/right/bottom/left, border-width, border-color, border-style - Custom property inheritance now uses
Rc<HashMap>with copy-on-write viaRc::make_mut. Only elements that set custom properties pay for a deep clone. Location:crates/style/src/types.rsininherit_from()andapply_custom_property() substitute_vars()returnsOption<Vec<CssToken>>and logs warnings - could return structuredResult<_, VarSubstitutionError>with specific error variants (CircularReference, UndefinedVariable, MaxDepthExceeded, InvalidSyntax) for better error handling
UA Stylesheet
The user agent stylesheet (crates/style/src/ua_stylesheet.rs) includes several CSS properties and selectors that are not yet implemented. These are silently ignored but should be implemented for full HTML rendering:
CSS Properties
font-weight- implemented in M5;<b>,<strong>,<th>render boldfont-style- implemented in M5;<em>,<i>render italicfont-family- implemented in M5;<code>,<pre>use monospacetext-decoration- needed for<a>links to render underlinedborder-spacing- needed for table cell spacingborder-collapse- needed for table border rendering modesborder-style: inset- is needed but not implemented
Pseudo-class Selectors
:link- not implemented;a:linkrules don't match any elements:visited- parsed but always returns false;a:visitedrules never match
Font Rendering (Milestone 5)
Weight class granularity
Font weights are bucketed into two classes: Regular (100-499) and Bold (500-900). Requests for intermediate weights like 300 (Light) or 600 (Semi-Bold) map to the nearest class. This is correct fallback behavior per CSS font matching but loses fidelity. Acceptable for the current Noto Sans font set which only provides Regular (400) and Bold (700). If more font weight variants are bundled in the future, the WeightClass enum in crates/fonts/src/font_db.rs should be expanded accordingly.
X-height approximation
X-height (height of lowercase 'x', used for vertical-align: middle) is approximated as 50% of ascent rather than read from the font's OS/2 table. ab_glyph does not expose the sxHeight field. This produces slightly inaccurate middle alignment for fonts with unusual x-height ratios. Location: crates/layout/src/text_measure.rs in font_metrics_styled().
Oblique maps to italic
FontStyle::Oblique silently maps to FontStyle::Italic during font resolution. True oblique (algorithmically slanted regular glyphs) differs from true italic (designed alternate letterforms). This matches common browser behavior when dedicated oblique faces are unavailable. Location: crates/fonts/src/font_db.rs in resolve().
Bundled font binary size
Five Noto Sans TTF files (~3.1 MB total) are embedded in the binary via include_bytes!(). This ensures deterministic cross-platform rendering but increases binary size. No system font discovery is performed. If binary size becomes a concern, consider lazy loading or system font fallback as a future enhancement.
No text shaping
Text is laid out character-by-character with kerning pairs (L-to-R only). There is no complex script shaping (ligatures, contextual alternates, bidi). A future milestone could add rustybuzz for HarfBuzz-compatible shaping.
No glyph cache
Glyph rasterization is not cached — the same glyph at the same size is re-rasterized on every paint. Font resolution is cached (in FontDb), but the rasterized alpha masks are not. For text-heavy pages with repeated characters, a glyph cache keyed on (glyph_id, size) would reduce redundant work.
Font shorthand not parsed
The CSS font shorthand property (e.g., font: bold 16px/1.2 Arial, sans-serif) is not parsed. Only the individual longhand properties font-weight, font-style, and font-family are supported.
Variable fonts not supported
Only static TTF font files are supported. Variable font axes (weight, width, slant) are not used even if present in the bundled font files.