18 KiB
libSceFont technical debt
Unknown function info
-
sceFontRenderCharGlyphImage, sceFontRenderCharGlyphImageHorizontal, sceFontRenderCharGlyphImageVertical (libSceFont) accept a surface whose width or height is 0, with any row stride, and return the glyph metrics and an empty update rectangle without writing to the surface. A negative width, height or stride, a zero stride on a surface with pixels, a null buffer and a pixel size other than 1 or 4 bytes still return
SCE_FONT_ERROR_NO_SUPPORT_SURFACE; those cases and the exact console result for a zero-extent surface are not measured. The extent-0 behaviour is inferred from the Tekken Dark Resurrection PSP emulator which, to measure a string, initialises the surface with width 0 and height 31 and an unbound stride, renders each character and sums the returned advances. -
sceFontCreateString: a string created from a default-form (0x10) text source gets the direction of its first strong character, 0x11 for right to left and 0x12 for left to right, and 0x12 when there is none; explicit 0x11 and 0x12 sources keep their form and sceFontStringGetWritingForm returns the stored form. LRM and RLM count as strong, embeddings and overrides do not, and text between an isolate initiator and its PDI is skipped. The rule follows a run of the firmware 13.42 library in a harness reported on the pull request: for non-empty text it was checked before a later glyph-stage failure and only empty text completed, so it is not full native right-to-left rendering. Which characters are strong is decided here by Unicode block ranges, not by the full bidi class tables.
-
sceFontRenderCharGlyphImage, sceFontRenderCharGlyphImageHorizontal, sceFontRenderCharGlyphImageVertical (libSceFont) - four titles disassembled for this entry import them: PPSA01530 (CharGlyphImage, 2 call sites), PPSA13356 (CharGlyphImage, 4), PPSA15246 (Horizontal, 3) and PPSA14421 (Horizontal, 1); none imports Vertical. PPSA13356 initialises two surfaces of 64 x 64 and 1920 x 1080 at 1 byte per pixel (0xba084, 0xba5e8) and calls again with the character '_' (0x5f) at 0xba111 when the first call (0xba0e2) returns nonzero; PPSA15246 (0x229413) and PPSA14421 (0x1054d8) do not test the result. The extents of the other surfaces are run-time values, so whether any title passes 0 is not shown.
-
Typographic design: native selector, feature, font-set eligibility and output-clearing rules are recovered. Driver typography selection and queries, feature-cache updates and glyph substitution remain unimplemented and throw instead of storing arbitrary selector/value pairs.
-
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
cellFontGetRenderScaledKerningin RPCS3 (PS3 predecessor of the library), not confirmed on a title. The kerning is thesceFontGetKerningone 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: PS5 traversal and multi-character shaping remain unverified; the host has one character and glyph per step. PS4 11.00 measurements establish an 8-byte pointer output into the writing, null for a null writing, and traversal to null after the current step is exhausted. The pointer ABI agrees with KytyPS5 and SharpProspero; shadPS4 and prosper instead treat the output as a struct. The internal letter step remains valid until writing destruction and is rebuilt when a character is returned.
-
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.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. -
sceFontCharactersRefersTextCodes, sceFontTextCodesStepNext and sceFontTextCodesStepBack (libSceFont) - the signatures follow the Orbital IDA type database and SharpProspero, and the 64-byte
FontTextCodeswith the order pointer at 0 and the code at 8 follows SharpProspero's SceFontTextCodes. The traversal follows the PS4 11.00libSceFont.sprxdisassembly posted in #4050, not a PS5 measurement: the cursor keeps the current, start and term characters at +0x28, +0x30 and +0x38;Refersnever compares the character with the term and returns null for a clustered or synthetic character;StepNextreturns null at the term after visiting it;StepBackreturns null when the current character is the start; both steps skip synthetic characters. Assumed and not covered by the report, which saysStepNextreturns null only at the term:StepNextalso returns null at the end of the chain (for example with a null term), andStepBackat 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 itsattributeargument 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 returnsOKfor 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 fromsceFontGenerateCharGlyphthat it deletes unused and draws withsceFontRenderCharGlyphImageHorizontal; 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 and their priority are inferred, 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. The SDK set names (
..._JP_AR,..._GBCJK_TH) and Hangul aliases (SCEPS4Yoongd-Light.otf,SCEPS4Yoongd-Medium.otf,SCEPS4Yoongd-Bold.otf) come from shadPS4; the Vietnamese bit rule and the priority used here are our inferences, not its fallback implementation. A character the primary file lacks is taken from the first of them that has it; kerning between two files is 0, andsceFontGetCharGlyphCodeandsceFontGetFontGlyphsCountanswer 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.
-
sceFontGetFontMetrics (libSceFont) - the 64-byte output, the form fallbacks (2 and 3 fall back to the
hheavalues when OS/2 is missing or gives an empty range, 4 builds vertical values fromvheaor OS/2) and the raw weight deltas and slant copied from the style are not measured on a console. For a font set the values are those of its primary file; which file the console reports is not recovered. Closes when: measured on a PS5 -
sceFontGetFontStyleInformation (libSceFont) - the 24-byte output (FreeType family and style names, italic and bold flags, OS/2 weight class when it is a multiple of 100 from 100 to 900, width class below 10, and 1 plus a right-to-left
headdirection plus 0x80 for vertical metrics) and the font-set record path are not measured on a console. A face without aheadtable, such as a BDF font, throws, as its console result is unknown. Closes when: measured on a PS5 -
sceFontGetFontGlyphsOutlineProfile (libSceFont) - the 16-byte output (the
maxpmaximum contours, points, composite contours and composite points) andSCE_FONT_ERROR_NO_SUPPORT_FUNCTIONfor amaxpolder than 1.0 are not measured on a console. A handle with a font-set record throws, as the maximum over the record's system font entries is not modelled. A face without amaxptable throws, as its console result is unknown. Closes when: measured on a PS5 -
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. Expansion-buffer outputs remain opaque pending field recovery. Protected implementations are unchanged.
-
Font graphics fill descriptors: the region, fill-method, fill-plot and fill-rates initialisers and setters, and
sceFontSetGraphicsErrorCallback, follow firmware 13.60libSceFont.sprx(read from disassembly, not measured on a console): argument checks in the same order, error codes, tags and the bytes written. What the layout selectors, mapping values, region corner flags and fill effects mean is unknown, because the calls that read these descriptors (sceFontGraphicsSetup*,sceFontGraphicsUpdate*) still throw. The error codes0x80460086to0x80460089have no public names; the source names them after the argument they reject
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.
- sceFontCreateGraphicsServiceWithEdition and sceFontCreateWords take their handle output in the fourth integer argument slot. The third slot is not read by the supplied module and is represented as an opaque 64-bit value; its declared source type remains unknown.
- Word dictionaries: building, depth limit, sort and error rules and longest-match selection are read from disassembly, not measured on a console. The text source is parsed once instead of twice. More than 65535 nodes return
SCE_FONT_ERROR_FUNCTIONAL_LIMIT, where the native 16-bit indices would wrap. The shape-entry test on the next character is skipped since strings built here have no shape entry. The low flag byte and flag bits 43-45 are tested as read; strings built here leave them clear, so names are ours.