11 KiB
11 KiB
libSceFont technical debt
Silent stubs
- sceFontGlyphDefineAttribute (libSceFont) checks the glyph and ignores the attribute and its value, whose meaning is unknown. PPSA01325 sets attribute 0x11 to 0 on a glyph from
sceFontGenerateCharGlyphthat it deletes unused, and draws the character withsceFontRenderCharGlyphImageHorizontal
Unknown function info
- sceFontSetScriptLanguage, sceFontGetScriptLanguage, sceFontSetTypographicDesign, sceFontGetTypographicDesign (libSceFont) - signatures follow SharpProspero, not confirmed for the PS5. The handle keeps the language set for each script and the feature set for each typographic design and returns them, with 0 for one never set; the console default and its valid ranges are unknown, so any value is accepted. Neither setting changes shaping or rendering yet
- sceFontGetRenderScaledKerning (libSceFont) - arguments, the cleared output and the bound renderer check taken from
cellFontGetRenderScaledKerningin RPCS3 (PS3 predecessor of the library), not confirmed on a title. The kerning is thesceFontGetKerningone at the render scale - sceFontGetPixelResolution (libSceFont) - signature taken from the IDA type database of Orbital, not confirmed on a title. The value is the one the library's driver reports (64 for FreeType); the argument checks and the cleared output follow
sceFontGetLibrary - sceFontDettachDeviceCacheBuffer (libSceFont) - signature taken from the IDA type database of Orbital, not confirmed on a title. It detaches the cache buffer attached by
sceFontAttachDeviceCacheBuffer, returns the buffer and its size, and reportsSCE_FONT_ERROR_NOT_ATTACHED_CACHE_BUFFERwhen no cache buffer is attached - sceFontGetFontGlyphsCount, sceFontGetCharGlyphCode (libSceFont) - signatures taken from the IDA type database of Orbital and matching the SharpProspero bindings, not confirmed on a title. The count is the face's glyph count and the glyph code its glyph index, as the library's driver reports them; a code with no glyph returns
NO_SUPPORT_GLYPHand code 0NO_SUPPORT_CODE, assceFontRenderCharGlyphImagedoes. The argument checks and the cleared output followsceFontGetPixelResolution - sceFontGetFontResolution (libSceFont) - signature taken from the IDA type database of Orbital, not confirmed on a title; the outputs are inferred from the names. The resolution is the face's units per EM and the scale pixel the driver's face scale (units per EM / 64 for FreeType), the pixel scale a font has when opened. Either output may be null, as in
sceFontGetResolutionDpi - sceFontCreateWritingLine, sceFontWritingLineWritesOrder (libSceFont) - signatures and the
SceFontWritingLineStep/SceFontCreateWritingLineDetaillayouts (detail id0x0FD5) taken from SharpProspero, not confirmed on a title. The 64-bit writing attribute is read as the PS4 11.00libSceFont.sprxreads it: low byte0xFA, embedding level in bits 8-15 (0 to 126), bit 30 and bit 31 marking space before and after the run; the PS5 library was not measured, and the names of the two bits are ours. PPSA01325 builds its attribute the same way (0xFA | level << 8, bits 30 and 31) and passes a null metrics pointer when its run has no metrics object. Attribute 0 is accepted and treated as0xFAwith level 0 and no spacing bits, as before this reading; the PS4 library rejects it and what the PS5 library does with it is unknown. Any other attribute, a level above 126 and a null orderer throw: the PS4 library returns0x80460002for them, not confirmed for the PS5 - sceFontWritingRefersRenderStepCharacter (libSceFont) - the second argument is an out pointer to the writing's letter step, as in KytyPS5 and the SharpProspero bindings. Measured on PS4 firmware 11.00
libSceFont.sprx(not on a PS5): exactly 8 bytes are written, the address of a step stored inside the writing, and a null writing writes null; shadPS4 and prosper treat the argument as a struct, which the measurement contradicts. The letter step lives in the writing, so the pointer stays valid as long as the writing does, and its contents are rebuilt by each call of this function. On the PS4 library repeated calls on one step walk the characters it covers and then return null; here every call returns the step's one character, so the second call differs. Assumed: each step covers one character and one glyph. PPSA06699 (Hot Shots Golf 2) dereferences the returned pointer for its character counts. - sceFontWritingLineGetOrderingSpace (libSceFont) - the four outputs are written in the order the PS4 11.00
libSceFont.sprxwrites them (line advance, leading space, space between spaced runs, trailing space); the parameter names in the Orbital IDA type database and the SharpProspero bindings order them differently (head, inline, tail, advance), and the PS5 library was not measured. PPSA01325's only call uses them in the PS4 order: it computes first - second - fourth - 0.25 * third and compares that, divided by a scale, with its width limit. The PS4 library writes the trailing space through its pointer without a null check whenever the leading-space pointer is set; that call throws here - sceFontCharacterGetSyllableStringState (libSceFont) - the signature
(textCharacter, int* syllableStringState)follows SharpProspero. Measured on PS4 firmware 11.00libSceFont.sprx(not on a PS5): the state is 0 for Latin, CJK, Hangul, Arabic, Hebrew, Devanagari and the other scripts tried, and the library sets 1, 3 or 4 (never 2 on real text) for Thai while it creates the string; a null character or a null result returnsSCE_FONT_ERROR_INVALID_PARAMETER, and a null character writes 0 to a non-null result. This returns 0 for every character outside the Thai block (U+0E00 to U+0E7F), as KytyPS5 does, and throws for Thai characters, whose cluster states are not modelled. SharpProspero'sSceFontSyllableStringnames 0 NonDetection, 1 Starting, 2 Following, 3 Depending and 4 Connecting. PPSA06699 (Hot Shots Golf 2) calls it.
Functional
- sceFontOpenFontSet (libSceFont) opens only the primary file of a system font set. Characters the console takes from the set's other files (Hangul, Thai and Arabic in Japanese and Chinese sets, Arabic in European sets) are reported as unsupported glyphs. The console file names are those of the PS4 firmware; the names of the PS5-only JG2 sets (
0x1A......) are unknown, so they use the SSTJpPro files. When a console file is missing, an openly licensed substitute (Noto Sans, Noto Sans Mono, Noto Sans Thai, Noto Sans CJK) is loaded instead. It is not the system font: its metrics differ, so text width, line height and wrapping differ from the console. System font faces are loaded by FreeType in host memory, not in the font memory the title passes to the library: FreeType needs about 1 MiB per CJK face, which the title's font memory is not sized for. - sceFontGetCharGlyphMetrics, sceFontGetRenderCharGlyphMetrics (libSceFont) report the vertical metrics the way the FreeType driver reports them for a rendered glyph, not confirmed on a title: FreeType's vertical advance, and for a face without vertical metrics a bearing of half the horizontal advance left of the horizontal bearing and of half the advance left over by the glyph height.
- Font writing lines (libSceFont) -
sceFontWritingLineWritesOrder,sceFontWritingLineRefersRenderStep,sceFontWritingLineGetRenderMetrics,sceFontWritingLineGetOrderingSpaceandsceFontWritingLineClearfollow the PS4 11.00libSceFont.sprx(firmware module, read from its disassembly and compared call for call on random sequences): runs are linked in visual order by embedding level, the space at each spaced join is summed for the line, steps walk the visual order from the left (form0x12) or from the right (form0x11) and the render metrics grow as steps are consumed. The PS5 library was not measured. Not from that module: form0x10is accepted and treated as left to right and a detail with id0x0FD5is accepted (the PS4 library rejects both); the memory argument ofsceFontCreateWritingLineand the rest of the detail are not read (the PS4 library validates its library object there); an unknown writing form, another detail id, a null line pointer on creation, unknown and null handles (except insceFontWritingLineRefersRenderStep, which returns null for a null line) and a null output ofsceFontWritingLineGetRenderMetricsthrow instead of returning the PS4 error codes, which are not confirmed for the PS5;sceFontDestroyWritingLinewas not compared. Lines are allocated on the host, not in the font memory the title passes to the library: FreeType needs about 1 MiB per CJK face, which the title's font memory is not sized for.