Enhance font rendering and management system

- Integrated `stb_truetype` for advanced font rendering.
- Added support for external and system fonts with logging.
- Introduced new structures for glyphs, metrics, and kerning.
- Implemented functions for font state management and scaling.
- Improved glyph rendering, including subpixel and caching.
- Enhanced render surface initialization and scissor handling.
- Refactored stubbed functions with proper implementations.
- Added ABI compatibility checks for key structures.
- Improved logging, error handling, and code organization.
- Updated documentation and comments for better clarity.
This commit is contained in:
w1naenator 2025-11-04 16:54:34 +02:00
parent 9b33b66322
commit 078a8ff865
2 changed files with 1071 additions and 206 deletions

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
#pragma once
#include <cstdint>
#include "common/types.h"
namespace Core::Loader {
@ -11,6 +12,128 @@ class SymbolsResolver;
namespace Libraries::Font {
using OrbisFontLib = void*;
struct OrbisFontHandleOpaque {
u32 reserved[64];
};
using OrbisFontHandle = OrbisFontHandleOpaque*;
using OrbisFontRendererCreateParams = void*;
using OrbisFontRenderer = void*;
using OrbisFontLibCreateParams = void*;
struct OrbisFontOpenParams {
u16 tag;
u16 pad16;
u32 flags;
u32 subfont_index;
s32 unique_id;
const void* reserved_ptr2;
const void* reserved_ptr1;
};
#if INTPTR_MAX == INT64_MAX
static_assert(sizeof(OrbisFontOpenParams) == 32, "OrbisFontOpenParams size");
#endif
struct OrbisFontGlyphMetrics {
float w;
float h;
float h_bearing_x;
float h_bearing_y;
float h_adv;
float v_bearing_x;
float v_bearing_y;
float v_adv;
};
#if INTPTR_MAX == INT64_MAX
static_assert(sizeof(OrbisFontGlyphMetrics) == 32, "OrbisFontGlyphMetrics size");
#endif
struct OrbisFontKerning {
float dx;
float dy;
float px;
float py;
};
#if INTPTR_MAX == INT64_MAX
static_assert(sizeof(OrbisFontKerning) == 16, "OrbisFontKerning size");
#endif
struct OrbisFontGlyphImageMetrics {
float bearing_x;
float bearing_y;
float dv;
float stride;
u32 width;
u32 height;
};
struct OrbisFontResultStage {
u8* p_00;
u32 u32_08;
u32 u32_0C;
u32 u32_10;
};
struct OrbisFontResultSlot {
u8* maybe_addr;
u32 maybe_rowBytes;
u8 maybe_pixelSize;
u8 maybe_pixelFmt;
};
struct OrbisFontRenderOutput {
const OrbisFontResultStage* stage;
OrbisFontResultSlot slot;
u32 new_x;
u32 new_y;
u32 new_w;
u32 new_h;
OrbisFontGlyphImageMetrics ImageMetrics;
};
struct OrbisFontMem;
using OrbisFontAllocFn = void*(void* object, u32 size);
using OrbisFontFreeFn = void(void* object, void* p);
using OrbisFontReallocFn = void*(void* object, void* p, u32 newSize);
using OrbisFontCallocFn = void*(void* object, u32 nBlock, u32 size);
using OrbisFontMspaceCreateFn = void*(void* parent, const char* name, void* address, u32 size,
u32 attr);
using OrbisFontMspaceDestroyFn = void(void* parent, void* mspace);
using OrbisFontMemDestroyFn = void(OrbisFontMem* fontMemory, void* object, void* destroyArg);
using OrbisFontAllocCb = OrbisFontAllocFn*;
using OrbisFontFreeCb = OrbisFontFreeFn*;
using OrbisFontReallocCb = OrbisFontReallocFn*;
using OrbisFontCallocCb = OrbisFontCallocFn*;
using OrbisFontMspaceCreateCb = OrbisFontMspaceCreateFn*;
using OrbisFontMspaceDestroyCb = OrbisFontMspaceDestroyFn*;
using OrbisFontMemDestroyCb = OrbisFontMemDestroyFn*;
struct OrbisFontMemInterface {
OrbisFontAllocCb alloc{};
OrbisFontFreeCb dealloc{};
OrbisFontReallocCb realloc_fn{};
OrbisFontCallocCb calloc_fn{};
OrbisFontMspaceCreateCb mspace_create{};
OrbisFontMspaceDestroyCb mspace_destroy{};
};
struct OrbisFontMem {
u16 mem_kind;
u16 attr_bits;
u32 region_size;
void* region_base;
void* mspace_handle;
const OrbisFontMemInterface* iface;
OrbisFontMemDestroyCb on_destroy;
void* destroy_ctx;
void* some_ctx1;
void* some_ctx2;
};
struct OrbisFontTextCharacter {
// Other fields...
struct OrbisFontTextCharacter* next; // Pointer to the next node 0x00
@ -28,33 +151,43 @@ struct OrbisFontRenderSurface {
void* buffer;
s32 widthByte;
s8 pixelSizeByte;
u8 unkn_0xd;
u8 pad0;
u8 styleFlag;
u8 unkn_0xf;
u8 pad2;
s32 width, height;
u32 sc_x0;
u32 sc_y0;
u32 sc_x1;
u32 sc_y1;
void* unkn_28[3];
u64 reserved_q[11];
};
#if INTPTR_MAX == INT64_MAX
static_assert(sizeof(OrbisFontRenderSurface) == 128, "OrbisFontRenderSurface ABI size");
#endif
struct OrbisFontStyleFrame {
/*0x00*/ u16 magic; // Expected to be 0xF09
/*0x02*/ u16 flags;
/*0x04*/ s32 dpiX; // DPI scaling factor for width
/*0x08*/ s32 dpiY; // DPI scaling factor for height
/*0x0c*/ s32 scalingFlag; // Indicates whether scaling is enabled
/*0x10*/
/*0x14*/ float scaleWidth; // Width scaling factor
/*0x18*/ float scaleHeight; // Height scaling factor
/*0x1c*/ float weightXScale;
/*0x20*/ float weightYScale;
/*0x24*/ float slantRatio;
/*0x10*/ float scaleWidth; // Width scaling factor
/*0x14*/ float scaleHeight; // Height scaling factor
/*0x18*/ float weightXScale;
/*0x1c*/ float weightYScale;
/*0x20*/ float slantRatio;
/*0x24*/
};
s32 PS4_SYSV_ABI sceFontAttachDeviceCacheBuffer();
s32 PS4_SYSV_ABI sceFontBindRenderer();
#if INTPTR_MAX == INT64_MAX
static_assert(sizeof(OrbisFontGlyphImageMetrics) == 24, "OrbisFontGlyphImageMetrics ABI size");
static_assert(sizeof(OrbisFontRenderOutput) == 64, "OrbisFontRenderOutput ABI size");
static_assert(sizeof(OrbisFontMem) == 64, "OrbisFontMem ABI size");
#endif
s32 PS4_SYSV_ABI sceFontAttachDeviceCacheBuffer(OrbisFontLib library, void* buffer, u32 size);
s32 PS4_SYSV_ABI sceFontBindRenderer(OrbisFontHandle fontHandle, OrbisFontRenderer renderer);
s32 PS4_SYSV_ABI sceFontCharacterGetBidiLevel(OrbisFontTextCharacter* textCharacter,
int* bidiLevel);
s32 PS4_SYSV_ABI sceFontCharacterGetSyllableStringState();
@ -75,9 +208,13 @@ s32 PS4_SYSV_ABI sceFontCreateGraphicsDevice();
s32 PS4_SYSV_ABI sceFontCreateGraphicsService();
s32 PS4_SYSV_ABI sceFontCreateGraphicsServiceWithEdition();
s32 PS4_SYSV_ABI sceFontCreateLibrary();
s32 PS4_SYSV_ABI sceFontCreateLibraryWithEdition();
s32 PS4_SYSV_ABI sceFontCreateLibraryWithEdition(const OrbisFontMem* memory,
OrbisFontLibCreateParams create_params,
u64 edition, OrbisFontLib* pLibrary);
s32 PS4_SYSV_ABI sceFontCreateRenderer();
s32 PS4_SYSV_ABI sceFontCreateRendererWithEdition();
s32 PS4_SYSV_ABI sceFontCreateRendererWithEdition(const OrbisFontMem* memory,
OrbisFontRendererCreateParams create_params,
u64 edition, OrbisFontRenderer* pRenderer);
s32 PS4_SYSV_ABI sceFontCreateString();
s32 PS4_SYSV_ABI sceFontCreateWords();
s32 PS4_SYSV_ABI sceFontCreateWritingLine();
@ -94,7 +231,8 @@ s32 PS4_SYSV_ABI sceFontDettachDeviceCacheBuffer();
s32 PS4_SYSV_ABI sceFontGenerateCharGlyph();
s32 PS4_SYSV_ABI sceFontGetAttribute();
s32 PS4_SYSV_ABI sceFontGetCharGlyphCode();
s32 PS4_SYSV_ABI sceFontGetCharGlyphMetrics();
s32 PS4_SYSV_ABI sceFontGetCharGlyphMetrics(OrbisFontHandle fontHandle, u32 code,
OrbisFontGlyphMetrics* metrics);
s32 PS4_SYSV_ABI sceFontGetEffectSlant();
s32 PS4_SYSV_ABI sceFontGetEffectWeight();
s32 PS4_SYSV_ABI sceFontGetFontGlyphsCount();
@ -104,8 +242,9 @@ s32 PS4_SYSV_ABI sceFontGetFontResolution();
s32 PS4_SYSV_ABI sceFontGetFontStyleInformation();
s32 PS4_SYSV_ABI sceFontGetGlyphExpandBufferState();
s32 PS4_SYSV_ABI sceFontGetHorizontalLayout();
s32 PS4_SYSV_ABI sceFontGetKerning();
s32 PS4_SYSV_ABI sceFontGetLibrary();
s32 PS4_SYSV_ABI sceFontGetKerning(OrbisFontHandle fontHandle, u32 preCode, u32 code,
OrbisFontKerning* kerning);
s32 PS4_SYSV_ABI sceFontGetLibrary(OrbisFontHandle fontHandle, OrbisFontLib* pLibrary);
s32 PS4_SYSV_ABI sceFontGetPixelResolution();
s32 PS4_SYSV_ABI sceFontGetRenderCharGlyphMetrics();
s32 PS4_SYSV_ABI sceFontGetRenderEffectSlant();
@ -114,7 +253,7 @@ s32 PS4_SYSV_ABI sceFontGetRenderScaledKerning();
s32 PS4_SYSV_ABI sceFontGetRenderScalePixel();
s32 PS4_SYSV_ABI sceFontGetRenderScalePoint();
s32 PS4_SYSV_ABI sceFontGetResolutionDpi();
s32 PS4_SYSV_ABI sceFontGetScalePixel();
s32 PS4_SYSV_ABI sceFontGetScalePixel(OrbisFontHandle fontHandle, float* w, float* h);
s32 PS4_SYSV_ABI sceFontGetScalePoint();
s32 PS4_SYSV_ABI sceFontGetScriptLanguage();
s32 PS4_SYSV_ABI sceFontGetTypographicDesign();
@ -182,15 +321,27 @@ s32 PS4_SYSV_ABI sceFontGraphicsUpdateRotation();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateScaling();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateShapeFill();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateShapeFillPlot();
s32 PS4_SYSV_ABI sceFontMemoryInit();
s32 PS4_SYSV_ABI sceFontMemoryInit(OrbisFontMem* fontMemory, void* address, u32 sizeByte,
const OrbisFontMemInterface* memInterface, void* mspaceObject,
OrbisFontMemDestroyCb destroyCallback, void* destroyObject);
s32 PS4_SYSV_ABI sceFontMemoryTerm();
s32 PS4_SYSV_ABI sceFontOpenFontFile();
s32 PS4_SYSV_ABI sceFontOpenFontInstance();
s32 PS4_SYSV_ABI sceFontOpenFontMemory();
s32 PS4_SYSV_ABI sceFontOpenFontSet();
s32 PS4_SYSV_ABI sceFontRebindRenderer();
s32 PS4_SYSV_ABI sceFontRenderCharGlyphImage();
s32 PS4_SYSV_ABI sceFontRenderCharGlyphImageHorizontal();
s32 PS4_SYSV_ABI sceFontOpenFontMemory(OrbisFontLib library, const void* fontAddress, u32 fontSize,
const OrbisFontOpenParams* open_params,
OrbisFontHandle* pFontHandle);
s32 PS4_SYSV_ABI sceFontOpenFontSet(OrbisFontLib library, u32 fontSetType, u32 openMode,
const OrbisFontOpenParams* open_params,
OrbisFontHandle* pFontHandle);
s32 PS4_SYSV_ABI sceFontRebindRenderer(OrbisFontHandle fontHandle);
s32 PS4_SYSV_ABI sceFontRenderCharGlyphImage(OrbisFontHandle fontHandle, u32 code,
OrbisFontRenderSurface* surf, float x, float y,
OrbisFontGlyphMetrics* metrics,
OrbisFontRenderOutput* result);
s32 PS4_SYSV_ABI sceFontRenderCharGlyphImageHorizontal(OrbisFontHandle fontHandle, u32 code,
OrbisFontRenderSurface* surf, float x,
float y, OrbisFontGlyphMetrics* metrics,
OrbisFontRenderOutput* result);
s32 PS4_SYSV_ABI sceFontRenderCharGlyphImageVertical();
s32 PS4_SYSV_ABI sceFontRendererGetOutlineBufferSize();
s32 PS4_SYSV_ABI sceFontRendererResetOutlineBuffer();
@ -206,13 +357,13 @@ s32 PS4_SYSV_ABI sceFontSetEffectSlant();
s32 PS4_SYSV_ABI sceFontSetEffectWeight();
s32 PS4_SYSV_ABI sceFontSetFontsOpenMode();
s32 PS4_SYSV_ABI sceFontSetResolutionDpi();
s32 PS4_SYSV_ABI sceFontSetScalePixel();
s32 PS4_SYSV_ABI sceFontSetScalePixel(OrbisFontHandle fontHandle, float w, float h);
s32 PS4_SYSV_ABI sceFontSetScalePoint();
s32 PS4_SYSV_ABI sceFontSetScriptLanguage();
s32 PS4_SYSV_ABI sceFontSetTypographicDesign();
s32 PS4_SYSV_ABI sceFontSetupRenderEffectSlant();
s32 PS4_SYSV_ABI sceFontSetupRenderEffectWeight();
s32 PS4_SYSV_ABI sceFontSetupRenderScalePixel();
s32 PS4_SYSV_ABI sceFontSetupRenderScalePixel(OrbisFontHandle fontHandle, float w, float h);
s32 PS4_SYSV_ABI sceFontSetupRenderScalePoint();
s32 PS4_SYSV_ABI sceFontStringGetTerminateCode();
s32 PS4_SYSV_ABI sceFontStringGetTerminateOrder();
@ -237,16 +388,16 @@ s32 PS4_SYSV_ABI sceFontStyleFrameSetScalePoint();
s32 PS4_SYSV_ABI sceFontStyleFrameUnsetEffectSlant();
s32 PS4_SYSV_ABI sceFontStyleFrameUnsetEffectWeight();
s32 PS4_SYSV_ABI sceFontStyleFrameUnsetScale();
s32 PS4_SYSV_ABI sceFontSupportExternalFonts();
s32 PS4_SYSV_ABI sceFontSupportExternalFonts(OrbisFontLib library, u32 fontMax, u32 formats);
s32 PS4_SYSV_ABI sceFontSupportGlyphs();
s32 PS4_SYSV_ABI sceFontSupportSystemFonts();
s32 PS4_SYSV_ABI sceFontSupportSystemFonts(OrbisFontLib library);
s32 PS4_SYSV_ABI sceFontTextCodesStepBack();
s32 PS4_SYSV_ABI sceFontTextCodesStepNext();
s32 PS4_SYSV_ABI sceFontTextSourceInit();
s32 PS4_SYSV_ABI sceFontTextSourceRewind();
s32 PS4_SYSV_ABI sceFontTextSourceSetDefaultFont();
s32 PS4_SYSV_ABI sceFontTextSourceSetWritingForm();
s32 PS4_SYSV_ABI sceFontUnbindRenderer();
s32 PS4_SYSV_ABI sceFontUnbindRenderer(OrbisFontHandle fontHandle);
s32 PS4_SYSV_ABI sceFontWordsFindWordCharacters();
s32 PS4_SYSV_ABI sceFontWritingGetRenderMetrics();
s32 PS4_SYSV_ABI sceFontWritingInit();
@ -296,4 +447,4 @@ s32 PS4_SYSV_ABI Func_FE4788A96EF46256();
s32 PS4_SYSV_ABI Func_FE7E5AE95D3058F5();
void RegisterlibSceFont(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Font
} // namespace Libraries::Font