From 18d124ab171d4bc7ce404af7e4084d0d07f48f06 Mon Sep 17 00:00:00 2001 From: isaac <> Date: Mon, 1 Jun 2026 02:20:10 +0200 Subject: [PATCH] InstantPage V2: text items measure true font height (A + D) Shift the line stack down by the ascender headroom (A - L, as `lineBoxTopInset` to avoid colliding with the existing formula-bleed `topInset` local) and pad the returned height by the last line's descender (D), so a single-line V2 text item is a true ascent/descent line box measuring exactly A + D instead of the cap box A - L. Inter-line advance unchanged; formulas still inflate via lineAscent/extraDescent. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../Sources/InstantPageV2Layout.swift | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/submodules/InstantPageUI/Sources/InstantPageV2Layout.swift b/submodules/InstantPageUI/Sources/InstantPageV2Layout.swift index f134c554e6..01065dacef 100644 --- a/submodules/InstantPageUI/Sources/InstantPageV2Layout.swift +++ b/submodules/InstantPageUI/Sources/InstantPageV2Layout.swift @@ -2754,10 +2754,18 @@ func layoutTextItem( let fontLineHeight = floor(fontAscent + fontDescent) let fontLineSpacing = floor(fontLineHeight * lineSpacingFactor) let fontDescentBelowBaseline = max(0.0, -fontDescent) + // True font-height line box: shift the whole line stack down by the ascender headroom above + // the cap line (A − L) and pad the final height by the descender (D) below the last baseline, + // so a single-line item measures exactly A + D. Exact (not pixel-snapped): this is an + // intra-item line offset; crispness rides on the item's own pixel-snapped frame origin, and + // intra-item line positions may already be fractional (e.g. after a non-integral extraDescent). + // Inter-line advance is unchanged. (Named `lineBoxTopInset` to avoid colliding with the + // formula-bleed `topInset` local near the end of this function.) + let lineBoxTopInset = max(0.0, fontAscent - fontLineHeight) let baselineToNextTopSlack = max(0.0, fontLineSpacing - 4.0) var lastIndex: CFIndex = 0 - var currentLineOrigin = CGPoint() + var currentLineOrigin = CGPoint(x: 0.0, y: lineBoxTopInset) var hasAnchors = false var maxLineWidth: CGFloat = 0.0 @@ -3097,7 +3105,9 @@ func layoutTextItem( var height: CGFloat = 0.0 if !lines.isEmpty && !(string.string == "\u{200b}" && hasAnchors) { - height = lines.last!.frame.maxY + extraDescent + // + fontDescentBelowBaseline: contain the last line's descender below its baseline, so + // (with the topInset shift) a single-line item measures exactly A + D = true font height. + height = lines.last!.frame.maxY + extraDescent + fontDescentBelowBaseline } var textWidth = boundingWidth