guest_font_metrics now opens the same buffer five times while the library
supports four external fonts. The fifth open only succeeds if ClaimEntry
reuses the active entry by address, so the address match is now covered.
AI-assisted: yes
When a font is closed, its context entry is marked inactive and its unique
ID is cleared, but its font address stays. ClaimEntry matched an entry by
that address without checking that it was active, so reopening a font from
the same memory took the old entry without claiming it: the entry stayed
inactive while it held the reopened font. The next sceFontOpenFontMemory of
another buffer then picked that entry as the first free one and cleared it,
which lost the first font's object and made its handle answer with the
second font's driver data, such as its metrics.
ClaimEntry now matches by address, like by unique ID, only an active entry,
so a reopen claims a free entry again.
AI-assisted: yes
sceFontGetFontMetrics fills the 64-byte metrics block through a new
driver slot at SysDriver+0x98, as libSceFont and libSceFontFt do in
firmware 13.60. Form 1 reads hhea, 2 the OS/2 typographic values, 3 the
OS/2 Windows values and 4 the vertical values from vhea or OS/2; 2 and 3
fall back to hhea when OS/2 is missing or gives an empty range. The
bounding box, em size, raw weight deltas and slant follow. A failed call
clears the block and sets both weights to 1.
Co-Authored-By: Claude Opus 5.5 <[email protected]>