Files
AnyPS5/docs/dev/debt/libSceFont.md
T

14 KiB

libSceFont technical debt

Unknown function info

  • sceFontSetTypographicDesign and sceFontGetTypographicDesign: signatures are confirmed by the supplied PS5 library. Native feature ranges, defaults and driver-dependent availability are not implemented; the host still accepts arbitrary values and stores them without affecting shaping or rendering.

  • sceFontSetScriptLanguage and sceFontGetScriptLanguage: native script/language ranges, handle-error precedence and clearing of failed getter outputs are implemented. Valid driver queries and updates throw; the previous arbitrary-value map and fabricated zero default are no longer used. Driver selection and actual language-dependent shaping remain unimplemented.

  • sceFontGetRenderScaledKerning (libSceFont) - arguments, the cleared output and the bound renderer check taken from cellFontGetRenderScaledKerning in RPCS3 (PS3 predecessor of the library), not confirmed on a title. The kerning is the sceFontGetKerning one at the render scale

  • sceFontGetFontGlyphsCount, sceFontGetCharGlyphCode: signatures, error precedence, failed-output clearing and external-font glyph-code encoding are confirmed by the PS5 library. Multi-face system-font glyph counts, face-selection bits and typographic glyph substitutions are not modeled.

  • sceFontGetFontResolution: the 32-bit resolution output, float scale and nullable outputs are confirmed by the PS5 library and FontFt driver. Native system font sets return resolution 1000; the host still uses its selected face resolution because multi-face system font sets are not modeled.

  • Writing-line ABI and allocation: PS5 layouts, creation forms, memory validation, allocator callbacks and error handling are recovered. The 2208-byte line and 64-byte orders use caller memory. Host registry bookkeeping still allocates separately; memory lifetime and concurrent destruction require caller synchronization.

  • 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: PS5 confirms output order, calculations and zeroed outputs on invalid handles. A non-null head output with a null tail output causes an unchecked native write; the host throws instead. With no head output, the tail output remains untouched.

  • sceFontCharacterGetSyllableStringState (libSceFont) - the signature (textCharacter, int* syllableStringState) follows SharpProspero. Measured on PS4 firmware 11.00 libSceFont.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 returns SCE_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's SceFontSyllableString names 0 NonDetection, 1 Starting, 2 Following, 3 Depending and 4 Connecting. PPSA06699 (Hot Shots Golf 2) calls it.

  • sceFontCharactersRefersTextCodes, sceFontTextCodesStepNext and sceFontTextCodesStepBack (libSceFont) - the signatures follow the Orbital IDA type database and SharpProspero, and the 64-byte FontTextCodes with the order pointer at 0 and the code at 8 follows SharpProspero's SceFontTextCodes. The traversal follows the PS4 11.00 libSceFont.sprx disassembly posted in #4050, not a PS5 measurement: the cursor keeps the current, start and term characters at +0x28, +0x30 and +0x38; Refers never compares the character with the term and returns null for a clustered or synthetic character; StepNext returns null at the term after visiting it; StepBack returns null when the current character is the start; both steps skip synthetic characters. Assumed and not covered by the report, which says StepNext returns null only at the term: StepNext also returns null at the end of the chain (for example with a null term), and StepBack at the head of the chain. A null cursor or output returns null as in KytyPS5; a null text character throws, as its console result is unknown

  • sceFontDefineAttribute, sceFontGetAttribute, sceFontGlyphDefineAttribute, sceFontGlyphGetAttribute (libSceFont) - the signatures (handle, int attribute, int* oldAttribute) and (handle, int attribute, int* nowAttribute), and the same shape for a glyph, follow the SharpProspero bindings, matching the IDA type database of Orbital and KytyPS5, not confirmed on a title. Every handle and every glyph keeps one attribute, an opaque int whose meaning and valid values are unknown: define stores the new value and returns the previous one, and get returns the stored value with its attribute argument unused, as in KytyPS5. An attribute never set is 0. The null checks and the invalid-object errors follow the other libSceFont functions and diverge from KytyPS5, which returns OK for a null handle or glyph after writing 0 to the old-attribute pointer: every other handle and glyph entry point in this library reports the invalid object instead, and a title that passes one is already failing. shadPS4 leaves both exports unimplemented, so there is no second implementation to compare. PPSA01325 calls the glyph define with 0x11 on a glyph from sceFontGenerateCharGlyph that it deletes unused and draws with sceFontRenderCharGlyphImageHorizontal; the three bindings all read the third argument as an out pointer, not a value, so this call sets the glyph's attribute to 0x11. The attribute changes neither shaping nor rendering.

Functional

  • sceFontOpenFontSet (libSceFont) - the other script files of a set are chosen from its type, not measured on a console: Vietnamese for low-byte bit 0x10, Thai for script bit 0x10, Japanese for 0x04, simplified Chinese for 0x80 (before Japanese with 0x08), Hangul for 0x20 and Arabic for low-byte bit 0x80, as the SDK set names (..._JP_AR, ..._GBCJK_TH) listed by shadPS4 suggest; the file order and the Hangul file name (SCEPS4Yoongd-Medium.otf, SCEPS4Yoongd-Bold.otf) also come from shadPS4. A character the primary file lacks is taken from the first of them that has it; kerning between two files is 0, and sceFontGetCharGlyphCode and sceFontGetFontGlyphsCount answer for the primary file only

  • sceFontOpenFontSet (libSceFont) - 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 Arabic, Noto Sans CJK with its Korean face for Hangul) is loaded instead; 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: visual ordering and spacing originated from PS4 measurements and match the supplied PS5 structure and control flow. Exhaustive floating-point equivalence, including NaN payloads and rounding, has not been verified against a running PS5 module.

  • Font graphics and metric signatures: graphics-device/service creation takes font memory, parameters and a handle output; destruction takes a handle pointer. Attribute selectors and outputs are 32-bit values. Metric, outline-profile, style-information and expansion-buffer outputs remain opaque pending field recovery. Protected implementations are unchanged.

  • Font graphics fill and transform signatures: region layout and scalar float arguments are confirmed from assembly, including the extra 32-bit corner flags omitted by the roundish-region decompilation. Fill-method, plot and rates layouts, layout selector meanings and mapping parameter meanings remain unresolved. Protected bodies are unchanged.

Frame lifecycle, drawing completion, device usage, frame policy, clipping and fill setup/update argument signatures in Unimplemented.cpp are recovered. Frame and resource layouts remain opaque; their runtime implementation is still unavailable.

Glyph image rendering uses six pointer arguments and two scalar coordinates, with existing style, surface, metrics and output layouts. Positioning takes a mask and two floats. Control, word-character search and resource release/exchange/render signatures in Unimplemented.cpp are recovered; control payload types depend on the command and remain unmodeled.

Canvas, design, surface texture and fill-pattern construction signatures in Unimplemented.cpp are recovered. Pattern mode/count semantics and the graphics surface descriptor fields still require reconstruction; distinct opaque types preserve the confirmed object categories.

Unimplemented.cpp now defines the 32-byte fill method, 64-byte fill plot/rates and 96-byte device usage layouts, with size and field-offset assertions. Uninterpreted descriptor tails remain reserved; pool statistics expose capacity, current usage, available bytes, peak and signed change.

The glyph support registration and texture-image fill signatures are recovered from native argument use. The image constructor takes a byte span and four scalar coordinates; the decompiler omits its successful path. CreateWords and CreateGraphicsServiceWithEdition consume the output pointer in the fourth general-purpose argument slot but do not read the third slot, whose source type is not established.