Hi Simon,
Thanks for the detailed explanation, that makes sense.
My use case: I’m building a monospaced text grid (terminal-style UI), where I need to know the fixed cell size (width/height in pixels) that a character will occupy on screen, before actually laying out the text, so I can size/position the grid cells accordingly.
Here’s roughly what I’m doing today:
/// <summary>
/// Computes the terminal cell size and the device-space font size that must be passed to
/// <c>MeshGenerationContext.DrawText</c> so a drawn glyph's advance lands exactly on the cell.
/// </summary>
/// <remarks>
/// <c>UIR.MeshGenerator.DrawText</c> rounds the font size it receives to the nearest device
/// pixel (<c>fontSize = (int)Mathf.Round(fontSize)</c>, verified in
/// <c>UnityEngine.UIElementsModule.dll</c> 6000.3.21f1), and the mesh it produces is later
/// divided by <c>scaledPixelsPerPoint</c> back into panel points. So the real glyph advance,
/// in panel points, is <c>horizontalAdvance * deviceFontSize / (faceInfo.pointSize *
/// pixelsPerPoint)</c> - not <c>horizontalAdvance * fontSize / faceInfo.pointSize</c> as a
/// naive calculation would give. Whenever <c>fontSize * pixelsPerPoint</c> isn't an integer
/// (i.e. almost always, since the panel is set to ScaleWithScreenSize), that difference
/// compounds across columns and text runs drift off the cell grid. Deriving both the cell
/// size and <c>deviceFontSize</c> from the same rounded value keeps every glyph exactly on
/// the grid regardless of <c>scaledPixelsPerPoint</c>.
/// </remarks>
private void CalculateCellMetrics(FontAsset font, char character, float fontSize, float pixelsPerPoint,
out Vector2 cellSize, out float deviceFontSize)
{
if (font == null || !font.HasCharacter(character, false, true))
{
cellSize = Vector2.zero;
deviceFontSize = 0f;
return;
}
var glyph = font.characterLookupTable[character].glyph;
var faceInfo = font.faceInfo;
deviceFontSize = Mathf.Round(fontSize * pixelsPerPoint);
float scale = deviceFontSize / (faceInfo.pointSize * pixelsPerPoint);
float advance = glyph.metrics.horizontalAdvance * scale;
float height = faceInfo.lineHeight * scale;
cellSize = new Vector2(advance, height);
}
Where pixelsPerPoint is scaledPixelsPerPoint and character is a fixed reference glyph (e.g. ‘A’ or ‘M’), since the font is monospaced and all glyphs should share the same advance width.
I get that this reads pre-shaping metrics and doesn’t account for things like per-tag size/spacing overrides — in my case that’s fine since I’m not applying rich text tags to this text, and I’m only using it for grid sizing, not final glyph placement.
Given that characterLookupTable is being deprecated, is there a recommended replacement API to get this same advance/lineHeight info for a single reference character in ATG, without going through the full shaping pipeline? Or is reading pre-shaping metrics for this specific “fixed grid cell size” use case still going to be supported some other way?
Thanks